Merge "Tear down VolumeDialogImplTest cleanly" into udc-qpr-dev
diff --git a/core/java/Android.bp b/core/java/Android.bp
index f8f4cc3..236d0b5 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -34,6 +34,15 @@
 }
 
 filegroup {
+    name: "feature_flags_aidl",
+    srcs: [
+        "android/flags/IFeatureFlags.aidl",
+        "android/flags/IFeatureFlagsCallback.aidl",
+        "android/flags/SyncableFlag.aidl",
+    ],
+}
+
+filegroup {
     name: "ITracingServiceProxy.aidl",
     srcs: ["android/tracing/ITracingServiceProxy.aidl"],
 }
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 4c90d7b..41c58ef 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4230,21 +4230,22 @@
         decorView.addView(view);
         view.requestLayout();
 
-        view.getViewTreeObserver().addOnDrawListener(new ViewTreeObserver.OnDrawListener() {
+        view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
             private boolean mHandled = false;
             @Override
-            public void onDraw() {
+            public boolean onPreDraw() {
                 if (mHandled) {
-                    return;
+                    return true;
                 }
                 mHandled = true;
                 // Transfer the splash screen view from shell to client.
-                // Call syncTransferSplashscreenViewTransaction at the first onDraw so we can ensure
-                // the client view is ready to show and we can use applyTransactionOnDraw to make
-                // all transitions happen at the same frame.
+                // Call syncTransferSplashscreenViewTransaction at the first onPreDraw, so we can
+                // ensure the client view is ready to show, and can use applyTransactionOnDraw to
+                // make all transitions happen at the same frame.
                 syncTransferSplashscreenViewTransaction(
                         view, r.token, decorView, startingWindowLeash);
-                view.post(() -> view.getViewTreeObserver().removeOnDrawListener(this));
+                view.post(() -> view.getViewTreeObserver().removeOnPreDrawListener(this));
+                return true;
             }
         });
     }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 8d2394b..44068dd 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -2171,6 +2171,10 @@
             }
         }
 
+        private void visitUris(@NonNull Consumer<Uri> visitor) {
+            visitIconUri(visitor, getIcon());
+        }
+
         @Override
         public Action clone() {
             return new Action(
@@ -2858,7 +2862,7 @@
 
         if (actions != null) {
             for (Action action : actions) {
-                visitIconUri(visitor, action.getIcon());
+                action.visitUris(visitor);
             }
         }
 
@@ -2939,6 +2943,11 @@
         if (mBubbleMetadata != null) {
             visitIconUri(visitor, mBubbleMetadata.getIcon());
         }
+
+        if (extras != null && extras.containsKey(WearableExtender.EXTRA_WEARABLE_EXTENSIONS)) {
+            WearableExtender extender = new WearableExtender(this);
+            extender.visitUris(visitor);
+        }
     }
 
     /**
@@ -3038,10 +3047,9 @@
         // cannot look into the extras as there may be parcelables there that
         // the platform does not know how to handle. To go around that we have
         // an explicit list of the pending intents in the extras bundle.
-        final boolean collectPendingIntents = (allPendingIntents == null);
-        if (collectPendingIntents) {
-            PendingIntent.setOnMarshaledListener(
-                    (PendingIntent intent, Parcel out, int outFlags) -> {
+        PendingIntent.OnMarshaledListener addedListener = null;
+        if (allPendingIntents == null) {
+            addedListener = (PendingIntent intent, Parcel out, int outFlags) -> {
                 if (parcel == out) {
                     synchronized (this) {
                         if (allPendingIntents == null) {
@@ -3050,7 +3058,8 @@
                         allPendingIntents.add(intent);
                     }
                 }
-            });
+            };
+            PendingIntent.addOnMarshaledListener(addedListener);
         }
         try {
             // IMPORTANT: Add marshaling code in writeToParcelImpl as we
@@ -3061,8 +3070,8 @@
                 parcel.writeArraySet(allPendingIntents);
             }
         } finally {
-            if (collectPendingIntents) {
-                PendingIntent.setOnMarshaledListener(null);
+            if (addedListener != null) {
+                PendingIntent.removeOnMarshaledListener(addedListener);
             }
         }
     }
@@ -3468,8 +3477,11 @@
      *
      * @hide
      */
-    public void setAllowlistToken(@Nullable IBinder token) {
-        mAllowlistToken = token;
+    public void clearAllowlistToken() {
+        mAllowlistToken = null;
+        if (publicVersion != null) {
+            publicVersion.clearAllowlistToken();
+        }
     }
 
     /**
@@ -11715,6 +11727,12 @@
                 mFlags &= ~mask;
             }
         }
+
+        private void visitUris(@NonNull Consumer<Uri> visitor) {
+            for (Action action : mActions) {
+                action.visitUris(visitor);
+            }
+        }
     }
 
     /**
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index 705b5ee..c7522b4 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -64,6 +64,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
@@ -391,11 +392,12 @@
         void onMarshaled(PendingIntent intent, Parcel parcel, int flags);
     }
 
-    private static final ThreadLocal<OnMarshaledListener> sOnMarshaledListener
-            = new ThreadLocal<>();
+    private static final ThreadLocal<List<OnMarshaledListener>> sOnMarshaledListener =
+            ThreadLocal.withInitial(ArrayList::new);
 
     /**
-     * Registers an listener for pending intents being written to a parcel.
+     * Registers an listener for pending intents being written to a parcel. This replaces any
+     * listeners previously added.
      *
      * @param listener The listener, null to clear.
      *
@@ -403,7 +405,27 @@
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public static void setOnMarshaledListener(OnMarshaledListener listener) {
-        sOnMarshaledListener.set(listener);
+        final List<OnMarshaledListener> listeners = sOnMarshaledListener.get();
+        listeners.clear();
+        if (listener != null) {
+            listeners.add(listener);
+        }
+    }
+
+    /**
+     * Adds a listener for pending intents being written to a parcel.
+     * @hide
+     */
+    static void addOnMarshaledListener(OnMarshaledListener listener) {
+        sOnMarshaledListener.get().add(listener);
+    }
+
+    /**
+     * Removes a listener for pending intents being written to a parcel.
+     * @hide
+     */
+    static void removeOnMarshaledListener(OnMarshaledListener listener) {
+        sOnMarshaledListener.get().remove(listener);
     }
 
     private static void checkPendingIntent(int flags, @NonNull Intent intent,
@@ -1451,11 +1473,11 @@
 
     public void writeToParcel(Parcel out, int flags) {
         out.writeStrongBinder(mTarget.asBinder());
-        OnMarshaledListener listener = sOnMarshaledListener.get();
-        if (listener != null) {
-            listener.onMarshaled(this, out, flags);
+        final List<OnMarshaledListener> listeners = sOnMarshaledListener.get();
+        final int numListeners = listeners.size();
+        for (int i = 0; i < numListeners; i++) {
+            listeners.get(i).onMarshaled(this, out, flags);
         }
-
     }
 
     public static final @NonNull Creator<PendingIntent> CREATOR = new Creator<PendingIntent>() {
@@ -1483,9 +1505,10 @@
             @NonNull Parcel out) {
         out.writeStrongBinder(sender != null ? sender.mTarget.asBinder() : null);
         if (sender != null) {
-            OnMarshaledListener listener = sOnMarshaledListener.get();
-            if (listener != null) {
-                listener.onMarshaled(sender, out, 0 /* flags */);
+            final List<OnMarshaledListener> listeners = sOnMarshaledListener.get();
+            final int numListeners = listeners.size();
+            for (int i = 0; i < numListeners; i++) {
+                listeners.get(i).onMarshaled(sender, out, 0 /* flags */);
             }
         }
     }
diff --git a/core/java/android/app/UiModeManager.java b/core/java/android/app/UiModeManager.java
index d90257a..0ccb9cd 100644
--- a/core/java/android/app/UiModeManager.java
+++ b/core/java/android/app/UiModeManager.java
@@ -315,7 +315,7 @@
     @SystemApi
     public static final int MODE_NIGHT_CUSTOM_TYPE_BEDTIME = 1;
 
-    private IUiModeManager mService;
+    private static Globals sGlobals;
 
     /**
      * Context required for getting the opPackageName of API caller; maybe be {@code null} if the
@@ -341,6 +341,60 @@
             mOnProjectionStateChangedListenerResourceManager =
             new OnProjectionStateChangedListenerResourceManager();
 
+    private static class Globals extends IUiModeManagerCallback.Stub {
+
+        private final IUiModeManager mService;
+        private final Object mGlobalsLock = new Object();
+
+        private float mContrast = ContrastUtils.CONTRAST_DEFAULT_VALUE;
+
+        /**
+         * Map that stores user provided {@link ContrastChangeListener} callbacks,
+         * and the executors on which these callbacks should be called.
+         */
+        private final ArrayMap<ContrastChangeListener, Executor>
+                mContrastChangeListeners = new ArrayMap<>();
+
+        Globals(IUiModeManager service) {
+            mService = service;
+            try {
+                mService.addCallback(this);
+                mContrast = mService.getContrast();
+            } catch (RemoteException e) {
+                Log.e(TAG, "Setup failed: UiModeManagerService is dead", e);
+            }
+        }
+
+        private float getContrast() {
+            synchronized (mGlobalsLock) {
+                return mContrast;
+            }
+        }
+
+        private void addContrastChangeListener(ContrastChangeListener listener, Executor executor) {
+            synchronized (mGlobalsLock) {
+                mContrastChangeListeners.put(listener, executor);
+            }
+        }
+
+        private void removeContrastChangeListener(ContrastChangeListener listener) {
+            synchronized (mGlobalsLock) {
+                mContrastChangeListeners.remove(listener);
+            }
+        }
+
+        @Override
+        public void notifyContrastChanged(float contrast) {
+            synchronized (mGlobalsLock) {
+                // if value changed in the settings, update the cached value and notify listeners
+                if (Math.abs(mContrast - contrast) < 1e-10) return;
+                mContrast = contrast;
+                mContrastChangeListeners.forEach((listener, executor) -> executor.execute(
+                        () -> listener.onContrastChanged(contrast)));
+            }
+        }
+    }
+
     /**
      * Define constants and conversions between {@link ContrastLevel}s and contrast values.
      * <p>
@@ -407,43 +461,18 @@
         }
     }
 
-    /**
-     * Map that stores user provided {@link ContrastChangeListener} callbacks,
-     * and the executors on which these callbacks should be called.
-     */
-    private final ArrayMap<ContrastChangeListener, Executor>
-            mContrastChangeListeners = new ArrayMap<>();
-    private float mContrast;
-
-    private final IUiModeManagerCallback.Stub mCallback = new IUiModeManagerCallback.Stub() {
-        @Override
-        public void notifyContrastChanged(float contrast) {
-            final ArrayMap<ContrastChangeListener, Executor> listeners;
-            synchronized (mLock) {
-                // if value changed in the settings, update the cached value and notify listeners
-                if (Math.abs(mContrast - contrast) < 1e-10) return;
-                mContrast = contrast;
-                listeners = new ArrayMap<>(mContrastChangeListeners);
-            }
-            listeners.forEach((listener, executor) -> executor.execute(
-                    () -> listener.onContrastChanged(mContrast)));
-        }
-    };
-
     @UnsupportedAppUsage
     /*package*/ UiModeManager() throws ServiceNotFoundException {
         this(null /* context */);
     }
 
     /*package*/ UiModeManager(Context context) throws ServiceNotFoundException {
-        mService = IUiModeManager.Stub.asInterface(
+        IUiModeManager service = IUiModeManager.Stub.asInterface(
                 ServiceManager.getServiceOrThrow(Context.UI_MODE_SERVICE));
         mContext = context;
-        try {
-            mService.addCallback(mCallback);
-            mContrast = mService.getContrast();
-        } catch (RemoteException e) {
-            Log.e(TAG, "Setup failed: UiModeManagerService is dead", e);
+        if (service == null) return;
+        synchronized (mLock) {
+            if (sGlobals == null) sGlobals = new Globals(service);
         }
     }
 
@@ -533,9 +562,9 @@
     @SystemApi
     @RequiresPermission(android.Manifest.permission.ENTER_CAR_MODE_PRIORITIZED)
     public void enableCarMode(@IntRange(from = 0) int priority, @EnableCarMode int flags) {
-        if (mService != null) {
+        if (sGlobals != null) {
             try {
-                mService.enableCarMode(flags, priority,
+                sGlobals.mService.enableCarMode(flags, priority,
                         mContext == null ? null : mContext.getOpPackageName());
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
@@ -585,9 +614,9 @@
      * @param flags One of the disable car mode flags.
      */
     public void disableCarMode(@DisableCarMode int flags) {
-        if (mService != null) {
+        if (sGlobals != null) {
             try {
-                mService.disableCarModeByCallingPackage(flags,
+                sGlobals.mService.disableCarModeByCallingPackage(flags,
                         mContext == null ? null : mContext.getOpPackageName());
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
@@ -606,9 +635,9 @@
      * {@link Configuration#UI_MODE_TYPE_VR_HEADSET Configuration.UI_MODE_TYPE_VR_HEADSET}.
      */
     public int getCurrentModeType() {
-        if (mService != null) {
+        if (sGlobals != null) {
             try {
-                return mService.getCurrentModeType();
+                return sGlobals.mService.getCurrentModeType();
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -653,9 +682,9 @@
      * @see #setApplicationNightMode(int)
      */
     public void setNightMode(@NightMode int mode) {
-        if (mService != null) {
+        if (sGlobals != null) {
             try {
-                mService.setNightMode(mode);
+                sGlobals.mService.setNightMode(mode);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -674,9 +703,9 @@
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_DAY_NIGHT_MODE)
     public void setNightModeCustomType(@NightModeCustomType int nightModeCustomType) {
-        if (mService != null) {
+        if (sGlobals != null) {
             try {
-                mService.setNightModeCustomType(nightModeCustomType);
+                sGlobals.mService.setNightModeCustomType(nightModeCustomType);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -693,9 +722,9 @@
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_DAY_NIGHT_MODE)
     public @NightModeCustomReturnType int getNightModeCustomType() {
-        if (mService != null) {
+        if (sGlobals != null) {
             try {
-                return mService.getNightModeCustomType();
+                return sGlobals.mService.getNightModeCustomType();
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -732,9 +761,9 @@
      * @see #setNightMode(int)
      */
     public void setApplicationNightMode(@NightMode int mode) {
-        if (mService != null) {
+        if (sGlobals != null) {
             try {
-                mService.setApplicationNightMode(mode);
+                sGlobals.mService.setApplicationNightMode(mode);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -757,9 +786,9 @@
      * @see #setNightMode(int)
      */
     public @NightMode int getNightMode() {
-        if (mService != null) {
+        if (sGlobals != null) {
             try {
-                return mService.getNightMode();
+                return sGlobals.mService.getNightMode();
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -774,9 +803,9 @@
      */
     @TestApi
     public boolean isUiModeLocked() {
-        if (mService != null) {
+        if (sGlobals != null) {
             try {
-                return mService.isUiModeLocked();
+                return sGlobals.mService.isUiModeLocked();
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -796,9 +825,9 @@
      */
     @TestApi
     public boolean isNightModeLocked() {
-        if (mService != null) {
+        if (sGlobals != null) {
             try {
-                return mService.isNightModeLocked();
+                return sGlobals.mService.isNightModeLocked();
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -820,9 +849,10 @@
     @RequiresPermission(android.Manifest.permission.MODIFY_DAY_NIGHT_MODE)
     public boolean setNightModeActivatedForCustomMode(@NightModeCustomType int nightModeCustomType,
             boolean active) {
-        if (mService != null) {
+        if (sGlobals != null) {
             try {
-                return mService.setNightModeActivatedForCustomMode(nightModeCustomType, active);
+                return sGlobals.mService.setNightModeActivatedForCustomMode(
+                        nightModeCustomType, active);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -838,9 +868,9 @@
      */
     @RequiresPermission(android.Manifest.permission.MODIFY_DAY_NIGHT_MODE)
     public boolean setNightModeActivated(boolean active) {
-        if (mService != null) {
+        if (sGlobals != null) {
             try {
-                return mService.setNightModeActivated(active);
+                return sGlobals.mService.setNightModeActivated(active);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -856,9 +886,9 @@
      */
     @NonNull
     public LocalTime getCustomNightModeStart() {
-        if (mService != null) {
+        if (sGlobals != null) {
             try {
-                return LocalTime.ofNanoOfDay(mService.getCustomNightModeStart() * 1000);
+                return LocalTime.ofNanoOfDay(sGlobals.mService.getCustomNightModeStart() * 1000);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -874,9 +904,9 @@
      * @param time The time of the day Dark theme should activate
      */
     public void setCustomNightModeStart(@NonNull LocalTime time) {
-        if (mService != null) {
+        if (sGlobals != null) {
             try {
-                mService.setCustomNightModeStart(time.toNanoOfDay() / 1000);
+                sGlobals.mService.setCustomNightModeStart(time.toNanoOfDay() / 1000);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -891,9 +921,9 @@
      */
     @NonNull
     public LocalTime getCustomNightModeEnd() {
-        if (mService != null) {
+        if (sGlobals != null) {
             try {
-                return LocalTime.ofNanoOfDay(mService.getCustomNightModeEnd() * 1000);
+                return LocalTime.ofNanoOfDay(sGlobals.mService.getCustomNightModeEnd() * 1000);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -909,9 +939,9 @@
      * @param time The time of the day Dark theme should deactivate
      */
     public void setCustomNightModeEnd(@NonNull LocalTime time) {
-        if (mService != null) {
+        if (sGlobals != null) {
             try {
-                mService.setCustomNightModeEnd(time.toNanoOfDay() / 1000);
+                sGlobals.mService.setCustomNightModeEnd(time.toNanoOfDay() / 1000);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -976,9 +1006,9 @@
     @RequiresPermission(value = android.Manifest.permission.TOGGLE_AUTOMOTIVE_PROJECTION,
             conditional = true)
     public boolean requestProjection(@ProjectionType int projectionType) {
-        if (mService != null) {
+        if (sGlobals != null) {
             try {
-                return mService.requestProjection(new Binder(), projectionType,
+                return sGlobals.mService.requestProjection(new Binder(), projectionType,
                         mContext.getOpPackageName());
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
@@ -1005,9 +1035,10 @@
     @RequiresPermission(value = android.Manifest.permission.TOGGLE_AUTOMOTIVE_PROJECTION,
             conditional = true)
     public boolean releaseProjection(@ProjectionType int projectionType) {
-        if (mService != null) {
+        if (sGlobals != null) {
             try {
-                return mService.releaseProjection(projectionType, mContext.getOpPackageName());
+                return sGlobals.mService.releaseProjection(
+                        projectionType, mContext.getOpPackageName());
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -1028,9 +1059,9 @@
     @RequiresPermission(android.Manifest.permission.READ_PROJECTION_STATE)
     @NonNull
     public Set<String> getProjectingPackages(@ProjectionType int projectionType) {
-        if (mService != null) {
+        if (sGlobals != null) {
             try {
-                return new ArraySet<>(mService.getProjectingPackages(projectionType));
+                return new ArraySet<>(sGlobals.mService.getProjectingPackages(projectionType));
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -1046,9 +1077,9 @@
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PROJECTION_STATE)
     public @ProjectionType int getActiveProjectionTypes() {
-        if (mService != null) {
+        if (sGlobals != null) {
             try {
-                return mService.getActiveProjectionTypes();
+                return sGlobals.mService.getActiveProjectionTypes();
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -1076,11 +1107,12 @@
                 Slog.i(TAG, "Attempted to add listener that was already added.");
                 return;
             }
-            if (mService != null) {
+            if (sGlobals != null) {
                 InnerListener innerListener = new InnerListener(executor, listener,
                         mOnProjectionStateChangedListenerResourceManager);
                 try {
-                    mService.addOnProjectionStateChangedListener(innerListener, projectionType);
+                    sGlobals.mService.addOnProjectionStateChangedListener(
+                            innerListener, projectionType);
                     mProjectionStateListenerMap.put(listener, innerListener);
                 } catch (RemoteException e) {
                     mOnProjectionStateChangedListenerResourceManager.remove(innerListener);
@@ -1107,9 +1139,9 @@
                 Slog.i(TAG, "Attempted to remove listener that was not added.");
                 return;
             }
-            if (mService != null) {
+            if (sGlobals != null) {
                 try {
-                    mService.removeOnProjectionStateChangedListener(innerListener);
+                    sGlobals.mService.removeOnProjectionStateChangedListener(innerListener);
                 } catch (RemoteException e) {
                     throw e.rethrowFromSystemServer();
                 }
@@ -1197,15 +1229,10 @@
      *     <li>       -1 corresponds to the minimum contrast </li>
      *     <li> &nbsp; 1 corresponds to the maximum contrast </li>
      * </ul>
-     *
-     *
-     *
      */
     @FloatRange(from = -1.0f, to = 1.0f)
     public float getContrast() {
-        synchronized (mLock) {
-            return mContrast;
-        }
+        return sGlobals.getContrast();
     }
 
     /**
@@ -1219,9 +1246,7 @@
             @NonNull ContrastChangeListener listener) {
         Objects.requireNonNull(executor);
         Objects.requireNonNull(listener);
-        synchronized (mLock) {
-            mContrastChangeListeners.put(listener, executor);
-        }
+        sGlobals.addContrastChangeListener(listener, executor);
     }
 
     /**
@@ -1232,8 +1257,6 @@
      */
     public void removeContrastChangeListener(@NonNull ContrastChangeListener listener) {
         Objects.requireNonNull(listener);
-        synchronized (mLock) {
-            mContrastChangeListeners.remove(listener);
-        }
+        sGlobals.removeContrastChangeListener(listener);
     }
 }
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 6d82922..2a6d84b 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -5298,6 +5298,13 @@
     public static final String APP_PREDICTION_SERVICE = "app_prediction";
 
     /**
+     * Used for reading system-wide, overridable flags.
+     *
+     * @hide
+     */
+    public static final String FEATURE_FLAGS_SERVICE = "feature_flags";
+
+    /**
      * Official published name of the search ui service.
      *
      * <p><b>NOTE: </b> this service is optional; callers of
diff --git a/core/java/android/flags/BooleanFlag.java b/core/java/android/flags/BooleanFlag.java
new file mode 100644
index 0000000..d4a35b2
--- /dev/null
+++ b/core/java/android/flags/BooleanFlag.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 android.flags;
+
+import android.annotation.NonNull;
+
+/**
+ * A flag representing a true or false value.
+ *
+ * The value will always be the same during the lifetime of the process it is read in.
+ *
+ * @hide
+ */
+public class BooleanFlag extends BooleanFlagBase {
+    private final boolean mDefault;
+
+    /**
+     * @param namespace A namespace for this flag. See {@link android.provider.DeviceConfig}.
+     * @param name A name for this flag.
+     * @param defaultValue The value of this flag if no other override is present.
+     */
+    BooleanFlag(String namespace, String name, boolean defaultValue) {
+        super(namespace, name);
+        mDefault = defaultValue;
+    }
+
+    @Override
+    @NonNull
+    public Boolean getDefault() {
+        return mDefault;
+    }
+
+    @Override
+    public BooleanFlag defineMetaData(String label, String description, String categoryName) {
+        super.defineMetaData(label, description, categoryName);
+        return this;
+    }
+}
diff --git a/core/java/android/flags/BooleanFlagBase.java b/core/java/android/flags/BooleanFlagBase.java
new file mode 100644
index 0000000..985dbe3
--- /dev/null
+++ b/core/java/android/flags/BooleanFlagBase.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.flags;
+
+import android.annotation.NonNull;
+
+abstract class BooleanFlagBase implements Flag<Boolean> {
+
+    private final String mNamespace;
+    private final String mName;
+    private String mLabel;
+    private String mDescription;
+    private String mCategoryName;
+
+    /**
+     * @param namespace A namespace for this flag. See {@link android.provider.DeviceConfig}.
+     * @param name A name for this flag.
+     */
+    BooleanFlagBase(String namespace, String name) {
+        mNamespace = namespace;
+        mName = name;
+        mLabel = name;
+    }
+
+    public abstract Boolean getDefault();
+
+    @Override
+    @NonNull
+    public String getNamespace() {
+        return mNamespace;
+    }
+
+    @Override
+    @NonNull
+    public String getName() {
+        return mName;
+    }
+
+    @Override
+    public BooleanFlagBase defineMetaData(String label, String description, String categoryName) {
+        mLabel = label;
+        mDescription = description;
+        mCategoryName = categoryName;
+        return this;
+    }
+
+    @Override
+    @NonNull
+    public String getLabel() {
+        return mLabel;
+    }
+
+    @Override
+    public String getDescription() {
+        return mDescription;
+    }
+
+    @Override
+    public String getCategoryName() {
+        return mCategoryName;
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        return getNamespace() + "." + getName() + "[" + getDefault() + "]";
+    }
+}
diff --git a/core/java/android/flags/DynamicBooleanFlag.java b/core/java/android/flags/DynamicBooleanFlag.java
new file mode 100644
index 0000000..271a8c5f4
--- /dev/null
+++ b/core/java/android/flags/DynamicBooleanFlag.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.flags;
+
+/**
+ * A flag representing a true or false value.
+ *
+ * The value may be different from one read to the next.
+ *
+ * @hide
+ */
+public class DynamicBooleanFlag extends BooleanFlagBase implements DynamicFlag<Boolean> {
+
+    private final boolean mDefault;
+
+    /**
+     * @param namespace A namespace for this flag. See {@link android.provider.DeviceConfig}.
+     * @param name A name for this flag.
+     * @param defaultValue The value of this flag if no other override is present.
+     */
+    DynamicBooleanFlag(String namespace, String name, boolean defaultValue) {
+        super(namespace, name);
+        mDefault = defaultValue;
+    }
+
+    @Override
+    public Boolean getDefault() {
+        return mDefault;
+    }
+
+    @Override
+    public DynamicBooleanFlag defineMetaData(String label, String description, String categoryName) {
+        super.defineMetaData(label, description, categoryName);
+        return this;
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/fragment/src/main/java/org/robolectric/shadows/androidx/fragment/package-info.java b/core/java/android/flags/DynamicFlag.java
similarity index 66%
copy from packages/SettingsLib/tests/robotests/fragment/src/main/java/org/robolectric/shadows/androidx/fragment/package-info.java
copy to core/java/android/flags/DynamicFlag.java
index dd89441..68819c5 100644
--- a/packages/SettingsLib/tests/robotests/fragment/src/main/java/org/robolectric/shadows/androidx/fragment/package-info.java
+++ b/core/java/android/flags/DynamicFlag.java
@@ -14,10 +14,18 @@
  * limitations under the License.
  */
 
+package android.flags;
+
 /**
- * Testing infrastructure for androidx.fragment library.
+ * A flag for which the value may be different from one read to the next.
  *
- * <p>To use this in your project, add the artifact {@code
- * org.robolectric:shadows-androidx-fragment} to your project.
+ * @param <T> The type of value that this flag stores. E.g. Boolean or String.
+ *
+ * @hide
  */
-package org.robolectric.shadows.androidx.fragment;
+public interface DynamicFlag<T> extends Flag<T> {
+    @Override
+    default boolean isDynamic() {
+        return true;
+    }
+}
diff --git a/core/java/android/flags/FeatureFlags.java b/core/java/android/flags/FeatureFlags.java
new file mode 100644
index 0000000..8d3112c
--- /dev/null
+++ b/core/java/android/flags/FeatureFlags.java
@@ -0,0 +1,379 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.flags;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.ArraySet;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A class for querying constants from the system - primarily booleans.
+ *
+ * Clients using this class can define their flags and their default values in one place,
+ * can override those values on running devices for debugging and testing purposes, and can control
+ * what flags are available to be used on release builds.
+ *
+ * TODO(b/279054964): A lot. This is skeleton code right now.
+ * @hide
+ */
+public class FeatureFlags {
+    private static final String TAG = "FeatureFlags";
+    private static FeatureFlags sInstance;
+    private static final Object sInstanceLock = new Object();
+
+    private final Set<Flag<?>> mKnownFlags = new ArraySet<>();
+    private final Set<Flag<?>> mDirtyFlags = new ArraySet<>();
+
+    private IFeatureFlags mIFeatureFlags;
+    private final Map<String, Map<String, Boolean>> mBooleanOverrides = new HashMap<>();
+    private final Set<ChangeListener> mListeners = new HashSet<>();
+
+    /**
+     * Obtain a per-process instance of FeatureFlags.
+     * @return A singleton instance of {@link FeatureFlags}.
+     */
+    @NonNull
+    public static FeatureFlags getInstance() {
+        synchronized (sInstanceLock) {
+            if (sInstance == null) {
+                sInstance = new FeatureFlags();
+            }
+        }
+
+        return sInstance;
+    }
+
+    /** See {@link FeatureFlagsFake}. */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    public static void setInstance(FeatureFlags instance) {
+        synchronized (sInstanceLock) {
+            sInstance = instance;
+        }
+    }
+
+    private final IFeatureFlagsCallback mIFeatureFlagsCallback = new IFeatureFlagsCallback.Stub() {
+        @Override
+        public void onFlagChange(SyncableFlag flag) {
+            for (Flag<?> f : mKnownFlags) {
+                if (flagEqualsSyncableFlag(f, flag)) {
+                    if (f instanceof DynamicFlag<?>) {
+                        if (f instanceof DynamicBooleanFlag) {
+                            String value = flag.getValue();
+                            if (value == null) {  // Null means any existing overrides were erased.
+                                value = ((DynamicBooleanFlag) f).getDefault().toString();
+                            }
+                            addBooleanOverride(flag.getNamespace(), flag.getName(), value);
+                        }
+                        FeatureFlags.this.onFlagChange((DynamicFlag<?>) f);
+                    }
+                    break;
+                }
+            }
+        }
+    };
+
+    private FeatureFlags() {
+        this(null);
+    }
+
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    public FeatureFlags(IFeatureFlags iFeatureFlags) {
+        mIFeatureFlags = iFeatureFlags;
+
+        if (mIFeatureFlags != null) {
+            try {
+                mIFeatureFlags.registerCallback(mIFeatureFlagsCallback);
+            } catch (RemoteException e) {
+                // Shouldn't happen with things passed into tests.
+                Log.e(TAG, "Could not register callbacks!", e);
+            }
+        }
+    }
+
+    /**
+     * Construct a new {@link BooleanFlag}.
+     *
+     * Use this instead of constructing a {@link BooleanFlag} directly, as it registers the flag
+     * with the internals of the flagging system.
+     */
+    @NonNull
+    public static BooleanFlag booleanFlag(
+            @NonNull String namespace, @NonNull String name, boolean def) {
+        return getInstance().addFlag(new BooleanFlag(namespace, name, def));
+    }
+
+    /**
+     * Construct a new {@link FusedOffFlag}.
+     *
+     * Use this instead of constructing a {@link FusedOffFlag} directly, as it registers the
+     * flag with the internals of the flagging system.
+     */
+    @NonNull
+    public static FusedOffFlag fusedOffFlag(@NonNull String namespace, @NonNull String name) {
+        return getInstance().addFlag(new FusedOffFlag(namespace, name));
+    }
+
+    /**
+     * Construct a new {@link FusedOnFlag}.
+     *
+     * Use this instead of constructing a {@link FusedOnFlag} directly, as it registers the flag
+     * with the internals of the flagging system.
+     */
+    @NonNull
+    public static FusedOnFlag fusedOnFlag(@NonNull String namespace, @NonNull String name) {
+        return getInstance().addFlag(new FusedOnFlag(namespace, name));
+    }
+
+    /**
+     * Construct a new {@link DynamicBooleanFlag}.
+     *
+     * Use this instead of constructing a {@link DynamicBooleanFlag} directly, as it registers
+     * the flag with the internals of the flagging system.
+     */
+    @NonNull
+    public static DynamicBooleanFlag dynamicBooleanFlag(
+            @NonNull String namespace, @NonNull String name, boolean def) {
+        return getInstance().addFlag(new DynamicBooleanFlag(namespace, name, def));
+    }
+
+    /**
+     * Add a listener to be alerted when a {@link DynamicFlag} changes.
+     *
+     * See also {@link #removeChangeListener(ChangeListener)}.
+     *
+     * @param listener The listener to add.
+     */
+    public void addChangeListener(@NonNull ChangeListener listener) {
+        mListeners.add(listener);
+    }
+
+    /**
+     * Remove a listener that was added earlier.
+     *
+     * See also {@link #addChangeListener(ChangeListener)}.
+     *
+     * @param listener The listener to remove.
+     */
+    public void removeChangeListener(@NonNull ChangeListener listener) {
+        mListeners.remove(listener);
+    }
+
+    protected void onFlagChange(@NonNull DynamicFlag<?> flag) {
+        for (ChangeListener l : mListeners) {
+            l.onFlagChanged(flag);
+        }
+    }
+
+    /**
+     * Returns whether the supplied flag is true or not.
+     *
+     * {@link BooleanFlag} should only be used in debug builds. They do not get optimized out.
+     *
+     * The first time a flag is read, its value is cached for the lifetime of the process.
+     */
+    public boolean isEnabled(@NonNull BooleanFlag flag) {
+        return getBooleanInternal(flag);
+    }
+
+    /**
+     * Returns whether the supplied flag is true or not.
+     *
+     * Always returns false.
+     */
+    public boolean isEnabled(@NonNull FusedOffFlag flag) {
+        return false;
+    }
+
+    /**
+     * Returns whether the supplied flag is true or not.
+     *
+     * Always returns true;
+     */
+    public boolean isEnabled(@NonNull FusedOnFlag flag) {
+        return true;
+    }
+
+    /**
+     * Returns whether the supplied flag is true or not.
+     *
+     * Can return a different value for the flag each time it is called if an override comes in.
+     */
+    public boolean isCurrentlyEnabled(@NonNull DynamicBooleanFlag flag) {
+        return getBooleanInternal(flag);
+    }
+
+    private boolean getBooleanInternal(Flag<Boolean> flag) {
+        sync();
+        Map<String, Boolean> ns = mBooleanOverrides.get(flag.getNamespace());
+        Boolean value = null;
+        if (ns != null) {
+            value = ns.get(flag.getName());
+        }
+        if (value == null) {
+            throw new IllegalStateException("Boolean flag being read but was not synced: " + flag);
+        }
+
+        return value;
+    }
+
+    private <T extends Flag<?>> T addFlag(T flag)  {
+        synchronized (FeatureFlags.class) {
+            mDirtyFlags.add(flag);
+            mKnownFlags.add(flag);
+        }
+        return flag;
+    }
+
+    /**
+     * Sync any known flags that have not yet been synced.
+     *
+     * This is called implicitly when any flag is read, and is not generally needed except in
+     * exceptional circumstances.
+     */
+    public void sync() {
+        synchronized (FeatureFlags.class) {
+            if (mDirtyFlags.isEmpty()) {
+                return;
+            }
+            syncInternal(mDirtyFlags);
+            mDirtyFlags.clear();
+        }
+    }
+
+    /**
+     * Called when new flags have been declared. Gives the implementation a chance to act on them.
+     *
+     * Guaranteed to be called from a synchronized, thread-safe context.
+     */
+    protected void syncInternal(Set<Flag<?>> dirtyFlags) {
+        IFeatureFlags iFeatureFlags = bind();
+        List<SyncableFlag> syncableFlags = new ArrayList<>();
+        for (Flag<?> f : dirtyFlags) {
+            syncableFlags.add(flagToSyncableFlag(f));
+        }
+
+        List<SyncableFlag> serverFlags = List.of();  // Need to initialize the list with something.
+        try {
+            // New values come back from the service.
+            serverFlags = iFeatureFlags.syncFlags(syncableFlags);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+
+        for (Flag<?> f : dirtyFlags) {
+            boolean found = false;
+            for (SyncableFlag sf : serverFlags) {
+                if (flagEqualsSyncableFlag(f, sf)) {
+                    if (f instanceof BooleanFlag || f instanceof DynamicBooleanFlag) {
+                        addBooleanOverride(sf.getNamespace(), sf.getName(), sf.getValue());
+                    }
+                    found = true;
+                    break;
+                }
+            }
+            if (!found) {
+                if (f instanceof BooleanFlag) {
+                    addBooleanOverride(
+                            f.getNamespace(),
+                            f.getName(),
+                            ((BooleanFlag) f).getDefault() ? "true" : "false");
+                }
+            }
+        }
+    }
+
+    private void addBooleanOverride(String namespace, String name, String override) {
+        Map<String, Boolean> nsOverrides = mBooleanOverrides.get(namespace);
+        if (nsOverrides == null) {
+            nsOverrides = new HashMap<>();
+            mBooleanOverrides.put(namespace, nsOverrides);
+        }
+        nsOverrides.put(name, parseBoolean(override));
+    }
+
+    private SyncableFlag flagToSyncableFlag(Flag<?> f) {
+        return new SyncableFlag(
+                f.getNamespace(),
+                f.getName(),
+                f.getDefault().toString(),
+                f instanceof DynamicFlag<?>);
+    }
+
+    private IFeatureFlags bind() {
+        if (mIFeatureFlags == null) {
+            mIFeatureFlags = IFeatureFlags.Stub.asInterface(
+                    ServiceManager.getService(Context.FEATURE_FLAGS_SERVICE));
+            try {
+                mIFeatureFlags.registerCallback(mIFeatureFlagsCallback);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to listen for flag changes!");
+            }
+        }
+
+        return mIFeatureFlags;
+    }
+
+    static boolean parseBoolean(String value) {
+        // Check for a truish string.
+        boolean result = value.equalsIgnoreCase("true")
+                || value.equals("1")
+                || value.equalsIgnoreCase("t")
+                || value.equalsIgnoreCase("on");
+        if (!result) {  // Expect a falsish string, else log an error.
+            if (!(value.equalsIgnoreCase("false")
+                    || value.equals("0")
+                    || value.equalsIgnoreCase("f")
+                    || value.equalsIgnoreCase("off"))) {
+                Log.e(TAG,
+                        "Tried parsing " + value + " as boolean but it doesn't look like one. "
+                                + "Value expected to be one of true|false, 1|0, t|f, on|off.");
+            }
+        }
+        return result;
+    }
+
+    private static boolean flagEqualsSyncableFlag(Flag<?> f, SyncableFlag sf) {
+        return f.getName().equals(sf.getName()) && f.getNamespace().equals(sf.getNamespace());
+    }
+
+
+    /**
+     * A simpler listener that is alerted when a {@link DynamicFlag} changes.
+     *
+     * See {@link #addChangeListener(ChangeListener)}
+     */
+    public interface ChangeListener {
+        /**
+         * Called when a {@link DynamicFlag} changes.
+         *
+         * @param flag The flag that has changed.
+         */
+        void onFlagChanged(DynamicFlag<?> flag);
+    }
+}
diff --git a/core/java/android/flags/FeatureFlagsFake.java b/core/java/android/flags/FeatureFlagsFake.java
new file mode 100644
index 0000000..daedcda
--- /dev/null
+++ b/core/java/android/flags/FeatureFlagsFake.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.flags;
+
+import android.annotation.NonNull;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * An implementation of {@link FeatureFlags} for testing.
+ *
+ * Before you read a flag from using this Fake, you must set that flag using
+ * {@link #setFlagValue(BooleanFlagBase, boolean)}. This ensures that your tests are deterministic.
+ *
+ * If you are relying on {@link FeatureFlags#getInstance()} to access FeatureFlags in your code
+ * under test, (instead of dependency injection), you can pass an instance of this fake to
+ * {@link FeatureFlags#setInstance(FeatureFlags)}. Be sure to call that method again, passing null,
+ * to ensure hermetic testing - you don't want static state persisting between your test methods.
+ *
+ * @hide
+ */
+public class FeatureFlagsFake extends FeatureFlags {
+    private final Map<BooleanFlagBase, Boolean> mFlagValues = new HashMap<>();
+    private final Set<BooleanFlagBase> mReadFlags = new HashSet<>();
+
+    public FeatureFlagsFake(IFeatureFlags iFeatureFlags) {
+        super(iFeatureFlags);
+    }
+
+    @Override
+    public boolean isEnabled(@NonNull BooleanFlag flag) {
+        return requireFlag(flag);
+    }
+
+    @Override
+    public boolean isEnabled(@NonNull FusedOffFlag flag) {
+        return requireFlag(flag);
+    }
+
+    @Override
+    public boolean isEnabled(@NonNull FusedOnFlag flag) {
+        return requireFlag(flag);
+    }
+
+    @Override
+    public boolean isCurrentlyEnabled(@NonNull DynamicBooleanFlag flag) {
+        return requireFlag(flag);
+    }
+
+    @Override
+    protected void syncInternal(Set<Flag<?>> dirtyFlags) {
+    }
+
+    /**
+     * Explicitly set a flag's value for reading in tests.
+     *
+     * You _must_ call this for every flag your code-under-test will read. Otherwise, an
+     * {@link IllegalStateException} will be thrown.
+     *
+     * You are able to set values for {@link FusedOffFlag} and {@link FusedOnFlag}, despite those
+     * flags having a fixed value at compile time, since unit tests should still test the state of
+     * those flags as both true and false. I.e. a flag that is off might be turned on in a future
+     * build or vice versa.
+     *
+     * You can not call this method _after_ a non-dynamic flag has been read. Non-dynamic flags
+     * are held stable in the system, so changing a value after reading would not match
+     * real-implementation behavior.
+     *
+     * Calling this method will trigger any {@link android.flags.FeatureFlags.ChangeListener}s that
+     * are registered for the supplied flag if the flag is a {@link DynamicFlag}.
+     *
+     * @param flag  The BooleanFlag that you want to set a value for.
+     * @param value The value that the flag should return when accessed.
+     */
+    public void setFlagValue(@NonNull BooleanFlagBase flag, boolean value) {
+        if (!(flag instanceof DynamicBooleanFlag) && mReadFlags.contains(flag)) {
+            throw new RuntimeException(
+                    "You can not set the value of a flag after it has been read. Tried to set "
+                            + flag + " to " + value + " but it already " + mFlagValues.get(flag));
+        }
+        mFlagValues.put(flag, value);
+        if (flag instanceof DynamicBooleanFlag) {
+            onFlagChange((DynamicFlag<?>) flag);
+        }
+    }
+
+    private boolean requireFlag(BooleanFlagBase flag) {
+        if (!mFlagValues.containsKey(flag)) {
+            throw new IllegalStateException(
+                    "Tried to access " + flag + " in test but no overrided specified. You must "
+                            + "call #setFlagValue for each flag read in a test.");
+        }
+        mReadFlags.add(flag);
+
+        return mFlagValues.get(flag);
+    }
+
+}
diff --git a/core/java/android/flags/Flag.java b/core/java/android/flags/Flag.java
new file mode 100644
index 0000000..b97a4c8
--- /dev/null
+++ b/core/java/android/flags/Flag.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.flags;
+
+import android.annotation.NonNull;
+
+/**
+ * Base class for constants read via {@link android.flags.FeatureFlags}.
+ *
+ * @param <T> The type of value that this flag stores. E.g. Boolean or String.
+ *
+ * @hide
+ */
+public interface Flag<T> {
+    /** The namespace for a flag. Should combine uniquely with its name. */
+    @NonNull
+    String getNamespace();
+
+    /** The name of the flag. Should combine uniquely with its namespace. */
+    @NonNull
+    String getName();
+
+    /** The value of this flag if no override has been set. Null values are not supported. */
+    @NonNull
+    T getDefault();
+
+    /** Returns true if the value of this flag can change at runtime. */
+    default boolean isDynamic() {
+        return false;
+    }
+
+    /**
+     * Add human-readable details to the flag. Flag client's are not required to set this.
+     *
+     * See {@link #getLabel()}, {@link #getDescription()}, and {@link #getCategoryName()}.
+     *
+     * @return Returns `this`, to make a fluent api.
+     */
+    Flag<T> defineMetaData(String label, String description, String categoryName);
+
+    /**
+     * A human-readable name for the flag. Defaults to {@link #getName()}
+     *
+     * See {@link #defineMetaData(String, String, String)}
+     */
+    @NonNull
+    default String getLabel() {
+        return getName();
+    }
+
+    /**
+     * A human-readable description for the flag. Defaults to null if unset.
+     *
+     * See {@link #defineMetaData(String, String, String)}
+     */
+    default String getDescription() {
+        return null;
+    }
+
+    /**
+     * A human-readable category name for the flag. Defaults to null if unset.
+     *
+     * See {@link #defineMetaData(String, String, String)}
+     */
+    default String getCategoryName() {
+        return null;
+    }
+}
diff --git a/core/java/android/flags/FusedOffFlag.java b/core/java/android/flags/FusedOffFlag.java
new file mode 100644
index 0000000..6844b8f
--- /dev/null
+++ b/core/java/android/flags/FusedOffFlag.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.flags;
+
+import android.annotation.NonNull;
+import android.provider.DeviceConfig;
+
+/**
+ * A flag representing a false value.
+ *
+ * The flag can never be changed or overridden. It is false at compile time.
+ *
+ * @hide
+ */
+public final class FusedOffFlag extends BooleanFlagBase {
+    /**
+     * @param namespace A namespace for this flag. See {@link DeviceConfig}.
+     * @param name      A name for this flag.
+     */
+    FusedOffFlag(String namespace, String name) {
+        super(namespace, name);
+    }
+
+    @Override
+    @NonNull
+    public Boolean getDefault() {
+        return false;
+    }
+
+    @Override
+    public FusedOffFlag defineMetaData(String label, String description, String categoryName) {
+        super.defineMetaData(label, description, categoryName);
+        return this;
+    }
+}
diff --git a/core/java/android/flags/FusedOnFlag.java b/core/java/android/flags/FusedOnFlag.java
new file mode 100644
index 0000000..e9adba7
--- /dev/null
+++ b/core/java/android/flags/FusedOnFlag.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.flags;
+
+import android.annotation.NonNull;
+import android.provider.DeviceConfig;
+
+/**
+ * A flag representing a true value.
+ *
+ * The flag can never be changed or overridden. It is true at compile time.
+ *
+ * @hide
+ */
+public final class FusedOnFlag extends BooleanFlagBase {
+    /**
+     * @param namespace A namespace for this flag. See {@link DeviceConfig}.
+     * @param name      A name for this flag.
+     */
+    FusedOnFlag(String namespace, String name) {
+        super(namespace, name);
+    }
+
+    @Override
+    @NonNull
+    public Boolean getDefault() {
+        return true;
+    }
+
+    @Override
+    public FusedOnFlag defineMetaData(String label, String description, String categoryName) {
+        super.defineMetaData(label, description, categoryName);
+        return this;
+    }
+}
diff --git a/core/java/android/flags/IFeatureFlags.aidl b/core/java/android/flags/IFeatureFlags.aidl
new file mode 100644
index 0000000..3efcec9
--- /dev/null
+++ b/core/java/android/flags/IFeatureFlags.aidl
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ package android.flags;
+
+import android.flags.IFeatureFlagsCallback;
+import android.flags.SyncableFlag;
+
+/**
+ * Binder interface for communicating with {@link com.android.server.flags.FeatureFlagsService}.
+ *
+ * This interface is used by {@link android.flags.FeatureFlags} and developers should use that to
+ * interface with the service. FeatureFlags is the "client" in this documentation.
+ *
+ * The methods allow client apps to communicate what flags they care about, and receive back
+ * current values for those flags. For stable flags, this is the finalized value until the device
+ * restarts. For {@link DynamicFlag}s, this is the last known value, though it may change in the
+ * future. Clients can listen for changes to flag values so that it can react accordingly.
+ * @hide
+ */
+interface IFeatureFlags {
+    /**
+     * Synchronize with the {@link com.android.server.flags.FeatureFlagsService} about flags of
+     * interest.
+     *
+     * The client should pass in a list of flags that it is using as {@link SyncableFlag}s, which
+     * includes what it thinks the default values of the flags are.
+     *
+     * The response will contain a list of matching SyncableFlags, whose values are set to what the
+     * value of the flags actually are. The client should update its internal state flag data to
+     * match.
+     *
+     * Generally speaking, if a flag that is passed in is new to the FeatureFlagsService, the
+     * service will cache the passed-in value, and return it back out. If, however, a different
+     * client has synced that flag with the service previously, FeatureFlagsService will return the
+     * existing cached value, which may or may not be what the current client passed in. This allows
+     * FeatureFlagsService to keep clients in agreement with one another.
+     */
+    List<SyncableFlag> syncFlags(in List<SyncableFlag> flagList);
+
+    /**
+     * Pass in an {@link IFeatureFlagsCallback} that will be called whenever a {@link DymamicFlag}
+     * changes.
+     */
+    void registerCallback(IFeatureFlagsCallback callback);
+
+    /**
+     * Remove a {@link IFeatureFlagsCallback} that was previously registered with
+     * {@link #registerCallback}.
+     */
+    void unregisterCallback(IFeatureFlagsCallback callback);
+
+    /**
+     * Query the {@link com.android.server.flags.FeatureFlagsService} for flags, but don't
+     * cache them. See {@link #syncFlags}.
+     *
+     * You almost certainly don't want this method. This is intended for the Flag Flipper
+     * application that needs to query the state of system but doesn't want to affect it by
+     * doing so. All other clients should use {@link syncFlags}.
+     */
+    List<SyncableFlag> queryFlags(in List<SyncableFlag> flagList);
+
+    /**
+     * Change a flags value in the system.
+     *
+     * This is intended for use by the Flag Flipper application.
+     */
+    void overrideFlag(in SyncableFlag flag);
+
+    /**
+     * Restore a flag to its default value.
+     *
+     * This is intended for use by the Flag Flipper application.
+     */
+    void resetFlag(in SyncableFlag flag);
+}
\ No newline at end of file
diff --git a/packages/SettingsLib/tests/robotests/fragment/src/main/java/org/robolectric/shadows/androidx/fragment/package-info.java b/core/java/android/flags/IFeatureFlagsCallback.aidl
similarity index 62%
copy from packages/SettingsLib/tests/robotests/fragment/src/main/java/org/robolectric/shadows/androidx/fragment/package-info.java
copy to core/java/android/flags/IFeatureFlagsCallback.aidl
index dd89441..f708667 100644
--- a/packages/SettingsLib/tests/robotests/fragment/src/main/java/org/robolectric/shadows/androidx/fragment/package-info.java
+++ b/core/java/android/flags/IFeatureFlagsCallback.aidl
@@ -14,10 +14,18 @@
  * limitations under the License.
  */
 
+ package android.flags;
+
+import android.flags.SyncableFlag;
+
 /**
- * Testing infrastructure for androidx.fragment library.
+ * Callback for {@link IFeatureFlags#registerCallback} to get alerts when a {@link DynamicFlag}
+ * changes.
  *
- * <p>To use this in your project, add the artifact {@code
- * org.robolectric:shadows-androidx-fragment} to your project.
+ * DynamicFlags can change at run time. Stable flags will never result in a call to this method.
+ *
+ * @hide
  */
-package org.robolectric.shadows.androidx.fragment;
+oneway interface IFeatureFlagsCallback {
+    void onFlagChange(in SyncableFlag flag);
+}
\ No newline at end of file
diff --git a/core/java/android/flags/OWNERS b/core/java/android/flags/OWNERS
new file mode 100644
index 0000000..fa125c4
--- /dev/null
+++ b/core/java/android/flags/OWNERS
@@ -0,0 +1,7 @@
+# Bug component: 1306523
+
+mankoff@google.com
+pixel@google.com
+
+dsandler@android.com
+
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/package-info.java b/core/java/android/flags/SyncableFlag.aidl
similarity index 82%
rename from packages/SettingsLib/tests/robotests/src/com/android/settingslib/package-info.java
rename to core/java/android/flags/SyncableFlag.aidl
index 9e9725f..1526ec1 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/package-info.java
+++ b/core/java/android/flags/SyncableFlag.aidl
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 
-@LooperMode(LooperMode.Mode.LEGACY)
-package com.android.settingslib;
+package android.flags;
 
-import org.robolectric.annotation.LooperMode;
+/**
+ * A parcelable data class for serializing {@link Flag} across a Binder.
+ */
+parcelable SyncableFlag;
\ No newline at end of file
diff --git a/core/java/android/flags/SyncableFlag.java b/core/java/android/flags/SyncableFlag.java
new file mode 100644
index 0000000..449bcc3c
--- /dev/null
+++ b/core/java/android/flags/SyncableFlag.java
@@ -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 android.flags;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * @hide
+ */
+public final class SyncableFlag implements Parcelable {
+    private final String mNamespace;
+    private final String mName;
+    private final String mValue;
+    private final boolean mDynamic;
+    private final boolean mOverridden;
+
+    public SyncableFlag(
+            @NonNull String namespace,
+            @NonNull String name,
+            @NonNull String value,
+            boolean dynamic) {
+        this(namespace, name, value, dynamic, false);
+    }
+
+    public SyncableFlag(
+            @NonNull String namespace,
+            @NonNull String name,
+            @NonNull String value,
+            boolean dynamic,
+            boolean overridden
+    ) {
+        mNamespace = namespace;
+        mName = name;
+        mValue = value;
+        mDynamic = dynamic;
+        mOverridden = overridden;
+    }
+
+    @NonNull
+    public String getNamespace() {
+        return mNamespace;
+    }
+
+    @NonNull
+    public String getName() {
+        return mName;
+    }
+
+    @NonNull
+    public String getValue() {
+        return mValue;
+    }
+
+    public boolean isDynamic() {
+        return mDynamic;
+    }
+
+    public boolean isOverridden() {
+        return mOverridden;
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<SyncableFlag> CREATOR = new Parcelable.Creator<>() {
+        public SyncableFlag createFromParcel(Parcel in) {
+            return new SyncableFlag(
+                    in.readString(),
+                    in.readString(),
+                    in.readString(),
+                    in.readBoolean(),
+                    in.readBoolean());
+        }
+
+        public SyncableFlag[] newArray(int size) {
+            return new SyncableFlag[size];
+        }
+    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(mNamespace);
+        dest.writeString(mName);
+        dest.writeString(mValue);
+        dest.writeBoolean(mDynamic);
+        dest.writeBoolean(mOverridden);
+    }
+
+    @Override
+    public String toString() {
+        return getNamespace() + "." + getName() + "[" + getValue() + "]";
+    }
+}
diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl
index 9d5073e..7080133 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -177,5 +177,5 @@
     // Internal operation used to clear face biometric scheduler.
     // Ensures that the scheduler is not stuck.
     @EnforcePermission("USE_BIOMETRIC_INTERNAL")
-    void scheduleWatchdog();
+    oneway void scheduleWatchdog();
 }
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index 9975852..e2840ec 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -213,5 +213,5 @@
     // Internal operation used to clear fingerprint biometric scheduler.
     // Ensures that the scheduler is not stuck.
     @EnforcePermission("USE_BIOMETRIC_INTERNAL")
-    void scheduleWatchdog();
+    oneway void scheduleWatchdog();
 }
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java
index 3da696a..7fbaf10 100644
--- a/core/java/android/net/Uri.java
+++ b/core/java/android/net/Uri.java
@@ -882,10 +882,11 @@
         }
 
         static Uri readFrom(Parcel parcel) {
+            final StringUri stringUri = new StringUri(parcel.readString8());
             return new OpaqueUri(
-                parcel.readString8(),
-                Part.readFrom(parcel),
-                Part.readFrom(parcel)
+                stringUri.parseScheme(),
+                stringUri.getSsp(),
+                stringUri.getFragmentPart()
             );
         }
 
@@ -895,9 +896,7 @@
 
         public void writeToParcel(Parcel parcel, int flags) {
             parcel.writeInt(TYPE_ID);
-            parcel.writeString8(scheme);
-            ssp.writeTo(parcel);
-            fragment.writeTo(parcel);
+            parcel.writeString8(toString());
         }
 
         public boolean isHierarchical() {
@@ -1196,22 +1195,25 @@
                 Part query, Part fragment) {
             this.scheme = scheme;
             this.authority = Part.nonNull(authority);
-            this.path = path == null ? PathPart.NULL : path;
+            this.path = generatePath(path);
             this.query = Part.nonNull(query);
             this.fragment = Part.nonNull(fragment);
         }
 
-        static Uri readFrom(Parcel parcel) {
-            final String scheme = parcel.readString8();
-            final Part authority = Part.readFrom(parcel);
+        private PathPart generatePath(PathPart originalPath) {
             // In RFC3986 the path should be determined based on whether there is a scheme or
             // authority present (https://www.rfc-editor.org/rfc/rfc3986.html#section-3.3).
             final boolean hasSchemeOrAuthority =
                     (scheme != null && scheme.length() > 0) || !authority.isEmpty();
-            final PathPart path = PathPart.readFrom(hasSchemeOrAuthority, parcel);
-            final Part query = Part.readFrom(parcel);
-            final Part fragment = Part.readFrom(parcel);
-            return new HierarchicalUri(scheme, authority, path, query, fragment);
+            final PathPart newPath = hasSchemeOrAuthority ? PathPart.makeAbsolute(originalPath)
+                                                          : originalPath;
+            return newPath == null ? PathPart.NULL : newPath;
+        }
+
+        static Uri readFrom(Parcel parcel) {
+            final StringUri stringUri = new StringUri(parcel.readString8());
+            return new HierarchicalUri(stringUri.getScheme(), stringUri.getAuthorityPart(),
+                    stringUri.getPathPart(), stringUri.getQueryPart(), stringUri.getFragmentPart());
         }
 
         public int describeContents() {
@@ -1220,11 +1222,7 @@
 
         public void writeToParcel(Parcel parcel, int flags) {
             parcel.writeInt(TYPE_ID);
-            parcel.writeString8(scheme);
-            authority.writeTo(parcel);
-            path.writeTo(parcel);
-            query.writeTo(parcel);
-            fragment.writeTo(parcel);
+            parcel.writeString8(toString());
         }
 
         public boolean isHierarchical() {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 820f454..753349c 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2186,6 +2186,16 @@
             = "android.settings.APP_NOTIFICATION_BUBBLE_SETTINGS";
 
     /**
+     * Intent Extra: The value of {@link android.app.settings.SettingsEnums#EntryPointType} for
+     * settings metrics that logs the entry point about physical keyboard settings.
+     * <p>
+     * This must be passed as an extra field to the {@link #ACTION_HARD_KEYBOARD_SETTINGS}.
+     * @hide
+     */
+    public static final String EXTRA_ENTRYPOINT =
+            "com.android.settings.inputmethod.EXTRA_ENTRYPOINT";
+
+    /**
      * Activity Extra: The package owner of the notification channel settings to display.
      * <p>
      * This must be passed as an extra field to the {@link #ACTION_CHANNEL_NOTIFICATION_SETTINGS}.
diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java
index 7fa0ac8..06e86af 100644
--- a/core/java/android/service/contentcapture/ContentCaptureService.java
+++ b/core/java/android/service/contentcapture/ContentCaptureService.java
@@ -15,6 +15,8 @@
  */
 package android.service.contentcapture;
 
+import static android.view.contentcapture.ContentCaptureEvent.TYPE_SESSION_PAUSED;
+import static android.view.contentcapture.ContentCaptureEvent.TYPE_SESSION_RESUMED;
 import static android.view.contentcapture.ContentCaptureHelper.sDebug;
 import static android.view.contentcapture.ContentCaptureHelper.sVerbose;
 import static android.view.contentcapture.ContentCaptureHelper.toList;
@@ -569,7 +571,16 @@
         List<ContentCaptureEvent> events = parceledEvents.getList();
         int sessionIdInt = events.isEmpty() ? NO_SESSION_ID : events.get(0).getSessionId();
         ContentCaptureSessionId sessionId = new ContentCaptureSessionId(sessionIdInt);
+
+        ContentCaptureEvent startEvent =
+                new ContentCaptureEvent(sessionIdInt, TYPE_SESSION_RESUMED);
+        startEvent.setSelectionIndex(0, events.size());
+        onContentCaptureEvent(sessionId, startEvent);
+
         events.forEach(event -> onContentCaptureEvent(sessionId, event));
+
+        ContentCaptureEvent endEvent = new ContentCaptureEvent(sessionIdInt, TYPE_SESSION_PAUSED);
+        onContentCaptureEvent(sessionId, endEvent);
     }
 
     private void handleOnActivitySnapshot(int sessionId, @NonNull SnapshotData snapshotData) {
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index c1eacb5..1d58268 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -302,11 +302,9 @@
     public static final int ANIMATION_TYPE_NONE = -1;
 
     /** Running animation will show insets */
-    @VisibleForTesting
     public static final int ANIMATION_TYPE_SHOW = 0;
 
     /** Running animation will hide insets */
-    @VisibleForTesting
     public static final int ANIMATION_TYPE_HIDE = 1;
 
     /** Running animation is controlled by user via {@link #controlWindowInsetsAnimation} */
@@ -447,21 +445,21 @@
                     if (mInputMethodJankContext == null) return;
                     ImeTracker.forJank().onRequestAnimation(
                             mInputMethodJankContext,
-                            mShow ? ANIMATION_TYPE_SHOW : ANIMATION_TYPE_HIDE,
+                            getAnimationType(),
                             !mHasAnimationCallbacks);
                 }
 
                 @Override
                 public void onAnimationCancel(Animator animation) {
                     if (mInputMethodJankContext == null) return;
-                    ImeTracker.forJank().onCancelAnimation();
+                    ImeTracker.forJank().onCancelAnimation(getAnimationType());
                 }
 
                 @Override
                 public void onAnimationEnd(Animator animation) {
                     onAnimationFinish();
                     if (mInputMethodJankContext == null) return;
-                    ImeTracker.forJank().onFinishAnimation();
+                    ImeTracker.forJank().onFinishAnimation(getAnimationType());
                 }
             });
             if (!mHasAnimationCallbacks) {
@@ -562,6 +560,14 @@
                 }
             }
         }
+
+        /**
+         * Returns the current animation type.
+         */
+        @AnimationType
+        private int getAnimationType() {
+            return mShow ? ANIMATION_TYPE_SHOW : ANIMATION_TYPE_HIDE;
+        }
     }
 
     /**
diff --git a/core/java/android/view/NotificationTopLineView.java b/core/java/android/view/NotificationTopLineView.java
index bd20f5b..a2919f5 100644
--- a/core/java/android/view/NotificationTopLineView.java
+++ b/core/java/android/view/NotificationTopLineView.java
@@ -21,6 +21,7 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Rect;
+import android.os.Trace;
 import android.util.AttributeSet;
 import android.widget.RemoteViews;
 
@@ -106,6 +107,7 @@
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        Trace.beginSection("NotificationTopLineView#onMeasure");
         final int givenWidth = MeasureSpec.getSize(widthMeasureSpec);
         final int givenHeight = MeasureSpec.getSize(heightMeasureSpec);
         final boolean wrapHeight = MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST;
@@ -161,6 +163,7 @@
                     .finish();
         }
         setMeasuredDimension(givenWidth, wrapHeight ? maxChildHeight : givenHeight);
+        Trace.endSection();
     }
 
     @Override
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 1e268be..5b69d7f 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -1340,7 +1340,7 @@
             mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession)
                     .setName(name)
                     .setLocalOwnerView(this)
-                    .setParent(viewRoot.getBoundsLayer())
+                    .setParent(viewRoot.updateAndGetBoundsLayer(surfaceUpdateTransaction))
                     .setCallsite("SurfaceView.updateSurface")
                     .setContainerLayer()
                     .build();
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index bef28b2..9d2bb58 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -716,9 +716,9 @@
 
     /**
      * Child container layer of {@code mSurface} with the same bounds as its parent, and cropped to
-     * the surface insets. This surface is created only if a client requests it via {@link
-     * #getBoundsLayer()}. By parenting to this bounds surface, child surfaces can ensure they do
-     * not draw into the surface inset region set by the parent window.
+     * the surface insets. This surface is created only if a client requests it via
+     * {@link #updateAndGetBoundsLayer(Transaction)}. By parenting to this bounds surface, child
+     * surfaces can ensure they do not draw into the surface inset region set by the parent window.
      */
     private SurfaceControl mBoundsLayer;
     private final SurfaceSession mSurfaceSession = new SurfaceSession();
@@ -2262,7 +2262,7 @@
      * <p>Parenting to this layer will ensure that its children are cropped by the view's surface
      * insets.
      */
-    public SurfaceControl getBoundsLayer() {
+    public SurfaceControl updateAndGetBoundsLayer(Transaction t) {
         if (mBoundsLayer == null) {
             mBoundsLayer = new SurfaceControl.Builder(mSurfaceSession)
                     .setContainerLayer()
@@ -2270,8 +2270,8 @@
                     .setParent(getSurfaceControl())
                     .setCallsite("ViewRootImpl.getBoundsLayer")
                     .build();
-            setBoundsLayerCrop(mTransaction);
-            mTransaction.show(mBoundsLayer).apply();
+            setBoundsLayerCrop(t);
+            t.show(mBoundsLayer);
         }
        return mBoundsLayer;
     }
@@ -11188,7 +11188,8 @@
     @Nullable public SurfaceControl.Transaction buildReparentTransaction(
         @NonNull SurfaceControl child) {
         if (mSurfaceControl.isValid()) {
-          return new SurfaceControl.Transaction().reparent(child, getBoundsLayer());
+            Transaction t = new Transaction();
+            return t.reparent(child, updateAndGetBoundsLayer(t));
         }
         return null;
     }
diff --git a/core/java/android/view/WindowManagerPolicyConstants.java b/core/java/android/view/WindowManagerPolicyConstants.java
index afc567e..c88048c 100644
--- a/core/java/android/view/WindowManagerPolicyConstants.java
+++ b/core/java/android/view/WindowManagerPolicyConstants.java
@@ -97,6 +97,12 @@
      */
     String EXTRA_START_REASON = "android.intent.extra.EXTRA_START_REASON";
 
+    /**
+     * Set to {@code true} when intent was invoked from pressing one of the brightness keys.
+     * @hide
+     */
+    String EXTRA_FROM_BRIGHTNESS_KEY = "android.intent.extra.FROM_BRIGHTNESS_KEY";
+
     // TODO: move this to a more appropriate place.
     interface PointerEventListener {
         /**
diff --git a/core/java/android/view/accessibility/IWindowMagnificationConnectionCallback.aidl b/core/java/android/view/accessibility/IWindowMagnificationConnectionCallback.aidl
index adfeb6d..21b4334 100644
--- a/core/java/android/view/accessibility/IWindowMagnificationConnectionCallback.aidl
+++ b/core/java/android/view/accessibility/IWindowMagnificationConnectionCallback.aidl
@@ -57,8 +57,9 @@
      *
      * @param displayId The logical display id.
      * @param scale the target scale, or {@link Float#NaN} to leave unchanged
+     * @param updatePersistence whether the new scale should be persisted in Settings
      */
-    void onPerformScaleAction(int displayId, float scale);
+    void onPerformScaleAction(int displayId, float scale, boolean updatePersistence);
 
     /**
      * Called when the accessibility action is performed.
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index c9afdc0..2c7d326 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -414,7 +414,7 @@
     /** @hide */
     public static final boolean DEFAULT_ENABLE_CONTENT_PROTECTION_RECEIVER = false;
     /** @hide */
-    public static final int DEFAULT_CONTENT_PROTECTION_APPS_BLOCKLIST_SIZE = 1000;
+    public static final int DEFAULT_CONTENT_PROTECTION_APPS_BLOCKLIST_SIZE = 5000;
     /** @hide */
     public static final int DEFAULT_CONTENT_PROTECTION_BUFFER_SIZE = 150;
 
diff --git a/core/java/android/view/inputmethod/ImeTracker.java b/core/java/android/view/inputmethod/ImeTracker.java
index f0d1019..03d1cd8 100644
--- a/core/java/android/view/inputmethod/ImeTracker.java
+++ b/core/java/android/view/inputmethod/ImeTracker.java
@@ -16,8 +16,12 @@
 
 package android.view.inputmethod;
 
+import static android.view.InsetsController.ANIMATION_TYPE_HIDE;
+import static android.view.InsetsController.ANIMATION_TYPE_SHOW;
+
 import static com.android.internal.inputmethod.InputMethodDebug.softInputDisplayReasonToString;
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_IME_INSETS_ANIMATION;
+import static com.android.internal.jank.InteractionJankMonitor.CUJ_IME_INSETS_HIDE_ANIMATION;
+import static com.android.internal.jank.InteractionJankMonitor.CUJ_IME_INSETS_SHOW_ANIMATION;
 import static com.android.internal.util.LatencyTracker.ACTION_REQUEST_IME_HIDDEN;
 import static com.android.internal.util.LatencyTracker.ACTION_REQUEST_IME_SHOWN;
 
@@ -696,20 +700,22 @@
         /**
          * Called when the animation, which is going to be monitored, starts.
          *
-         * @param jankContext context which is needed by {@link InteractionJankMonitor}
-         * @param animType {@link AnimationType}
+         * @param jankContext context which is needed by {@link InteractionJankMonitor}.
+         * @param animType the animation type.
          * @param useSeparatedThread {@code true} if the animation is handled by the app,
          *                           {@code false} if the animation will be scheduled on the
-         *                           {@link android.view.InsetsAnimationThread}
+         *                           {@link android.view.InsetsAnimationThread}.
          */
         public void onRequestAnimation(@NonNull InputMethodJankContext jankContext,
                 @AnimationType int animType, boolean useSeparatedThread) {
+            final int cujType = getImeInsetsCujFromAnimation(animType);
             if (jankContext.getDisplayContext() == null
-                    || jankContext.getTargetSurfaceControl() == null) {
+                    || jankContext.getTargetSurfaceControl() == null
+                    || cujType == -1) {
                 return;
             }
             final Configuration.Builder builder = Configuration.Builder.withSurface(
-                            CUJ_IME_INSETS_ANIMATION,
+                            cujType,
                             jankContext.getDisplayContext(),
                             jankContext.getTargetSurfaceControl())
                     .setTag(String.format(Locale.US, "%d@%d@%s", animType,
@@ -719,16 +725,44 @@
 
         /**
          * Called when the animation, which is going to be monitored, cancels.
+         *
+         * @param animType the animation type.
          */
-        public void onCancelAnimation() {
-            InteractionJankMonitor.getInstance().cancel(CUJ_IME_INSETS_ANIMATION);
+        public void onCancelAnimation(@AnimationType int animType) {
+            final int cujType = getImeInsetsCujFromAnimation(animType);
+            if (cujType == -1) {
+                InteractionJankMonitor.getInstance().cancel(cujType);
+            }
         }
 
         /**
          * Called when the animation, which is going to be monitored, ends.
+         *
+         * @param animType the animation type.
          */
-        public void onFinishAnimation() {
-            InteractionJankMonitor.getInstance().end(CUJ_IME_INSETS_ANIMATION);
+        public void onFinishAnimation(@AnimationType int animType) {
+            final int cujType = getImeInsetsCujFromAnimation(animType);
+            if (cujType != -1) {
+                InteractionJankMonitor.getInstance().end(cujType);
+            }
+        }
+
+        /**
+         * A helper method to translate animation type to CUJ type for IME animations.
+         *
+         * @param animType the animation type.
+         * @return the integer in {@link com.android.internal.jank.InteractionJankMonitor.CujType},
+         * or {@code -1} if the animation type is not supported for tracking yet.
+         */
+        private static int getImeInsetsCujFromAnimation(@AnimationType int animType) {
+            switch (animType) {
+                case ANIMATION_TYPE_SHOW:
+                    return CUJ_IME_INSETS_SHOW_ANIMATION;
+                case ANIMATION_TYPE_HIDE:
+                    return CUJ_IME_INSETS_HIDE_ANIMATION;
+                default:
+                    return -1;
+            }
         }
     }
 
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 27d8a8f..b74c879 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -6938,12 +6938,26 @@
      *                                  parameters used to create the PrecomputedText mismatches
      *                                  with this TextView.
      */
-    @android.view.RemotableViewMethod
+    @android.view.RemotableViewMethod(asyncImpl = "setTextAsync")
     public final void setText(CharSequence text) {
         setText(text, mBufferType);
     }
 
     /**
+     * RemotableViewMethod's asyncImpl of {@link #setText(CharSequence)}.
+     * This should be called on a background thread, and returns a Runnable which is then must be
+     * called on the main thread to complete the operation and set text.
+     * @param text text to be displayed
+     * @return Runnable that sets text; must be called on the main thread by the caller of this
+     * method to complete the operation
+     * @hide
+     */
+    @NonNull
+    public Runnable setTextAsync(@Nullable CharSequence text) {
+        return () -> setText(text);
+    }
+
+    /**
      * Sets the text to be displayed but retains the cursor position. Same as
      * {@link #setText(CharSequence)} except that the cursor position (if any) is retained in the
      * new text.
diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java
index 9f804b1..3323ae5 100644
--- a/core/java/android/window/WindowContainerTransaction.java
+++ b/core/java/android/window/WindowContainerTransaction.java
@@ -688,6 +688,7 @@
                         .setInsetsFrameProvider(new InsetsFrameProvider(owner, index, type)
                                 .setSource(InsetsFrameProvider.SOURCE_ARBITRARY_RECTANGLE)
                                 .setArbitraryRectangle(frame))
+                        .setInsetsFrameOwner(owner)
                         .build();
         mHierarchyOps.add(hierarchyOp);
         return this;
@@ -712,6 +713,7 @@
                 new HierarchyOp.Builder(HierarchyOp.HIERARCHY_OP_TYPE_REMOVE_INSETS_FRAME_PROVIDER)
                         .setContainer(receiver.asBinder())
                         .setInsetsFrameProvider(new InsetsFrameProvider(owner, index, type))
+                        .setInsetsFrameOwner(owner)
                         .build();
         mHierarchyOps.add(hierarchyOp);
         return this;
@@ -1344,8 +1346,12 @@
         @Nullable
         private IBinder mReparent;
 
+        @Nullable
         private InsetsFrameProvider mInsetsFrameProvider;
 
+        @Nullable
+        private IBinder mInsetsFrameOwner;
+
         // Moves/reparents to top of parent when {@code true}, otherwise moves/reparents to bottom.
         private boolean mToTop;
 
@@ -1478,6 +1484,7 @@
             mContainer = copy.mContainer;
             mReparent = copy.mReparent;
             mInsetsFrameProvider = copy.mInsetsFrameProvider;
+            mInsetsFrameOwner = copy.mInsetsFrameOwner;
             mToTop = copy.mToTop;
             mReparentTopOnly = copy.mReparentTopOnly;
             mWindowingModes = copy.mWindowingModes;
@@ -1496,6 +1503,7 @@
             mContainer = in.readStrongBinder();
             mReparent = in.readStrongBinder();
             mInsetsFrameProvider = in.readTypedObject(InsetsFrameProvider.CREATOR);
+            mInsetsFrameOwner = in.readStrongBinder();
             mToTop = in.readBoolean();
             mReparentTopOnly = in.readBoolean();
             mWindowingModes = in.createIntArray();
@@ -1527,6 +1535,11 @@
             return mInsetsFrameProvider;
         }
 
+        @Nullable
+        public IBinder getInsetsFrameOwner() {
+            return mInsetsFrameOwner;
+        }
+
         @NonNull
         public IBinder getContainer() {
             return mContainer;
@@ -1657,7 +1670,8 @@
                 case HIERARCHY_OP_TYPE_ADD_INSETS_FRAME_PROVIDER:
                 case HIERARCHY_OP_TYPE_REMOVE_INSETS_FRAME_PROVIDER:
                     sb.append("container=").append(mContainer)
-                            .append(" provider=").append(mInsetsFrameProvider);
+                            .append(" provider=").append(mInsetsFrameProvider)
+                            .append(" owner=").append(mInsetsFrameOwner);
                     break;
                 case HIERARCHY_OP_TYPE_SET_ALWAYS_ON_TOP:
                     sb.append("container=").append(mContainer)
@@ -1697,6 +1711,7 @@
             dest.writeStrongBinder(mContainer);
             dest.writeStrongBinder(mReparent);
             dest.writeTypedObject(mInsetsFrameProvider, flags);
+            dest.writeStrongBinder(mInsetsFrameOwner);
             dest.writeBoolean(mToTop);
             dest.writeBoolean(mReparentTopOnly);
             dest.writeIntArray(mWindowingModes);
@@ -1737,8 +1752,12 @@
             @Nullable
             private IBinder mReparent;
 
+            @Nullable
             private InsetsFrameProvider mInsetsFrameProvider;
 
+            @Nullable
+            private IBinder mInsetsFrameOwner;
+
             private boolean mToTop;
 
             private boolean mReparentTopOnly;
@@ -1782,8 +1801,13 @@
                 return this;
             }
 
-            Builder setInsetsFrameProvider(InsetsFrameProvider providers) {
-                mInsetsFrameProvider = providers;
+            Builder setInsetsFrameProvider(InsetsFrameProvider provider) {
+                mInsetsFrameProvider = provider;
+                return this;
+            }
+
+            Builder setInsetsFrameOwner(IBinder owner) {
+                mInsetsFrameOwner = owner;
                 return this;
             }
 
@@ -1854,6 +1878,7 @@
                         ? Arrays.copyOf(mActivityTypes, mActivityTypes.length)
                         : null;
                 hierarchyOp.mInsetsFrameProvider = mInsetsFrameProvider;
+                hierarchyOp.mInsetsFrameOwner = mInsetsFrameOwner;
                 hierarchyOp.mToTop = mToTop;
                 hierarchyOp.mReparentTopOnly = mReparentTopOnly;
                 hierarchyOp.mLaunchOptions = mLaunchOptions;
diff --git a/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java b/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
index 6b8ae94..81cd280 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
@@ -84,11 +84,14 @@
 
         /** Gating the holding of WakeLocks until NLSes are told about a new notification. */
         public static final Flag WAKE_LOCK_FOR_POSTING_NOTIFICATION =
-                devFlag("persist.sysui.notification.wake_lock_for_posting_notification");
+                releasedFlag("persist.sysui.notification.wake_lock_for_posting_notification");
 
         /** Gating storing NotificationRankingUpdate ranking map in shared memory. */
         public static final Flag RANKING_UPDATE_ASHMEM = devFlag(
                 "persist.sysui.notification.ranking_update_ashmem");
+
+        public static final Flag PROPAGATE_CHANNEL_UPDATES_TO_CONVERSATIONS = devFlag(
+                "persist.sysui.notification.propagate_channel_updates_to_conversations");
     }
 
     //// == End of flags.  Everything below this line is the implementation. == ////
diff --git a/core/java/com/android/internal/flags/CoreFlags.java b/core/java/com/android/internal/flags/CoreFlags.java
new file mode 100644
index 0000000..f177ef8
--- /dev/null
+++ b/core/java/com/android/internal/flags/CoreFlags.java
@@ -0,0 +1,93 @@
+/*
+ * 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.flags;
+
+import android.flags.BooleanFlag;
+import android.flags.DynamicBooleanFlag;
+import android.flags.FeatureFlags;
+import android.flags.FusedOffFlag;
+import android.flags.FusedOnFlag;
+import android.flags.SyncableFlag;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Flags defined here are can be read by code in core.
+ *
+ * Flags not defined here will throw a security exception if third-party processes attempts to read
+ * them.
+ *
+ * DO NOT define a flag here unless you explicitly intend for that flag to be readable by code that
+ * runs inside a third party process.
+ */
+public abstract class CoreFlags {
+    private static final List<SyncableFlag> sKnownFlags = new ArrayList<>();
+
+    public static BooleanFlag BOOL_FLAG = booleanFlag("core", "bool_flag", false);
+    public static FusedOffFlag OFF_FLAG = fusedOffFlag("core", "off_flag");
+    public static FusedOnFlag ON_FLAG = fusedOnFlag("core", "on_flag");
+    public static DynamicBooleanFlag DYN_FLAG = dynamicBooleanFlag("core", "dyn_flag", true);
+
+    /** Returns true if the passed in flag matches a flag in this class. */
+    public static boolean isCoreFlag(SyncableFlag flag) {
+        for (SyncableFlag knownFlag : sKnownFlags) {
+            if (knownFlag.getName().equals(flag.getName())
+                    && knownFlag.getNamespace().equals(flag.getNamespace())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static List<SyncableFlag> getCoreFlags() {
+        return sKnownFlags;
+    }
+
+    private static BooleanFlag booleanFlag(String namespace, String name, boolean defaultValue) {
+        BooleanFlag f = FeatureFlags.booleanFlag(namespace, name, defaultValue);
+
+        sKnownFlags.add(new SyncableFlag(namespace, name, Boolean.toString(defaultValue), false));
+
+        return f;
+    }
+
+    private static FusedOffFlag fusedOffFlag(String namespace, String name) {
+        FusedOffFlag f = FeatureFlags.fusedOffFlag(namespace, name);
+
+        sKnownFlags.add(new SyncableFlag(namespace, name, "false", false));
+
+        return f;
+    }
+
+    private static FusedOnFlag fusedOnFlag(String namespace, String name) {
+        FusedOnFlag f = FeatureFlags.fusedOnFlag(namespace, name);
+
+        sKnownFlags.add(new SyncableFlag(namespace, name, "true", false));
+
+        return f;
+    }
+
+    private static DynamicBooleanFlag dynamicBooleanFlag(
+            String namespace, String name, boolean defaultValue) {
+        DynamicBooleanFlag f = FeatureFlags.dynamicBooleanFlag(namespace, name, defaultValue);
+
+        sKnownFlags.add(new SyncableFlag(namespace, name, Boolean.toString(defaultValue), true));
+
+        return f;
+    }
+}
diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java
index 92427ec..03d7450 100644
--- a/core/java/com/android/internal/jank/InteractionJankMonitor.java
+++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java
@@ -25,7 +25,8 @@
 import static com.android.internal.jank.FrameTracker.REASON_END_NORMAL;
 import static com.android.internal.jank.FrameTracker.REASON_END_UNKNOWN;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__BIOMETRIC_PROMPT_TRANSITION;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__IME_INSETS_ANIMATION;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__IME_INSETS_HIDE_ANIMATION;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__IME_INSETS_SHOW_ANIMATION;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_ALL_APPS_SCROLL;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_CLOSE_TO_HOME;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK;
@@ -257,7 +258,6 @@
     public static final int CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS = 66;
     public static final int CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE = 67;
     public static final int CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME = 68;
-    public static final int CUJ_IME_INSETS_ANIMATION = 69;
     public static final int CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION = 70;
     public static final int CUJ_LAUNCHER_OPEN_SEARCH_RESULT = 71;
     // 72 - 77 are reserved for b/281564325.
@@ -269,8 +269,10 @@
      */
     public static final int CUJ_LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK = 78;
     public static final int CUJ_SHADE_EXPAND_FROM_STATUS_BAR = 79;
+    public static final int CUJ_IME_INSETS_SHOW_ANIMATION = 80;
+    public static final int CUJ_IME_INSETS_HIDE_ANIMATION = 81;
 
-    private static final int LAST_CUJ = CUJ_SHADE_EXPAND_FROM_STATUS_BAR;
+    private static final int LAST_CUJ = CUJ_IME_INSETS_HIDE_ANIMATION;
     private static final int NO_STATSD_LOGGING = -1;
 
     // Used to convert CujType to InteractionType enum value for statsd logging.
@@ -348,7 +350,7 @@
         CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_SWIPE_TO_RECENTS;
         CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_CLOSE_ALL_APPS_SWIPE;
         CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_CLOSE_ALL_APPS_TO_HOME;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_IME_INSETS_ANIMATION] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__IME_INSETS_ANIMATION;
+        CUJ_TO_STATSD_INTERACTION_TYPE[69] = NO_STATSD_LOGGING; // This is deprecated.
         CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_CLOCK_MOVE_ANIMATION;
         CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_OPEN_SEARCH_RESULT] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_OPEN_SEARCH_RESULT;
         // 72 - 77 are reserved for b/281564325.
@@ -360,6 +362,8 @@
         CUJ_TO_STATSD_INTERACTION_TYPE[77] = NO_STATSD_LOGGING;
         CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK;
         CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SHADE_EXPAND_FROM_STATUS_BAR] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_EXPAND_FROM_STATUS_BAR;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_IME_INSETS_SHOW_ANIMATION] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__IME_INSETS_SHOW_ANIMATION;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_IME_INSETS_HIDE_ANIMATION] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__IME_INSETS_HIDE_ANIMATION;
     }
 
     private static class InstanceHolder {
@@ -456,11 +460,12 @@
             CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS,
             CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE,
             CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME,
-            CUJ_IME_INSETS_ANIMATION,
             CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION,
             CUJ_LAUNCHER_OPEN_SEARCH_RESULT,
             CUJ_LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK,
             CUJ_SHADE_EXPAND_FROM_STATUS_BAR,
+            CUJ_IME_INSETS_SHOW_ANIMATION,
+            CUJ_IME_INSETS_HIDE_ANIMATION,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface CujType {
@@ -1066,8 +1071,6 @@
                 return "LAUNCHER_CLOSE_ALL_APPS_SWIPE";
             case CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME:
                 return "LAUNCHER_CLOSE_ALL_APPS_TO_HOME";
-            case CUJ_IME_INSETS_ANIMATION:
-                return "IME_INSETS_ANIMATION";
             case CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION:
                 return "LOCKSCREEN_CLOCK_MOVE_ANIMATION";
             case CUJ_LAUNCHER_OPEN_SEARCH_RESULT:
@@ -1076,6 +1079,10 @@
                 return "LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK";
             case CUJ_SHADE_EXPAND_FROM_STATUS_BAR:
                 return "SHADE_EXPAND_FROM_STATUS_BAR";
+            case CUJ_IME_INSETS_SHOW_ANIMATION:
+                return "IME_INSETS_SHOW_ANIMATION";
+            case CUJ_IME_INSETS_HIDE_ANIMATION:
+                return "IME_INSETS_HIDE_ANIMATION";
         }
         return "UNKNOWN";
     }
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 2063542..0c6d6f9 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -195,6 +195,11 @@
      */
     public static final int PROFILEABLE = 1 << 24;
 
+    /**
+     * Enable ptrace.  This is enabled on eng or userdebug builds, or if the app is debuggable.
+     */
+    public static final int DEBUG_ENABLE_PTRACE = 1 << 25;
+
     /** No external storage should be mounted. */
     public static final int MOUNT_EXTERNAL_NONE = IVold.REMOUNT_MODE_NONE;
     /** Default external storage should be mounted. */
@@ -1028,6 +1033,9 @@
         if (Build.IS_ENG || ENABLE_JDWP) {
             args.mRuntimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
         }
+        if (RoSystemProperties.DEBUGGABLE) {
+            args.mRuntimeFlags |= Zygote.DEBUG_ENABLE_PTRACE;
+        }
     }
 
     /**
diff --git a/core/java/com/android/internal/widget/ImageFloatingTextView.java b/core/java/com/android/internal/widget/ImageFloatingTextView.java
index 1ac5e1f..de10bd2 100644
--- a/core/java/com/android/internal/widget/ImageFloatingTextView.java
+++ b/core/java/com/android/internal/widget/ImageFloatingTextView.java
@@ -18,6 +18,7 @@
 
 import android.annotation.Nullable;
 import android.content.Context;
+import android.os.Trace;
 import android.text.BoringLayout;
 import android.text.Layout;
 import android.text.StaticLayout;
@@ -68,6 +69,7 @@
     protected Layout makeSingleLayout(int wantWidth, BoringLayout.Metrics boring, int ellipsisWidth,
             Layout.Alignment alignment, boolean shouldEllipsize,
             TextUtils.TruncateAt effectiveEllipsize, boolean useSaved) {
+        Trace.beginSection("ImageFloatingTextView#makeSingleLayout");
         TransformationMethod transformationMethod = getTransformationMethod();
         CharSequence text = getText();
         if (transformationMethod != null) {
@@ -110,7 +112,9 @@
             builder.setIndents(null, margins);
         }
 
-        return builder.build();
+        final StaticLayout result = builder.build();
+        Trace.endSection();
+        return result;
     }
 
     /**
@@ -135,6 +139,7 @@
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        Trace.beginSection("ImageFloatingTextView#onMeasure");
         int availableHeight = MeasureSpec.getSize(heightMeasureSpec) - mPaddingTop - mPaddingBottom;
         if (getLayout() != null && getLayout().getHeight() != availableHeight) {
             // We've been measured before and the new size is different than before, lets make sure
@@ -161,6 +166,7 @@
                 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
             }
         }
+        Trace.endSection();
     }
 
     @Override
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 361bdce..e018393 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -1082,7 +1082,10 @@
      */
     @UnsupportedAppUsage
     public boolean isVisiblePatternEnabled(int userId) {
-        return getBoolean(Settings.Secure.LOCK_PATTERN_VISIBLE, false, userId);
+        // Default to true, since this gets explicitly set to true when a pattern is first set
+        // anyway, which makes true the user-visible default.  The low-level default should be the
+        // same, in order for FRP credential verification to get the same default.
+        return getBoolean(Settings.Secure.LOCK_PATTERN_VISIBLE, true, userId);
     }
 
     /**
diff --git a/core/jni/android_view_InputDevice.cpp b/core/jni/android_view_InputDevice.cpp
index 0bc0878..f97d41b 100644
--- a/core/jni/android_view_InputDevice.cpp
+++ b/core/jni/android_view_InputDevice.cpp
@@ -42,6 +42,13 @@
         return NULL;
     }
 
+    // b/274058082: Pass a copy of the key character map to avoid concurrent
+    // access
+    std::shared_ptr<KeyCharacterMap> map = deviceInfo.getKeyCharacterMap();
+    if (map != nullptr) {
+        map = std::make_shared<KeyCharacterMap>(*map);
+    }
+
     ScopedLocalRef<jstring> descriptorObj(env,
             env->NewStringUTF(deviceInfo.getIdentifier().descriptor.c_str()));
     if (!descriptorObj.get()) {
@@ -61,8 +68,8 @@
                                                                   : NULL));
 
     ScopedLocalRef<jobject> kcmObj(env,
-            android_view_KeyCharacterMap_create(env, deviceInfo.getId(),
-            deviceInfo.getKeyCharacterMap()));
+                                   android_view_KeyCharacterMap_create(env, deviceInfo.getId(),
+                                                                       map));
     if (!kcmObj.get()) {
         return NULL;
     }
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index ce806a0..c368fa8 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -356,6 +356,7 @@
     GWP_ASAN_LEVEL_DEFAULT = 3 << 21,
     NATIVE_HEAP_ZERO_INIT_ENABLED = 1 << 23,
     PROFILEABLE = 1 << 24,
+    DEBUG_ENABLE_PTRACE = 1 << 25,
 };
 
 enum UnsolicitedZygoteMessageTypes : uint32_t {
@@ -1887,8 +1888,10 @@
     }
 
     // Set process properties to enable debugging if required.
-    if ((runtime_flags & RuntimeFlags::DEBUG_ENABLE_JDWP) != 0) {
+    if ((runtime_flags & RuntimeFlags::DEBUG_ENABLE_PTRACE) != 0) {
         EnableDebugger();
+        // Don't pass unknown flag to the ART runtime.
+        runtime_flags &= ~RuntimeFlags::DEBUG_ENABLE_PTRACE;
     }
     if ((runtime_flags & RuntimeFlags::PROFILE_FROM_SHELL) != 0) {
         // simpleperf needs the process to be dumpable to profile it.
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index a01c7b6..10cf353 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -7655,6 +7655,24 @@
     <permission android:name="android.permission.GET_ANY_PROVIDER_TYPE"
                 android:protectionLevel="signature" />
 
+
+    <!-- @hide Allows internal applications to read and synchronize non-core flags.
+         Apps without this permission can only read a subset of flags specifically intended
+         for use in "core", (i.e. third party apps). Apps with this permission can define their
+         own flags, and federate those values with other system-level apps.
+         <p>Not for use by third-party applications.
+         <p>Protection level: signature
+    -->
+    <permission android:name="android.permission.SYNC_FLAGS"
+        android:protectionLevel="signature" />
+
+    <!-- @hide Allows internal applications to override flags in the FeatureFlags service.
+         <p>Not for use by third-party applications.
+         <p>Protection level: signature
+    -->
+    <permission android:name="android.permission.WRITE_FLAGS"
+        android:protectionLevel="signature" />
+
     <!-- Attribution for Geofencing service. -->
     <attribution android:tag="GeofencingService" android:label="@string/geofencing_service"/>
     <!-- Attribution for Country Detector. -->
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index a941dc7..f5d73f9 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"WEIER"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Kies invoermetode"</string>
     <string name="show_ime" msgid="6406112007347443383">"Hou dit op die skerm terwyl fisieke sleutelbord aktief is"</string>
-    <string name="hardware" msgid="1800597768237606953">"Wys virtuele sleutelbord"</string>
+    <string name="hardware" msgid="3611039921284836033">"Gebruik skermsleutelbord"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Stel <xliff:g id="DEVICE_NAME">%s</xliff:g> op"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Stel fisieke sleutelborde op"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Tik om taal en uitleg te kies"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index f97768e..9b30681 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"አትቀበል"</string>
     <string name="select_input_method" msgid="3971267998568587025">"የግቤት ስልት ምረጥ"</string>
     <string name="show_ime" msgid="6406112007347443383">"አካላዊ የቁልፍ ሰሌዳ ገቢር ሆኖ ሳለ በማያ ገፅ ላይ አቆየው"</string>
-    <string name="hardware" msgid="1800597768237606953">"ምናባዊ የቁልፍ ሰሌዳን አሳይ"</string>
+    <string name="hardware" msgid="3611039921284836033">"የማያ ገጽ ላይ የቁልፍ ሰሌዳ ይጠቀሙ"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g>ን ያዋቅሩ"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"አካላዊ የቁልፍ ሰሌዳዎችን ያዋቅሩ"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ቋንቋ እና አቀማመጥን ለመምረጥ መታ ያድርጉ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index a812ac0..f480d3a 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1398,7 +1398,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"رفض"</string>
     <string name="select_input_method" msgid="3971267998568587025">"اختيار أسلوب الإدخال"</string>
     <string name="show_ime" msgid="6406112007347443383">"استمرار عرضها على الشاشة عندما تكون لوحة المفاتيح الخارجية متصلة"</string>
-    <string name="hardware" msgid="1800597768237606953">"إظهار لوحة المفاتيح الافتراضية"</string>
+    <string name="hardware" msgid="3611039921284836033">"استخدام لوحة المفاتيح على الشاشة"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"إعداد <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"إعداد لوحات المفاتيح الخارجية"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"انقر لاختيار لغة وتنسيق"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 626c3d6..15563c1 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"প্ৰত্যাখ্যান কৰক"</string>
     <string name="select_input_method" msgid="3971267998568587025">"ইনপুট পদ্ধতি বাছনি কৰক"</string>
     <string name="show_ime" msgid="6406112007347443383">"কায়িক কীব’ৰ্ড সক্ৰিয় হৈ থাকোঁতে ইয়াক স্ক্ৰীনত ৰাখক"</string>
-    <string name="hardware" msgid="1800597768237606953">"ভাৰ্শ্বুৱল কীব\'ৰ্ড দেখুৱাওক"</string>
+    <string name="hardware" msgid="3611039921284836033">"অন-স্ক্ৰীন কীব’ৰ্ড ব্যৱহাৰ কৰক"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> কনফিগাৰ কৰক"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"ভৌতিক কীব’ৰ্ড কনফিগাৰ কৰক"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ভাষা আৰু চানেকি বাছনি কৰিবলৈ ইয়াত টিপক"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 5a41074..d7bec06 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"RƏDD EDİN"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Daxiletmə metodunu seçin"</string>
     <string name="show_ime" msgid="6406112007347443383">"Fiziki klaviatura aktiv olanda görünsün"</string>
-    <string name="hardware" msgid="1800597768237606953">"Virtual klaviaturanı göstərin"</string>
+    <string name="hardware" msgid="3611039921284836033">"Ekran klaviaturası işlədin"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> cihazını konfiqurasiya edin"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Fiziki klaviaturaları konfiqurasiya edin"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Dil və tərtibatı seçmək üçün tıklayın"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 1baf387..a6254f6 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -1395,7 +1395,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ODBIJ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Izbor metoda unosa"</string>
     <string name="show_ime" msgid="6406112007347443383">"Zadržava se na ekranu dok je fizička tastatura aktivna"</string>
-    <string name="hardware" msgid="1800597768237606953">"Prikaži virtuelnu tastaturu"</string>
+    <string name="hardware" msgid="3611039921284836033">"Koristi tastaturu na ekranu"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfigurišite uređaj <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfigurišite fizičke tastature"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Dodirnite da biste izabrali jezik i raspored"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index f226b96..624de9c 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1259,7 +1259,7 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Запуск прыкладанняў."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Завяршэнне загрузкі."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Вы націснулі кнопку сілкавання. Звычайна ў выніку гэтага дзеяння выключаецца экран.\n\nПадчас наладжвання адбітка пальца злёгку дакраніцеся да кнопкі."</string>
-    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Каб завяршыць наладку, выключыце экран"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Каб скончыць наладку, выключыце экран"</string>
     <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Выключыць"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Працягнуць спраўджанне адбітка пальца?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Вы націснулі кнопку сілкавання. Звычайна ў выніку гэтага дзеяння выключаецца экран.\n\nКаб спраўдзіць адбітак пальца, злёгку дакраніцеся да кнопкі."</string>
@@ -1396,7 +1396,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"АДХІЛІЦЬ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Выберыце метад уводу"</string>
     <string name="show_ime" msgid="6406112007347443383">"Захоўваць яе на экране ў той час, калі фізічная клавіятура актыўная"</string>
-    <string name="hardware" msgid="1800597768237606953">"Паказаць віртуальную клавіятуру"</string>
+    <string name="hardware" msgid="3611039921284836033">"Экранная клавіятура"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Наладзьце прыладу \"<xliff:g id="DEVICE_NAME">%s</xliff:g>\""</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Наладзьце фізічныя клавіятуры"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Дакраніцеся, каб выбраць мову і раскладку"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index b4ba000..a71c0af 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ОТХВЪРЛЯНЕ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Избор на метод на въвеждане"</string>
     <string name="show_ime" msgid="6406112007347443383">"Показване на екрана, докато физическата клавиатура е активна"</string>
-    <string name="hardware" msgid="1800597768237606953">"Показване на вирт. клавиатура"</string>
+    <string name="hardware" msgid="3611039921284836033">"Ползв. на екранната клавиатура"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Конфигуриране на <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Конфигуриране на физически клавиатури"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Докоснете, за да изберете език и подредба"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 25c0d42..ea0b949 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"অস্বীকার করুন"</string>
     <string name="select_input_method" msgid="3971267998568587025">"ইনপুট পদ্ধতি বেছে নিন"</string>
     <string name="show_ime" msgid="6406112007347443383">"ফিজিক্যাল কীবোর্ড সক্রিয় থাকার সময় এটিকে স্ক্রীনে রাখুন"</string>
-    <string name="hardware" msgid="1800597768237606953">"ভার্চুয়াল কীবোর্ড দেখুন"</string>
+    <string name="hardware" msgid="3611039921284836033">"স্ক্রিনের কীবোর্ড ব্যবহার করুন"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> কনফিগার করুন"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"ফিজিক্যাল কীবোর্ড কনফিগার করুন"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ভাষা ও লেআউট বেছে নিতে ট্যাপ করুন"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index e824ecc..afafa1c 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -1395,7 +1395,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ODBACI"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Odaberite način unosa"</string>
     <string name="show_ime" msgid="6406112007347443383">"Prikaži na ekranu dok je fizička tastatura aktivna"</string>
-    <string name="hardware" msgid="1800597768237606953">"Prikaz virtuelne tastature"</string>
+    <string name="hardware" msgid="3611039921284836033">"Koristi tastaturu na ekranu"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfigurirajte uređaj <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfigurirajte fizičke tastature"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Dodirnite da odaberete jezik i raspored"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 46fc3a3..5264557 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1395,7 +1395,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"REBUTJA"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Selecciona un mètode d\'introducció"</string>
     <string name="show_ime" msgid="6406112007347443383">"Mantén-lo en pantalla mentre el teclat físic està actiu"</string>
-    <string name="hardware" msgid="1800597768237606953">"Mostra el teclat virtual"</string>
+    <string name="hardware" msgid="3611039921284836033">"Utilitza el teclat en pantalla"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configura <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configura els teclats físics"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Toca per seleccionar l\'idioma i la disposició"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 196fa56..4510eff 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1396,7 +1396,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ODMÍTNOUT"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Vybrat metodu zadávání"</string>
     <string name="show_ime" msgid="6406112007347443383">"Ponechat na obrazovce, když je aktivní fyzická klávesnice"</string>
-    <string name="hardware" msgid="1800597768237606953">"Zobrazit virtuální klávesnici"</string>
+    <string name="hardware" msgid="3611039921284836033">"Použít softwarovou klávesnici"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Nakonfigurujte zařízení <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Nakonfigurujte fyzické klávesnice"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Klepnutím vyberte jazyk a rozvržení"</string>
@@ -1953,7 +1953,7 @@
     <string name="app_suspended_default_message" msgid="6451215678552004172">"Aplikace <xliff:g id="APP_NAME_0">%1$s</xliff:g> momentálně není dostupná. Tato předvolba se spravuje v aplikaci <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string>
     <string name="app_suspended_more_details" msgid="211260942831587014">"Další informace"</string>
     <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Zrušit pozastavení aplikace"</string>
-    <string name="work_mode_off_title" msgid="6367463960165135829">"Zrušit pozast. prac. aplikací?"</string>
+    <string name="work_mode_off_title" msgid="6367463960165135829">"Zrušit pozastavení pracovních aplikací?"</string>
     <string name="work_mode_turn_on" msgid="5316648862401307800">"Zrušit pozastavení"</string>
     <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Stav nouze"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"Aplikace není k dispozici"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index c1f0e71..2f62531 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"AFVIS"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Vælg inputmetode"</string>
     <string name="show_ime" msgid="6406112007347443383">"Behold den på skærmen, mens det fysiske tastatur er aktivt"</string>
-    <string name="hardware" msgid="1800597768237606953">"Vis virtuelt tastatur"</string>
+    <string name="hardware" msgid="3611039921284836033">"Brug skærmtastaturet"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfigurer <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfigurer fysiske tastaturer"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Tryk for at vælge sprog og layout"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index ad6cfbf..713a62f 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ABLEHNEN"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Eingabemethode wählen"</string>
     <string name="show_ime" msgid="6406112007347443383">"Bildschirmtastatur auch dann anzeigen, wenn physische Tastatur aktiv ist"</string>
-    <string name="hardware" msgid="1800597768237606953">"Virtuelle Tastatur einblenden"</string>
+    <string name="hardware" msgid="3611039921284836033">"Bildschirmtastatur verwenden"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> konfigurieren"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Physische Tastaturen konfigurieren"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Zum Auswählen von Sprache und Layout tippen"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 4ea1eab..a58b780 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ΑΠΟΡΡΙΨΗ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Επιλογή μεθόδου εισόδου"</string>
     <string name="show_ime" msgid="6406112007347443383">"Να παραμένει στην οθόνη όταν είναι ενεργό το κανονικό πληκτρολόγιο"</string>
-    <string name="hardware" msgid="1800597768237606953">"Εμφάνιση εικονικού πληκτρολ."</string>
+    <string name="hardware" msgid="3611039921284836033">"Χρήση πληκτρολογίου οθόνης"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Διαμόρφωση <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Διαμόρφωση φυσικών πληκτρολογίων"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Πατήστε για να επιλέξετε γλώσσα και διάταξη"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 675add9..2a5847c 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"DECLINE"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Choose input method"</string>
     <string name="show_ime" msgid="6406112007347443383">"Keep it on screen while physical keyboard is active"</string>
-    <string name="hardware" msgid="1800597768237606953">"Show virtual keyboard"</string>
+    <string name="hardware" msgid="3611039921284836033">"Use on-screen keyboard"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configure <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configure physical keyboards"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Tap to select language and layout"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 7b6ccf3..1942428 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"DECLINE"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Choose input method"</string>
     <string name="show_ime" msgid="6406112007347443383">"Keep it on screen while physical keyboard is active"</string>
-    <string name="hardware" msgid="1800597768237606953">"Show virtual keyboard"</string>
+    <string name="hardware" msgid="3611039921284836033">"Use on-screen keyboard"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configure <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configure physical keyboards"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Tap to select language and layout"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index a1c7872..45b09f5 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"DECLINE"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Choose input method"</string>
     <string name="show_ime" msgid="6406112007347443383">"Keep it on screen while physical keyboard is active"</string>
-    <string name="hardware" msgid="1800597768237606953">"Show virtual keyboard"</string>
+    <string name="hardware" msgid="3611039921284836033">"Use on-screen keyboard"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configure <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configure physical keyboards"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Tap to select language and layout"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 7c467e8..81145e8 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"DECLINE"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Choose input method"</string>
     <string name="show_ime" msgid="6406112007347443383">"Keep it on screen while physical keyboard is active"</string>
-    <string name="hardware" msgid="1800597768237606953">"Show virtual keyboard"</string>
+    <string name="hardware" msgid="3611039921284836033">"Use on-screen keyboard"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configure <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configure physical keyboards"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Tap to select language and layout"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 4f6c120..54d0278 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‏‎‏‎‎‎‎‏‎‎‏‎‎‎‏‏‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‏‎‎‎‏‎‎‎‎‎‏‏‎‎‏‏‎‏‎‎DECLINE‎‏‎‎‏‎"</string>
     <string name="select_input_method" msgid="3971267998568587025">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‎‏‏‏‎‎‏‏‎‎‎‏‏‏‎‎‏‏‎‏‎‎‎‎‏‏‏‎‏‎‏‎‎‎‏‏‏‎‏‎‎‏‏‏‏‏‎‎‎‏‎‎‎‏‎Choose input method‎‏‎‎‏‎"</string>
     <string name="show_ime" msgid="6406112007347443383">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎‎‏‏‏‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‏‎‎‎‏‎‏‏‎‏‎‏‏‎‏‏‏‎Keep it on screen while physical keyboard is active‎‏‎‎‏‎"</string>
-    <string name="hardware" msgid="1800597768237606953">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‎‎‎‏‎‎‎‎‏‎‏‎‏‎‏‏‏‎‎‏‎‏‎‎‏‏‏‏‎‏‎‎‎‎‎‏‎‏‎‎‏‎Show virtual keyboard‎‏‎‎‏‎"</string>
+    <string name="hardware" msgid="3611039921284836033">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‎‏‏‏‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‎‏‎Use on-screen keyboard‎‏‎‎‏‎"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‏‎‎‎‎‎‎‏‎‏‎‎‏‎‏‏‏‎‎‏‏‏‏‎‎‎‎‎‎‏‏‎‎‎‏‎‏‏‎‎‏‏‏‎‏‏‎‎‏‎‏‎‏‎Configure ‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‎‎‎‏‏‎‎‏‏‎‎‎‎‎‎‎‎‎‎‎‎‏‎‏‎‎‎‎‏‎‎‏‏‎‏‎‏‎‏‎‏‎‎‎‏‎‎‎‏‎‎‏‎‎Configure physical keyboards‎‏‎‎‏‎"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‏‏‎‎‏‎‎‏‏‎‎‏‏‏‎‏‏‎‎‎‎‏‎‎‏‏‎‎‏‏‎‏‎‎‏‎‏‏‏‎‎‎‎‎‏‎‏‎‎Tap to select language and layout‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 9343060..fcb3f08 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1395,7 +1395,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"RECHAZAR"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Selecciona el método de entrada"</string>
     <string name="show_ime" msgid="6406112007347443383">"Mientras el teclado físico está activo"</string>
-    <string name="hardware" msgid="1800597768237606953">"Mostrar teclado virtual"</string>
+    <string name="hardware" msgid="3611039921284836033">"Usar teclado en pantalla"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configura <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configura teclados físicos"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Presiona para seleccionar el idioma y el diseño"</string>
@@ -2336,9 +2336,9 @@
     <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Desactivar"</string>
     <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Se configuró <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Diseño de teclado establecido en <xliff:g id="LAYOUT_1">%s</xliff:g>. Presiona para cambiar esta opción."</string>
-    <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Diseño de teclado establecido en <xliff:g id="LAYOUT_1">%1$s</xliff:g> y <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Presiona para cambiar esta opción."</string>
-    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Diseño de teclado establecido en <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> y <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Presiona para cambiar esta opción."</string>
-    <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Diseño de teclado establecido en <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> y <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Presiona para cambiarlo."</string>
+    <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Diseño de teclado establecido en <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Presiona para cambiar esta opción."</string>
+    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Diseño de teclado establecido en <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Presiona para cambiar esta opción."</string>
+    <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Diseño de teclado establecido en <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Presiona para cambiar esta opción."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Teclados físicos configurados"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Presiona para ver los teclados"</string>
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index c0e705c..4c5939c 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1395,7 +1395,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"RECHAZAR"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Selecciona un método de entrada"</string>
     <string name="show_ime" msgid="6406112007347443383">"Mantenlo en pantalla mientras el teclado físico está activo"</string>
-    <string name="hardware" msgid="1800597768237606953">"Mostrar teclado virtual"</string>
+    <string name="hardware" msgid="3611039921284836033">"Usar teclado en pantalla"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configura <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configura teclados físicos"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Toca para seleccionar el idioma y el diseño"</string>
@@ -2336,8 +2336,8 @@
     <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Desactivar"</string>
     <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> configurado"</string>
     <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Diseño del teclado definido como <xliff:g id="LAYOUT_1">%s</xliff:g>. Toca para cambiarlo."</string>
-    <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Diseño del teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g> y <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Toca para cambiarlo."</string>
-    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Diseño del teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> y <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Toca para cambiarlo."</string>
+    <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Diseño del teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Toca para cambiarlo."</string>
+    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Diseño del teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Toca para cambiarlo."</string>
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Diseño del teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Toca para cambiarlo."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Teclados físicos configurados"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Toca para ver los teclados"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index c50f3ba..df2e2af 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"KEELDU"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Valige sisestusmeetod"</string>
     <string name="show_ime" msgid="6406112007347443383">"Hoia seda ekraanil, kui füüsiline klaviatuur on aktiivne"</string>
-    <string name="hardware" msgid="1800597768237606953">"Virtuaalse klaviatuuri kuvam."</string>
+    <string name="hardware" msgid="3611039921284836033">"Kasuta ekraaniklaviatuuri"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Seadistage <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Seadistage füüsilised klaviatuurid"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Puudutage keele ja paigutuse valimiseks"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 51f41ef..5ccae4a 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"BAZTERTU"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Aukeratu idazketa-metodoa"</string>
     <string name="show_ime" msgid="6406112007347443383">"Erakutsi pantailan teklatu fisikoa aktibo dagoen bitartean"</string>
-    <string name="hardware" msgid="1800597768237606953">"Erakutsi teklatu birtuala"</string>
+    <string name="hardware" msgid="3611039921284836033">"Erabili pantailako teklatua"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfiguratu <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfiguratu teklatu fisikoak"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Hizkuntza eta diseinua hautatzeko, sakatu hau"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index b594258..226be57 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -393,7 +393,7 @@
     <string name="permdesc_killBackgroundProcesses" msgid="2357013583055434685">"به برنامه امکان می‌دهد به فرآیندهای پس‌زمینه سایر برنامه‌ها پایان دهد. این ممکن است باعث شود سایر برنامه‌ها متوقف شوند."</string>
     <string name="permlab_systemAlertWindow" msgid="5757218350944719065">"این برنامه می‌تواند روی برنامه‌های دیگر ظاهر شود"</string>
     <string name="permdesc_systemAlertWindow" msgid="1145660714855738308">"این برنامه می‌تواند روی برنامه‌های دیگر یا سایر قسمت‌های صفحه ظاهر شود. ممکن است در عملکرد معمول برنامه‌های دیگر اختلال ایجاد کند و شیوه نمایش آن‌ها را تغییر دهد."</string>
-    <string name="permlab_hideOverlayWindows" msgid="6382697828482271802">"پنهان کردن هم‌پوشانی برنامه‌های دیگر"</string>
+    <string name="permlab_hideOverlayWindows" msgid="6382697828482271802">"پنهان کردن رونهاد برنامه‌های دیگر"</string>
     <string name="permdesc_hideOverlayWindows" msgid="5660242821651958225">"این برنامه می‌تواند از سیستم بخواهد تا هم‌پوشانی‌های ایجادشده توسط برنامه‌های دیگر را روی برنامه نشان ندهد."</string>
     <string name="permlab_runInBackground" msgid="541863968571682785">"اجرا شدن در پس‌زمینه"</string>
     <string name="permdesc_runInBackground" msgid="4344539472115495141">"این برنامه می‌تواند در پس‌زمینه اجرا شود. ممکن است شارژ باتری زودتر مصرف شود."</string>
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"نپذیرفتن"</string>
     <string name="select_input_method" msgid="3971267998568587025">"انتخاب روش ورودی"</string>
     <string name="show_ime" msgid="6406112007347443383">"وقتی صفحه‌کلید فیزیکی فعال است این ویرایشگر را روی صفحه نگه‌می‌دارد"</string>
-    <string name="hardware" msgid="1800597768237606953">"نمایش صفحه‌کلید مجازی"</string>
+    <string name="hardware" msgid="3611039921284836033">"استفاده از صفحه‌کلید مجازی"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"پیکربندی <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"پیکربندی صفحه‌کلیدهای فیزیکی"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"برای انتخاب زبان و چیدمان ضربه بزنید"</string>
@@ -1640,7 +1640,7 @@
     <string name="media_route_status_in_use" msgid="6684112905244944724">"در حال استفاده"</string>
     <string name="display_manager_built_in_display_name" msgid="1015775198829722440">"صفحه نمایش از خود"</string>
     <string name="display_manager_hdmi_display_name" msgid="1022758026251534975">"‏صفحه HDMI"</string>
-    <string name="display_manager_overlay_display_name" msgid="5306088205181005861">"هم‌پوشانی #<xliff:g id="ID">%1$d</xliff:g>"</string>
+    <string name="display_manager_overlay_display_name" msgid="5306088205181005861">"رونهاد #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="1480158037150469170">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="2810034719482834679">"، امن"</string>
     <string name="kg_forgot_pattern_button_text" msgid="406145459223122537">"الگو را فراموش کرده‌اید"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index edfae76..b88abb0 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"HYLKÄÄ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Valitse syöttötapa"</string>
     <string name="show_ime" msgid="6406112007347443383">"Pidä näytöllä, kun fyysinen näppäimistö on aktiivinen"</string>
-    <string name="hardware" msgid="1800597768237606953">"Näytä virtuaalinen näppäimistö"</string>
+    <string name="hardware" msgid="3611039921284836033">"Käytä näyttönäppäimistöä"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Määritä <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Määritä fyysiset näppäimistöt"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Valitse kieli ja asettelu koskettamalla."</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index bca6087..02bc75c 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1395,7 +1395,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"REFUSER"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Sélectionnez le mode de saisie"</string>
     <string name="show_ime" msgid="6406112007347443383">"Afficher lorsque le clavier physique est activé"</string>
-    <string name="hardware" msgid="1800597768237606953">"Afficher le clavier virtuel"</string>
+    <string name="hardware" msgid="3611039921284836033">"Utiliser le clavier à l\'écran"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configurer <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configurer les claviers physiques"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Touchez pour sélectionner la langue et la configuration du clavier"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 221c526..e922931 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1395,7 +1395,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"REFUSER"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Sélectionnez le mode de saisie"</string>
     <string name="show_ime" msgid="6406112007347443383">"Afficher le clavier virtuel même lorsque le clavier physique est actif"</string>
-    <string name="hardware" msgid="1800597768237606953">"Afficher le clavier virtuel"</string>
+    <string name="hardware" msgid="3611039921284836033">"Utiliser le clavier à l\'écran"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configurer <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configurez les claviers physiques"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Appuyez pour sélectionner la langue et la disposition"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 39ae243..d868975 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ANULAR"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Escoller método de introdución de texto"</string>
     <string name="show_ime" msgid="6406112007347443383">"Móstrase na pantalla mentres o teclado físico estea activo"</string>
-    <string name="hardware" msgid="1800597768237606953">"Mostrar teclado virtual"</string>
+    <string name="hardware" msgid="3611039921284836033">"Utilizar o teclado en pantalla"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configura o teclado (<xliff:g id="DEVICE_NAME">%s</xliff:g>)"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configura os teclados físicos"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Toca para seleccionar o idioma e o deseño"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 703bb44..9531ff8 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"નકારો"</string>
     <string name="select_input_method" msgid="3971267998568587025">"ઇનપુટ પદ્ધતિ પસંદ કરો"</string>
     <string name="show_ime" msgid="6406112007347443383">"જ્યારે ભૌતિક કીબોર્ડ સક્રિય હોય ત્યારે તેને સ્ક્રીન પર રાખો"</string>
-    <string name="hardware" msgid="1800597768237606953">"વર્ચ્યુઅલ કીબોર્ડ બતાવો"</string>
+    <string name="hardware" msgid="3611039921284836033">"ઑન-સ્ક્રીન કીબોર્ડનો ઉપયોગ કરો"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g>ની ગોઠવણી કરો"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"ભૌતિક કીબોર્ડની ગોઠવણી કરો"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ભાષા અને લેઆઉટ પસંદ કરવા માટે ટૅપ કરો"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index bfa4f39..bed4cfa 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"अस्वीकार करें"</string>
     <string name="select_input_method" msgid="3971267998568587025">"इनपुट का तरीका चुनें"</string>
     <string name="show_ime" msgid="6406112007347443383">"सामान्य कीबोर्ड के सक्रिय होने के दौरान इसे स्‍क्रीन पर बनाए रखें"</string>
-    <string name="hardware" msgid="1800597768237606953">"वर्चुअल कीबोर्ड दिखाएं"</string>
+    <string name="hardware" msgid="3611039921284836033">"ऑन-स्क्रीन कीबोर्ड इस्तेमाल करें"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> को कॉन्फ़िगर करें"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"फ़िज़िकल कीबोर्ड को कॉन्फ़िगर करें"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"भाषा और लेआउट चुनने के लिए टैप करें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index d655dd4..b4c5cd4 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1395,7 +1395,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ODBIJ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Odabir načina unosa"</string>
     <string name="show_ime" msgid="6406112007347443383">"Zadrži na zaslonu dok je fizička tipkovnica aktivna"</string>
-    <string name="hardware" msgid="1800597768237606953">"Prikaži virtualnu tipkovnicu"</string>
+    <string name="hardware" msgid="3611039921284836033">"Upotreba zaslonske tipkovnice"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfigurirajte uređaj <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfigurirajte fizičke tipkovnice"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Dodirnite da biste odabrali jezik i raspored"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index e5efd16..0f364ed 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ELUTASÍTÁS"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Beviteli mód kiválasztása"</string>
     <string name="show_ime" msgid="6406112007347443383">"Maradjon a képernyőn, amíg a billentyűzet aktív"</string>
-    <string name="hardware" msgid="1800597768237606953">"Virtuális billentyűzet"</string>
+    <string name="hardware" msgid="3611039921284836033">"Képernyő-billentyűzet"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"A(z) <xliff:g id="DEVICE_NAME">%s</xliff:g> beállítása"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Fizikai billentyűzetek beállítása"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Koppintson a nyelv és a billentyűzetkiosztás kiválasztásához"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index f831700..33a90c2 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ՄԵՐԺԵԼ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Ընտրեք ներածման եղանակը"</string>
     <string name="show_ime" msgid="6406112007347443383">"Պահել էկրանին, երբ ֆիզիկական ստեղնաշարն ակտիվ է"</string>
-    <string name="hardware" msgid="1800597768237606953">"Ցույց տալ վիրտուալ ստեղնաշարը"</string>
+    <string name="hardware" msgid="3611039921284836033">"Օգտագործել էկրանային ստեղնաշար"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Կարգավորեք <xliff:g id="DEVICE_NAME">%s</xliff:g> սարքը"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Կարգավորեք ֆիզիկական ստեղնաշարերը"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Հպեք՝ լեզուն և դասավորությունն ընտրելու համար"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 92d85c7..d834470 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"TOLAK"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Pilih metode masukan"</string>
     <string name="show_ime" msgid="6406112007347443383">"Biarkan di layar meski keyboard fisik aktif"</string>
-    <string name="hardware" msgid="1800597768237606953">"Tampilkan keyboard virtual"</string>
+    <string name="hardware" msgid="3611039921284836033">"Gunakan keyboard virtual"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfigurasi <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfigurasi keyboard fisik"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Ketuk untuk memilih bahasa dan tata letak"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 1c7f5b3..b3c802b 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"HAFNA"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Veldu innsláttaraðferð"</string>
     <string name="show_ime" msgid="6406112007347443383">"Halda því á skjánum meðan vélbúnaðarlyklaborðið er virkt"</string>
-    <string name="hardware" msgid="1800597768237606953">"Sýna sýndarlyklaborð"</string>
+    <string name="hardware" msgid="3611039921284836033">"Nota skjályklaborð"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Stilla <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Stilla vélbúnaðarlyklaborð"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Ýttu til að velja tungumál og útlit"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index fe663dd..d180154 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1395,7 +1395,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"RIFIUTO"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Scegli il metodo di immissione"</string>
     <string name="show_ime" msgid="6406112007347443383">"Tieni sullo schermo quando è attiva la tastiera fisica"</string>
-    <string name="hardware" msgid="1800597768237606953">"Mostra tastiera virtuale"</string>
+    <string name="hardware" msgid="3611039921284836033">"Usa tastiera sullo schermo"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configura <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configura le tastiere fisiche"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Tocca per selezionare la lingua e il layout"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 1bba6e5..96a3618 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1395,7 +1395,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"עדיף שלא"</string>
     <string name="select_input_method" msgid="3971267998568587025">"בחירה של שיטת הזנה"</string>
     <string name="show_ime" msgid="6406112007347443383">"להשאיר במסך בזמן שהמקלדת הפיזית פעילה"</string>
-    <string name="hardware" msgid="1800597768237606953">"הצגת מקלדת וירטואלית"</string>
+    <string name="hardware" msgid="3611039921284836033">"שימוש במקלדת שמופיעה במסך"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"הגדרה של <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"הגדרת מקלדות פיזיות"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"יש להקיש כדי לבחור שפה ופריסה"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 64eb303..5acb6c8 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"共有しない"</string>
     <string name="select_input_method" msgid="3971267998568587025">"入力方法の選択"</string>
     <string name="show_ime" msgid="6406112007347443383">"物理キーボードが有効になっていても画面に表示させます"</string>
-    <string name="hardware" msgid="1800597768237606953">"仮想キーボードの表示"</string>
+    <string name="hardware" msgid="3611039921284836033">"画面キーボードの使用"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g>の設定"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"物理キーボードの設定"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"タップして言語とレイアウトを選択してください"</string>
@@ -2337,7 +2337,7 @@
     <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"キーボードのレイアウトは<xliff:g id="LAYOUT_1">%s</xliff:g>に設定されています。タップで変更できます。"</string>
     <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"キーボードのレイアウトは<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>に設定されています。タップで変更できます。"</string>
     <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"キーボードのレイアウトは<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>、<xliff:g id="LAYOUT_3">%3$s</xliff:g>に設定されています。タップで変更できます。"</string>
-    <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"キーボードのレイアウトは<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>、<xliff:g id="LAYOUT_3">%3$s</xliff:g>に設定されています。タップで変更できます。"</string>
+    <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"キーボードのレイアウトは<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>、<xliff:g id="LAYOUT_3">%3$s</xliff:g>などに設定されています。タップで変更できます。"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"物理キーボードの設定完了"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"タップするとキーボードを表示できます"</string>
 </resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index e09aa15..01bf9b0 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"უარყოფა"</string>
     <string name="select_input_method" msgid="3971267998568587025">"აირჩიეთ შეყვანის მეთოდი"</string>
     <string name="show_ime" msgid="6406112007347443383">"აქტიური ფიზიკური კლავიატურისას ეკრანზე შენარჩუნება"</string>
-    <string name="hardware" msgid="1800597768237606953">"ვირტუალური კლავიატურის ჩვენება"</string>
+    <string name="hardware" msgid="3611039921284836033">"ეკრანული კლავიატურის გამოყენება"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"მოახდინეთ <xliff:g id="DEVICE_NAME">%s</xliff:g>-ის კონფიგურირება"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"მოახდინეთ ფიზიკური კლავიატურების კონფიგურირება"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"შეეხეთ ენისა და განლაგების ასარჩევად"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 70f5828..0659408 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -229,7 +229,7 @@
     <string name="reboot_to_update_reboot" msgid="4474726009984452312">"Қайта іске қосылуда…"</string>
     <string name="reboot_to_reset_title" msgid="2226229680017882787">"Зауыттық деректерді қалпына келтіру"</string>
     <string name="reboot_to_reset_message" msgid="3347690497972074356">"Қайта іске қосылуда…"</string>
-    <string name="shutdown_progress" msgid="5017145516412657345">"Өшірілуде…"</string>
+    <string name="shutdown_progress" msgid="5017145516412657345">"Өшіріліп жатыр…"</string>
     <string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"Планшет өшіріледі."</string>
     <string name="shutdown_confirm" product="tv" msgid="7975942887313518330">"Android TV құрылғысы өшеді."</string>
     <string name="shutdown_confirm" product="watch" msgid="2977299851200240146">"Сағатыңыз өшіріледі."</string>
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ҚАБЫЛДАМАУ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Енгізу әдісін таңдау"</string>
     <string name="show_ime" msgid="6406112007347443383">"Физикалық пернетақта қосулы кезде оны экранға шығару"</string>
-    <string name="hardware" msgid="1800597768237606953">"Виртуалдық пернетақтаны көрсету"</string>
+    <string name="hardware" msgid="3611039921284836033">"Экрандағы пернетақтаны пайдалану"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> конфигурациялау"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Физикалық пернетақталарды конфигурациялау"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Тіл мен пернетақта схемасын таңдау үшін түртіңіз."</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 8647785..549dce8 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1042,7 +1042,7 @@
     <string name="keyguard_accessibility_expand_lock_area" msgid="4215280881346033434">"ពង្រីក​តំបន់​ដោះ​សោ។"</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2968195219692413046">"រុញ​ដោះ​សោ។"</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"លំនាំ​ដោះ​សោ​។"</string>
-    <string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"ដោះ​សោ​តាម​​ទម្រង់​មុខ។"</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"ការដោះ​សោ​ដោយស្កេន​មុខ។"</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="4020864007967340068">"កូដ PIN ដោះ​សោ។"</string>
     <string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"ដោះ​កូដ Pin របស់​សីុម។"</string>
     <string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"ដោះ​កូដ Puk របស់​សីុម។"</string>
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"បដិសេធ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"ជ្រើស​វិធីសាស្ត្រ​បញ្ចូល"</string>
     <string name="show_ime" msgid="6406112007347443383">"ទុកវានៅលើអេក្រង់ខណៈពេលក្តារចុចពិតប្រាកដកំពុងសកម្ម"</string>
-    <string name="hardware" msgid="1800597768237606953">"បង្ហាញក្ដារចុចនិម្មិត"</string>
+    <string name="hardware" msgid="3611039921284836033">"ប្រើក្ដារចុច​លើអេក្រង់"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"កំណត់រចនាសម្ព័ន្ធ <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"កំណត់រចនាសម្ព័ន្ធ​ក្ដារចុចរូបវន្ត"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ប៉ះដើម្បីជ្រើសភាសា និងប្លង់"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 26aa63d..a103f08 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ನಿರಾಕರಿಸಿ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"ಇನ್‌ಪುಟ್‌‌ ವಿಧಾನವನ್ನು ಆರಿಸಿ"</string>
     <string name="show_ime" msgid="6406112007347443383">"ಭೌತಿಕ ಕೀಬೋರ್ಡ್ ಸಕ್ರಿಯವಾಗಿರುವಾಗ ಅದನ್ನು ಪರದೆಯ ಮೇಲಿರಿಸಿ"</string>
-    <string name="hardware" msgid="1800597768237606953">"ವರ್ಚುವಲ್ ಕೀಬೋರ್ಡ್ ತೋರಿಸಿ"</string>
+    <string name="hardware" msgid="3611039921284836033">"ಆನ್-ಸ್ಕ್ರೀನ್ ಕೀಬೋರ್ಡ್ ಬಳಸಿ"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> ಕಾನ್ಫಿಗರ್ ಮಾಡಿ"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"ಭೌತಿಕ ಕೀಬೋರ್ಡ್‌ಗಳನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡಿ"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ಭಾಷೆ ಮತ್ತು ವಿನ್ಯಾಸವನ್ನು ಆಯ್ಕೆ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 18fe689..c15240f 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"거부"</string>
     <string name="select_input_method" msgid="3971267998568587025">"입력 방법 선택"</string>
     <string name="show_ime" msgid="6406112007347443383">"물리적 키보드가 활성 상태인 경우 화면에 켜 둠"</string>
-    <string name="hardware" msgid="1800597768237606953">"가상 키보드 표시"</string>
+    <string name="hardware" msgid="3611039921284836033">"터치 키보드 사용"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> 설정"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"실제 키보드 설정"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"탭하여 언어와 레이아웃을 선택하세요."</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index ede68e4..99c2ead 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -1007,7 +1007,7 @@
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"Android TV түзмөгүңүздүн кулпусун <xliff:g id="NUMBER">%d</xliff:g> жолу туура эмес ачууга аракет жасадыңыз. Android TV түзмөгүңүз эми демейки параметрлерге кайтарылат."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"Сиз телефонду бөгөттөн чыгарууга <xliff:g id="NUMBER">%d</xliff:g> жолу туура эмес аракет кылдыңыз. Телефон баштапкы абалына келтирилет."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"<xliff:g id="NUMBER">%d</xliff:g> секунддан кийин кайталаңыз."</string>
-    <string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"Сүрөт үлгүсүн унутуп калдыңызбы?"</string>
+    <string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"Сүрөт үлгүсүн унутуп койдуңузбу?"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"Аккаунт менен кулпусун ачуу"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"Өтө көп үлгү киргизүү аракети болду"</string>
     <string name="lockscreen_glogin_instructions" msgid="4695162942525531700">"Бөгөттөн чыгарыш үчүн, Google эсебиңиз менен кириңиз."</string>
@@ -1015,7 +1015,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="3031027901286812848">"Сырсөз"</string>
     <string name="lockscreen_glogin_submit_button" msgid="3590556636347843733">"Кирүү"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="4369219936865697679">"Колдонуучу атыңыз же сырсөзүңүз туура эмес."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1683405808525090649">"Колдонуучу атыңызды же сырсөзүңүздү унутуп калдыңызбы?\n"<b>"google.com/accounts/recovery"</b>" дарегине кайрылыңыз."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1683405808525090649">"Колдонуучу атыңызды же сырсөзүңүздү унутуп койдуңузбу?\n"<b>"google.com/accounts/recovery"</b>" дарегине кайрылыңыз."</string>
     <string name="lockscreen_glogin_checking_password" msgid="2607271802803381645">"Текшерүүдө…"</string>
     <string name="lockscreen_unlock_label" msgid="4648257878373307582">"Кулпусун ачуу"</string>
     <string name="lockscreen_sound_on_label" msgid="1660281470535492430">"Добушу күйүк"</string>
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ЧЕТКЕ КАГУУ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Дайын киргизүү ыкмасын тандаңыз"</string>
     <string name="show_ime" msgid="6406112007347443383">"Баскычтоп иштетилгенде экранда көрүнүп турат"</string>
-    <string name="hardware" msgid="1800597768237606953">"Виртуалдык баскычтоп"</string>
+    <string name="hardware" msgid="3611039921284836033">"Экрандагы баскычтопту колдонуу"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> түзмөгүн конфигурациялоо"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Физикалык баскычтопторду конфигурациялоо"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Тил жана калып тандоо үчүн таптап коюңуз"</string>
@@ -1666,7 +1666,7 @@
     <string name="kg_login_password_hint" msgid="3330530727273164402">"Сырсөз"</string>
     <string name="kg_login_submit_button" msgid="893611277617096870">"Кирүү"</string>
     <string name="kg_login_invalid_input" msgid="8292367491901220210">"Колдонуучу атыңыз же сырсөзүңүз туура эмес."</string>
-    <string name="kg_login_account_recovery_hint" msgid="4892466171043541248">"Колдонуучу атыңызды же сырсөзүңүздү унутуп калдыңызбы?\n"<b>"google.com/accounts/recovery"</b>" дарегине кайрылыңыз."</string>
+    <string name="kg_login_account_recovery_hint" msgid="4892466171043541248">"Колдонуучу атыңызды же сырсөзүңүздү унутуп койдуңузбу?\n"<b>"google.com/accounts/recovery"</b>" дарегине кайрылыңыз."</string>
     <string name="kg_login_checking_password" msgid="4676010303243317253">"Эсеп текшерилүүдө…"</string>
     <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Сиз PIN кодуңузду <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин кайталаңыз."</string>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"Сиз сырсөзүңүздү <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин кайталаңыз."</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index b600d2e..3a06f72 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ປະຕິເສດ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"ເລືອກຮູບແບບການປ້ອນ"</string>
     <string name="show_ime" msgid="6406112007347443383">"ເປີດໃຊ້ໃຫ້ມັນຢູ່ໃນໜ້າຈໍໃນຂະນະທີ່ໃຊ້ແປ້ນພິມພາຍນອກຢູ່"</string>
-    <string name="hardware" msgid="1800597768237606953">"ສະແດງແປ້ນພິມສະເໝືອນ"</string>
+    <string name="hardware" msgid="3611039921284836033">"ໃຊ້ແປ້ນພິມໃນໜ້າຈໍ"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"ຕັ້ງຄ່າ <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"ຕັ້ງຄ່າແປ້ນພິມແທ້"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ແຕະເພື່ອເລືອກພາສາ ແລະ ໂຄງແປ້ນພິມ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index e3f1952..f5530fe 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1396,7 +1396,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ATMESTI"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Pasirinkite įvesties metodą"</string>
     <string name="show_ime" msgid="6406112007347443383">"Palikti ekrane, kol fizinė klaviatūra aktyvi"</string>
-    <string name="hardware" msgid="1800597768237606953">"Rodyti virtualiąją klaviatūrą"</string>
+    <string name="hardware" msgid="3611039921284836033">"Ekrano klaviatūros naudojimas"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"„<xliff:g id="DEVICE_NAME">%s</xliff:g>“ konfigūravimas"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Fizinių klaviatūrų konfigūravimas"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Palieskite, kad pasirinktumėte kalbą ir išdėstymą"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index d874fdd..08865b3 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1395,7 +1395,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"NORAIDĪT"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Ievades metodes izvēle"</string>
     <string name="show_ime" msgid="6406112007347443383">"Paturēt ekrānā, kamēr ir aktīva fiziskā tastatūra"</string>
-    <string name="hardware" msgid="1800597768237606953">"Virtuālās tastatūras rādīšana"</string>
+    <string name="hardware" msgid="3611039921284836033">"Izmantojiet ekrāna tastatūru"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Jākonfigurē <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfigurējiet fiziskās tastatūras"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Pieskarieties, lai atlasītu valodu un izkārtojumu"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 06a3530..b574380 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -1257,7 +1257,7 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Се стартуваат апликациите."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Подигањето завршува."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Го притиснавте копчето за вклучување — така обично се исклучува екранот.\n\nДопрете лесно додека го поставувате отпечатокот."</string>
-    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"За да завршите со поставувањето, исклучете го екранот"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"За излез, исклучете го екранот"</string>
     <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Исклучи"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Да продолжи потврдувањето на отпечаток?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Го притиснавте копчето за вклучување — така обично се исклучува екранот.\n\nДопрете лесно за да го потврдите отпечатокот."</string>
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ОДБИЈ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Одбери метод на внес"</string>
     <string name="show_ime" msgid="6406112007347443383">"Прикажувај ја на екранот додека е активна физичката тастатура"</string>
-    <string name="hardware" msgid="1800597768237606953">"Прикажи виртуелна тастатура"</string>
+    <string name="hardware" msgid="3611039921284836033">"Користете тастатура на екран"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Конфигурирање на <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Конфигурирање физички тастатури"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Допрете за избирање јазик и распоред"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 0ca9b37..7856654 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"നിരസിക്കുക"</string>
     <string name="select_input_method" msgid="3971267998568587025">"ഇൻപുട്ട് രീതി തിരഞ്ഞെടുക്കുക"</string>
     <string name="show_ime" msgid="6406112007347443383">"ഫിസിക്കൽ കീബോർഡ് സജീവമായിരിക്കുമ്പോൾ സ്ക്രീനിൽ നിലനിർത്തുക"</string>
-    <string name="hardware" msgid="1800597768237606953">"വെർച്വൽ കീബോർഡ് കാണിക്കുക"</string>
+    <string name="hardware" msgid="3611039921284836033">"ഓൺ-സ്ക്രീൻ കീബോർഡ് ഉപയോഗിക്കൂ"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> കോൺഫിഗർ ചെയ്യുക"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"യഥാർത്ഥ കീബോർഡുകൾ കോൺഫിഗർ ചെയ്യുക"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ഭാഷയും ലേഔട്ടും തിരഞ്ഞെടുക്കുന്നതിന് ടാപ്പ് ചെയ്യുക"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 8df63ec..ef4d07d 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ТАТГАЛЗАХ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Оруулах аргыг сонгоно уу"</string>
     <string name="show_ime" msgid="6406112007347443383">"Биет гар идэвхтэй үед үүнийг дэлгэцэд харуулна уу"</string>
-    <string name="hardware" msgid="1800597768237606953">"Хийсвэр гарыг харуулах"</string>
+    <string name="hardware" msgid="3611039921284836033">"Дэлгэц дээрх гарыг ашиглах"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g>-г тохируулна уу"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Биет гарыг тохируулна уу"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Хэл болон бүдүүвчийг сонгохын тулд дарна уу"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 432ffce..26108cc 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"नकार द्या"</string>
     <string name="select_input_method" msgid="3971267998568587025">"इनपुट पद्धत निवडा"</string>
     <string name="show_ime" msgid="6406112007347443383">"भौतिक कीबोर्ड सक्रिय असताना त्यास स्क्रीनवर ठेवा"</string>
-    <string name="hardware" msgid="1800597768237606953">"व्हर्च्युअल कीबोर्ड दर्शवा"</string>
+    <string name="hardware" msgid="3611039921284836033">"ऑन-स्क्रीन कीबोर्ड वापरा"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> कॉंफिगर करा"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"वास्तविक कीबोर्ड कॉंफिगर करा"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"भाषा आणि लेआउट निवडण्यासाठी टॅप करा"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index ec737c9..12846f9 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"TOLAK"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Pilih kaedah input"</string>
     <string name="show_ime" msgid="6406112007347443383">"Pastikannya pada skrin, semasa papan kekunci fizikal aktif"</string>
-    <string name="hardware" msgid="1800597768237606953">"Tunjukkan papan kekunci maya"</string>
+    <string name="hardware" msgid="3611039921284836033">"Guna papan kekunci pada skrin"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfigurasikan <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfigurasikan papan kekunci fizikal"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Ketik untuk memilih bahasa dan reka letak"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 2df17b4..0ba4c1f 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -229,7 +229,7 @@
     <string name="reboot_to_update_reboot" msgid="4474726009984452312">"ပြန်လည်စတင်နေ…"</string>
     <string name="reboot_to_reset_title" msgid="2226229680017882787">"စက်ရုံထုတ်အခြေအနေပြန်ယူခြင်း"</string>
     <string name="reboot_to_reset_message" msgid="3347690497972074356">"ပြန်လည်စတင်နေ…"</string>
-    <string name="shutdown_progress" msgid="5017145516412657345">"စက်ပိတ်ပါမည်"</string>
+    <string name="shutdown_progress" msgid="5017145516412657345">"စက်ပိတ်နေသည်…"</string>
     <string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"သင့်တက်ဘလက်အား စက်ပိတ်ပါမည်"</string>
     <string name="shutdown_confirm" product="tv" msgid="7975942887313518330">"သင့် Android TV စက်ပစ္စည်း ပိတ်သွားပါမည်။"</string>
     <string name="shutdown_confirm" product="watch" msgid="2977299851200240146">"သင်၏ ကြည့်ရှုမှု ပိတ်ပစ်မည်။"</string>
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ငြင်းပယ်ပါ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"ထည့်သွင်းရေး နည်းကို ရွေးရန်"</string>
     <string name="show_ime" msgid="6406112007347443383">"စက်၏ကီးဘုတ် ဖွင့်ထားစဉ်တွင် ၎င်းကို ဖန်သားပြင်ပေါ်တွင် ဆက်ထားပါ"</string>
-    <string name="hardware" msgid="1800597768237606953">"ပကတိအသွင်ကီးဘုတ်ပြရန်"</string>
+    <string name="hardware" msgid="3611039921284836033">"မျက်နှာပြင် လက်ကွက် သုံးခြင်း"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> ကို စီစဉ်သတ်မှတ်ရန်"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"ပကတိကီးဘုတ်များကို စီစဉ်သတ်မှတ်ရန်"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ဘာသာစကားနှင့် အသွင်အပြင်ရွေးချယ်ရန် တို့ပါ"</string>
@@ -1952,7 +1952,7 @@
     <string name="app_suspended_more_details" msgid="211260942831587014">"ပိုမိုလေ့လာရန်"</string>
     <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"အက်ပ်ကို ခဏမရပ်တော့ရန်"</string>
     <string name="work_mode_off_title" msgid="6367463960165135829">"အလုပ်သုံးအက်ပ် ပြန်ဖွင့်မလား။"</string>
-    <string name="work_mode_turn_on" msgid="5316648862401307800">"ပြန်စရန်"</string>
+    <string name="work_mode_turn_on" msgid="5316648862401307800">"ပြန်ဖွင့်ရန်"</string>
     <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"အရေးပေါ်"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"အက်ပ်ကို မရနိုင်ပါ"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ကို ယခု မရနိုင်ပါ။"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index f8c8aaa..1aa7b71 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"AVSLÅ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Velg inndatametode"</string>
     <string name="show_ime" msgid="6406112007347443383">"Ha den på skjermen mens det fysiske tastaturet er aktivt"</string>
-    <string name="hardware" msgid="1800597768237606953">"Vis det virtuelle tastaturet"</string>
+    <string name="hardware" msgid="3611039921284836033">"Bruk skjermtastaturet"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfigurer <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfigurer de fysiske tastaturene"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Trykk for å velge språk og layout"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index bbb1992..438fc7a 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"अस्वीकार गर्नुहोस्"</string>
     <string name="select_input_method" msgid="3971267998568587025">"निवेश विधि छान्नुहोस्"</string>
     <string name="show_ime" msgid="6406112007347443383">"फिजिकल किबोर्ड सक्रिय हुँदा यसलाई स्क्रिनमा राखियोस्"</string>
-    <string name="hardware" msgid="1800597768237606953">"भर्चुअल किबोर्ड देखाउनुहोस्"</string>
+    <string name="hardware" msgid="3611039921284836033">"अनस्क्रिन किबोर्ड प्रयोग गर्नुहोस्"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> कन्फिगर गर्नुहोस्"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"भौतिक किबोर्डहरू कन्फिगर गर्नुहोस्"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"भाषा र लेआउट चयन गर्न ट्याप गर्नुहोस्"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 5457872..6ab3750 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"WEIGEREN"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Invoermethode selecteren"</string>
     <string name="show_ime" msgid="6406112007347443383">"Toon op het scherm terwijl het fysieke toetsenbord actief is"</string>
-    <string name="hardware" msgid="1800597768237606953">"Virtueel toetsenbord tonen"</string>
+    <string name="hardware" msgid="3611039921284836033">"Schermtoetsenbord gebruiken"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> instellen"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Fysieke toetsenborden instellen"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Tik om een taal en indeling te selecteren"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 6932b44..2dfe517 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -229,7 +229,7 @@
     <string name="reboot_to_update_reboot" msgid="4474726009984452312">"ରିଷ୍ଟାର୍ଟ କରାଯାଉଛି…"</string>
     <string name="reboot_to_reset_title" msgid="2226229680017882787">"ଫ୍ୟାକ୍ଟୋରୀ ଡାଟା ରିସେଟ୍‌"</string>
     <string name="reboot_to_reset_message" msgid="3347690497972074356">"ରିଷ୍ଟାର୍ଟ କରାଯାଉଛି…"</string>
-    <string name="shutdown_progress" msgid="5017145516412657345">"ବନ୍ଦ କରାଯାଉଛି…"</string>
+    <string name="shutdown_progress" msgid="5017145516412657345">"ବନ୍ଦ ହେଉଛି…"</string>
     <string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"ଆପଣଙ୍କ ଟାବଲେଟ୍ ବନ୍ଦ ହୋଇଯିବ।"</string>
     <string name="shutdown_confirm" product="tv" msgid="7975942887313518330">"ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍ ବନ୍ଦ ହୋଇଯିବ।"</string>
     <string name="shutdown_confirm" product="watch" msgid="2977299851200240146">"ଆପଣଙ୍କ ଘଣ୍ଟା ବନ୍ଦ ହୋଇଯିବ।"</string>
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ଅଗ୍ରାହ୍ୟ କରନ୍ତୁ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"ଇନପୁଟ୍ ପଦ୍ଧତି ବାଛନ୍ତୁ"</string>
     <string name="show_ime" msgid="6406112007347443383">"ଫିଜିକାଲ୍‌ କୀବୋର୍ଡ ସକ୍ରିୟ ଥିବାବେଳେ ଏହାକୁ ସ୍କ୍ରିନ୍‌ ଉପରେ ରଖନ୍ତୁ"</string>
-    <string name="hardware" msgid="1800597768237606953">"ଭର୍ଚୁଆଲ୍ କୀ’ବୋର୍ଡ ଦେଖାନ୍ତୁ"</string>
+    <string name="hardware" msgid="3611039921284836033">"ଅନ-ସ୍କ୍ରିନ କୀବୋର୍ଡ ବ୍ୟବହାର କର"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g>କୁ କନଫିଗର କରନ୍ତୁ"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"ଫିଜିକାଲ କୀବୋର୍ଡଗୁଡ଼ିକୁ କନଫିଗର କରନ୍ତୁ"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ଭାଷା ଓ ଲେଆଉଟ ଚୟନ କରିବା ପାଇଁ ଟାପ କରନ୍ତୁ"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 0d0e0c8..2d16afc 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ਅਸਵੀਕਾਰ ਕਰੋ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"ਇਨਪੁਟ ਵਿਧੀ ਚੁਣੋ"</string>
     <string name="show_ime" msgid="6406112007347443383">"ਭੌਤਿਕ ਕੀ-ਬੋਰਡ ਸਰਗਰਮ ਹੋਣ ਦੌਰਾਨ ਇਸ ਨੂੰ ਸਕ੍ਰੀਨ \'ਤੇ ਬਣਾਈ ਰੱਖੋ"</string>
-    <string name="hardware" msgid="1800597768237606953">"ਆਭਾਸੀ ਕੀ-ਬੋਰਡ ਦਿਖਾਓ"</string>
+    <string name="hardware" msgid="3611039921284836033">"ਆਨ-ਸਕ੍ਰੀਨ ਕੀ-ਬੋਰਡ ਨੂੰ ਵਰਤੋ"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> ਦਾ ਸੰਰੂਪਣ ਕਰੋ"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"ਭੌਤਿਕ ਕੀ-ਬੋਰਡਾਂ ਦਾ ਸੰਰੂਪਣ ਕਰੋ"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ਭਾਸ਼ਾ ਅਤੇ ਖਾਕਾ ਚੁਣਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index f72ff68..52869c4 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1396,7 +1396,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ODRZUĆ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Wybierz metodę wprowadzania"</string>
     <string name="show_ime" msgid="6406112007347443383">"Pozostaw na ekranie, gdy aktywna jest klawiatura fizyczna"</string>
-    <string name="hardware" msgid="1800597768237606953">"Pokaż klawiaturę wirtualną"</string>
+    <string name="hardware" msgid="3611039921284836033">"Używaj klawiatury ekranowej"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Skonfiguruj urządzenie <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Skonfiguruj klawiatury fizyczne"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Kliknij, aby wybrać język i układ"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 72cb00e..ccd10c4 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1395,7 +1395,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"RECUSAR"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Selecione o método de entrada"</string>
     <string name="show_ime" msgid="6406112007347443383">"Mantém o teclado virtual na tela enquanto o teclado físico está ativo"</string>
-    <string name="hardware" msgid="1800597768237606953">"Mostrar teclado virtual"</string>
+    <string name="hardware" msgid="3611039921284836033">"Usar teclado na tela"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configure o dispositivo <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configure teclados físicos"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Toque para selecionar o idioma e o layout"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 2158dfd..7335d2b 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1395,7 +1395,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"RECUSAR"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Escolher o método de entrada"</string>
     <string name="show_ime" msgid="6406112007347443383">"Manter no ecrã enquanto o teclado físico estiver ativo"</string>
-    <string name="hardware" msgid="1800597768237606953">"Mostrar o teclado virtual"</string>
+    <string name="hardware" msgid="3611039921284836033">"Usar o teclado no ecrã"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configure o dispositivo <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configure teclados físicos"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Toque para selecionar o idioma e o esquema"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 72cb00e..ccd10c4 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1395,7 +1395,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"RECUSAR"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Selecione o método de entrada"</string>
     <string name="show_ime" msgid="6406112007347443383">"Mantém o teclado virtual na tela enquanto o teclado físico está ativo"</string>
-    <string name="hardware" msgid="1800597768237606953">"Mostrar teclado virtual"</string>
+    <string name="hardware" msgid="3611039921284836033">"Usar teclado na tela"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configure o dispositivo <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configure teclados físicos"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Toque para selecionar o idioma e o layout"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index b52c0eb..e31d465c 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1395,7 +1395,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"REFUZ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Alege metoda de introducere de text"</string>
     <string name="show_ime" msgid="6406112007347443383">"Se păstrează pe ecran cât timp este activată tastatura fizică"</string>
-    <string name="hardware" msgid="1800597768237606953">"Afișează tastatura virtuală"</string>
+    <string name="hardware" msgid="3611039921284836033">"Folosește tastatura pe ecran"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configurează <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configurează tastaturi fizice"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Atinge pentru a selecta limba și aspectul"</string>
@@ -1952,7 +1952,7 @@
     <string name="app_suspended_default_message" msgid="6451215678552004172">"Momentan, aplicația <xliff:g id="APP_NAME_0">%1$s</xliff:g> nu este disponibilă. Aceasta este gestionată de <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string>
     <string name="app_suspended_more_details" msgid="211260942831587014">"Află mai multe"</string>
     <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Anulează întreruperea aplicației"</string>
-    <string name="work_mode_off_title" msgid="6367463960165135829">"Reactivezi aplicații lucru?"</string>
+    <string name="work_mode_off_title" msgid="6367463960165135829">"Reactivezi aplicații de lucru?"</string>
     <string name="work_mode_turn_on" msgid="5316648862401307800">"Reactivează"</string>
     <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Urgență"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"Aplicația nu este disponibilă"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index f8f323f..9ad5dd4 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1396,7 +1396,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ОТКЛОНИТЬ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Выберите способ ввода"</string>
     <string name="show_ime" msgid="6406112007347443383">"Не скрывать экранную клавиатуру, когда включена физическая"</string>
-    <string name="hardware" msgid="1800597768237606953">"Виртуальная клавиатура"</string>
+    <string name="hardware" msgid="3611039921284836033">"Использовать экранную клавиатуру"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Настройте устройство \"<xliff:g id="DEVICE_NAME">%s</xliff:g>\""</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Настройте физические клавиатуры"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Нажмите, чтобы выбрать язык и раскладку"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index a62caeb..c476342 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ප්‍රතික්ෂේප කරන්න"</string>
     <string name="select_input_method" msgid="3971267998568587025">"ආදාන ක්‍රමයක් තෝරන්න"</string>
     <string name="show_ime" msgid="6406112007347443383">"භෞතික යතුරු පුවරුව සක්‍රිය අතරතුර එය තිරය මත තබා ගන්න"</string>
-    <string name="hardware" msgid="1800597768237606953">"අතථ්‍ය යතුරු පුවරුව පෙන්වන්න"</string>
+    <string name="hardware" msgid="3611039921284836033">"තිරය මත යතුරු පුවරුව භාවිතය"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> වින්‍යාස කරන්න"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"භෞතික යතුරුපුවරුව වින්‍යාස කරන්න"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"භාෂාව හා පිරිසැලසුම තේරීමට තට්ටු කරන්න"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 9c3c655..16fa3cc 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -231,7 +231,7 @@
     <string name="reboot_to_update_reboot" msgid="4474726009984452312">"Reštartuje sa…"</string>
     <string name="reboot_to_reset_title" msgid="2226229680017882787">"Obnovenie výrobných nastavení"</string>
     <string name="reboot_to_reset_message" msgid="3347690497972074356">"Reštartuje sa…"</string>
-    <string name="shutdown_progress" msgid="5017145516412657345">"Prebieha vypínanie..."</string>
+    <string name="shutdown_progress" msgid="5017145516412657345">"Vypína sa..."</string>
     <string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"Váš tablet bude vypnutý."</string>
     <string name="shutdown_confirm" product="tv" msgid="7975942887313518330">"Zariadenie Android TV sa vypne."</string>
     <string name="shutdown_confirm" product="watch" msgid="2977299851200240146">"Hodinky sa vypnú."</string>
@@ -1396,7 +1396,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ODMIETNUŤ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Zvoliť metódu vstupu"</string>
     <string name="show_ime" msgid="6406112007347443383">"Ponechať na obrazovke, keď je aktívna fyzická klávesnica"</string>
-    <string name="hardware" msgid="1800597768237606953">"Zobraziť virtuálnu klávesnicu"</string>
+    <string name="hardware" msgid="3611039921284836033">"Použiť klávesnicu na obrazovke"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Nakonfigurujte <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Nakonfigurujte fyzické klávesnice"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Klepnutím vyberte jazyk a rozloženie"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index f92a5bd..bc6af03 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -231,7 +231,7 @@
     <string name="reboot_to_update_reboot" msgid="4474726009984452312">"Vnovičen zagon …"</string>
     <string name="reboot_to_reset_title" msgid="2226229680017882787">"Ponastavitev na tovarniške nastavitve"</string>
     <string name="reboot_to_reset_message" msgid="3347690497972074356">"Vnovičen zagon …"</string>
-    <string name="shutdown_progress" msgid="5017145516412657345">"Se zaustavlja ..."</string>
+    <string name="shutdown_progress" msgid="5017145516412657345">"Izklaplja se ..."</string>
     <string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"Tablični računalnik se bo zaustavil."</string>
     <string name="shutdown_confirm" product="tv" msgid="7975942887313518330">"Naprava Android TV se bo zaustavila."</string>
     <string name="shutdown_confirm" product="watch" msgid="2977299851200240146">"Ura se bo izklopila."</string>
@@ -1396,7 +1396,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"NE SPREJMEM"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Izberite način vnosa"</string>
     <string name="show_ime" msgid="6406112007347443383">"Ohrani na zaslonu, dokler je aktivna fizična tipkovnica"</string>
-    <string name="hardware" msgid="1800597768237606953">"Pokaži navidezno tipkovnico"</string>
+    <string name="hardware" msgid="3611039921284836033">"Uporaba zaslonske tipkovnice"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfiguriranje naprave <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfiguriranje fizičnih tipkovnic"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Dotaknite se, če želite izbrati jezik in postavitev."</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 512dbc7..5ce4aa9 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"REFUZO"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Zgjidh metodën e hyrjes"</string>
     <string name="show_ime" msgid="6406112007347443383">"Mbaje në ekran ndërsa tastiera fizike është aktive"</string>
-    <string name="hardware" msgid="1800597768237606953">"Shfaq tastierën virtuale"</string>
+    <string name="hardware" msgid="3611039921284836033">"Përdor tastierën në ekran"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfiguro <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfiguro tastierat fizike"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Trokit për të zgjedhur gjuhën dhe strukturën"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index ccd638e..84713fd 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1395,7 +1395,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ОДБИЈ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Избор метода уноса"</string>
     <string name="show_ime" msgid="6406112007347443383">"Задржава се на екрану док је физичка тастатура активна"</string>
-    <string name="hardware" msgid="1800597768237606953">"Прикажи виртуелну тастатуру"</string>
+    <string name="hardware" msgid="3611039921284836033">"Користи тастатуру на екрану"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Конфигуришите уређај <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Конфигуришите физичке тастатуре"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Додирните да бисте изабрали језик и распоред"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 4b5d45e..99dc2da 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"AVVISA"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Välj inmatningsmetod"</string>
     <string name="show_ime" msgid="6406112007347443383">"Ha kvar det på skärmen när det fysiska tangentbordet används"</string>
-    <string name="hardware" msgid="1800597768237606953">"Visa virtuellt tangentbord"</string>
+    <string name="hardware" msgid="3611039921284836033">"Använd skärmtangentbord"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfigurera <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfigurera fysiska tangentbord"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Tryck om du vill välja språk och layout"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 5e30e0d..aeb0d2b 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"KATAA"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Chagua njia ya ingizo"</string>
     <string name="show_ime" msgid="6406112007347443383">"Ionyeshe kwenye skrini wakati kibodi halisi inatumika"</string>
-    <string name="hardware" msgid="1800597768237606953">"Onyesha kibodi pepe"</string>
+    <string name="hardware" msgid="3611039921284836033">"Tumia kibodi ya skrini"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Wekea mipangilio <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Wekea kibodi halisi mipangilio"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Gusa ili uchague lugha na muundo"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 26442bf..f0e90ea 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"வேண்டாம்"</string>
     <string name="select_input_method" msgid="3971267998568587025">"உள்ளீட்டு முறையைத் தேர்வுசெய்க"</string>
     <string name="show_ime" msgid="6406112007347443383">"கைமுறை கீபோர்டு இயக்கத்தில் இருக்கும் போது IMEஐ திரையில் வைத்திரு"</string>
-    <string name="hardware" msgid="1800597768237606953">"விர்ச்சுவல் கீபோர்டை காட்டு"</string>
+    <string name="hardware" msgid="3611039921284836033">"ஸ்கிரீன் கீபோர்டை உபயோகி"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> சாதனத்தை உள்ளமைத்தல்"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"கீபோர்டுகளை உள்ளமைத்தல்"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"மொழியையும் தளவமைப்பையும் தேர்ந்தெடுக்க, தட்டவும்"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 73aab58..5a97285 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -657,7 +657,7 @@
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"సెన్సార్ తాత్కాలికంగా డిజేబుల్ చేయబడింది."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"వేలిముద్ర సెన్సార్‌ను ఉపయోగించడం సాధ్యం కాదు. రిపెయిర్ ప్రొవైడర్‌ను సందర్శించండి"</string>
     <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Power button pressed"</string>
-    <string name="fingerprint_name_template" msgid="8941662088160289778">"వేలు <xliff:g id="FINGERID">%d</xliff:g>"</string>
+    <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>వ వేలు"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"వేలిముద్రను ఉపయోగించండి"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"వేలిముద్ర లేదా స్క్రీన్ లాక్‌ను ఉపయోగించండి"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"కొనసాగించడానికి మీ వేలిముద్రను ఉపయోగించండి"</string>
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"తిరస్కరిస్తున్నాను"</string>
     <string name="select_input_method" msgid="3971267998568587025">"ఇన్‌పుట్ పద్ధతిని ఎంచుకోండి"</string>
     <string name="show_ime" msgid="6406112007347443383">"దీన్ని భౌతిక కీబోర్డ్ యాక్టివ్‌గా ఉన్నప్పుడు స్క్రీన్‌పై ఉంచుతుంది"</string>
-    <string name="hardware" msgid="1800597768237606953">"వర్చువల్ కీబోర్డ్‌ను చూపు"</string>
+    <string name="hardware" msgid="3611039921284836033">"స్క్రీన్‌పై కీబోర్డ్ ఉపయోగించు"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g>‌ను కాన్ఫిగర్ చేయండి"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"ఫిజికల్ కీబోర్డ్‌లను కాన్ఫిగ‌ర్ చేయండి"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"భాషను, లేఅవుట్‌ను ఎంచుకోవడానికి ట్యాప్ చేయండి"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 916e857..8aab6fa 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ปฏิเสธ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"เลือกวิธีการป้อนข้อมูล"</string>
     <string name="show_ime" msgid="6406112007347443383">"เปิดทิ้งไว้บนหน้าจอในระหว่างใช้งานแป้นพิมพ์จริง"</string>
-    <string name="hardware" msgid="1800597768237606953">"แสดงแป้นพิมพ์เสมือน"</string>
+    <string name="hardware" msgid="3611039921284836033">"ใช้แป้นพิมพ์บนหน้าจอ"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"กำหนดค่า <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"กำหนดค่าแป้นพิมพ์จริง"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"แตะเพื่อเลือกภาษาและรูปแบบ"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 786c324..beb0c0d 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"TANGGIHAN"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Pumili ng pamamaraan ng pag-input"</string>
     <string name="show_ime" msgid="6406112007347443383">"Panatilihin ito sa screen habang aktibo ang pisikal na keyboard"</string>
-    <string name="hardware" msgid="1800597768237606953">"Ipakita ang virtual keyboard"</string>
+    <string name="hardware" msgid="3611039921284836033">"Gumamit ng on-screen keyboard"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"I-configure ang <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"I-configure ang mga pisikal na keyboard"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"I-tap upang pumili ng wika at layout"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index a0c71b5..c002f0f 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"REDDET"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Giriş yöntemini seçin"</string>
     <string name="show_ime" msgid="6406112007347443383">"Fiziksel klavye etkin durumdayken ekranda tut"</string>
-    <string name="hardware" msgid="1800597768237606953">"Sanal klavyeyi göster"</string>
+    <string name="hardware" msgid="3611039921284836033">"Ekran klavyesi kullanın"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> ayarlarını yapılandır"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Fiziksel klavyeleri yapılandırın"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Dili ve düzeni seçmek için dokunun"</string>
@@ -1951,7 +1951,7 @@
     <string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> uygulaması şu anda kullanılamıyor. Uygulamanın kullanım durumu <xliff:g id="APP_NAME_1">%2$s</xliff:g> tarafından yönetiliyor."</string>
     <string name="app_suspended_more_details" msgid="211260942831587014">"Daha fazla bilgi"</string>
     <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Uygulamanın duraklatmasını kaldır"</string>
-    <string name="work_mode_off_title" msgid="6367463960165135829">"İş uygulamaları açılsın mı?"</string>
+    <string name="work_mode_off_title" msgid="6367463960165135829">"İş uygulamaları devam ettirilsin mi?"</string>
     <string name="work_mode_turn_on" msgid="5316648862401307800">"Devam ettir"</string>
     <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Acil durum"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"Uygulama kullanılamıyor"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 0c9f99a..d782f2d 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -673,7 +673,7 @@
     <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Натисніть, щоб видалити свою модель обличчя, а потім знову додайте її"</string>
     <string name="face_setup_notification_title" msgid="8843461561970741790">"Налаштування фейс-контролю"</string>
     <string name="face_setup_notification_content" msgid="5463999831057751676">"Ви зможете розблоковувати телефон, подивившись на нього"</string>
-    <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Щоб використовувати фейсконтроль, увімкніть "<b>"Доступ до камери"</b>" в розділі \"Налаштування\" &gt; \"Конфіденційність\""</string>
+    <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Щоб використовувати фейс-контроль, увімкніть "<b>"Доступ до камери"</b>" в розділі \"Налаштування\" &gt; \"Конфіденційність\""</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Налаштуйте більше способів розблокування"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Натисніть, щоб додати відбиток пальця"</string>
     <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Розблокування відбитком пальця"</string>
@@ -717,12 +717,12 @@
     <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Забагато спроб. Фейс-контроль недоступний."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Забагато спроб. Розблокуйте екран іншим способом."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Не вдається перевірити обличчя. Повторіть спробу."</string>
-    <string name="face_error_not_enrolled" msgid="1134739108536328412">"Ви не налаштували фейсконтроль"</string>
-    <string name="face_error_hw_not_present" msgid="7940978724978763011">"Фейсконтроль не підтримується на цьому пристрої"</string>
+    <string name="face_error_not_enrolled" msgid="1134739108536328412">"Ви не налаштували фейс-контроль"</string>
+    <string name="face_error_hw_not_present" msgid="7940978724978763011">"Фейс-контроль не підтримується на цьому пристрої"</string>
     <string name="face_error_security_update_required" msgid="5076017208528750161">"Датчик тимчасово вимкнено."</string>
     <string name="face_name_template" msgid="3877037340223318119">"Обличчя <xliff:g id="FACEID">%d</xliff:g>"</string>
-    <string name="face_app_setting_name" msgid="5854024256907828015">"Доступ через фейсконтроль"</string>
-    <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Використовувати фейсконтроль або дані для розблокування екрана"</string>
+    <string name="face_app_setting_name" msgid="5854024256907828015">"Доступ через фейс-контроль"</string>
+    <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Використовувати фейс-контроль або дані для розблокування екрана"</string>
     <string name="face_dialog_default_subtitle" msgid="6620492813371195429">"Щоб продовжити, скористайтеся фейсконтролем"</string>
     <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Щоб продовжити, скористайтеся фейсконтролем або даними для розблокування екрана"</string>
   <string-array name="face_error_vendor">
@@ -974,7 +974,7 @@
     <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Повторіть спробу"</string>
     <string name="lockscreen_password_wrong" msgid="8605355913868947490">"Повторіть спробу"</string>
     <string name="lockscreen_storage_locked" msgid="634993789186443380">"Розблокуйте, щоб бачити всі функції й дані"</string>
-    <string name="faceunlock_multiple_failures" msgid="681991538434031708">"Перевищено максимальну кількість спроб розблокування за допомогою функції \"Фейсконтроль\""</string>
+    <string name="faceunlock_multiple_failures" msgid="681991538434031708">"Перевищено максимальну кількість спроб розблокування за допомогою функції \"Фейс-контроль\""</string>
     <string name="lockscreen_missing_sim_message_short" msgid="1229301273156907613">"Немає SIM-карти"</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="3986843848305639161">"У планшеті немає SIM-карти."</string>
     <string name="lockscreen_missing_sim_message" product="tv" msgid="3903140876952198273">"У пристрої Android TV немає SIM-карти."</string>
@@ -1396,7 +1396,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ВІДХИЛИТИ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Вибрати метод введення"</string>
     <string name="show_ime" msgid="6406112007347443383">"Утримуйте на екрані, коли активна фізична клавіатура"</string>
-    <string name="hardware" msgid="1800597768237606953">"Показати віртуальну клавіатуру"</string>
+    <string name="hardware" msgid="3611039921284836033">"Екранна клавіатура"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Налаштуйте клавіатуру \"<xliff:g id="DEVICE_NAME">%s</xliff:g>\""</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Налаштуйте фізичні клавіатури"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Торкніться, щоб вибрати мову та розкладку"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index e1c2752..91b3e95 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"مسترد کریں"</string>
     <string name="select_input_method" msgid="3971267998568587025">"ان پٹ کا طریقہ منتخب کریں"</string>
     <string name="show_ime" msgid="6406112007347443383">"‏جب فزیکل کی بورڈ فعال ہو تو IME کو اسکرین پر رکھیں"</string>
-    <string name="hardware" msgid="1800597768237606953">"ورچوئل کی بورڈ دکھائیں"</string>
+    <string name="hardware" msgid="3611039921284836033">"آن اسکرین کی بورڈ استعمال کریں"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> کنفیگر کریں"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"فزیکل کی بورڈز کنفیگر کریں"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"زبان اور لے آؤٹ منتخب کرنے کیلئے تھپتھپائیں"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 93ad0ce..284abb2 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"RAD ETISH"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Matn kiritish usulini tanlang"</string>
     <string name="show_ime" msgid="6406112007347443383">"Tashqi klaviatura ulanganida ekranda chiqib turadi"</string>
-    <string name="hardware" msgid="1800597768237606953">"Virtual klaviatura"</string>
+    <string name="hardware" msgid="3611039921284836033">"Ekrandagi klaviatura"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Sozlang: <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Tashqi klaviaturalarni sozlang"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Til va sxemani belgilash uchun bosing"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index bfe1561..621eadd 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"TỪ CHỐI"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Chọn phương thức nhập"</string>
     <string name="show_ime" msgid="6406112007347443383">"Hiện bàn phím ảo trên màn hình trong khi bàn phím vật lý đang hoạt động"</string>
-    <string name="hardware" msgid="1800597768237606953">"Hiện bàn phím ảo"</string>
+    <string name="hardware" msgid="3611039921284836033">"Sử dụng bàn phím ảo"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Định cấu hình <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Định cấu hình bàn phím vật lý"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Nhấn để chọn ngôn ngữ và bố cục"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index d7101f4..5152c37 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"拒绝"</string>
     <string name="select_input_method" msgid="3971267998568587025">"选择输入法"</string>
     <string name="show_ime" msgid="6406112007347443383">"开启后,连接到实体键盘时,它会一直显示在屏幕上"</string>
-    <string name="hardware" msgid="1800597768237606953">"显示虚拟键盘"</string>
+    <string name="hardware" msgid="3611039921284836033">"使用屏幕键盘"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"配置“<xliff:g id="DEVICE_NAME">%s</xliff:g>”"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"配置物理键盘"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"点按即可选择语言和布局"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index a471a42..e7f24ad 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"拒絕"</string>
     <string name="select_input_method" msgid="3971267998568587025">"選擇輸入法"</string>
     <string name="show_ime" msgid="6406112007347443383">"在實體鍵盤處於連接狀態時保持顯示"</string>
-    <string name="hardware" msgid="1800597768237606953">"顯示虛擬鍵盤"</string>
+    <string name="hardware" msgid="3611039921284836033">"使用屏幕鍵盤"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"設定「<xliff:g id="DEVICE_NAME">%s</xliff:g>」"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"設定實體鍵盤"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"輕按即可選取語言和鍵盤配置"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 1449ab6..41f2930 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1393,8 +1393,8 @@
     <string name="share_remote_bugreport_action" msgid="7630880678785123682">"分享"</string>
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"拒絕"</string>
     <string name="select_input_method" msgid="3971267998568587025">"選擇輸入法"</string>
-    <string name="show_ime" msgid="6406112007347443383">"使用實體鍵盤時仍繼續顯示虛擬鍵盤"</string>
-    <string name="hardware" msgid="1800597768237606953">"顯示虛擬鍵盤"</string>
+    <string name="show_ime" msgid="6406112007347443383">"使用實體鍵盤時仍繼續顯示螢幕小鍵盤"</string>
+    <string name="hardware" msgid="3611039921284836033">"使用螢幕小鍵盤"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"設定「<xliff:g id="DEVICE_NAME">%s</xliff:g>」"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"設定實體鍵盤"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"輕觸即可選取語言和版面配置"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 72b4404..7f85020 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1394,7 +1394,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"YENQABA"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Khetha indlela yokufaka"</string>
     <string name="show_ime" msgid="6406112007347443383">"Yigcine kusikrini ngenkathi kusebenza ikhibhodi ephathekayo"</string>
-    <string name="hardware" msgid="1800597768237606953">"Bonisa ikhibhodi ebonakalayo"</string>
+    <string name="hardware" msgid="3611039921284836033">"Sebenzisa ikhibhodi ekuskrini"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Lungisa i-<xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Lungiselela amakhibhodi aphathekayo"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Thepha ukuze ukhethe ulimi nesakhiwo"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 3be0d7f..2d8bfbb 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -5574,13 +5574,13 @@
 
     <!-- Blur radius for the Option 3 in R.integer.config_letterboxBackgroundType. Values < 0 are
         ignored and 0 is used. -->
-    <dimen name="config_letterboxBackgroundWallpaperBlurRadius">31dp</dimen>
+    <dimen name="config_letterboxBackgroundWallpaperBlurRadius">24dp</dimen>
 
     <!-- Alpha of a black translucent scrim showed over wallpaper letterbox background when
         the Option 3 is selected for R.integer.config_letterboxBackgroundType.
         Values < 0 or >= 1 are ignored and 0.0 (transparent) is used instead. -->
     <item name="config_letterboxBackgroundWallaperDarkScrimAlpha" format="float" type="dimen">
-        0.5
+        0.68
     </item>
 
     <!-- Corners appearance of the letterbox background.
@@ -5605,7 +5605,7 @@
             but isn't supported on the device or both dark scrim alpha and blur radius aren't
             provided.
      -->
-    <color name="config_letterboxBackgroundColor">@color/letterbox_background</color>
+    <color name="config_letterboxBackgroundColor">@color/system_on_secondary_fixed</color>
 
     <!-- Horizontal position of a center of the letterboxed app window.
         0 corresponds to the left side of the screen and 1 to the right side. If given value < 0
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 24da59a..b129321 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -95,8 +95,10 @@
     <dimen name="navigation_bar_height_landscape_car_mode">96dp</dimen>
     <!-- Width of the navigation bar when it is placed vertically on the screen in car mode -->
     <dimen name="navigation_bar_width_car_mode">96dp</dimen>
-    <!-- Height of notification icons in the status bar -->
+    <!-- Original dp height of notification icons in the status bar  -->
     <dimen name="status_bar_icon_size">22dip</dimen>
+    <!-- New sp height of notification icons in the status bar  -->
+    <dimen name="status_bar_icon_size_sp">22sp</dimen>
     <!-- Desired size of system icons in status bar. -->
     <dimen name="status_bar_system_icon_size">15dp</dimen>
     <!-- Intrinsic size of most system icons in status bar. This is the default value that
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 85e9792..34332a5 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2298,6 +2298,7 @@
 
   <java-symbol type="bool" name="config_alwaysUseCdmaRssi" />
   <java-symbol type="dimen" name="status_bar_icon_size" />
+  <java-symbol type="dimen" name="status_bar_icon_size_sp" />
   <java-symbol type="dimen" name="status_bar_system_icon_size" />
   <java-symbol type="dimen" name="status_bar_system_icon_intrinsic_size" />
   <java-symbol type="drawable" name="list_selector_pressed_holo_dark" />
diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java
index eba7f58..7c69e65 100644
--- a/core/tests/coretests/src/android/app/NotificationTest.java
+++ b/core/tests/coretests/src/android/app/NotificationTest.java
@@ -271,6 +271,54 @@
     }
 
     @Test
+    public void allPendingIntents_resilientToAnotherNotificationInExtras() {
+        PendingIntent contentIntent = createPendingIntent("content");
+        PendingIntent actionIntent = createPendingIntent("action");
+        Notification another = new Notification.Builder(mContext, "channel").build();
+        Bundle bundleContainingAnotherNotification = new Bundle();
+        bundleContainingAnotherNotification.putParcelable(null, another);
+        Notification source = new Notification.Builder(mContext, "channel")
+                .setContentIntent(contentIntent)
+                .addAction(new Notification.Action.Builder(null, "action", actionIntent).build())
+                .setExtras(bundleContainingAnotherNotification)
+                .build();
+
+        Parcel p = Parcel.obtain();
+        source.writeToParcel(p, 0);
+        p.setDataPosition(0);
+        Notification unparceled = new Notification(p);
+
+        assertThat(unparceled.allPendingIntents).containsExactly(contentIntent, actionIntent);
+    }
+
+    @Test
+    public void allPendingIntents_alsoInPublicVersion() {
+        PendingIntent contentIntent = createPendingIntent("content");
+        PendingIntent actionIntent = createPendingIntent("action");
+        PendingIntent publicContentIntent = createPendingIntent("publicContent");
+        PendingIntent publicActionIntent = createPendingIntent("publicAction");
+        Notification source = new Notification.Builder(mContext, "channel")
+                .setContentIntent(contentIntent)
+                .addAction(new Notification.Action.Builder(null, "action", actionIntent).build())
+                .setPublicVersion(new Notification.Builder(mContext, "channel")
+                        .setContentIntent(publicContentIntent)
+                        .addAction(new Notification.Action.Builder(
+                                null, "publicAction", publicActionIntent).build())
+                        .build())
+                .build();
+
+        Parcel p = Parcel.obtain();
+        source.writeToParcel(p, 0);
+        p.setDataPosition(0);
+        Notification unparceled = new Notification(p);
+
+        assertThat(unparceled.allPendingIntents).containsExactly(contentIntent, actionIntent,
+                publicContentIntent, publicActionIntent);
+        assertThat(unparceled.publicVersion.allPendingIntents).containsExactly(publicContentIntent,
+                publicActionIntent);
+    }
+
+    @Test
     public void messagingStyle_isGroupConversation() {
         mContext.getApplicationInfo().targetSdkVersion = Build.VERSION_CODES.P;
         Notification.MessagingStyle messagingStyle = new Notification.MessagingStyle("self name")
diff --git a/core/tests/coretests/src/android/flags/FeatureFlagsTest.java b/core/tests/coretests/src/android/flags/FeatureFlagsTest.java
new file mode 100644
index 0000000..3fc9439
--- /dev/null
+++ b/core/tests/coretests/src/android/flags/FeatureFlagsTest.java
@@ -0,0 +1,155 @@
+/*
+ * 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 android.flags;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+
+@SmallTest
+@Presubmit
+public class FeatureFlagsTest {
+
+    IFeatureFlagsFake mIFeatureFlagsFake = new IFeatureFlagsFake();
+    FeatureFlags mFeatureFlags = new FeatureFlags(mIFeatureFlagsFake);
+
+    @Before
+    public void setup() {
+        FeatureFlags.setInstance(mFeatureFlags);
+    }
+
+    @Test
+    public void testFusedOff_Disabled() {
+        FusedOffFlag flag = FeatureFlags.fusedOffFlag("test", "a");
+        assertThat(mFeatureFlags.isEnabled(flag)).isFalse();
+    }
+
+    @Test
+    public void testFusedOn_Enabled() {
+        FusedOnFlag flag = FeatureFlags.fusedOnFlag("test", "a");
+        assertThat(mFeatureFlags.isEnabled(flag)).isTrue();
+    }
+
+    @Test
+    public void testBooleanFlag_DefaultDisabled() {
+        BooleanFlag flag = FeatureFlags.booleanFlag("test", "a", false);
+        assertThat(mFeatureFlags.isEnabled(flag)).isFalse();
+    }
+
+    @Test
+    public void testBooleanFlag_DefaultEnabled() {
+        BooleanFlag flag = FeatureFlags.booleanFlag("test", "a", true);
+        assertThat(mFeatureFlags.isEnabled(flag)).isTrue();
+    }
+
+    @Test
+    public void testDynamicBooleanFlag_DefaultDisabled() {
+        DynamicBooleanFlag flag = FeatureFlags.dynamicBooleanFlag("test", "a", false);
+        assertThat(mFeatureFlags.isCurrentlyEnabled(flag)).isFalse();
+    }
+
+    @Test
+    public void testDynamicBooleanFlag_DefaultEnabled() {
+        DynamicBooleanFlag flag = FeatureFlags.dynamicBooleanFlag("test", "a", true);
+        assertThat(mFeatureFlags.isCurrentlyEnabled(flag)).isTrue();
+    }
+
+    @Test
+    public void testBooleanFlag_OverrideBeforeRead() {
+        BooleanFlag flag = FeatureFlags.booleanFlag("test", "a", false);
+        SyncableFlag syncableFlag = new SyncableFlag(
+                flag.getNamespace(), flag.getName(), "true", false);
+
+        mIFeatureFlagsFake.setFlagOverrides(List.of(syncableFlag));
+
+        assertThat(mFeatureFlags.isEnabled(flag)).isTrue();
+    }
+
+    @Test
+    public void testFusedOffFlag_OverrideHasNoEffect() {
+        FusedOffFlag flag = FeatureFlags.fusedOffFlag("test", "a");
+        SyncableFlag syncableFlag = new SyncableFlag(
+                flag.getNamespace(), flag.getName(), "true", false);
+
+        mIFeatureFlagsFake.setFlagOverrides(List.of(syncableFlag));
+
+        assertThat(mFeatureFlags.isEnabled(flag)).isFalse();
+    }
+
+    @Test
+    public void testFusedOnFlag_OverrideHasNoEffect() {
+        FusedOnFlag flag = FeatureFlags.fusedOnFlag("test", "a");
+        SyncableFlag syncableFlag = new SyncableFlag(
+                flag.getNamespace(), flag.getName(), "false", false);
+
+        mIFeatureFlagsFake.setFlagOverrides(List.of(syncableFlag));
+
+        assertThat(mFeatureFlags.isEnabled(flag)).isTrue();
+    }
+
+    @Test
+    public void testDynamicFlag_OverrideBeforeRead() {
+        DynamicBooleanFlag flag = FeatureFlags.dynamicBooleanFlag("test", "a", false);
+        SyncableFlag syncableFlag = new SyncableFlag(
+                flag.getNamespace(), flag.getName(), "true", true);
+
+        mIFeatureFlagsFake.setFlagOverrides(List.of(syncableFlag));
+
+        // Changes to true
+        assertThat(mFeatureFlags.isCurrentlyEnabled(flag)).isTrue();
+    }
+
+    @Test
+    public void testDynamicFlag_OverrideAfterRead() {
+        DynamicBooleanFlag flag = FeatureFlags.dynamicBooleanFlag("test", "a", false);
+        SyncableFlag syncableFlag = new SyncableFlag(
+                flag.getNamespace(), flag.getName(), "true", true);
+
+        // Starts false
+        assertThat(mFeatureFlags.isCurrentlyEnabled(flag)).isFalse();
+
+        mIFeatureFlagsFake.setFlagOverrides(List.of(syncableFlag));
+
+        // Changes to true
+        assertThat(mFeatureFlags.isCurrentlyEnabled(flag)).isTrue();
+    }
+
+    @Test
+    public void testDynamicFlag_FiresListener() {
+        DynamicBooleanFlag flag = FeatureFlags.dynamicBooleanFlag("test", "a", false);
+        AtomicBoolean called = new AtomicBoolean(false);
+        FeatureFlags.ChangeListener listener = flag1 -> called.set(true);
+
+        mFeatureFlags.addChangeListener(listener);
+
+        SyncableFlag syncableFlag = new SyncableFlag(
+                flag.getNamespace(), flag.getName(), flag.getDefault().toString(), true);
+
+        mIFeatureFlagsFake.setFlagOverrides(List.of(syncableFlag));
+
+        // Fires listener.
+        assertThat(called.get()).isTrue();
+    }
+}
diff --git a/core/tests/coretests/src/android/flags/IFeatureFlagsFake.java b/core/tests/coretests/src/android/flags/IFeatureFlagsFake.java
new file mode 100644
index 0000000..bc5d8aa
--- /dev/null
+++ b/core/tests/coretests/src/android/flags/IFeatureFlagsFake.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.flags;
+
+import android.os.IBinder;
+import android.os.RemoteException;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+class IFeatureFlagsFake implements IFeatureFlags {
+
+    private final Set<IFeatureFlagsCallback> mCallbacks = new HashSet<>();
+
+    List<SyncableFlag> mOverrides;
+
+    @Override
+    public IBinder asBinder() {
+        return null;
+    }
+
+    @Override
+    public List<SyncableFlag> syncFlags(List<SyncableFlag> flagList) {
+        return mOverrides == null ? flagList : mOverrides;
+    }
+
+    @Override
+    public List<SyncableFlag> queryFlags(List<SyncableFlag> flagList) {
+        return mOverrides == null ? flagList : mOverrides;    }
+
+    @Override
+    public void overrideFlag(SyncableFlag syncableFlag) {
+        SyncableFlag match = findFlag(syncableFlag);
+        if (match != null) {
+            mOverrides.remove(match);
+        }
+
+        mOverrides.add(syncableFlag);
+
+        for (IFeatureFlagsCallback cb : mCallbacks) {
+            try {
+                cb.onFlagChange(syncableFlag);
+            } catch (RemoteException e) {
+                // does not happen in fakes.
+            }
+        }
+    }
+
+    @Override
+    public void resetFlag(SyncableFlag syncableFlag) {
+        SyncableFlag match = findFlag(syncableFlag);
+        if (match != null) {
+            mOverrides.remove(match);
+        }
+
+        for (IFeatureFlagsCallback cb : mCallbacks) {
+            try {
+                cb.onFlagChange(syncableFlag);
+            } catch (RemoteException e) {
+                // does not happen in fakes.
+            }
+        }
+    }
+
+    private SyncableFlag findFlag(SyncableFlag syncableFlag) {
+        SyncableFlag match = null;
+        for (SyncableFlag sf : mOverrides) {
+            if (sf.getName().equals(syncableFlag.getName())
+                    && sf.getNamespace().equals(syncableFlag.getNamespace())) {
+                match = sf;
+                break;
+            }
+        }
+
+        return match;
+    }
+    @Override
+    public void registerCallback(IFeatureFlagsCallback callback) {
+        mCallbacks.add(callback);
+    }
+
+    @Override
+    public void unregisterCallback(IFeatureFlagsCallback callback) {
+        mCallbacks.remove(callback);
+    }
+
+    public void setFlagOverrides(List<SyncableFlag> flagList) {
+        mOverrides = flagList;
+        for (SyncableFlag sf : flagList) {
+            for (IFeatureFlagsCallback cb : mCallbacks) {
+                try {
+                    cb.onFlagChange(sf);
+                } catch (RemoteException e) {
+                    // does not happen in fakes.
+                }
+            }
+        }
+    }
+}
diff --git a/core/tests/coretests/src/android/net/UriTest.java b/core/tests/coretests/src/android/net/UriTest.java
index 89632a4..2a4ca79 100644
--- a/core/tests/coretests/src/android/net/UriTest.java
+++ b/core/tests/coretests/src/android/net/UriTest.java
@@ -25,8 +25,6 @@
 
 import java.io.File;
 import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.Iterator;
 import java.util.List;
@@ -869,84 +867,90 @@
         return (Uri) hierarchicalUriConstructor.newInstance("https", authority, path, null, null);
     }
 
-    /** Attempting to unparcel a legacy parcel format of Uri.{,Path}Part should fail. */
-    public void testUnparcelLegacyPart_fails() throws Exception {
-        assertUnparcelLegacyPart_fails(Class.forName("android.net.Uri$Part"));
-        assertUnparcelLegacyPart_fails(Class.forName("android.net.Uri$PathPart"));
-    }
-
-    private static void assertUnparcelLegacyPart_fails(Class partClass) throws Exception {
-        Parcel parcel = Parcel.obtain();
-        parcel.writeInt(0 /* BOTH */);
-        parcel.writeString("encoded");
-        parcel.writeString("decoded");
-        parcel.setDataPosition(0);
-
-        Method readFromMethod = partClass.getDeclaredMethod("readFrom", Parcel.class);
-        readFromMethod.setAccessible(true);
-        try {
-            readFromMethod.invoke(null, parcel);
-            fail();
-        } catch (InvocationTargetException expected) {
-            Throwable targetException = expected.getTargetException();
-            // Check that the exception was thrown for the correct reason.
-            assertEquals("Unknown representation: 0", targetException.getMessage());
-        } finally {
-            parcel.recycle();
-        }
-    }
-
-    private Uri buildUriFromRawParcel(boolean argumentsEncoded,
+    private Uri buildUriFromParts(boolean argumentsEncoded,
                                       String scheme,
                                       String authority,
                                       String path,
                                       String query,
                                       String fragment) {
-        // Representation value (from AbstractPart.REPRESENTATION_{ENCODED,DECODED}).
-        final int representation = argumentsEncoded ? 1 : 2;
-        Parcel parcel = Parcel.obtain();
-        try {
-            parcel.writeInt(3);  // hierarchical
-            parcel.writeString8(scheme);
-            parcel.writeInt(representation);
-            parcel.writeString8(authority);
-            parcel.writeInt(representation);
-            parcel.writeString8(path);
-            parcel.writeInt(representation);
-            parcel.writeString8(query);
-            parcel.writeInt(representation);
-            parcel.writeString8(fragment);
-            parcel.setDataPosition(0);
-            return Uri.CREATOR.createFromParcel(parcel);
-        } finally {
-            parcel.recycle();
+        final Uri.Builder builder = new Uri.Builder();
+        builder.scheme(scheme);
+        if (argumentsEncoded) {
+            builder.encodedAuthority(authority);
+            builder.encodedPath(path);
+            builder.encodedQuery(query);
+            builder.encodedFragment(fragment);
+        } else {
+            builder.authority(authority);
+            builder.path(path);
+            builder.query(query);
+            builder.fragment(fragment);
         }
+        return builder.build();
     }
 
     public void testUnparcelMalformedPath() {
         // Regression tests for b/171966843.
 
         // Test cases with arguments encoded (covering testing `scheme` * `authority` options).
-        Uri uri0 = buildUriFromRawParcel(true, "https", "google.com", "@evil.com", null, null);
+        Uri uri0 = buildUriFromParts(true, "https", "google.com", "@evil.com", null, null);
         assertEquals("https://google.com/@evil.com", uri0.toString());
-        Uri uri1 = buildUriFromRawParcel(true, null, "google.com", "@evil.com", "name=spark", "x");
+        Uri uri1 = buildUriFromParts(true, null, "google.com", "@evil.com", "name=spark", "x");
         assertEquals("//google.com/@evil.com?name=spark#x", uri1.toString());
-        Uri uri2 = buildUriFromRawParcel(true, "http:", null, "@evil.com", null, null);
+        Uri uri2 = buildUriFromParts(true, "http:", null, "@evil.com", null, null);
         assertEquals("http::/@evil.com", uri2.toString());
-        Uri uri3 = buildUriFromRawParcel(true, null, null, "@evil.com", null, null);
+        Uri uri3 = buildUriFromParts(true, null, null, "@evil.com", null, null);
         assertEquals("@evil.com", uri3.toString());
 
         // Test cases with arguments not encoded (covering testing `scheme` * `authority` options).
-        Uri uriA = buildUriFromRawParcel(false, "https", "google.com", "@evil.com", null, null);
+        Uri uriA = buildUriFromParts(false, "https", "google.com", "@evil.com", null, null);
         assertEquals("https://google.com/%40evil.com", uriA.toString());
-        Uri uriB = buildUriFromRawParcel(false, null, "google.com", "@evil.com", null, null);
+        Uri uriB = buildUriFromParts(false, null, "google.com", "@evil.com", null, null);
         assertEquals("//google.com/%40evil.com", uriB.toString());
-        Uri uriC = buildUriFromRawParcel(false, "http:", null, "@evil.com", null, null);
+        Uri uriC = buildUriFromParts(false, "http:", null, "@evil.com", null, null);
         assertEquals("http::/%40evil.com", uriC.toString());
-        Uri uriD = buildUriFromRawParcel(false, null, null, "@evil.com", "name=spark", "y");
+        Uri uriD = buildUriFromParts(false, null, null, "@evil.com", "name=spark", "y");
         assertEquals("%40evil.com?name%3Dspark#y", uriD.toString());
     }
 
+    public void testParsedUriFromStringEquality() {
+        Uri uri = buildUriFromParts(
+                true, "https", "google.com", "@evil.com", null, null);
+        assertEquals(uri, Uri.parse(uri.toString()));
+        Uri uri2 = buildUriFromParts(
+                true, "content://evil.authority?foo=", "safe.authority", "@evil.com", null, null);
+        assertEquals(uri2, Uri.parse(uri2.toString()));
+        Uri uri3 = buildUriFromParts(
+                false, "content://evil.authority?foo=", "safe.authority", "@evil.com", null, null);
+        assertEquals(uri3, Uri.parse(uri3.toString()));
+    }
+
+    public void testParceledUrisAreEqual() {
+        Uri opaqueUri = Uri.fromParts("fake://uri#", "ssp", "fragment");
+        Parcel parcel = Parcel.obtain();
+        try {
+            opaqueUri.writeToParcel(parcel, 0);
+            parcel.setDataPosition(0);
+            Uri postParcelUri = Uri.CREATOR.createFromParcel(parcel);
+            Uri parsedUri = Uri.parse(postParcelUri.toString());
+            assertEquals(parsedUri.getScheme(), postParcelUri.getScheme());
+        } finally {
+            parcel.recycle();
+        }
+
+        Uri hierarchicalUri = new Uri.Builder().scheme("fake://uri#").authority("auth").build();
+        parcel = Parcel.obtain();
+        try {
+            hierarchicalUri.writeToParcel(parcel, 0);
+            parcel.setDataPosition(0);
+            Uri postParcelUri = Uri.CREATOR.createFromParcel(parcel);
+            Uri parsedUri = Uri.parse(postParcelUri.toString());
+            assertEquals(parsedUri.getScheme(), postParcelUri.getScheme());
+        } finally {
+            parcel.recycle();
+        }
+    }
+
     public void testToSafeString() {
         checkToSafeString("tel:xxxxxx", "tel:Google");
         checkToSafeString("tel:xxxxxxxxxx", "tel:1234567890");
diff --git a/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java b/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
index 8f83461..b61f995 100644
--- a/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
+++ b/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
@@ -79,6 +79,7 @@
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -93,6 +94,8 @@
     private static final String ENUM_NAME_PREFIX =
             "UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__";
 
+    private static final ArrayList<String> DEPRECATED_VALUES = new ArrayList<>();
+
     private ViewAttachTestActivity mActivity;
     private View mView;
     private HandlerThread mWorker;
@@ -126,6 +129,7 @@
                 CUJ_NOTIFICATION_SHADE_ROW_SWIPE, getEnumName("SHADE_ROW_SWIPE"));
         ENUM_NAME_EXCEPTION_MAP.put(
                 CUJ_NOTIFICATION_SHADE_SCROLL_FLING, getEnumName("SHADE_SCROLL_FLING"));
+        DEPRECATED_VALUES.add(ENUM_NAME_PREFIX + "IME_INSETS_ANIMATION");
     }
 
     private static String getEnumName(String name) {
@@ -239,6 +243,7 @@
 
         Map<Integer, String> enumsMap = Arrays.stream(FrameworkStatsLog.class.getDeclaredFields())
                 .filter(f -> f.getName().startsWith(ENUM_NAME_PREFIX)
+                        && !DEPRECATED_VALUES.contains(f.getName())
                         && Modifier.isStatic(f.getModifiers())
                         && f.getType() == int.class)
                 .collect(Collectors.toMap(this::getIntFieldChecked, Field::getName));
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index ea44bea..9c5e0c4 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -79,7 +79,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Burbuja"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Gestionar"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Burbuja cerrada."</string>
-    <string name="restart_button_description" msgid="6712141648865547958">"Toca para reiniciar esta aplicación y obtener una mejor vista."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Toca para reiniciar esta aplicación y verlo mejor."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"¿Problemas con la cámara?\nToca para reajustar"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"¿No se ha solucionado?\nToca para revertir"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"¿No hay problemas con la cámara? Toca para cerrar."</string>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index 39d717d..55697ca 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -79,7 +79,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"버블"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"관리"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"대화창을 닫았습니다."</string>
-    <string name="restart_button_description" msgid="6712141648865547958">"보기를 개선하려면 탭하여 앱을 다시 시작합니다."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"더 편하게 보기를 원하면 탭하여 앱을 다시 시작하세요."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"카메라 문제가 있나요?\n해결하려면 탭하세요."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"해결되지 않았나요?\n되돌리려면 탭하세요."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"카메라에 문제가 없나요? 닫으려면 탭하세요."</string>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 14e8253..64fed1c 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -226,14 +226,12 @@
     <dimen name="bubble_user_education_padding_end">58dp</dimen>
     <!-- Padding between the bubble and the user education text. -->
     <dimen name="bubble_user_education_stack_padding">16dp</dimen>
-    <!-- Size of the bubble bar (height), should match transient_taskbar_size in Launcher. -->
-    <dimen name="bubblebar_size">72dp</dimen>
-    <!-- The size of the drag handle / menu shown along with a bubble bar expanded view. -->
-    <dimen name="bubble_bar_expanded_view_handle_size">40dp</dimen>
-    <!-- The width of the drag handle shown along with a bubble bar expanded view. -->
-    <dimen name="bubble_bar_expanded_view_handle_width">128dp</dimen>
-    <!-- The height of the drag handle shown along with a bubble bar expanded view. -->
-    <dimen name="bubble_bar_expanded_view_handle_height">4dp</dimen>
+    <!-- The size of the caption bar inset at the top of bubble bar expanded view. -->
+    <dimen name="bubble_bar_expanded_view_caption_height">32dp</dimen>
+    <!-- The height of the dots shown for the caption menu in the bubble bar expanded view.. -->
+    <dimen name="bubble_bar_expanded_view_caption_dot_size">4dp</dimen>
+    <!-- The spacing between the dots for the caption menu in the bubble bar expanded view.. -->
+    <dimen name="bubble_bar_expanded_view_caption_dot_spacing">4dp</dimen>
     <!-- Minimum width of the bubble bar manage menu. -->
     <dimen name="bubble_bar_manage_menu_min_width">200dp</dimen>
     <!-- Size of the dismiss icon in the bubble bar manage menu. -->
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index 6880237..6385fd3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -1075,8 +1075,9 @@
      * <p>This is used by external callers (launcher).
      */
     @VisibleForTesting
-    public void expandStackAndSelectBubbleFromLauncher(String key, boolean onLauncherHome) {
-        mBubblePositioner.setShowingInBubbleBar(onLauncherHome);
+    public void expandStackAndSelectBubbleFromLauncher(String key, int bubbleBarXCoordinate,
+            int bubbleBarYCoordinate) {
+        mBubblePositioner.setBubbleBarPosition(bubbleBarXCoordinate, bubbleBarYCoordinate);
 
         if (BubbleOverflow.KEY.equals(key)) {
             mBubbleData.setSelectedBubbleFromLauncher(mBubbleData.getOverflow());
@@ -2087,9 +2088,10 @@
         }
 
         @Override
-        public void showBubble(String key, boolean onLauncherHome) {
+        public void showBubble(String key, int bubbleBarXCoordinate, int bubbleBarYCoordinate) {
             mMainExecutor.execute(
-                    () -> mController.expandStackAndSelectBubbleFromLauncher(key, onLauncherHome));
+                    () -> mController.expandStackAndSelectBubbleFromLauncher(
+                            key, bubbleBarXCoordinate, bubbleBarYCoordinate));
         }
 
         @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
index cb08f93..6a5e310 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
@@ -22,6 +22,7 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Insets;
+import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -102,10 +103,7 @@
     private int[] mPaddings = new int[4];
 
     private boolean mShowingInBubbleBar;
-    private boolean mBubblesOnHome;
-    private int mBubbleBarSize;
-    private int mBubbleBarHomeAdjustment;
-    private final PointF mBubbleBarPosition = new PointF();
+    private final Point mBubbleBarPosition = new Point();
 
     public BubblePositioner(Context context, WindowManager windowManager) {
         mContext = context;
@@ -166,11 +164,9 @@
         mSpacingBetweenBubbles = res.getDimensionPixelSize(R.dimen.bubble_spacing);
         mDefaultMaxBubbles = res.getInteger(R.integer.bubbles_max_rendered);
         mExpandedViewPadding = res.getDimensionPixelSize(R.dimen.bubble_expanded_view_padding);
-        mBubbleBarHomeAdjustment = mExpandedViewPadding / 2;
         mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
         mBubbleOffscreenAmount = res.getDimensionPixelSize(R.dimen.bubble_stack_offscreen);
         mStackOffset = res.getDimensionPixelSize(R.dimen.bubble_stack_offset);
-        mBubbleBarSize = res.getDimensionPixelSize(R.dimen.bubblebar_size);
 
         if (mShowingInBubbleBar) {
             mExpandedViewLargeScreenWidth = isLandscape()
@@ -722,11 +718,9 @@
         mShowingInBubbleBar = showingInBubbleBar;
     }
 
-    /**
-     * Sets whether bubbles are showing on launcher home, in which case positions are different.
-     */
-    public void setBubblesOnHome(boolean bubblesOnHome) {
-        mBubblesOnHome = bubblesOnHome;
+    /** Sets the position of the bubble bar in screen coordinates. */
+    public void setBubbleBarPosition(int x, int y) {
+        mBubbleBarPosition.set(x, y);
     }
 
     /**
@@ -747,11 +741,7 @@
 
     /** The bottom position of the expanded view when showing above the bubble bar. */
     public int getExpandedViewBottomForBubbleBar() {
-        return getAvailableRect().height()
-                + mInsets.top
-                - mBubbleBarSize
-                - mExpandedViewPadding
-                - getBubbleBarHomeAdjustment();
+        return mBubbleBarPosition.y - mExpandedViewPadding;
     }
 
     /**
@@ -764,19 +754,7 @@
     /**
      * Returns the on screen co-ordinates of the bubble bar.
      */
-    public PointF getBubbleBarPosition() {
-        mBubbleBarPosition.set(getAvailableRect().width() - mBubbleBarSize,
-                getAvailableRect().height() - mBubbleBarSize
-                        - mExpandedViewPadding - getBubbleBarHomeAdjustment());
+    public Point getBubbleBarPosition() {
         return mBubbleBarPosition;
     }
-
-    /**
-     * When bubbles are shown on launcher home, there's an extra bit of padding that needs to
-     * be applied between the expanded view and the bubble bar. This returns the adjustment value
-     * if bubbles are showing on home.
-     */
-    private int getBubbleBarHomeAdjustment() {
-        return mBubblesOnHome ? mBubbleBarHomeAdjustment : 0;
-    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl
index 20ae846..59332f4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl
@@ -29,7 +29,8 @@
 
     oneway void unregisterBubbleListener(in IBubblesListener listener) = 2;
 
-    oneway void showBubble(in String key, in boolean onLauncherHome) = 3;
+    oneway void showBubble(in String key, in int bubbleBarXCoordinate,
+                    in int bubbleBarYCoordinate) = 3;
 
     oneway void removeBubble(in String key, in int reason) = 4;
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
index f729d02..b3602b3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
@@ -21,10 +21,12 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
 import android.content.Context;
-import android.graphics.PointF;
+import android.graphics.Point;
 import android.util.Log;
 import android.widget.FrameLayout;
 
+import androidx.annotation.Nullable;
+
 import com.android.wm.shell.animation.Interpolators;
 import com.android.wm.shell.animation.PhysicsAnimator;
 import com.android.wm.shell.bubbles.BubbleOverflow;
@@ -111,7 +113,8 @@
     /**
      * Animates the provided bubble's expanded view to the expanded state.
      */
-    public void animateExpansion(BubbleViewProvider expandedBubble) {
+    public void animateExpansion(BubbleViewProvider expandedBubble,
+            @Nullable Runnable afterAnimation) {
         mExpandedBubble = expandedBubble;
         if (mExpandedBubble == null) {
             return;
@@ -133,7 +136,7 @@
         bev.setVisibility(VISIBLE);
 
         // Set the pivot point for the scale, so the view animates out from the bubble bar.
-        PointF bubbleBarPosition = mPositioner.getBubbleBarPosition();
+        Point bubbleBarPosition = mPositioner.getBubbleBarPosition();
         mExpandedViewContainerMatrix.setScale(
                 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT,
                 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT,
@@ -160,6 +163,9 @@
                     bev.setAnimationMatrix(null);
                     updateExpandedView();
                     bev.setSurfaceZOrderedOnTop(false);
+                    if (afterAnimation != null) {
+                        afterAnimation.run();
+                    }
                 })
                 .start();
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
index 396aa0e..6b6d6ba 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
@@ -16,12 +16,12 @@
 
 package com.android.wm.shell.bubbles.bar;
 
-import android.annotation.ColorInt;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Color;
+import android.graphics.Insets;
 import android.graphics.Outline;
 import android.graphics.Rect;
 import android.util.AttributeSet;
@@ -63,7 +63,8 @@
     private @Nullable TaskView mTaskView;
     private @Nullable BubbleOverflowContainerView mOverflowView;
 
-    private int mHandleHeight;
+    private int mCaptionHeight;
+
     private int mBackgroundColor;
     private float mCornerRadius = 0f;
 
@@ -97,8 +98,8 @@
         super.onFinishInflate();
         Context context = getContext();
         setElevation(getResources().getDimensionPixelSize(R.dimen.bubble_elevation));
-        mHandleHeight = context.getResources().getDimensionPixelSize(
-                R.dimen.bubble_bar_expanded_view_handle_size);
+        mCaptionHeight = context.getResources().getDimensionPixelSize(
+                R.dimen.bubble_bar_expanded_view_caption_height);
         addView(mHandleView);
         applyThemeAttrs();
         setClipToOutline(true);
@@ -136,6 +137,9 @@
             addView(mTaskView);
             mTaskView.setEnableSurfaceClipping(true);
             mTaskView.setCornerRadius(mCornerRadius);
+
+            // Handle view needs to draw on top of task view.
+            bringChildToFront(mHandleView);
         }
         mMenuViewController = new BubbleBarMenuViewController(mContext, this);
         mMenuViewController.setListener(new BubbleBarMenuViewController.Listener() {
@@ -169,6 +173,10 @@
         });
     }
 
+    public BubbleBarHandleView getHandleView() {
+        return mHandleView;
+    }
+
     // TODO (b/275087636): call this when theme/config changes
     /** Updates the view based on the current theme. */
     public void applyThemeAttrs() {
@@ -183,12 +191,12 @@
 
         ta.recycle();
 
-        mHandleHeight = getResources().getDimensionPixelSize(
-                R.dimen.bubble_bar_expanded_view_handle_size);
+        mCaptionHeight = getResources().getDimensionPixelSize(
+                R.dimen.bubble_bar_expanded_view_caption_height);
 
         if (mTaskView != null) {
             mTaskView.setCornerRadius(mCornerRadius);
-            updateHandleAndBackgroundColor(true /* animated */);
+            updateHandleColor(true /* animated */);
         }
     }
 
@@ -196,13 +204,12 @@
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
         int height = MeasureSpec.getSize(heightMeasureSpec);
-        int menuViewHeight = Math.min(mHandleHeight, height);
+        int menuViewHeight = Math.min(mCaptionHeight, height);
         measureChild(mHandleView, widthMeasureSpec, MeasureSpec.makeMeasureSpec(menuViewHeight,
                 MeasureSpec.getMode(heightMeasureSpec)));
 
         if (mTaskView != null) {
-            int taskViewHeight = height - menuViewHeight;
-            measureChild(mTaskView, widthMeasureSpec, MeasureSpec.makeMeasureSpec(taskViewHeight,
+            measureChild(mTaskView, widthMeasureSpec, MeasureSpec.makeMeasureSpec(height,
                     MeasureSpec.getMode(heightMeasureSpec)));
         }
     }
@@ -210,19 +217,20 @@
     @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         super.onLayout(changed, l, t, r, b);
-        // Drag handle above
-        final int dragHandleBottom = t + mHandleView.getMeasuredHeight();
-        mHandleView.layout(l, t, r, dragHandleBottom);
+        final int captionBottom = t + mCaptionHeight;
         if (mTaskView != null) {
-            mTaskView.layout(l, dragHandleBottom, r,
-                    dragHandleBottom + mTaskView.getMeasuredHeight());
+            mTaskView.layout(l, t, r,
+                    t + mTaskView.getMeasuredHeight());
+            mTaskView.setCaptionInsets(Insets.of(0, mCaptionHeight, 0, 0));
         }
+        // Handle draws on top of task view in the caption area.
+        mHandleView.layout(l, t, r, captionBottom);
     }
 
     @Override
     public void onTaskCreated() {
         setContentVisibility(true);
-        updateHandleAndBackgroundColor(false /* animated */);
+        updateHandleColor(false /* animated */);
     }
 
     @Override
@@ -298,33 +306,20 @@
     }
 
     /**
-     * Updates the background color to match with task view status/bg color, and sets handle color
-     * to contrast with the background
+     * Updates the handle color based on the task view status bar or background color; if those
+     * are transparent it defaults to the background color pulled from system theme attributes.
      */
-    private void updateHandleAndBackgroundColor(boolean animated) {
-        if (mTaskView == null) return;
-        final int color = getTaskViewColor();
-        final boolean isRegionDark = Color.luminance(color) <= 0.5;
-        mHandleView.updateHandleColor(isRegionDark, animated);
-        setBackgroundColor(color);
-    }
-
-    /**
-     * Retrieves task view status/nav bar color or background if available
-     *
-     * TODO (b/283075226): Update with color sampling when
-     *                     RegionSamplingHelper or alternative is available
-     */
-    private @ColorInt int getTaskViewColor() {
-        if (mTaskView == null || mTaskView.getTaskInfo() == null) return mBackgroundColor;
+    private void updateHandleColor(boolean animated) {
+        if (mTaskView == null || mTaskView.getTaskInfo() == null) return;
+        int color = mBackgroundColor;
         ActivityManager.TaskDescription taskDescription = mTaskView.getTaskInfo().taskDescription;
         if (taskDescription.getStatusBarColor() != Color.TRANSPARENT) {
-            return taskDescription.getStatusBarColor();
+            color = taskDescription.getStatusBarColor();
         } else if (taskDescription.getBackgroundColor() != Color.TRANSPARENT) {
-            return taskDescription.getBackgroundColor();
-        } else {
-            return mBackgroundColor;
+            color = taskDescription.getBackgroundColor();
         }
+        final boolean isRegionDark = Color.luminance(color) <= 0.5;
+        mHandleView.updateHandleColor(isRegionDark, animated);
     }
 
     /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java
index ce26bc0..2b7a070 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java
@@ -21,7 +21,8 @@
 import android.annotation.Nullable;
 import android.content.Context;
 import android.graphics.Outline;
-import android.graphics.Rect;
+import android.graphics.Path;
+import android.graphics.RectF;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewOutlineProvider;
@@ -37,8 +38,12 @@
 public class BubbleBarHandleView extends View {
     private static final long COLOR_CHANGE_DURATION = 120;
 
-    private int mHandleWidth;
-    private int mHandleHeight;
+    // The handle view is currently rendered as 3 evenly spaced dots.
+    private int mDotSize;
+    private int mDotSpacing;
+    // Path used to draw the dots
+    private final Path mPath = new Path();
+
     private @ColorInt int mHandleLightColor;
     private @ColorInt int mHandleDarkColor;
     private @Nullable ObjectAnimator mColorChangeAnim;
@@ -58,11 +63,10 @@
     public BubbleBarHandleView(Context context, AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
-
-        mHandleWidth = getResources().getDimensionPixelSize(
-                R.dimen.bubble_bar_expanded_view_handle_width);
-        mHandleHeight = getResources().getDimensionPixelSize(
-                R.dimen.bubble_bar_expanded_view_handle_height);
+        mDotSize = getResources().getDimensionPixelSize(
+                R.dimen.bubble_bar_expanded_view_caption_dot_size);
+        mDotSpacing = getResources().getDimensionPixelSize(
+                R.dimen.bubble_bar_expanded_view_caption_dot_spacing);
         mHandleLightColor = ContextCompat.getColor(getContext(),
                 R.color.bubble_bar_expanded_view_handle_light);
         mHandleDarkColor = ContextCompat.getColor(getContext(),
@@ -74,13 +78,26 @@
             public void getOutline(View view, Outline outline) {
                 final int handleCenterX = view.getWidth() / 2;
                 final int handleCenterY = view.getHeight() / 2;
-                final float handleRadius = mHandleHeight / 2f;
-                Rect handleBounds = new Rect(
-                        handleCenterX - mHandleWidth / 2,
-                        handleCenterY - mHandleHeight / 2,
-                        handleCenterX + mHandleWidth / 2,
-                        handleCenterY + mHandleHeight / 2);
-                outline.setRoundRect(handleBounds, handleRadius);
+                final int handleTotalWidth = mDotSize * 3 + mDotSpacing * 2;
+                final int handleLeft = handleCenterX - handleTotalWidth / 2;
+                final int handleTop = handleCenterY - mDotSize / 2;
+                final int handleBottom = handleTop + mDotSize;
+                RectF dot1 = new RectF(
+                        handleLeft, handleTop,
+                        handleLeft + mDotSize, handleBottom);
+                RectF dot2 = new RectF(
+                        dot1.right + mDotSpacing, handleTop,
+                        dot1.right + mDotSpacing + mDotSize, handleBottom
+                );
+                RectF dot3 = new RectF(
+                        dot2.right + mDotSpacing, handleTop,
+                        dot2.right + mDotSpacing + mDotSize, handleBottom
+                );
+                mPath.reset();
+                mPath.addOval(dot1, Path.Direction.CW);
+                mPath.addOval(dot2, Path.Direction.CW);
+                mPath.addOval(dot3, Path.Direction.CW);
+                outline.setPath(mPath);
             }
         });
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
index d20b33e..8ead18b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
@@ -24,6 +24,7 @@
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.graphics.drawable.ColorDrawable;
+import android.view.TouchDelegate;
 import android.view.View;
 import android.view.ViewTreeObserver;
 import android.widget.FrameLayout;
@@ -68,6 +69,10 @@
     private final Region mTouchableRegion = new Region();
     private final Rect mTempRect = new Rect();
 
+    // Used to ensure touch target size for the menu shown on a bubble expanded view
+    private TouchDelegate mHandleTouchDelegate;
+    private final Rect mHandleTouchBounds = new Rect();
+
     public BubbleBarLayerView(Context context, BubbleController controller) {
         super(context);
         mBubbleController = controller;
@@ -164,7 +169,17 @@
 
         mIsExpanded = true;
         mBubbleController.getSysuiProxy().onStackExpandChanged(true);
-        mAnimationHelper.animateExpansion(mExpandedBubble);
+        mAnimationHelper.animateExpansion(mExpandedBubble, () -> {
+            if (mExpandedView == null) return;
+            // Touch delegate for the menu
+            BubbleBarHandleView view = mExpandedView.getHandleView();
+            view.getBoundsOnScreen(mHandleTouchBounds);
+            mHandleTouchBounds.top -= mPositioner.getBubblePaddingTop();
+            mHandleTouchDelegate = new TouchDelegate(mHandleTouchBounds,
+                    mExpandedView.getHandleView());
+            setTouchDelegate(mHandleTouchDelegate);
+        });
+
         showScrim(true);
     }
 
@@ -175,6 +190,7 @@
         mAnimationHelper.animateCollapse(() -> removeView(viewToRemove));
         mBubbleController.getSysuiProxy().onStackExpandChanged(false);
         mExpandedView = null;
+        setTouchDelegate(null);
         showScrim(false);
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleInfo.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleInfo.java
index 21355a3..24608d6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleInfo.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleInfo.java
@@ -129,6 +129,11 @@
         return (mFlags & Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION) != 0;
     }
 
+    /** Sets the flags for this bubble. */
+    public void setFlags(int flags) {
+        mFlags = flags;
+    }
+
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
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 40ea276..6d14440 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
@@ -63,6 +63,7 @@
 import com.android.wm.shell.transition.Transitions
 import com.android.wm.shell.util.KtProtoLog
 import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration
+import com.android.wm.shell.windowdecor.MoveToDesktopAnimator
 import java.io.PrintWriter
 import java.util.concurrent.Executor
 import java.util.function.Consumer
@@ -204,7 +205,11 @@
      * Moves a single task to freeform and sets the taskBounds to the passed in bounds,
      * startBounds
      */
-    fun moveToFreeform(taskInfo: RunningTaskInfo, startBounds: Rect) {
+    fun moveToFreeform(
+            taskInfo: RunningTaskInfo,
+            startBounds: Rect,
+            dragToDesktopValueAnimator: MoveToDesktopAnimator
+    ) {
         KtProtoLog.v(
             WM_SHELL_DESKTOP_MODE,
             "DesktopTasksController: moveToFreeform with bounds taskId=%d",
@@ -216,8 +221,8 @@
         wct.setBounds(taskInfo.token, startBounds)
 
         if (Transitions.ENABLE_SHELL_TRANSITIONS) {
-            enterDesktopTaskTransitionHandler.startTransition(
-                    Transitions.TRANSIT_ENTER_FREEFORM, wct, mOnAnimationFinishedCallback)
+            enterDesktopTaskTransitionHandler.startMoveToFreeformAnimation(wct,
+                    dragToDesktopValueAnimator, mOnAnimationFinishedCallback)
         } else {
             shellTaskOrganizer.applyTransaction(wct)
         }
@@ -270,7 +275,7 @@
      * Move a task to fullscreen after being dragged from fullscreen and released back into
      * status bar area
      */
-    fun cancelMoveToFreeform(task: RunningTaskInfo, position: Point) {
+    fun cancelMoveToFreeform(task: RunningTaskInfo, moveToDesktopAnimator: MoveToDesktopAnimator) {
         KtProtoLog.v(
             WM_SHELL_DESKTOP_MODE,
             "DesktopTasksController: cancelMoveToFreeform taskId=%d",
@@ -280,8 +285,8 @@
         wct.setBounds(task.token, null)
 
         if (Transitions.ENABLE_SHELL_TRANSITIONS) {
-            enterDesktopTaskTransitionHandler.startCancelMoveToDesktopMode(
-                wct, position) { t ->
+            enterDesktopTaskTransitionHandler.startCancelMoveToDesktopMode(wct,
+                    moveToDesktopAnimator) { t ->
                 val callbackWCT = WindowContainerTransaction()
                 visualIndicator?.releaseVisualIndicator(t)
                 visualIndicator = null
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java
index 3e175f3..650cac5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java
@@ -22,9 +22,10 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
 import android.app.ActivityManager;
-import android.graphics.Point;
+import android.graphics.PointF;
 import android.graphics.Rect;
 import android.os.IBinder;
+import android.util.Slog;
 import android.view.SurfaceControl;
 import android.view.WindowManager;
 import android.window.TransitionInfo;
@@ -35,6 +36,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.wm.shell.transition.Transitions;
+import com.android.wm.shell.windowdecor.MoveToDesktopAnimator;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -47,18 +49,17 @@
  */
 public class EnterDesktopTaskTransitionHandler implements Transitions.TransitionHandler {
 
+    private static final String TAG = "EnterDesktopTaskTransitionHandler";
     private final Transitions mTransitions;
     private final Supplier<SurfaceControl.Transaction> mTransactionSupplier;
 
-    // The size of the screen during drag relative to the fullscreen size
-    public static final float DRAG_FREEFORM_SCALE = 0.4f;
     // The size of the screen after drag relative to the fullscreen size
     public static final float FINAL_FREEFORM_SCALE = 0.6f;
     public static final int FREEFORM_ANIMATION_DURATION = 336;
 
     private final List<IBinder> mPendingTransitionTokens = new ArrayList<>();
-    private Point mPosition;
     private Consumer<SurfaceControl.Transaction> mOnAnimationFinishedCallback;
+    private MoveToDesktopAnimator mMoveToDesktopAnimator;
 
     public EnterDesktopTaskTransitionHandler(
             Transitions transitions) {
@@ -87,15 +88,30 @@
     }
 
     /**
+     * Starts Transition of type TRANSIT_ENTER_FREEFORM
+     * @param wct WindowContainerTransaction for transition
+     * @param moveToDesktopAnimator Animator that shrinks and positions task during two part move
+     *                              to desktop animation
+     * @param onAnimationEndCallback to be called after animation
+     */
+    public void startMoveToFreeformAnimation(@NonNull WindowContainerTransaction wct,
+            @NonNull MoveToDesktopAnimator moveToDesktopAnimator,
+            Consumer<SurfaceControl.Transaction> onAnimationEndCallback) {
+        mMoveToDesktopAnimator = moveToDesktopAnimator;
+        startTransition(Transitions.TRANSIT_ENTER_FREEFORM, wct, onAnimationEndCallback);
+    }
+
+    /**
      * Starts Transition of type TRANSIT_CANCEL_ENTERING_DESKTOP_MODE
      * @param wct WindowContainerTransaction for transition
-     * @param position Position of task when transition is triggered
+     * @param moveToDesktopAnimator Animator that shrinks and positions task during two part move
+     *                              to desktop animation
      * @param onAnimationEndCallback to be called after animation
      */
     public void startCancelMoveToDesktopMode(@NonNull WindowContainerTransaction wct,
-            Point position,
+            MoveToDesktopAnimator moveToDesktopAnimator,
             Consumer<SurfaceControl.Transaction> onAnimationEndCallback) {
-        mPosition = position;
+        mMoveToDesktopAnimator = moveToDesktopAnimator;
         startTransition(Transitions.TRANSIT_CANCEL_ENTERING_DESKTOP_MODE, wct,
                 onAnimationEndCallback);
     }
@@ -145,9 +161,23 @@
             // to null and we don't require an animation
             final SurfaceControl sc = change.getLeash();
             startT.setWindowCrop(sc, null);
+
+            if (mMoveToDesktopAnimator == null
+                    || mMoveToDesktopAnimator.getTaskId() != change.getTaskInfo().taskId) {
+                Slog.e(TAG, "No animator available for this transition");
+                return false;
+            }
+
+            // Calculate and set position of the task
+            final PointF position = mMoveToDesktopAnimator.getPosition();
+            startT.setPosition(sc, position.x, position.y);
+            finishT.setPosition(sc, position.x, position.y);
+
             startT.apply();
+
             mTransitions.getMainExecutor().execute(
                     () -> finishCallback.onTransitionFinished(null, null));
+
             return true;
         }
 
@@ -162,12 +192,18 @@
                     endBounds.height());
             startT.apply();
 
+            // End the animation that shrinks the window when task is first dragged from fullscreen
+            if (mMoveToDesktopAnimator != null) {
+                mMoveToDesktopAnimator.endAnimator();
+            }
+
             // We want to find the scale of the current bounds relative to the end bounds. The
             // task is currently scaled to DRAG_FREEFORM_SCALE and the final bounds will be
             // scaled to FINAL_FREEFORM_SCALE. So, it is scaled to
             // DRAG_FREEFORM_SCALE / FINAL_FREEFORM_SCALE relative to the freeform bounds
             final ValueAnimator animator =
-                    ValueAnimator.ofFloat(DRAG_FREEFORM_SCALE / FINAL_FREEFORM_SCALE, 1f);
+                    ValueAnimator.ofFloat(
+                            MoveToDesktopAnimator.DRAG_FREEFORM_SCALE / FINAL_FREEFORM_SCALE, 1f);
             animator.setDuration(FREEFORM_ANIMATION_DURATION);
             final SurfaceControl.Transaction t = mTransactionSupplier.get();
             animator.addUpdateListener(animation -> {
@@ -199,8 +235,7 @@
         }
 
         if (type == Transitions.TRANSIT_CANCEL_ENTERING_DESKTOP_MODE
-                && taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM
-                && mPosition != null) {
+                && taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
             // This Transition animates a task to fullscreen after being dragged from the status
             // bar and then released back into the status bar area
             final SurfaceControl sc = change.getLeash();
@@ -210,13 +245,27 @@
                     .setWindowCrop(sc, endBounds.width(), endBounds.height())
                     .apply();
 
+            if (mMoveToDesktopAnimator == null
+                    || mMoveToDesktopAnimator.getTaskId() != change.getTaskInfo().taskId) {
+                Slog.e(TAG, "No animator available for this transition");
+                return false;
+            }
+
+            // End the animation that shrinks the window when task is first dragged from fullscreen
+            mMoveToDesktopAnimator.endAnimator();
+
             final ValueAnimator animator = new ValueAnimator();
-            animator.setFloatValues(DRAG_FREEFORM_SCALE, 1f);
+            animator.setFloatValues(MoveToDesktopAnimator.DRAG_FREEFORM_SCALE, 1f);
             animator.setDuration(FREEFORM_ANIMATION_DURATION);
             final SurfaceControl.Transaction t = mTransactionSupplier.get();
+
+            // Get position of the task
+            final float x = mMoveToDesktopAnimator.getPosition().x;
+            final float y = mMoveToDesktopAnimator.getPosition().y;
+
             animator.addUpdateListener(animation -> {
                 final float scale = (float) animation.getAnimatedValue();
-                t.setPosition(sc, mPosition.x * (1 - scale), mPosition.y * (1 - scale))
+                t.setPosition(sc, x * (1 - scale), y * (1 - scale))
                         .setScale(sc, scale, scale)
                         .show(sc)
                         .apply();
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 be2489d..0bf8ec3 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
@@ -16,9 +16,6 @@
 
 package com.android.wm.shell.draganddrop;
 
-import static android.content.ClipDescription.MIMETYPE_APPLICATION_ACTIVITY;
-import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT;
-import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.DragEvent.ACTION_DRAG_ENDED;
 import static android.view.DragEvent.ACTION_DRAG_ENTERED;
@@ -38,6 +35,7 @@
 import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
 import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_DRAG_AND_DROP;
 
+import android.app.ActivityTaskManager;
 import android.content.ClipDescription;
 import android.content.ComponentCallbacks2;
 import android.content.Context;
@@ -205,8 +203,6 @@
         final Context context = mDisplayController.getDisplayContext(displayId)
                 .createWindowContext(TYPE_APPLICATION_OVERLAY, null);
         final WindowManager wm = context.getSystemService(WindowManager.class);
-
-        // TODO(b/169894807): Figure out the right layer for this, needs to be below the task bar
         final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
                 ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT,
                 TYPE_APPLICATION_OVERLAY,
@@ -279,15 +275,11 @@
         }
 
         if (event.getAction() == ACTION_DRAG_STARTED) {
-            final boolean hasValidClipData = event.getClipData().getItemCount() > 0
-                    && (description.hasMimeType(MIMETYPE_APPLICATION_ACTIVITY)
-                            || description.hasMimeType(MIMETYPE_APPLICATION_SHORTCUT)
-                            || description.hasMimeType(MIMETYPE_APPLICATION_TASK));
-            pd.isHandlingDrag = hasValidClipData;
+            pd.isHandlingDrag = DragUtils.canHandleDrag(event);
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
                     "Clip description: handlingDrag=%b itemCount=%d mimeTypes=%s",
                     pd.isHandlingDrag, event.getClipData().getItemCount(),
-                    getMimeTypes(description));
+                    DragUtils.getMimeTypesConcatenated(description));
         }
 
         if (!pd.isHandlingDrag) {
@@ -300,10 +292,13 @@
                     Slog.w(TAG, "Unexpected drag start during an active drag");
                     return false;
                 }
+                // TODO(b/290391688): Also update the session data with task stack changes
                 InstanceId loggerSessionId = mLogger.logStart(event);
                 pd.activeDragCount++;
-                pd.dragLayout.prepare(mDisplayController.getDisplayLayout(displayId),
-                        event.getClipData(), loggerSessionId);
+                pd.dragSession = new DragSession(mContext, ActivityTaskManager.getInstance(),
+                        mDisplayController.getDisplayLayout(displayId), event.getClipData());
+                pd.dragSession.update();
+                pd.dragLayout.prepare(pd.dragSession, loggerSessionId);
                 setDropTargetWindowVisibility(pd, View.VISIBLE);
                 notifyDragStarted();
                 break;
@@ -324,7 +319,7 @@
                 break;
             }
             case ACTION_DRAG_ENDED:
-                // TODO(b/169894807): Ensure sure it's not possible to get ENDED without DROP
+                // TODO(b/290391688): Ensure sure it's not possible to get ENDED without DROP
                 // or EXITED
                 if (pd.dragLayout.hasDropped()) {
                     mLogger.logDrop();
@@ -362,17 +357,6 @@
         pd.setWindowVisibility(visibility);
     }
 
-    private String getMimeTypes(ClipDescription description) {
-        String mimeTypes = "";
-        for (int i = 0; i < description.getMimeTypeCount(); i++) {
-            if (i > 0) {
-                mimeTypes += ", ";
-            }
-            mimeTypes += description.getMimeType(i);
-        }
-        return mimeTypes;
-    }
-
     /**
      * Returns if any displays are currently ready to handle a drag/drop.
      */
@@ -462,6 +446,8 @@
         // A count of the number of active drags in progress to ensure that we only hide the window
         // when all the drag animations have completed
         int activeDragCount;
+        // The active drag session
+        DragSession dragSession;
 
         PerDisplay(int dispId, Context c, WindowManager w, FrameLayout rv, DragLayout dl) {
             displayId = dispId;
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 fb08c87..e70768b 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
@@ -21,7 +21,6 @@
 import static android.app.ComponentOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED_BY_PERMISSION;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.content.ClipDescription.EXTRA_ACTIVITY_OPTIONS;
 import static android.content.ClipDescription.EXTRA_PENDING_INTENT;
 import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT;
@@ -41,16 +40,13 @@
 import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_RIGHT;
 import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_TOP;
 
-import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
 import android.app.PendingIntent;
-import android.app.WindowConfiguration;
 import android.content.ActivityNotFoundException;
 import android.content.ClipData;
 import android.content.ClipDescription;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.ActivityInfo;
 import android.content.pm.LauncherApps;
 import android.graphics.Insets;
 import android.graphics.Rect;
@@ -67,14 +63,12 @@
 
 import com.android.internal.logging.InstanceId;
 import com.android.wm.shell.R;
-import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
 import com.android.wm.shell.splitscreen.SplitScreenController;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
-import java.util.List;
 
 /**
  * The policy for handling drag and drop operations to shell.
@@ -84,7 +78,6 @@
     private static final String TAG = DragAndDropPolicy.class.getSimpleName();
 
     private final Context mContext;
-    private final ActivityTaskManager mActivityTaskManager;
     private final Starter mStarter;
     private final SplitScreenController mSplitScreen;
     private final ArrayList<DragAndDropPolicy.Target> mTargets = new ArrayList<>();
@@ -94,14 +87,12 @@
     private DragSession mSession;
 
     public DragAndDropPolicy(Context context, SplitScreenController splitScreen) {
-        this(context, ActivityTaskManager.getInstance(), splitScreen, new DefaultStarter(context));
+        this(context, splitScreen, new DefaultStarter(context));
     }
 
     @VisibleForTesting
-    DragAndDropPolicy(Context context, ActivityTaskManager activityTaskManager,
-            SplitScreenController splitScreen, Starter starter) {
+    DragAndDropPolicy(Context context, SplitScreenController splitScreen, Starter starter) {
         mContext = context;
-        mActivityTaskManager = activityTaskManager;
         mSplitScreen = splitScreen;
         mStarter = mSplitScreen != null ? mSplitScreen : starter;
     }
@@ -109,11 +100,9 @@
     /**
      * Starts a new drag session with the given initial drag data.
      */
-    void start(DisplayLayout displayLayout, ClipData data, InstanceId loggerSessionId) {
+    void start(DragSession session, InstanceId loggerSessionId) {
         mLoggerSessionId = loggerSessionId;
-        mSession = new DragSession(mActivityTaskManager, displayLayout, data);
-        // TODO(b/169894807): Also update the session data with task stack changes
-        mSession.update();
+        mSession = session;
         RectF disallowHitRegion = (RectF) mSession.dragData.getExtra(EXTRA_DISALLOW_HIT_REGION);
         if (disallowHitRegion == null) {
             mDisallowHitRegion.setEmpty();
@@ -123,13 +112,6 @@
     }
 
     /**
-     * Returns the last running task.
-     */
-    ActivityManager.RunningTaskInfo getLatestRunningTask() {
-        return mSession.runningTaskInfo;
-    }
-
-    /**
      * Returns the number of targets.
      */
     int getNumTargets() {
@@ -286,49 +268,6 @@
     }
 
     /**
-     * Per-drag session data.
-     */
-    private static class DragSession {
-        private final ActivityTaskManager mActivityTaskManager;
-        private final ClipData mInitialDragData;
-
-        final DisplayLayout displayLayout;
-        Intent dragData;
-        ActivityManager.RunningTaskInfo runningTaskInfo;
-        @WindowConfiguration.WindowingMode
-        int runningTaskWinMode = WINDOWING_MODE_UNDEFINED;
-        @WindowConfiguration.ActivityType
-        int runningTaskActType = ACTIVITY_TYPE_STANDARD;
-        boolean dragItemSupportsSplitscreen;
-
-        DragSession(ActivityTaskManager activityTaskManager,
-                DisplayLayout dispLayout, ClipData data) {
-            mActivityTaskManager = activityTaskManager;
-            mInitialDragData = data;
-            displayLayout = dispLayout;
-        }
-
-        /**
-         * Updates the session data based on the current state of the system.
-         */
-        void update() {
-            List<ActivityManager.RunningTaskInfo> tasks =
-                    mActivityTaskManager.getTasks(1, false /* filterOnlyVisibleRecents */);
-            if (!tasks.isEmpty()) {
-                final ActivityManager.RunningTaskInfo task = tasks.get(0);
-                runningTaskInfo = task;
-                runningTaskWinMode = task.getWindowingMode();
-                runningTaskActType = task.getActivityType();
-            }
-
-            final ActivityInfo info = mInitialDragData.getItemAt(0).getActivityInfo();
-            dragItemSupportsSplitscreen = info == null
-                    || ActivityInfo.isResizeableMode(info.resizeMode);
-            dragData = mInitialDragData.getItemAt(0).getIntent();
-        }
-    }
-
-    /**
      * Interface for actually committing the task launches.
      */
     public interface Starter {
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 fe42822a..205a455 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
@@ -35,7 +35,6 @@
 import android.annotation.SuppressLint;
 import android.app.ActivityManager;
 import android.app.StatusBarManager;
-import android.content.ClipData;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.Color;
@@ -53,14 +52,13 @@
 import com.android.launcher3.icons.IconProvider;
 import com.android.wm.shell.R;
 import com.android.wm.shell.animation.Interpolators;
-import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.splitscreen.SplitScreenController;
 
 import java.util.ArrayList;
 
 /**
- * Coordinates the visible drop targets for the current drag.
+ * Coordinates the visible drop targets for the current drag within a single display.
  */
 public class DragLayout extends LinearLayout {
 
@@ -86,6 +84,7 @@
 
     private boolean mIsShowing;
     private boolean mHasDropped;
+    private DragSession mSession;
 
     @SuppressLint("WrongConstant")
     public DragLayout(Context context, SplitScreenController splitScreenController,
@@ -182,16 +181,19 @@
         return mHasDropped;
     }
 
-    public void prepare(DisplayLayout displayLayout, ClipData initialData,
-            InstanceId loggerSessionId) {
-        mPolicy.start(displayLayout, initialData, loggerSessionId);
+    /**
+     * Called when a new drag is started.
+     */
+    public void prepare(DragSession session, InstanceId loggerSessionId) {
+        mPolicy.start(session, loggerSessionId);
+        mSession = session;
         mHasDropped = false;
         mCurrentTarget = null;
 
         boolean alreadyInSplit = mSplitScreenController != null
                 && mSplitScreenController.isSplitScreenVisible();
         if (!alreadyInSplit) {
-            ActivityManager.RunningTaskInfo taskInfo1 = mPolicy.getLatestRunningTask();
+            ActivityManager.RunningTaskInfo taskInfo1 = mSession.runningTaskInfo;
             if (taskInfo1 != null) {
                 final int activityType = taskInfo1.getActivityType();
                 if (activityType == ACTIVITY_TYPE_STANDARD) {
@@ -356,7 +358,16 @@
      */
     public void hide(DragEvent event, Runnable hideCompleteCallback) {
         mIsShowing = false;
-        animateSplitContainers(false, hideCompleteCallback);
+        animateSplitContainers(false, () -> {
+            if (hideCompleteCallback != null) {
+                hideCompleteCallback.run();
+            }
+            switch (event.getAction()) {
+                case DragEvent.ACTION_DROP:
+                case DragEvent.ACTION_DRAG_ENDED:
+                    mSession = null;
+            }
+        });
         // Reset the state if we previously force-ignore the bottom margin
         mDropZoneView1.setForceIgnoreBottomMargin(false);
         mDropZoneView2.setForceIgnoreBottomMargin(false);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragSession.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragSession.java
new file mode 100644
index 0000000..478b6a9
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragSession.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.draganddrop;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.content.ClipDescription.EXTRA_PENDING_INTENT;
+import static android.content.ClipDescription.MIMETYPE_APPLICATION_ACTIVITY;
+import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT;
+import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK;
+import static android.content.Intent.EXTRA_USER;
+
+import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
+import android.app.PendingIntent;
+import android.app.WindowConfiguration;
+import android.content.ClipData;
+import android.content.ClipDescription;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.net.Uri;
+import android.os.UserHandle;
+
+import androidx.annotation.IntDef;
+import androidx.annotation.Nullable;
+
+import com.android.wm.shell.common.DisplayLayout;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+
+/**
+ * Per-drag session data.
+ */
+public class DragSession {
+    private final ActivityTaskManager mActivityTaskManager;
+    private final ClipData mInitialDragData;
+
+    final DisplayLayout displayLayout;
+    Intent dragData;
+    ActivityManager.RunningTaskInfo runningTaskInfo;
+    @WindowConfiguration.WindowingMode
+    int runningTaskWinMode = WINDOWING_MODE_UNDEFINED;
+    @WindowConfiguration.ActivityType
+    int runningTaskActType = ACTIVITY_TYPE_STANDARD;
+    boolean dragItemSupportsSplitscreen;
+
+    DragSession(Context context, ActivityTaskManager activityTaskManager,
+            DisplayLayout dispLayout, ClipData data) {
+        mActivityTaskManager = activityTaskManager;
+        mInitialDragData = data;
+        displayLayout = dispLayout;
+    }
+
+    /**
+     * Updates the session data based on the current state of the system.
+     */
+    void update() {
+        List<ActivityManager.RunningTaskInfo> tasks =
+                mActivityTaskManager.getTasks(1, false /* filterOnlyVisibleRecents */);
+        if (!tasks.isEmpty()) {
+            final ActivityManager.RunningTaskInfo task = tasks.get(0);
+            runningTaskInfo = task;
+            runningTaskWinMode = task.getWindowingMode();
+            runningTaskActType = task.getActivityType();
+        }
+
+        final ActivityInfo info = mInitialDragData.getItemAt(0).getActivityInfo();
+        dragItemSupportsSplitscreen = info == null
+                || ActivityInfo.isResizeableMode(info.resizeMode);
+        dragData = mInitialDragData.getItemAt(0).getIntent();
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragUtils.java
new file mode 100644
index 0000000..7c0883d
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragUtils.java
@@ -0,0 +1,60 @@
+/*
+ * 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;
+
+import static android.content.ClipDescription.MIMETYPE_APPLICATION_ACTIVITY;
+import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT;
+import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK;
+
+import android.content.ClipDescription;
+import android.view.DragEvent;
+
+/** Collection of utility classes for handling drag and drop. */
+public class DragUtils {
+    private static final String TAG = "DragUtils";
+
+    /**
+     * Returns whether we can handle this particular drag.
+     */
+    public static boolean canHandleDrag(DragEvent event) {
+        return event.getClipData().getItemCount() > 0
+                && (isAppDrag(event.getClipDescription()));
+    }
+
+    /**
+     * Returns whether this clip data description represents an app drag.
+     */
+    public static boolean isAppDrag(ClipDescription description) {
+        return description.hasMimeType(MIMETYPE_APPLICATION_ACTIVITY)
+                || description.hasMimeType(MIMETYPE_APPLICATION_SHORTCUT)
+                || description.hasMimeType(MIMETYPE_APPLICATION_TASK);
+    }
+
+    /**
+     * Returns a list of the mime types provided in the clip description.
+     */
+    public static String getMimeTypesConcatenated(ClipDescription description) {
+        String mimeTypes = "";
+        for (int i = 0; i < description.getMimeTypeCount(); i++) {
+            if (i > 0) {
+                mimeTypes += ", ";
+            }
+            mimeTypes += description.getMimeType(i);
+        }
+        return mimeTypes;
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropOutlineDrawable.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropOutlineDrawable.java
deleted file mode 100644
index 73deea5..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropOutlineDrawable.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.draganddrop;
-
-import android.animation.ObjectAnimator;
-import android.animation.RectEvaluator;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorFilter;
-import android.graphics.Paint;
-import android.graphics.PixelFormat;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.util.IntProperty;
-import android.util.Property;
-import android.view.animation.Interpolator;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.internal.graphics.ColorUtils;
-import com.android.internal.policy.ScreenDecorationsUtils;
-import com.android.internal.protolog.common.ProtoLog;
-import com.android.wm.shell.protolog.ShellProtoLogGroup;
-import com.android.wm.shell.R;
-
-/**
- * Drawable to draw the region that the target will have once it is dropped.
- */
-public class DropOutlineDrawable extends Drawable {
-
-    private static final int BOUNDS_DURATION = 200;
-    private static final int ALPHA_DURATION = 135;
-
-    private final IntProperty<DropOutlineDrawable> ALPHA =
-            new IntProperty<DropOutlineDrawable>("alpha") {
-        @Override
-        public void setValue(DropOutlineDrawable d, int alpha) {
-            d.setAlpha(alpha);
-        }
-
-        @Override
-        public Integer get(DropOutlineDrawable d) {
-            return d.getAlpha();
-        }
-    };
-
-    private final Property<DropOutlineDrawable, Rect> BOUNDS =
-            new Property<DropOutlineDrawable, Rect>(Rect.class, "bounds") {
-        @Override
-        public void set(DropOutlineDrawable d, Rect bounds) {
-            d.setRegionBounds(bounds);
-        }
-
-        @Override
-        public Rect get(DropOutlineDrawable d) {
-            return d.getRegionBounds();
-        }
-    };
-
-    private final RectEvaluator mRectEvaluator = new RectEvaluator(new Rect());
-    private ObjectAnimator mBoundsAnimator;
-    private ObjectAnimator mAlphaAnimator;
-
-    private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-    private final Rect mBounds = new Rect();
-    private final float mCornerRadius;
-    private final int mMaxAlpha;
-    private int mColor;
-
-    public DropOutlineDrawable(Context context) {
-        super();
-        // TODO(b/169894807): Use corner specific radii and maybe lower radius for non-edge corners
-        mCornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context);
-        mColor = context.getColor(R.color.drop_outline_background);
-        mMaxAlpha = Color.alpha(mColor);
-        // Initialize as hidden
-        ALPHA.set(this, 0);
-    }
-
-    @Override
-    public void setColorFilter(@Nullable ColorFilter colorFilter) {
-        // Do nothing
-    }
-
-    @Override
-    public void setAlpha(int alpha) {
-        mColor = ColorUtils.setAlphaComponent(mColor, alpha);
-        mPaint.setColor(mColor);
-        invalidateSelf();
-    }
-
-    @Override
-    public int getAlpha() {
-        return Color.alpha(mColor);
-    }
-
-    @Override
-    public int getOpacity() {
-        return PixelFormat.TRANSLUCENT;
-    }
-
-    @Override
-    protected void onBoundsChange(Rect bounds) {
-        invalidateSelf();
-    }
-
-    @Override
-    public void draw(@NonNull Canvas canvas) {
-        canvas.drawRoundRect(mBounds.left, mBounds.top, mBounds.right, mBounds.bottom,
-                mCornerRadius, mCornerRadius, mPaint);
-    }
-
-    public void setRegionBounds(Rect bounds) {
-        mBounds.set(bounds);
-        invalidateSelf();
-    }
-
-    public Rect getRegionBounds() {
-        return mBounds;
-    }
-
-    ObjectAnimator startBoundsAnimation(Rect toBounds, Interpolator interpolator) {
-        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Animate bounds: from=%s to=%s",
-                mBounds, toBounds);
-        if (mBoundsAnimator != null) {
-            mBoundsAnimator.cancel();
-        }
-        mBoundsAnimator = ObjectAnimator.ofObject(this, BOUNDS, mRectEvaluator,
-                mBounds, toBounds);
-        mBoundsAnimator.setDuration(BOUNDS_DURATION);
-        mBoundsAnimator.setInterpolator(interpolator);
-        mBoundsAnimator.start();
-        return mBoundsAnimator;
-    }
-
-    ObjectAnimator startVisibilityAnimation(boolean visible, Interpolator interpolator) {
-        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Animate alpha: from=%d to=%d",
-                Color.alpha(mColor), visible ? mMaxAlpha : 0);
-        if (mAlphaAnimator != null) {
-            mAlphaAnimator.cancel();
-        }
-        mAlphaAnimator = ObjectAnimator.ofInt(this, ALPHA, Color.alpha(mColor),
-                visible ? mMaxAlpha : 0);
-        mAlphaAnimator.setDuration(ALPHA_DURATION);
-        mAlphaAnimator.setInterpolator(interpolator);
-        mAlphaAnimator.start();
-        return mAlphaAnimator;
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipSizeSpecHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipSizeSpecHandler.java
index 7971c04..c6e5cf2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipSizeSpecHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipSizeSpecHandler.java
@@ -123,18 +123,19 @@
             final int totalVerticalPadding = getInsetBounds().top
                     + (getDisplayBounds().height() - getInsetBounds().bottom);
 
-            final int shorterLength = (int) (1f * Math.min(
-                    getDisplayBounds().width() - totalHorizontalPadding,
-                    getDisplayBounds().height() - totalVerticalPadding));
+            final int shorterLength = Math.min(getDisplayBounds().width() - totalHorizontalPadding,
+                    getDisplayBounds().height() - totalVerticalPadding);
 
             int maxWidth, maxHeight;
 
             // use the optimized max sizing logic only within a certain aspect ratio range
             if (aspectRatio >= mOptimizedAspectRatio && aspectRatio <= 1 / mOptimizedAspectRatio) {
                 // this formula and its derivation is explained in b/198643358#comment16
-                maxWidth = (int) (mOptimizedAspectRatio * shorterLength
+                maxWidth = Math.round(mOptimizedAspectRatio * shorterLength
                         + shorterLength * (aspectRatio - mOptimizedAspectRatio) / (1
                         + aspectRatio));
+                // make sure the max width doesn't go beyond shorter screen length after rounding
+                maxWidth = Math.min(maxWidth, shorterLength);
                 maxHeight = Math.round(maxWidth / aspectRatio);
             } else {
                 if (aspectRatio > 1f) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java
index b0fa993..3af1b75 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java
@@ -35,7 +35,7 @@
     WM_SHELL_RECENTS_TRANSITION(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, true,
             "ShellRecents"),
     WM_SHELL_DRAG_AND_DROP(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, true,
-            Consts.TAG_WM_SHELL),
+            "ShellDragAndDrop"),
     WM_SHELL_STARTING_WINDOW(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
             Consts.TAG_WM_STARTING_WINDOW),
     WM_SHELL_BACK_PREVIEW(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, true,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
index 837f118..39b6675 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -573,10 +573,12 @@
                 }
                 final boolean isRootTask = taskInfo != null
                         && TransitionInfo.isIndependent(change, info);
+                final boolean isRecentsTask = mRecentsTask != null
+                        && mRecentsTask.equals(change.getContainer());
                 hasTaskChange = hasTaskChange || isRootTask;
                 final boolean isLeafTask = leafTaskFilter.test(change);
                 if (TransitionUtil.isOpeningType(change.getMode())) {
-                    if (mRecentsTask != null && mRecentsTask.equals(change.getContainer())) {
+                    if (isRecentsTask) {
                         recentsOpening = change;
                     } else if (isRootTask || isLeafTask) {
                         if (isLeafTask && taskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
@@ -591,7 +593,7 @@
                         openingTaskIsLeafs.add(isLeafTask ? 1 : 0);
                     }
                 } else if (TransitionUtil.isClosingType(change.getMode())) {
-                    if (mRecentsTask != null && mRecentsTask.equals(change.getContainer())) {
+                    if (isRecentsTask) {
                         foundRecentsClosing = true;
                     } else if (isRootTask || isLeafTask) {
                         if (closingTasks == null) {
@@ -612,7 +614,7 @@
                     if (!TransitionUtil.isOrderOnly(change) && isLeafTask) {
                         hasChangingApp = true;
                     } else if (isLeafTask && taskInfo.topActivityType == ACTIVITY_TYPE_HOME
-                            && !mRecentsTask.equals(change.getContainer())) {
+                            && !isRecentsTask ) {
                         // Unless it is a 3p launcher. This means that the 3p launcher was already
                         // visible (eg. the "pausing" task is translucent over the 3p launcher).
                         // Treat it as if we are "re-opening" the 3p launcher.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index 3669bce..af8ef17 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -624,8 +624,8 @@
                         Toast.LENGTH_SHORT).show();
             }
         }
-        mStageCoordinator.startShortcutAndTask(shortcutInfo, options1, taskId, options2,
-                splitPosition, splitRatio, remoteTransition, instanceId);
+        mStageCoordinator.startShortcutAndTask(shortcutInfo, activityOptions.toBundle(), taskId,
+                options2, splitPosition, splitRatio, remoteTransition, instanceId);
     }
 
     /**
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 6961dab..7d62f58 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
@@ -219,6 +219,8 @@
     private boolean mIsDropEntering;
     private boolean mIsExiting;
     private boolean mIsRootTranslucent;
+    @VisibleForTesting
+    int mTopStageAfterFoldDismiss;
 
     private DefaultMixedHandler mMixedHandler;
     private final Toast mSplitUnsupportedToast;
@@ -738,12 +740,12 @@
             mMainStage.activate(wct, false /* reparent */);
         }
 
+        setSideStagePosition(splitPosition, wct);
         mSplitLayout.setDivideRatio(splitRatio);
         updateWindowBounds(mSplitLayout, wct);
         wct.reorder(mRootTaskInfo.token, true);
         setRootForceTranslucent(false, wct);
 
-        setSideStagePosition(splitPosition, wct);
         options1 = options1 != null ? options1 : new Bundle();
         addActivityOptions(options1, mSideStage);
         if (shortcutInfo1 != null) {
@@ -1310,6 +1312,24 @@
             final StageTaskListener toTop = mainStageVisible ? mMainStage : mSideStage;
             exitSplitScreen(toTop, EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP);
         }
+
+        // Dismiss split if the flag record any side of stages.
+        if (mTopStageAfterFoldDismiss != STAGE_TYPE_UNDEFINED) {
+            if (ENABLE_SHELL_TRANSITIONS) {
+                // Need manually clear here due to this transition might be aborted due to keyguard
+                // on top and lead to no visible change.
+                clearSplitPairedInRecents(EXIT_REASON_DEVICE_FOLDED);
+                final WindowContainerTransaction wct = new WindowContainerTransaction();
+                prepareExitSplitScreen(mTopStageAfterFoldDismiss, wct);
+                mSplitTransitions.startDismissTransition(wct, this,
+                        mTopStageAfterFoldDismiss, EXIT_REASON_DEVICE_FOLDED);
+            } else {
+                exitSplitScreen(
+                        mTopStageAfterFoldDismiss == STAGE_TYPE_MAIN ? mMainStage : mSideStage,
+                        EXIT_REASON_DEVICE_FOLDED);
+            }
+            mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
+        }
     }
 
     void exitSplitScreenOnHide(boolean exitSplitScreenOnHide) {
@@ -1346,15 +1366,8 @@
         if (!mMainStage.isActive() || mIsExiting) return;
 
         onSplitScreenExit();
+        clearSplitPairedInRecents(exitReason);
 
-        mRecentTasks.ifPresent(recentTasks -> {
-            // 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.getTopVisibleChildTaskId());
-                recentTasks.removeSplitPair(mSideStage.getTopVisibleChildTaskId());
-            }
-        });
         mShouldUpdateRecents = false;
         mIsDividerRemoteAnimating = false;
         mSplitRequest = null;
@@ -1481,6 +1494,17 @@
         }
     }
 
+    private void clearSplitPairedInRecents(@ExitReason int exitReason) {
+        if (!shouldBreakPairedTaskInRecents(exitReason) || !mShouldUpdateRecents) return;
+
+        mRecentTasks.ifPresent(recentTasks -> {
+            // 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
+            mMainStage.doForAllChildTasks(taskId -> recentTasks.removeSplitPair(taskId));
+            mSideStage.doForAllChildTasks(taskId -> recentTasks.removeSplitPair(taskId));
+        });
+    }
+
     /**
      * Unlike exitSplitScreen, this takes a stagetype vs an actual stage-reference and populates
      * an existing WindowContainerTransaction (rather than applying immediately). This is intended
@@ -2208,7 +2232,11 @@
         }
     }
 
-    void updateSurfaces(SurfaceControl.Transaction transaction) {
+    /**
+     * Update surfaces of the split screen layout based on the current state
+     * @param transaction to write the updates to
+     */
+    public void updateSurfaces(SurfaceControl.Transaction transaction) {
         updateSurfaceBounds(mSplitLayout, transaction, /* applyResizingOffset */ false);
         mSplitLayout.update(transaction);
     }
@@ -2227,26 +2255,18 @@
 
     @VisibleForTesting
     void onFoldedStateChanged(boolean folded) {
-        int topStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
+        mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
         if (!folded) return;
 
-        if (!mMainStage.isActive()) return;
+        if (!isSplitActive() || !isSplitScreenVisible()) return;
 
+        // To avoid split dismiss when user fold the device and unfold to use later, we only
+        // record the flag here and try to dismiss on wakeUp callback to ensure split dismiss
+        // when user interact on phone folded.
         if (mMainStage.isFocused()) {
-            topStageAfterFoldDismiss = STAGE_TYPE_MAIN;
+            mTopStageAfterFoldDismiss = STAGE_TYPE_MAIN;
         } else if (mSideStage.isFocused()) {
-            topStageAfterFoldDismiss = STAGE_TYPE_SIDE;
-        }
-
-        if (ENABLE_SHELL_TRANSITIONS) {
-            final WindowContainerTransaction wct = new WindowContainerTransaction();
-            prepareExitSplitScreen(topStageAfterFoldDismiss, wct);
-            mSplitTransitions.startDismissTransition(wct, this,
-                    topStageAfterFoldDismiss, EXIT_REASON_DEVICE_FOLDED);
-        } else {
-            exitSplitScreen(
-                    topStageAfterFoldDismiss == STAGE_TYPE_MAIN ? mMainStage : mSideStage,
-                    EXIT_REASON_DEVICE_FOLDED);
+            mTopStageAfterFoldDismiss = STAGE_TYPE_SIDE;
         }
     }
 
@@ -2544,6 +2564,9 @@
                 // so don't handle it.
                 Log.e(TAG, "Somehow removed the last task in a stage outside of a proper "
                         + "transition.");
+                // This new transition would be merged to current one so we need to clear
+                // tile manually here.
+                clearSplitPairedInRecents(EXIT_REASON_APP_FINISHED);
                 final WindowContainerTransaction wct = new WindowContainerTransaction();
                 final int dismissTop = (dismissStages.size() == 1
                         && getStageType(dismissStages.valueAt(0)) == STAGE_TYPE_MAIN)
@@ -2568,8 +2591,11 @@
             // handling to the mixed-handler to deal with splitting it up.
             if (mMixedHandler.animatePendingSplitWithDisplayChange(transition, info,
                     startTransaction, finishTransaction, finishCallback)) {
-                mSplitLayout.update(startTransaction);
-                startTransaction.apply();
+                if (mSplitTransitions.isPendingResize(transition)) {
+                    // Only need to update in resize because divider exist before transition.
+                    mSplitLayout.update(startTransaction);
+                    startTransaction.apply();
+                }
                 return true;
             }
         }
@@ -2724,6 +2750,12 @@
                 Log.w(TAG, splitFailureMessage("startPendingEnterAnimation",
                         "launched 2 tasks in split, but didn't receive "
                         + "2 tasks in transition. Possibly one of them failed to launch"));
+                if (mRecentTasks.isPresent() && mainChild != null) {
+                    mRecentTasks.get().removeSplitPair(mainChild.getTaskInfo().taskId);
+                }
+                if (mRecentTasks.isPresent() && sideChild != null) {
+                    mRecentTasks.get().removeSplitPair(sideChild.getTaskInfo().taskId);
+                }
                 mSplitUnsupportedToast.show();
                 return true;
             }
@@ -2939,8 +2971,6 @@
             mSideStage.getSplitDecorManager().release(callbackT);
             callbackWct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token, false);
         });
-
-        addDividerBarToTransition(info, false /* show */);
         return true;
     }
 
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 e2c55e4..af7bf36 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
@@ -55,6 +55,7 @@
 
 import java.io.PrintWriter;
 import java.util.Optional;
+import java.util.function.Consumer;
 import java.util.function.Predicate;
 
 /**
@@ -347,6 +348,13 @@
         wct.reorder(mChildrenTaskInfo.get(taskId).token, onTop /* onTop */);
     }
 
+    void doForAllChildTasks(Consumer<Integer> consumer) {
+        for (int i = mChildrenTaskInfo.size() - 1; i >= 0; i--) {
+            final ActivityManager.RunningTaskInfo taskInfo = mChildrenTaskInfo.valueAt(i);
+            consumer.accept(taskInfo.taskId);
+        }
+    }
+
     /** Collects all the current child tasks and prepares transaction to evict them to display. */
     void evictAllChildren(WindowContainerTransaction wct) {
         for (int i = mChildrenTaskInfo.size() - 1; i >= 0; i--) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
index 5baf2e3..16f0e39 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
@@ -202,15 +202,10 @@
         if (taskView == null) return null;
         // Opening types should all be initiated by shell
         if (!TransitionUtil.isClosingType(request.getType())) return null;
-        PendingTransition pending = findPendingCloseTransition(taskView);
-        if (pending == null) {
-            pending = new PendingTransition(request.getType(), null, taskView, null /* cookie */);
-        }
-        if (pending.mClaimed != null) {
-            throw new IllegalStateException("Task is closing in 2 collecting transitions?"
-                    + " This state doesn't make sense");
-        }
+        PendingTransition pending = new PendingTransition(request.getType(), null,
+                taskView, null /* cookie */);
         pending.mClaimed = transition;
+        mPending.add(pending);
         return new WindowContainerTransaction();
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
index d9edde1..c5c22de 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
@@ -704,6 +704,9 @@
         if (mPipHandler != null) {
             mPipHandler.syncPipSurfaceState(info, startTransaction, finishTransaction);
         }
+        if (mSplitHandler != null && mSplitHandler.isSplitActive()) {
+            mSplitHandler.updateSurfaces(startTransaction);
+        }
         return mUnfoldHandler.startAnimation(
                 mixed.mTransition, info, startTransaction, finishTransaction, finishCB);
     }
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 21994a9..bb5d546 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
@@ -270,7 +270,6 @@
     @Override
     public void prepareStartTransaction(Transaction transaction) {
         mUnfoldBackgroundController.ensureBackground(transaction);
-        mSplitScreenController.get().get().updateSplitScreenSurfaces(transaction);
     }
 
     @Override
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 7245bc9..1a18fc2 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
@@ -24,9 +24,9 @@
 
 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.desktopmode.EnterDesktopTaskTransitionHandler.DRAG_FREEFORM_SCALE;
 import static com.android.wm.shell.desktopmode.EnterDesktopTaskTransitionHandler.FINAL_FREEFORM_SCALE;
 import static com.android.wm.shell.desktopmode.EnterDesktopTaskTransitionHandler.FREEFORM_ANIMATION_DURATION;
+import static com.android.wm.shell.windowdecor.MoveToDesktopAnimator.DRAG_FREEFORM_SCALE;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -112,9 +112,8 @@
 
     private SplitScreenController mSplitScreenController;
 
-    private ValueAnimator mDragToDesktopValueAnimator;
+    private MoveToDesktopAnimator mMoveToDesktopAnimator;
     private final Rect mDragToDesktopAnimationStartBounds = new Rect();
-    private boolean mDragToDesktopAnimationStarted;
 
     public DesktopModeWindowDecorViewModel(
             Context context,
@@ -233,7 +232,6 @@
             removeTaskFromEventReceiver(oldTaskInfo.displayId);
             incrementEventReceiverTasks(taskInfo.displayId);
         }
-
         decoration.relayout(taskInfo);
     }
 
@@ -599,7 +597,7 @@
             }
             case MotionEvent.ACTION_UP: {
                 if (relevantDecor == null) {
-                    mDragToDesktopAnimationStarted = false;
+                    mMoveToDesktopAnimator = null;
                     mTransitionDragActive = false;
                     return;
                 }
@@ -613,14 +611,14 @@
                         } else if (DesktopModeStatus.isProto1Enabled()) {
                             mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(true));
                         }
-                        mDragToDesktopAnimationStarted = false;
+                        mMoveToDesktopAnimator = null;
                         return;
-                    } else if (mDragToDesktopAnimationStarted) {
-                        Point position = new Point((int) ev.getX(), (int) ev.getY());
+                    } else if (mMoveToDesktopAnimator != null) {
                         relevantDecor.incrementRelayoutBlock();
                         mDesktopTasksController.ifPresent(
-                                c -> c.cancelMoveToFreeform(relevantDecor.mTaskInfo, position));
-                        mDragToDesktopAnimationStarted = false;
+                                c -> c.cancelMoveToFreeform(relevantDecor.mTaskInfo,
+                                        mMoveToDesktopAnimator));
+                        mMoveToDesktopAnimator = null;
                         return;
                     }
                 }
@@ -640,21 +638,19 @@
                     final int statusBarHeight = getStatusBarHeight(
                             relevantDecor.mTaskInfo.displayId);
                     if (ev.getY() > statusBarHeight) {
-                        if (!mDragToDesktopAnimationStarted) {
-                            mDragToDesktopAnimationStarted = true;
+                        if (mMoveToDesktopAnimator == null) {
+                            mMoveToDesktopAnimator = new MoveToDesktopAnimator(
+                                    mDragToDesktopAnimationStartBounds, relevantDecor.mTaskInfo,
+                                    relevantDecor.mTaskSurface);
                             mDesktopTasksController.ifPresent(
                                     c -> c.moveToFreeform(relevantDecor.mTaskInfo,
-                                            mDragToDesktopAnimationStartBounds));
-                            startAnimation(relevantDecor);
+                                            mDragToDesktopAnimationStartBounds,
+                                            mMoveToDesktopAnimator));
+                            mMoveToDesktopAnimator.startAnimation();
                         }
                     }
-                    if (mDragToDesktopAnimationStarted) {
-                        Transaction t = mTransactionFactory.get();
-                        float width = (float) mDragToDesktopValueAnimator.getAnimatedValue()
-                                * mDragToDesktopAnimationStartBounds.width();
-                        float x = ev.getX() - (width / 2);
-                        t.setPosition(relevantDecor.mTaskSurface, x, ev.getY());
-                        t.apply();
+                    if (mMoveToDesktopAnimator != null) {
+                        mMoveToDesktopAnimator.updatePosition(ev);
                     }
                 }
                 break;
@@ -662,7 +658,7 @@
 
             case MotionEvent.ACTION_CANCEL: {
                 mTransitionDragActive = false;
-                mDragToDesktopAnimationStarted = false;
+                mMoveToDesktopAnimator = null;
             }
         }
     }
@@ -729,20 +725,6 @@
         animator.start();
     }
 
-    private void startAnimation(@NonNull DesktopModeWindowDecoration focusedDecor) {
-        mDragToDesktopValueAnimator = ValueAnimator.ofFloat(1f, DRAG_FREEFORM_SCALE);
-        mDragToDesktopValueAnimator.setDuration(FREEFORM_ANIMATION_DURATION);
-        final Transaction t = mTransactionFactory.get();
-        mDragToDesktopValueAnimator.addUpdateListener(animation -> {
-            final float animatorValue = (float) animation.getAnimatedValue();
-            SurfaceControl sc = focusedDecor.mTaskSurface;
-            t.setScale(sc, animatorValue, animatorValue);
-            t.apply();
-        });
-
-        mDragToDesktopValueAnimator.start();
-    }
-
     @Nullable
     private DesktopModeWindowDecoration getRelevantWindowDecor(MotionEvent ev) {
         if (mSplitScreenController != null && mSplitScreenController.isSplitScreenVisible()) {
@@ -817,6 +799,7 @@
         return DesktopModeStatus.isProto2Enabled()
                 && taskInfo.getWindowingMode() != WINDOWING_MODE_PINNED
                 && taskInfo.getActivityType() == ACTIVITY_TYPE_STANDARD
+                && !taskInfo.configuration.windowConfiguration.isAlwaysOnTop()
                 && mDisplayController.getDisplayContext(taskInfo.displayId)
                 .getResources().getConfiguration().smallestScreenWidthDp >= 600;
     }
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 336d95e..7c6fb99 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
@@ -336,6 +336,7 @@
         private final Runnable mConsumeBatchEventRunnable;
         private boolean mConsumeBatchEventScheduled;
         private boolean mShouldHandleEvents;
+        private int mLastCursorType = PointerIcon.TYPE_DEFAULT;
 
         private TaskResizeInputEventReceiver(
                 InputChannel inputChannel, Handler handler, Choreographer choreographer) {
@@ -437,7 +438,6 @@
                     break;
                 }
                 case MotionEvent.ACTION_HOVER_EXIT:
-                    mInputManager.setPointerIconType(PointerIcon.TYPE_DEFAULT);
                     result = true;
                     break;
             }
@@ -477,7 +477,13 @@
             if (y > mTaskHeight - mTaskCornerRadius) {
                 ctrlType |= CTRL_TYPE_BOTTOM;
             }
-            return checkDistanceFromCenter(ctrlType, x, y);
+            // Check distances from the center if it's in one of four corners.
+            if ((ctrlType & (CTRL_TYPE_LEFT | CTRL_TYPE_RIGHT)) != 0
+                    && (ctrlType & (CTRL_TYPE_TOP | CTRL_TYPE_BOTTOM)) != 0) {
+                return checkDistanceFromCenter(ctrlType, x, y);
+            }
+            // Otherwise, we should make sure we don't resize tasks inside task bounds.
+            return (x < 0 || y < 0 || x >= mTaskWidth || y >= mTaskHeight) ? ctrlType : 0;
         }
 
         // If corner input is not within appropriate distance of corner radius, do not use it.
@@ -511,7 +517,8 @@
                     break;
                 }
                 default: {
-                    return ctrlType;
+                    throw new IllegalArgumentException("ctrlType should be complex, but it's 0x"
+                            + Integer.toHexString(ctrlType));
                 }
             }
             double distanceFromCenter = Math.hypot(x - centerX, y - centerY);
@@ -564,7 +571,19 @@
                     cursorType = PointerIcon.TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW;
                     break;
             }
-            mInputManager.setPointerIconType(cursorType);
+            // Only update the cursor type to default once so that views behind the decor container
+            // layer that aren't in the active resizing regions have chances to update the cursor
+            // type. We would like to enforce the cursor type by setting the cursor type multilple
+            // times in active regions because we shouldn't allow the views behind to change it, as
+            // we'll pilfer the gesture initiated in this area. This is necessary because 1) we
+            // should allow the views behind regions only for touches to set the cursor type; and 2)
+            // there is a small region out of each rounded corner that's inside the task bounds,
+            // where views in the task can receive input events because we can't set touch regions
+            // of input sinks to have rounded corners.
+            if (mLastCursorType != cursorType || cursorType != PointerIcon.TYPE_DEFAULT) {
+                mInputManager.setPointerIconType(cursorType);
+                mLastCursorType = cursorType;
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MoveToDesktopAnimator.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MoveToDesktopAnimator.kt
new file mode 100644
index 0000000..b2267dd
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MoveToDesktopAnimator.kt
@@ -0,0 +1,72 @@
+package com.android.wm.shell.windowdecor
+
+import android.animation.ValueAnimator
+import android.app.ActivityManager.RunningTaskInfo
+import android.graphics.PointF
+import android.graphics.Rect
+import android.view.MotionEvent
+import android.view.SurfaceControl
+
+/**
+ * Creates an animator to shrink and position task after a user drags a fullscreen task from
+ * the top of the screen to transition it into freeform and before the user releases the task. The
+ * MoveToDesktopAnimator object also holds information about the state of the task that are
+ * accessed by the EnterDesktopTaskTransitionHandler.
+ */
+class MoveToDesktopAnimator @JvmOverloads constructor(
+        private val startBounds: Rect,
+        private val taskInfo: RunningTaskInfo,
+        private val taskSurface: SurfaceControl,
+        private val transactionFactory: () -> SurfaceControl.Transaction =
+                SurfaceControl::Transaction
+) {
+    companion object {
+        // The size of the screen during drag relative to the fullscreen size
+        const val DRAG_FREEFORM_SCALE: Float = 0.4f
+        const val ANIMATION_DURATION = 336
+    }
+
+    private val animatedTaskWidth
+        get() = dragToDesktopAnimator.animatedValue as Float * startBounds.width()
+    private val dragToDesktopAnimator: ValueAnimator = ValueAnimator.ofFloat(1f,
+            DRAG_FREEFORM_SCALE)
+            .setDuration(ANIMATION_DURATION.toLong())
+            .apply {
+                val t = SurfaceControl.Transaction()
+                addUpdateListener { animation ->
+                    val animatorValue = animation.animatedValue as Float
+                    t.setScale(taskSurface, animatorValue, animatorValue)
+                            .apply()
+                }
+            }
+
+    val taskId get() = taskInfo.taskId
+    val position: PointF = PointF(0.0f, 0.0f)
+
+    /**
+     * Starts the animation that scales the task down.
+     */
+    fun startAnimation() {
+        dragToDesktopAnimator.start()
+    }
+
+    /**
+     * Uses the position of the motion event and the current scale of the task as defined by the
+     * ValueAnimator to update the local position variable and set the task surface's position
+     */
+    fun updatePosition(ev: MotionEvent) {
+        position.x = ev.x - animatedTaskWidth / 2
+        position.y = ev.y
+
+        val t = transactionFactory()
+        t.setPosition(taskSurface, position.x, position.y)
+        t.apply()
+    }
+
+    /**
+     * Ends the animation, setting the scale and position to the final animation value
+     */
+    fun endAnimator() {
+        dragToDesktopAnimator.end()
+    }
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/Android.bp b/libs/WindowManager/Shell/tests/flicker/Android.bp
index 89747df..208ae84 100644
--- a/libs/WindowManager/Shell/tests/flicker/Android.bp
+++ b/libs/WindowManager/Shell/tests/flicker/Android.bp
@@ -138,7 +138,7 @@
 android_test {
     name: "WMShellFlickerServiceTests",
     defaults: ["WMShellFlickerTestsDefault"],
-    additional_manifests: ["manifests/AndroidManifestSplitScreen.xml"],
+    additional_manifests: ["manifests/AndroidManifestService.xml"],
     package_name: "com.android.wm.shell.flicker.service",
     instrumentation_target_package: "com.android.wm.shell.flicker.service",
     srcs: [
diff --git a/libs/WindowManager/Shell/tests/flicker/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/flicker/AndroidTestTemplate.xml
index 991d7b5..c8a9637 100644
--- a/libs/WindowManager/Shell/tests/flicker/AndroidTestTemplate.xml
+++ b/libs/WindowManager/Shell/tests/flicker/AndroidTestTemplate.xml
@@ -93,6 +93,8 @@
                 value="/data/user/0/com.android.server.wm.flicker.pip/files"/>
         <option name="directory-keys"
                 value="/data/user/0/com.android.server.wm.flicker.splitscreen/files"/>
+        <option name="directory-keys"
+            value="/data/user/0/com.android.server.wm.flicker.service/files"/>
         <option name="collect-on-run-ended-only" value="true"/>
         <option name="clean-up" value="true"/>
     </metrics_collector>
diff --git a/libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifestService.xml b/libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifestService.xml
new file mode 100644
index 0000000..c7aca1a
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifestService.xml
@@ -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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.wm.shell.flicker.service">
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.wm.shell.flicker.service"
+                     android:label="WindowManager Flicker Service Tests">
+    </instrumentation>
+</manifest>
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/Utils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/Utils.kt
new file mode 100644
index 0000000..610cede
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/Utils.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.wm.shell.flicker.service
+
+import android.app.Instrumentation
+import android.platform.test.rule.NavigationModeRule
+import android.platform.test.rule.PressHomeRule
+import android.platform.test.rule.UnlockScreenRule
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.device.apphelpers.MessagingAppHelper
+import android.tools.device.flicker.rules.ChangeDisplayOrientationRule
+import android.tools.device.flicker.rules.LaunchAppRule
+import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule
+import androidx.test.platform.app.InstrumentationRegistry
+import org.junit.rules.RuleChain
+
+object Utils {
+    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+
+    fun testSetupRule(navigationMode: NavBar, rotation: Rotation): RuleChain {
+        return RuleChain.outerRule(UnlockScreenRule())
+            .around(
+                NavigationModeRule(navigationMode.value, /* changeNavigationModeAfterTest */ false)
+            )
+            .around(
+                LaunchAppRule(MessagingAppHelper(instrumentation), clearCacheAfterParsing = false)
+            )
+            .around(RemoveAllTasksButHomeRule())
+            .around(
+                ChangeDisplayOrientationRule(
+                    rotation,
+                    resetOrientationAfterTest = false,
+                    clearCacheAfterParsing = false
+                )
+            )
+            .around(PressHomeRule())
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/CopyContentInSplit.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/CopyContentInSplit.kt
index 76ad6b9..5bfc889 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/CopyContentInSplit.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/CopyContentInSplit.kt
@@ -23,6 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.wm.shell.flicker.service.Utils
 import org.junit.After
 import org.junit.Before
 import org.junit.Ignore
@@ -42,9 +43,7 @@
     private val secondaryApp = SplitScreenUtils.getSecondary(instrumentation)
     private val textEditApp = SplitScreenUtils.getIme(instrumentation)
 
-    @Rule
-    @JvmField
-    val testSetupRule = SplitScreenUtils.testSetupRule({ NavBar.MODE_GESTURAL }, { rotation })
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
 
     @Before
     fun setup() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByDivider.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByDivider.kt
index 25182b4..d07daff 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByDivider.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByDivider.kt
@@ -23,6 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.wm.shell.flicker.service.Utils
 import org.junit.After
 import org.junit.Before
 import org.junit.Ignore
@@ -40,9 +41,7 @@
     private val primaryApp = SplitScreenUtils.getPrimary(instrumentation)
     private val secondaryApp = SplitScreenUtils.getSecondary(instrumentation)
 
-    @Rule
-    @JvmField
-    val testSetupRule = SplitScreenUtils.testSetupRule({ NavBar.MODE_GESTURAL }, { rotation })
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
 
     @Before
     fun setup() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByGoHome.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByGoHome.kt
index 000b628..d428dea 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByGoHome.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByGoHome.kt
@@ -23,6 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.wm.shell.flicker.service.Utils
 import org.junit.After
 import org.junit.Before
 import org.junit.Ignore
@@ -40,9 +41,7 @@
     private val primaryApp = SplitScreenUtils.getPrimary(instrumentation)
     private val secondaryApp = SplitScreenUtils.getSecondary(instrumentation)
 
-    @Rule
-    @JvmField
-    val testSetupRule = SplitScreenUtils.testSetupRule({ NavBar.MODE_GESTURAL }, { rotation })
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
 
     @Before
     fun setup() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt
index dd9ff3c..dc2a6ac 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt
@@ -23,6 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.wm.shell.flicker.service.Utils
 import org.junit.After
 import org.junit.Before
 import org.junit.Ignore
@@ -40,9 +41,7 @@
     private val primaryApp = SplitScreenUtils.getPrimary(instrumentation)
     private val secondaryApp = SplitScreenUtils.getSecondary(instrumentation)
 
-    @Rule
-    @JvmField
-    val testSetupRule = SplitScreenUtils.testSetupRule({ NavBar.MODE_GESTURAL }, { rotation })
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
 
     @Before
     fun setup() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromAllApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromAllApps.kt
index 4bbb9aa..677aeb07 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromAllApps.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromAllApps.kt
@@ -23,6 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.wm.shell.flicker.service.Utils
 import org.junit.After
 import org.junit.Before
 import org.junit.Ignore
@@ -40,9 +41,7 @@
     private val primaryApp = SplitScreenUtils.getPrimary(instrumentation)
     private val secondaryApp = SplitScreenUtils.getSecondary(instrumentation)
 
-    @Rule
-    @JvmField
-    val testSetupRule = SplitScreenUtils.testSetupRule({ NavBar.MODE_GESTURAL }, { rotation })
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
 
     @Before
     fun setup() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt
index a2b7526..f4f6878 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt
@@ -23,6 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.wm.shell.flicker.service.Utils
 import org.junit.After
 import org.junit.Before
 import org.junit.Ignore
@@ -41,9 +42,7 @@
     private val secondaryApp = SplitScreenUtils.getSecondary(instrumentation)
     private val sendNotificationApp = SplitScreenUtils.getSendNotification(instrumentation)
 
-    @Rule
-    @JvmField
-    val testSetupRule = SplitScreenUtils.testSetupRule({ NavBar.MODE_GESTURAL }, { rotation })
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
 
     @Before
     fun setup() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromShortcut.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromShortcut.kt
index 1ccd813..36a458f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromShortcut.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromShortcut.kt
@@ -23,6 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.wm.shell.flicker.service.Utils
 import org.junit.After
 import org.junit.Assume
 import org.junit.Before
@@ -41,9 +42,7 @@
     private val primaryApp = SplitScreenUtils.getPrimary(instrumentation)
     private val secondaryApp = SplitScreenUtils.getSecondary(instrumentation)
 
-    @Rule
-    @JvmField
-    val testSetupRule = SplitScreenUtils.testSetupRule({ NavBar.MODE_GESTURAL }, { rotation })
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
 
     @Before
     fun setup() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromTaskbar.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromTaskbar.kt
index 664786b..322f711 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromTaskbar.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromTaskbar.kt
@@ -23,6 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.wm.shell.flicker.service.Utils
 import org.junit.After
 import org.junit.Before
 import org.junit.Ignore
@@ -40,9 +41,7 @@
     private val primaryApp = SplitScreenUtils.getPrimary(instrumentation)
     private val secondaryApp = SplitScreenUtils.getSecondary(instrumentation)
 
-    @Rule
-    @JvmField
-    val testSetupRule = SplitScreenUtils.testSetupRule({ NavBar.MODE_GESTURAL }, { rotation })
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
 
     @Before
     fun setup() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenFromOverview.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenFromOverview.kt
index 88fd084..f164451 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenFromOverview.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenFromOverview.kt
@@ -23,6 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.wm.shell.flicker.service.Utils
 import org.junit.After
 import org.junit.Before
 import org.junit.Ignore
@@ -40,9 +41,7 @@
     private val primaryApp = SplitScreenUtils.getPrimary(instrumentation)
     private val secondaryApp = SplitScreenUtils.getSecondary(instrumentation)
 
-    @Rule
-    @JvmField
-    val testSetupRule = SplitScreenUtils.testSetupRule({ NavBar.MODE_GESTURAL }, { rotation })
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
 
     @Before
     fun setup() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SplitScreenUtils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SplitScreenUtils.kt
index 83a18e8..3831c65 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SplitScreenUtils.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SplitScreenUtils.kt
@@ -19,25 +19,15 @@
 import android.app.Instrumentation
 import android.graphics.Point
 import android.os.SystemClock
-import android.platform.test.rule.NavigationModeRule
-import android.platform.test.rule.PressHomeRule
-import android.platform.test.rule.UnlockScreenRule
-import android.tools.common.NavBar
-import android.tools.common.Rotation
 import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.common.traces.component.IComponentMatcher
 import android.tools.common.traces.component.IComponentNameMatcher
-import android.tools.device.apphelpers.MessagingAppHelper
 import android.tools.device.apphelpers.StandardAppHelper
-import android.tools.device.flicker.rules.ChangeDisplayOrientationRule
-import android.tools.device.flicker.rules.LaunchAppRule
-import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule
 import android.tools.device.traces.parsers.WindowManagerStateHelper
 import android.tools.device.traces.parsers.toFlickerComponent
 import android.view.InputDevice
 import android.view.MotionEvent
 import android.view.ViewConfiguration
-import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.By
 import androidx.test.uiautomator.BySelector
 import androidx.test.uiautomator.UiDevice
@@ -52,7 +42,6 @@
 import com.android.wm.shell.flicker.LAUNCHER_UI_PACKAGE_NAME
 import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME
 import org.junit.Assert.assertNotNull
-import org.junit.rules.RuleChain
 
 object SplitScreenUtils {
     private const val TIMEOUT_MS = 3_000L
@@ -73,30 +62,6 @@
     private val overviewSnapshotSelector: BySelector
         get() = By.res(LAUNCHER_UI_PACKAGE_NAME, OVERVIEW_SNAPSHOT)
 
-    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
-
-    fun testSetupRule(navigationMode: () -> NavBar, rotation: () -> Rotation): RuleChain {
-        return RuleChain.outerRule(UnlockScreenRule())
-            .around(
-                NavigationModeRule(
-                    navigationMode().value,
-                    /* changeNavigationModeAfterTest */ false
-                )
-            )
-            .around(
-                LaunchAppRule(MessagingAppHelper(instrumentation), clearCacheAfterParsing = false)
-            )
-            .around(RemoveAllTasksButHomeRule())
-            .around(
-                ChangeDisplayOrientationRule(
-                    rotation(),
-                    resetOrientationAfterTest = false,
-                    clearCacheAfterParsing = false
-                )
-            )
-            .around(PressHomeRule())
-    }
-
     fun getPrimary(instrumentation: Instrumentation): StandardAppHelper =
         SimpleAppHelper(
             instrumentation,
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt
index e5501f4..805d987 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt
@@ -25,6 +25,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.wm.shell.flicker.service.Utils
 import org.junit.After
 import org.junit.Before
 import org.junit.Ignore
@@ -42,9 +43,7 @@
     private val primaryApp = SplitScreenUtils.getPrimary(instrumentation)
     private val secondaryApp = SplitScreenUtils.getSecondary(instrumentation)
 
-    @Rule
-    @JvmField
-    val testSetupRule = SplitScreenUtils.testSetupRule({ NavBar.MODE_GESTURAL }, { rotation })
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
 
     @Before
     fun setup() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromAnotherApp.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromAnotherApp.kt
index b3f1e87..4229ebb 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromAnotherApp.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromAnotherApp.kt
@@ -23,6 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.wm.shell.flicker.service.Utils
 import org.junit.After
 import org.junit.Before
 import org.junit.Ignore
@@ -41,9 +42,7 @@
     private val secondaryApp = SplitScreenUtils.getSecondary(instrumentation)
     private val thirdApp = SplitScreenUtils.getNonResizeable(instrumentation)
 
-    @Rule
-    @JvmField
-    val testSetupRule = SplitScreenUtils.testSetupRule({ NavBar.MODE_GESTURAL }, { rotation })
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
 
     @Before
     fun setup() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromHome.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromHome.kt
index d112116..f2d56b9 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromHome.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromHome.kt
@@ -23,6 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.wm.shell.flicker.service.Utils
 import org.junit.After
 import org.junit.Before
 import org.junit.Ignore
@@ -40,9 +41,7 @@
     private val primaryApp = SplitScreenUtils.getPrimary(instrumentation)
     private val secondaryApp = SplitScreenUtils.getSecondary(instrumentation)
 
-    @Rule
-    @JvmField
-    val testSetupRule = SplitScreenUtils.testSetupRule({ NavBar.MODE_GESTURAL }, { rotation })
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
 
     @Before
     fun setup() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromRecent.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromRecent.kt
index 9ab924c..d44d177 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromRecent.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromRecent.kt
@@ -23,6 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.wm.shell.flicker.service.Utils
 import org.junit.After
 import org.junit.Before
 import org.junit.Ignore
@@ -40,9 +41,7 @@
     private val primaryApp = SplitScreenUtils.getPrimary(instrumentation)
     private val secondaryApp = SplitScreenUtils.getSecondary(instrumentation)
 
-    @Rule
-    @JvmField
-    val testSetupRule = SplitScreenUtils.testSetupRule({ NavBar.MODE_GESTURAL }, { rotation })
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
 
     @Before
     fun setup() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBetweenSplitPairs.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBetweenSplitPairs.kt
index b694dfa..e2c6ca6 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBetweenSplitPairs.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBetweenSplitPairs.kt
@@ -23,6 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.wm.shell.flicker.service.Utils
 import org.junit.After
 import org.junit.Before
 import org.junit.Ignore
@@ -42,9 +43,7 @@
     private val thirdApp = SplitScreenUtils.getIme(instrumentation)
     private val fourthApp = SplitScreenUtils.getSendNotification(instrumentation)
 
-    @Rule
-    @JvmField
-    val testSetupRule = SplitScreenUtils.testSetupRule({ NavBar.MODE_GESTURAL }, { rotation })
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
 
     @Before
     fun setup() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/UnlockKeyguardToSplitScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/UnlockKeyguardToSplitScreen.kt
index f78b788..df98d8f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/UnlockKeyguardToSplitScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/UnlockKeyguardToSplitScreen.kt
@@ -23,6 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.wm.shell.flicker.service.Utils
 import org.junit.After
 import org.junit.Before
 import org.junit.Ignore
@@ -40,8 +41,7 @@
 
     @Rule
     @JvmField
-    val testSetupRule =
-        SplitScreenUtils.testSetupRule({ NavBar.MODE_GESTURAL }, { Rotation.ROTATION_0 })
+    val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, Rotation.ROTATION_0)
 
     @Before
     fun setup() {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandlerTest.java
index 8592dea..c6642f3 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandlerTest.java
@@ -28,6 +28,7 @@
 import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.app.WindowConfiguration;
+import android.graphics.PointF;
 import android.graphics.Rect;
 import android.os.IBinder;
 import android.view.SurfaceControl;
@@ -41,6 +42,7 @@
 
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.transition.Transitions;
+import com.android.wm.shell.windowdecor.MoveToDesktopAnimator;
 
 import junit.framework.AssertionFailedError;
 
@@ -73,6 +75,10 @@
     ShellExecutor mExecutor;
     @Mock
     SurfaceControl mSurfaceControl;
+    @Mock
+    MoveToDesktopAnimator mMoveToDesktopAnimator;
+    @Mock
+    PointF mPosition;
 
     private EnterDesktopTaskTransitionHandler mEnterDesktopTaskTransitionHandler;
 
@@ -82,6 +88,7 @@
 
         doReturn(mExecutor).when(mTransitions).getMainExecutor();
         doReturn(mAnimationT).when(mTransactionFactory).get();
+        doReturn(mPosition).when(mMoveToDesktopAnimator).getPosition();
 
         mEnterDesktopTaskTransitionHandler = new EnterDesktopTaskTransitionHandler(mTransitions,
                 mTransactionFactory);
@@ -89,12 +96,15 @@
 
     @Test
     public void testEnterFreeformAnimation() {
-        final int transitionType = Transitions.TRANSIT_ENTER_FREEFORM;
         final int taskId = 1;
         WindowContainerTransaction wct = new WindowContainerTransaction();
         doReturn(mToken).when(mTransitions)
-                .startTransition(transitionType, wct, mEnterDesktopTaskTransitionHandler);
-        mEnterDesktopTaskTransitionHandler.startTransition(transitionType, wct, null);
+                .startTransition(Transitions.TRANSIT_ENTER_FREEFORM, wct,
+                        mEnterDesktopTaskTransitionHandler);
+        doReturn(taskId).when(mMoveToDesktopAnimator).getTaskId();
+
+        mEnterDesktopTaskTransitionHandler.startMoveToFreeformAnimation(wct,
+                mMoveToDesktopAnimator, null);
 
         TransitionInfo.Change change =
                 createChange(WindowManager.TRANSIT_CHANGE, taskId, WINDOWING_MODE_FREEFORM);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java
index 7c1da35..527dc01 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java
@@ -133,8 +133,7 @@
         mPortraitDisplayLayout = new DisplayLayout(info2, res, false, false);
         mInsets = Insets.of(0, 0, 0, 0);
 
-        mPolicy = spy(new DragAndDropPolicy(
-                mContext, mActivityTaskManager, mSplitScreenStarter, mSplitScreenStarter));
+        mPolicy = spy(new DragAndDropPolicy(mContext, mSplitScreenStarter, mSplitScreenStarter));
         mActivityClipData = createClipData(MIMETYPE_APPLICATION_ACTIVITY);
         mNonResizeableActivityClipData = createClipData(MIMETYPE_APPLICATION_ACTIVITY);
         setClipDataResizeable(mNonResizeableActivityClipData, false);
@@ -206,7 +205,10 @@
     @Test
     public void testDragAppOverFullscreenHome_expectOnlyFullscreenTarget() {
         setRunningTask(mHomeTask);
-        mPolicy.start(mLandscapeDisplayLayout, mActivityClipData, mLoggerSessionId);
+        DragSession dragSession = new DragSession(mContext, mActivityTaskManager,
+                mLandscapeDisplayLayout, mActivityClipData);
+        dragSession.update();
+        mPolicy.start(dragSession, mLoggerSessionId);
         ArrayList<Target> targets = assertExactTargetTypes(
                 mPolicy.getTargets(mInsets), TYPE_FULLSCREEN);
 
@@ -218,7 +220,10 @@
     @Test
     public void testDragAppOverFullscreenApp_expectSplitScreenTargets() {
         setRunningTask(mFullscreenAppTask);
-        mPolicy.start(mLandscapeDisplayLayout, mActivityClipData, mLoggerSessionId);
+        DragSession dragSession = new DragSession(mContext, mActivityTaskManager,
+                mLandscapeDisplayLayout, mActivityClipData);
+        dragSession.update();
+        mPolicy.start(dragSession, mLoggerSessionId);
         ArrayList<Target> targets = assertExactTargetTypes(
                 mPolicy.getTargets(mInsets), TYPE_SPLIT_LEFT, TYPE_SPLIT_RIGHT);
 
@@ -235,7 +240,10 @@
     @Test
     public void testDragAppOverFullscreenAppPhone_expectVerticalSplitScreenTargets() {
         setRunningTask(mFullscreenAppTask);
-        mPolicy.start(mPortraitDisplayLayout, mActivityClipData, mLoggerSessionId);
+        DragSession dragSession = new DragSession(mContext, mActivityTaskManager,
+                mPortraitDisplayLayout, mActivityClipData);
+        dragSession.update();
+        mPolicy.start(dragSession, mLoggerSessionId);
         ArrayList<Target> targets = assertExactTargetTypes(
                 mPolicy.getTargets(mInsets), TYPE_SPLIT_TOP, TYPE_SPLIT_BOTTOM);
 
@@ -252,7 +260,10 @@
     @Test
     public void testTargetHitRects() {
         setRunningTask(mFullscreenAppTask);
-        mPolicy.start(mLandscapeDisplayLayout, mActivityClipData, mLoggerSessionId);
+        DragSession dragSession = new DragSession(mContext, mActivityTaskManager,
+                mLandscapeDisplayLayout, mActivityClipData);
+        dragSession.update();
+        mPolicy.start(dragSession, mLoggerSessionId);
         ArrayList<Target> targets = mPolicy.getTargets(mInsets);
         for (Target t : targets) {
             assertTrue(mPolicy.getTargetAtLocation(t.hitRegion.left, t.hitRegion.top) == t);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipSizeSpecHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipSizeSpecHandlerTest.java
index 1379aed..528c23c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipSizeSpecHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipSizeSpecHandlerTest.java
@@ -110,17 +110,17 @@
         sExpectedDefaultSizes.put(16f / 9, new Size(600, 338));
         sExpectedMinSizes.put(16f / 9, new Size(501, 282));
 
-        sExpectedMaxSizes.put(4f / 3, new Size(892, 669));
-        sExpectedDefaultSizes.put(4f / 3, new Size(535, 401));
+        sExpectedMaxSizes.put(4f / 3, new Size(893, 670));
+        sExpectedDefaultSizes.put(4f / 3, new Size(536, 402));
         sExpectedMinSizes.put(4f / 3, new Size(447, 335));
 
-        sExpectedMaxSizes.put(3f / 4, new Size(669, 892));
-        sExpectedDefaultSizes.put(3f / 4, new Size(401, 535));
+        sExpectedMaxSizes.put(3f / 4, new Size(670, 893));
+        sExpectedDefaultSizes.put(3f / 4, new Size(402, 536));
         sExpectedMinSizes.put(3f / 4, new Size(335, 447));
 
-        sExpectedMaxSizes.put(9f / 16, new Size(562, 999));
-        sExpectedDefaultSizes.put(9f / 16, new Size(337, 599));
-        sExpectedMinSizes.put(9f / 16, new Size(281, 500));
+        sExpectedMaxSizes.put(9f / 16, new Size(563, 1001));
+        sExpectedDefaultSizes.put(9f / 16, new Size(338, 601));
+        sExpectedMinSizes.put(9f / 16, new Size(282, 501));
     }
 
     private void forEveryTestCaseCheck(Map<Float, Size> expectedSizes,
@@ -192,7 +192,7 @@
         // an initial size with 16:9 aspect ratio
         Size initSize = new Size(600, 337);
 
-        Size expectedSize = new Size(337, 599);
+        Size expectedSize = new Size(338, 601);
         Size actualSize = mPipSizeSpecHandler.getSizeForAspectRatio(initSize, 9f / 16);
 
         Assert.assertEquals(expectedSize, actualSize);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
index e59d09c..cc4db22 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
@@ -347,13 +347,20 @@
     }
 
     @Test
-    public void testExitSplitScreenAfterFolded() {
-        when(mMainStage.isActive()).thenReturn(true);
+    public void testExitSplitScreenAfterFoldedAndWakeUp() {
         when(mMainStage.isFocused()).thenReturn(true);
         when(mMainStage.getTopVisibleChildTaskId()).thenReturn(INVALID_TASK_ID);
+        mSideStage.mRootTaskInfo = new TestRunningTaskInfoBuilder().setVisible(true).build();
+        mMainStage.mRootTaskInfo = new TestRunningTaskInfoBuilder().setVisible(true).build();
+        when(mStageCoordinator.isSplitActive()).thenReturn(true);
+        when(mStageCoordinator.isSplitScreenVisible()).thenReturn(true);
 
         mStageCoordinator.onFoldedStateChanged(true);
 
+        assertEquals(mStageCoordinator.mTopStageAfterFoldDismiss, STAGE_TYPE_MAIN);
+
+        mStageCoordinator.onFinishedWakingUp();
+
         if (Transitions.ENABLE_SHELL_TRANSITIONS) {
             verify(mTaskOrganizer).startNewTransition(eq(TRANSIT_SPLIT_DISMISS), notNull());
         } else {
diff --git a/libs/dream/lowlight/src/com/android/dream/lowlight/LowLightTransitionCoordinator.kt b/libs/dream/lowlight/src/com/android/dream/lowlight/LowLightTransitionCoordinator.kt
index 26efb55..4736030 100644
--- a/libs/dream/lowlight/src/com/android/dream/lowlight/LowLightTransitionCoordinator.kt
+++ b/libs/dream/lowlight/src/com/android/dream/lowlight/LowLightTransitionCoordinator.kt
@@ -111,8 +111,14 @@
             }
             animator.addListener(listener)
             continuation.invokeOnCancellation {
-                animator.removeListener(listener)
-                animator.cancel()
+                try {
+                    animator.removeListener(listener)
+                    animator.cancel()
+                } catch (exception: IndexOutOfBoundsException) {
+                    // TODO(b/285666217): remove this try/catch once a proper fix is implemented.
+                    // Cancelling the animator can cause an exception since we may be removing a
+                    // listener during the cancellation. See b/285666217 for more details.
+                }
             }
         }
 }
diff --git a/libs/hwui/jni/BitmapRegionDecoder.cpp b/libs/hwui/jni/BitmapRegionDecoder.cpp
index 4c9a23d..740988f 100644
--- a/libs/hwui/jni/BitmapRegionDecoder.cpp
+++ b/libs/hwui/jni/BitmapRegionDecoder.cpp
@@ -90,8 +90,8 @@
                                            requireUnpremul, prefColorSpace);
     }
 
-    bool decodeGainmapRegion(sp<uirenderer::Gainmap>* outGainmap, const SkIRect& desiredSubset,
-                             int sampleSize, bool requireUnpremul) {
+    bool decodeGainmapRegion(sp<uirenderer::Gainmap>* outGainmap, int outWidth, int outHeight,
+                             const SkIRect& desiredSubset, int sampleSize, bool requireUnpremul) {
         SkColorType decodeColorType = mGainmapBRD->computeOutputColorType(kN32_SkColorType);
         sk_sp<SkColorSpace> decodeColorSpace =
                 mGainmapBRD->computeOutputColorSpace(decodeColorType, nullptr);
@@ -109,9 +109,8 @@
         // kPremul_SkAlphaType is used just as a placeholder as it doesn't change the underlying
         // allocation type. RecyclingClippingPixelAllocator will populate this with the
         // actual alpha type in either allocPixelRef() or copyIfNecessary()
-        sk_sp<Bitmap> nativeBitmap = Bitmap::allocateHeapBitmap(
-                SkImageInfo::Make(desiredSubset.width(), desiredSubset.height(), decodeColorType,
-                                  kPremul_SkAlphaType, decodeColorSpace));
+        sk_sp<Bitmap> nativeBitmap = Bitmap::allocateHeapBitmap(SkImageInfo::Make(
+                outWidth, outHeight, decodeColorType, kPremul_SkAlphaType, decodeColorSpace));
         if (!nativeBitmap) {
             ALOGE("OOM allocating Bitmap for Gainmap");
             return false;
@@ -134,9 +133,12 @@
         return true;
     }
 
-    SkIRect calculateGainmapRegion(const SkIRect& mainImageRegion) {
+    SkIRect calculateGainmapRegion(const SkIRect& mainImageRegion, int* inOutWidth,
+                                   int* inOutHeight) {
         const float scaleX = ((float)mGainmapBRD->width()) / mMainImageBRD->width();
         const float scaleY = ((float)mGainmapBRD->height()) / mMainImageBRD->height();
+        *inOutWidth *= scaleX;
+        *inOutHeight *= scaleY;
         // TODO: Account for rounding error?
         return SkIRect::MakeLTRB(mainImageRegion.left() * scaleX, mainImageRegion.top() * scaleY,
                                  mainImageRegion.right() * scaleX,
@@ -328,21 +330,16 @@
     sp<uirenderer::Gainmap> gainmap;
     bool hasGainmap = brd->hasGainmap();
     if (hasGainmap) {
-        SkIRect adjustedSubset{};
+        int gainmapWidth = bitmap.width();
+        int gainmapHeight = bitmap.height();
         if (javaBitmap) {
-            // Clamp to the width/height of the recycled bitmap in case the reused bitmap
-            // was too small for the specified rectangle, in which case we need to clip
-            adjustedSubset = SkIRect::MakeXYWH(inputX, inputY,
-                                               std::min(subset.width(), recycledBitmap->width()),
-                                               std::min(subset.height(), recycledBitmap->height()));
-        } else {
-            // We are not recycling, so use the decoded width/height for calculating the gainmap
-            // subset instead to ensure the gainmap region proportionally matches
-            adjustedSubset = SkIRect::MakeXYWH(std::max(0, inputX), std::max(0, inputY),
-                                               bitmap.width(), bitmap.height());
+            // If we are recycling we must match the inBitmap's relative dimensions
+            gainmapWidth = recycledBitmap->width();
+            gainmapHeight = recycledBitmap->height();
         }
-        SkIRect gainmapSubset = brd->calculateGainmapRegion(adjustedSubset);
-        if (!brd->decodeGainmapRegion(&gainmap, gainmapSubset, sampleSize, requireUnpremul)) {
+        SkIRect gainmapSubset = brd->calculateGainmapRegion(subset, &gainmapWidth, &gainmapHeight);
+        if (!brd->decodeGainmapRegion(&gainmap, gainmapWidth, gainmapHeight, gainmapSubset,
+                                      sampleSize, requireUnpremul)) {
             // If there is an error decoding Gainmap - we don't fail. We just don't provide Gainmap
             hasGainmap = false;
         }
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseActivity.java
index b100980..fcc4ec1 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseActivity.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseActivity.java
@@ -31,9 +31,11 @@
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.phone.slice.SlicePurchaseController;
 
 import java.net.URL;
+import java.util.Base64;
 
 /**
  * Activity that launches when the user clicks on the performance boost notification.
@@ -56,11 +58,17 @@
 public class SlicePurchaseActivity extends Activity {
     private static final String TAG = "SlicePurchaseActivity";
 
+    private static final int CONTENTS_TYPE_UNSPECIFIED = 0;
+    private static final int CONTENTS_TYPE_JSON = 1;
+    private static final int CONTENTS_TYPE_XML = 2;
+
     @NonNull private WebView mWebView;
     @NonNull private Context mApplicationContext;
     @NonNull private Intent mIntent;
     @NonNull private URL mUrl;
     @TelephonyManager.PremiumCapability protected int mCapability;
+    @Nullable private String mUserData;
+    private int mContentsType;
     private boolean mIsUserTriggeredFinish;
 
     @Override
@@ -72,6 +80,7 @@
         mCapability = mIntent.getIntExtra(SlicePurchaseController.EXTRA_PREMIUM_CAPABILITY,
                 SlicePurchaseController.PREMIUM_CAPABILITY_INVALID);
         String url = mIntent.getStringExtra(SlicePurchaseController.EXTRA_PURCHASE_URL);
+        mUserData = mIntent.getStringExtra(SlicePurchaseController.EXTRA_USER_DATA);
         mApplicationContext = getApplicationContext();
         mIsUserTriggeredFinish = true;
         logd("onCreate: subId=" + subId + ", capability="
@@ -81,7 +90,17 @@
         SlicePurchaseBroadcastReceiver.cancelNotification(mApplicationContext, mCapability);
 
         // Verify purchase URL is valid
-        mUrl = SlicePurchaseBroadcastReceiver.getPurchaseUrl(url);
+        String contentsType = mIntent.getStringExtra(SlicePurchaseController.EXTRA_CONTENTS_TYPE);
+        mContentsType = CONTENTS_TYPE_UNSPECIFIED;
+        if (!TextUtils.isEmpty(contentsType)) {
+            if (contentsType.equals("json")) {
+                mContentsType = CONTENTS_TYPE_JSON;
+            } else if (contentsType.equals("xml")) {
+                mContentsType = CONTENTS_TYPE_XML;
+            }
+        }
+        mUrl = SlicePurchaseBroadcastReceiver.getPurchaseUrl(url, mUserData,
+                mContentsType == CONTENTS_TYPE_UNSPECIFIED);
         if (mUrl == null) {
             String error = "Unable to create a purchase URL.";
             loge(error);
@@ -95,6 +114,20 @@
             return;
         }
 
+        // Verify user data exists if contents type is specified
+        if (mContentsType != CONTENTS_TYPE_UNSPECIFIED && TextUtils.isEmpty(mUserData)) {
+            String error = "Contents type was specified but user data does not exist.";
+            loge(error);
+            Intent data = new Intent();
+            data.putExtra(SlicePurchaseController.EXTRA_FAILURE_CODE,
+                    SlicePurchaseController.FAILURE_CODE_NO_USER_DATA);
+            data.putExtra(SlicePurchaseController.EXTRA_FAILURE_REASON, error);
+            SlicePurchaseBroadcastReceiver.sendSlicePurchaseAppResponseWithData(mApplicationContext,
+                    mIntent, SlicePurchaseController.EXTRA_INTENT_CARRIER_ERROR, data);
+            finishAndRemoveTask();
+            return;
+        }
+
         // Verify intent is valid
         if (!SlicePurchaseBroadcastReceiver.isIntentValid(mIntent)) {
             loge("Not starting SlicePurchaseActivity with an invalid Intent: " + mIntent);
@@ -115,9 +148,7 @@
         }
 
         // Clear any cookies that might be persisted from previous sessions before loading WebView
-        CookieManager.getInstance().removeAllCookies(value -> {
-            setupWebView();
-        });
+        CookieManager.getInstance().removeAllCookies(value -> setupWebView());
     }
 
     protected void onPurchaseSuccessful() {
@@ -190,14 +221,46 @@
         // Display WebView
         setContentView(mWebView);
 
-        // Load the URL
-        String userData = mIntent.getStringExtra(SlicePurchaseController.EXTRA_USER_DATA);
-        if (TextUtils.isEmpty(userData)) {
-            logd("Starting WebView with url: " + mUrl.toString());
-            mWebView.loadUrl(mUrl.toString());
+        // Start the WebView
+        startWebView(mWebView, mUrl.toString(), mContentsType, mUserData);
+    }
+
+    /**
+     * Send the URL to the WebView as either a GET or POST request, based on the contents type:
+     * <ul>
+     *     <li>
+     *         CONTENTS_TYPE_UNSPECIFIED:
+     *         If the user data exists, append it to the purchase URL and load it as a GET request.
+     *         If the user data does not exist, load just the purchase URL as a GET request.
+     *     </li>
+     *     <li>
+     *         CONTENTS_TYPE_JSON or CONTENTS_TYPE_XML:
+     *         The user data must exist. Send the JSON or XML formatted user data in a POST request.
+     *         If the user data is encoded, it must be prefaced by {@code encodedValue=} and will be
+     *         encoded in Base64. Decode the user data and send it in the POST request.
+     *     </li>
+     * </ul>
+     * @param webView The WebView to start.
+     * @param url The URL to start the WebView with.
+     * @param contentsType The contents type of the userData.
+     * @param userData The user data to send with the GET or POST request, if it exists.
+     */
+    @VisibleForTesting
+    public static void startWebView(@NonNull WebView webView, @NonNull String url, int contentsType,
+            @Nullable String userData) {
+        if (contentsType == CONTENTS_TYPE_UNSPECIFIED) {
+            logd("Starting WebView GET with url: " + url);
+            webView.loadUrl(url);
         } else {
-            logd("Starting WebView with url: " + mUrl.toString() + ", userData=" + userData);
-            mWebView.postUrl(mUrl.toString(), userData.getBytes());
+            byte[] data = userData.getBytes();
+            String[] split = userData.split("encodedValue=");
+            if (split.length > 1) {
+                logd("Decoding encoded value: " + split[1]);
+                data = Base64.getDecoder().decode(split[1]);
+            }
+            logd("Starting WebView POST with url: " + url + ", contentsType: " + contentsType
+                    + ", data: " + new String(data));
+            webView.postUrl(url, data);
         }
     }
 
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseBroadcastReceiver.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseBroadcastReceiver.java
index 23b9766..9b33704 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseBroadcastReceiver.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseBroadcastReceiver.java
@@ -173,7 +173,9 @@
         }
 
         String purchaseUrl = intent.getStringExtra(SlicePurchaseController.EXTRA_PURCHASE_URL);
-        if (getPurchaseUrl(purchaseUrl) == null) {
+        String userData = intent.getStringExtra(SlicePurchaseController.EXTRA_USER_DATA);
+        String contentsType = intent.getStringExtra(SlicePurchaseController.EXTRA_CONTENTS_TYPE);
+        if (getPurchaseUrl(purchaseUrl, userData, TextUtils.isEmpty(contentsType)) == null) {
             loge("isIntentValid: invalid purchase URL: " + purchaseUrl);
             return false;
         }
@@ -195,12 +197,39 @@
     }
 
     /**
+     * Get the {@link URL} from the given purchase URL String and user data, if it is valid.
+     *
+     * @param purchaseUrl The purchase URL String to use to create the URL.
+     * @param userData The user data parameter from the entitlement server.
+     * @param shouldAppendUserData If this is {@code true} and the {@code userData} exists,
+     *        the {@code userData} should be appended to the {@code purchaseUrl} to create the URL.
+     *        If this is false, only the {@code purchaseUrl} should be used and the {@code userData}
+     *        will be sent as data to the POST request instead.
+     * @return The URL from the given purchase URL and user data or {@code null} if it is invalid.
+     */
+    @Nullable public static URL getPurchaseUrl(@Nullable String purchaseUrl,
+            @Nullable String userData, boolean shouldAppendUserData) {
+        if (purchaseUrl == null) {
+            return null;
+        }
+        // Only append user data if it exists, otherwise just return the purchase URL
+        if (!shouldAppendUserData || TextUtils.isEmpty(userData)) {
+            return getPurchaseUrl(purchaseUrl);
+        }
+        URL url = getPurchaseUrl(purchaseUrl + "?" + userData);
+        if (url == null) {
+            url = getPurchaseUrl(purchaseUrl);
+        }
+        return url;
+    }
+
+    /**
      * Get the {@link URL} from the given purchase URL String, if it is valid.
      *
      * @param purchaseUrl The purchase URL String to use to create the URL.
      * @return The purchase URL from the given String or {@code null} if it is invalid.
      */
-    @Nullable public static URL getPurchaseUrl(@Nullable String purchaseUrl) {
+    @Nullable private static URL getPurchaseUrl(@Nullable String purchaseUrl) {
         if (!URLUtil.isValidUrl(purchaseUrl)) {
             return null;
         }
diff --git a/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/SlicePurchaseActivityTest.java b/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/SlicePurchaseActivityTest.java
index cc103fa..1ec180b 100644
--- a/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/SlicePurchaseActivityTest.java
+++ b/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/SlicePurchaseActivityTest.java
@@ -21,6 +21,7 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
 import android.app.NotificationManager;
@@ -33,6 +34,7 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.test.ActivityUnitTestCase;
+import android.webkit.WebView;
 
 import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
@@ -46,6 +48,8 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.Base64;
+
 @RunWith(AndroidJUnit4.class)
 public class SlicePurchaseActivityTest extends ActivityUnitTestCase<SlicePurchaseActivity> {
     private static final String CARRIER = "Some Carrier";
@@ -59,6 +63,7 @@
     @Mock CarrierConfigManager mCarrierConfigManager;
     @Mock NotificationManager mNotificationManager;
     @Mock PersistableBundle mPersistableBundle;
+    @Mock WebView mWebView;
 
     private SlicePurchaseActivity mSlicePurchaseActivity;
     private Context mContext;
@@ -153,4 +158,23 @@
         mSlicePurchaseActivity.onDismissFlow();
         verify(mRequestFailedIntent).send();
     }
+
+    @Test
+    public void testStartWebView() {
+        // unspecified contents type
+        SlicePurchaseActivity.startWebView(mWebView, URL, 0 /* CONTENTS_TYPE_UNSPECIFIED */, null);
+        verify(mWebView).loadUrl(eq(URL));
+
+        // specified contents type with user data
+        String userData = "userData";
+        byte[] userDataBytes = userData.getBytes();
+        SlicePurchaseActivity.startWebView(mWebView, URL, 1 /* CONTENTS_TYPE_JSON */, userData);
+        verify(mWebView).postUrl(eq(URL), eq(userDataBytes));
+
+        // specified contents type with encoded user data
+        byte[] encodedUserData = Base64.getEncoder().encode(userDataBytes);
+        userData = "encodedValue=" + new String(encodedUserData);
+        SlicePurchaseActivity.startWebView(mWebView, URL, 1 /* CONTENTS_TYPE_JSON */, userData);
+        verify(mWebView, times(2)).postUrl(eq(URL), eq(userDataBytes));
+    }
 }
diff --git a/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/SlicePurchaseBroadcastReceiverTest.java b/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/SlicePurchaseBroadcastReceiverTest.java
index 952789c..61847b5 100644
--- a/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/SlicePurchaseBroadcastReceiverTest.java
+++ b/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/SlicePurchaseBroadcastReceiverTest.java
@@ -160,14 +160,35 @@
                 "file:///android_asset/slice_store_test.html"
         };
 
+        // test invalid URLs
         for (String url : invalidUrls) {
-            URL purchaseUrl = SlicePurchaseBroadcastReceiver.getPurchaseUrl(url);
+            URL purchaseUrl = SlicePurchaseBroadcastReceiver.getPurchaseUrl(url, null, false);
             assertNull(purchaseUrl);
         }
 
+        // test asset URL
         assertEquals(SlicePurchaseController.SLICE_PURCHASE_TEST_FILE,
                 SlicePurchaseBroadcastReceiver.getPurchaseUrl(
-                        SlicePurchaseController.SLICE_PURCHASE_TEST_FILE).toString());
+                        SlicePurchaseController.SLICE_PURCHASE_TEST_FILE, null, false).toString());
+
+        // test normal URL
+        String validUrl = "http://www.google.com";
+        assertEquals(validUrl,
+                SlicePurchaseBroadcastReceiver.getPurchaseUrl(validUrl, null, false).toString());
+
+        // test normal URL with user data but no append
+        String userData = "encryptedUserData=data";
+        assertEquals(validUrl,
+                SlicePurchaseBroadcastReceiver.getPurchaseUrl(validUrl, userData, false)
+                        .toString());
+
+        // test normal URL with user data and append
+        assertEquals(validUrl + "?" + userData,
+                SlicePurchaseBroadcastReceiver.getPurchaseUrl(validUrl, userData, true).toString());
+
+        // test normal URL without user data and append
+        assertEquals(validUrl,
+                SlicePurchaseBroadcastReceiver.getPurchaseUrl(validUrl, null, true).toString());
     }
 
     @Test
diff --git a/packages/InputDevices/res/values-bs/strings.xml b/packages/InputDevices/res/values-bs/strings.xml
index df58464..c6cacbc 100644
--- a/packages/InputDevices/res/values-bs/strings.xml
+++ b/packages/InputDevices/res/values-bs/strings.xml
@@ -34,7 +34,7 @@
     <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"brazilski"</string>
     <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"portugalski"</string>
     <string name="keyboard_layout_slovak" msgid="2469379934672837296">"slovački"</string>
-    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"slovenački"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"slovenski"</string>
     <string name="keyboard_layout_turkish" msgid="7736163250907964898">"turski"</string>
     <string name="keyboard_layout_turkish_f" msgid="9130320856010776018">"turski F"</string>
     <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"ukrajinski"</string>
diff --git a/packages/InputDevices/res/values-hi/strings.xml b/packages/InputDevices/res/values-hi/strings.xml
index 892fbc5..2562854 100644
--- a/packages/InputDevices/res/values-hi/strings.xml
+++ b/packages/InputDevices/res/values-hi/strings.xml
@@ -28,7 +28,7 @@
     <string name="keyboard_layout_croatian" msgid="4172229471079281138">"क्रोएशियन"</string>
     <string name="keyboard_layout_czech" msgid="1349256901452975343">"चेक"</string>
     <string name="keyboard_layout_czech_qwerty" msgid="3331402534128515501">"चेक QWERTY स्टाइल"</string>
-    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"एस्टोनियाई"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"एस्टोनियन"</string>
     <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"हंगेरियाई"</string>
     <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"आइसलैंडिक"</string>
     <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"ब्राज़ीलियाई"</string>
diff --git a/packages/InputDevices/res/values-sv/strings.xml b/packages/InputDevices/res/values-sv/strings.xml
index a08a74b..3d0b945 100644
--- a/packages/InputDevices/res/values-sv/strings.xml
+++ b/packages/InputDevices/res/values-sv/strings.xml
@@ -12,13 +12,13 @@
     <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Tyskt"</string>
     <string name="keyboard_layout_french_label" msgid="813450119589383723">"Franskt"</string>
     <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Franskt (Kanada)"</string>
-    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Ryskt"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"ryska"</string>
     <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Ryskt, Mac"</string>
     <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Spanskt"</string>
     <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Franskt (Schweiz)"</string>
     <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Tyskt (Schweiz)"</string>
     <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belgiskt"</string>
-    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Bulgariskt"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"bulgariska"</string>
     <string name="keyboard_layout_bulgarian_phonetic" msgid="7568914730360106653">"Bulgariska (fonetiskt)"</string>
     <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italienskt"</string>
     <string name="keyboard_layout_danish" msgid="8036432066627127851">"Danskt"</string>
@@ -38,9 +38,9 @@
     <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turkiskt"</string>
     <string name="keyboard_layout_turkish_f" msgid="9130320856010776018">"turkiska, F"</string>
     <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ukrainskt"</string>
-    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"Arabiska"</string>
-    <string name="keyboard_layout_greek" msgid="7289253560162386040">"Grekiska"</string>
-    <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"Hebreiska"</string>
+    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"arabiska"</string>
+    <string name="keyboard_layout_greek" msgid="7289253560162386040">"grekiska"</string>
+    <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"hebreiska"</string>
     <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"Litauiska"</string>
     <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"Spanska (latinamerikansk)"</string>
     <string name="keyboard_layout_latvian" msgid="4405417142306250595">"lettiska"</string>
diff --git a/packages/SettingsLib/tests/robotests/Android.bp b/packages/SettingsLib/tests/robotests/Android.bp
index c037c40..5c55a43 100644
--- a/packages/SettingsLib/tests/robotests/Android.bp
+++ b/packages/SettingsLib/tests/robotests/Android.bp
@@ -42,10 +42,7 @@
     name: "SettingsLibRoboTests",
     srcs: ["src/**/*.java"],
     static_libs: [
-        "Settings_robolectric_meta_service_file",
-        "Robolectric_shadows_androidx_fragment_upstream",
         "SettingsLib-robo-testutils",
-        "androidx.fragment_fragment",
         "androidx.test.core",
         "androidx.core_core",
         "testng", // TODO: remove once JUnit on Android provides assertThrows
@@ -56,20 +53,6 @@
     test_options: {
         timeout: 36000,
     },
-    upstream: true,
-}
-
-java_genrule {
-    name: "Settings_robolectric_meta_service_file",
-    out: ["robolectric_meta_service_file.jar"],
-    tools: ["soong_zip"],
-    cmd: "mkdir -p $(genDir)/META-INF/services/ && touch $(genDir)/META-INF/services/org.robolectric.internal.ShadowProvider &&" +
-        "echo -e 'org.robolectric.Shadows' >> $(genDir)/META-INF/services/org.robolectric.internal.ShadowProvider && " +
-        "echo -e 'org.robolectric.shadows.multidex.Shadows' >> $(genDir)/META-INF/services/org.robolectric.internal.ShadowProvider && " +
-        "echo -e 'org.robolectric.shadows.httpclient.Shadows' >> $(genDir)/META-INF/services/org.robolectric.internal.ShadowProvider && " +
-        //"echo -e 'com.android.settings.testutils.shadow.Shadows' >> $(genDir)/META-INF/services/org.robolectric.internal.ShadowProvider && " +
-        "echo -e 'com.android.settingslib.testutils.shadow.Shadows' >> $(genDir)/META-INF/services/org.robolectric.internal.ShadowProvider && " +
-        "$(location soong_zip) -o $(out) -C $(genDir) -D $(genDir)/META-INF/services/",
 }
 
 java_library {
@@ -77,23 +60,9 @@
     srcs: [
         "testutils/com/android/settingslib/testutils/**/*.java",
     ],
-    javacflags: [
-        "-Aorg.robolectric.annotation.processing.shadowPackage=com.android.settingslib.testutils.shadow",
-        "-Aorg.robolectric.annotation.processing.sdkCheckMode=ERROR",
-        // Uncomment the below to debug annotation processors not firing.
-        //"-verbose",
-        //"-XprintRounds",
-        //"-XprintProcessorInfo",
-        //"-Xlint",
-        //"-J-verbose",
-    ],
-    plugins: [
-        "auto_value_plugin_1.9",
-        "auto_value_builder_plugin_1.9",
-        "Robolectric_processor_upstream",
-    ],
+
     libs: [
-        "Robolectric_all-target_upstream",
+        "Robolectric_all-target",
         "mockito-robolectric-prebuilt",
         "truth-prebuilt",
     ],
diff --git a/packages/SettingsLib/tests/robotests/config/robolectric.properties b/packages/SettingsLib/tests/robotests/config/robolectric.properties
index 2a9e50d..fab7251 100644
--- a/packages/SettingsLib/tests/robotests/config/robolectric.properties
+++ b/packages/SettingsLib/tests/robotests/config/robolectric.properties
@@ -1,2 +1 @@
 sdk=NEWEST_SDK
-instrumentedPackages=androidx.preference
diff --git a/packages/SettingsLib/tests/robotests/fragment/Android.bp b/packages/SettingsLib/tests/robotests/fragment/Android.bp
deleted file mode 100644
index 3e67156..0000000
--- a/packages/SettingsLib/tests/robotests/fragment/Android.bp
+++ /dev/null
@@ -1,40 +0,0 @@
-//#############################################
-// Compile Robolectric shadows framework misapplied to androidx
-//#############################################
-
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-java_library {
-    name: "Robolectric_shadows_androidx_fragment_upstream",
-    srcs: [
-        "src/main/java/**/*.java",
-        "src/main/java/**/*.kt",
-    ],
-    javacflags: [
-        "-Aorg.robolectric.annotation.processing.shadowPackage=org.robolectric.shadows.androidx.fragment",
-        "-Aorg.robolectric.annotation.processing.sdkCheckMode=ERROR",
-        // Uncomment the below to debug annotation processors not firing.
-        //"-verbose",
-        //"-XprintRounds",
-        //"-XprintProcessorInfo",
-        //"-Xlint",
-        //"-J-verbose",
-    ],
-    libs: [
-        "Robolectric_all-target_upstream",
-        "androidx.fragment_fragment",
-    ],
-    plugins: [
-        "auto_value_plugin_1.9",
-        "auto_value_builder_plugin_1.9",
-        "Robolectric_processor_upstream",
-    ],
-
-}
diff --git a/packages/SettingsLib/tests/robotests/fragment/BUILD b/packages/SettingsLib/tests/robotests/fragment/BUILD
deleted file mode 100644
index 393a02e..0000000
--- a/packages/SettingsLib/tests/robotests/fragment/BUILD
+++ /dev/null
@@ -1,69 +0,0 @@
-load("//third_party/java/android/android_sdk_linux/extras/android/compatibility/jetify:jetify.bzl", "jetify_android_library", "jetify_android_local_test")
-
-package(
-    default_applicable_licenses = ["//third_party/java_src/robolectric:license"],
-    default_visibility = ["//third_party/java_src/robolectric:__subpackages__"],
-)
-
-licenses(["notice"])
-
-#==============================================================================
-# Test resources library
-#==============================================================================
-jetify_android_library(
-    name = "test_resources",
-    custom_package = "org.robolectric.shadows.androidx.fragment",
-    manifest = "src/test/AndroidManifest.xml",
-    resource_files = glob(
-        ["src/test/resources/**/*"],
-    ),
-)
-
-#==============================================================================
-# AndroidX fragment module library
-#==============================================================================
-jetify_android_library(
-    name = "androidx_fragment",
-    testonly = 1,
-    srcs = glob(
-        ["src/main/java/**"],
-    ),
-    custom_package = "org.robolectric.shadows.androidx.fragment",
-    javacopts = [
-        "-Aorg.robolectric.annotation.processing.shadowPackage=org.robolectric.shadows.androidx.fragment",
-    ],
-    jetify_sources = True,
-    plugins = [
-        "//java/com/google/thirdparty/robolectric/processor",
-    ],
-    deps = [
-        "//third_party/java/androidx/core",
-        "//third_party/java/androidx/fragment",
-        "//third_party/java/androidx/lifecycle",
-        "//third_party/java_src/robolectric/shadowapi",
-        "//third_party/java_src/robolectric/shadows/framework",
-    ],
-)
-
-[
-    jetify_android_local_test(
-        name = "test_" + src.rstrip(".java"),
-        size = "small",
-        srcs = glob(
-            ["src/test/java/**/*.java"],
-        ),
-        jetify_sources = True,
-        deps = [
-            ":androidx_fragment",
-            ":test_resources",
-            "//third_party/java/androidx/fragment",
-            "//third_party/java/androidx/loader",
-            "//third_party/java/mockito",
-            "//third_party/java/robolectric",
-            "//third_party/java/truth",
-        ],
-    )
-    for src in glob(
-        ["src/test/java/**/*Test.java"],
-    )
-]
diff --git a/packages/SettingsLib/tests/robotests/fragment/build.gradle b/packages/SettingsLib/tests/robotests/fragment/build.gradle
deleted file mode 100644
index d9dcd84..0000000
--- a/packages/SettingsLib/tests/robotests/fragment/build.gradle
+++ /dev/null
@@ -1,48 +0,0 @@
-plugins {
-    id "net.ltgt.errorprone" version "0.0.13"
-}
-
-apply plugin: 'com.android.library'
-
-android {
-    compileSdkVersion 28
-
-    android {
-        sourceSets {
-            main {
-                res.srcDirs = ['src/test/resources/res']
-            }
-        }
-        testOptions {
-            unitTests {
-                includeAndroidResources = true
-            }
-        }
-    }
-}
-
-dependencies {
-    // Project dependencies
-    compileOnly project(":robolectric")
-
-    // Compile dependencies
-    compileOnly AndroidSdk.MAX_SDK.coordinates
-    compileOnly "androidx.core:core:1.0.0-rc02"
-    compileOnly 'androidx.fragment:fragment:1.0.0-rc02'
-    compileOnly "androidx.lifecycle:lifecycle-viewmodel:2.0.0-rc01"
-    compileOnly "androidx.lifecycle:lifecycle-common:2.0.0-beta01"
-
-    // Testing dependencies
-    testImplementation "com.google.truth:truth:0.44"
-    testImplementation "org.mockito:mockito-core:2.5.4"
-    testImplementation "androidx.arch.core:core-common:2.0.0-beta01"
-    testImplementation "androidx.arch.core:core-runtime:2.0.0-rc01"
-    testImplementation "androidx.collection:collection:1.0.0-rc01"
-    testImplementation "androidx.core:core:1.0.0-rc02"
-    testImplementation 'androidx.fragment:fragment:1.0.0-rc02'
-    testImplementation "androidx.lifecycle:lifecycle-viewmodel:2.0.0-rc01"
-    testImplementation "androidx.lifecycle:lifecycle-common:2.0.0-beta01"
-    testImplementation "androidx.lifecycle:lifecycle-runtime:2.0.0-rc01"
-    testImplementation "androidx.lifecycle:lifecycle-livedata-core:2.0.0-rc01"
-    testImplementation "androidx.loader:loader:1.0.0-rc02"
-}
diff --git a/packages/SettingsLib/tests/robotests/fragment/src/main/java/org/robolectric/shadows/androidx/fragment/FragmentController.java b/packages/SettingsLib/tests/robotests/fragment/src/main/java/org/robolectric/shadows/androidx/fragment/FragmentController.java
deleted file mode 100644
index c688683..0000000
--- a/packages/SettingsLib/tests/robotests/fragment/src/main/java/org/robolectric/shadows/androidx/fragment/FragmentController.java
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.robolectric.shadows.androidx.fragment;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.widget.LinearLayout;
-
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentActivity;
-
-import org.robolectric.android.controller.ActivityController;
-import org.robolectric.android.controller.ComponentController;
-import org.robolectric.util.ReflectionHelpers;
-
-/** A Controller that can be used to drive the lifecycle of a {@link Fragment} */
-public class FragmentController<F extends Fragment>
-        extends ComponentController<FragmentController<F>, F> {
-
-    private final F mFragment;
-    private final ActivityController<? extends FragmentActivity> mActivityController;
-
-    private FragmentController(F fragment, Class<? extends FragmentActivity> activityClass) {
-        this(fragment, activityClass, null /*intent*/, null /*arguments*/);
-    }
-
-    private FragmentController(
-            F fragment, Class<? extends FragmentActivity> activityClass, Intent intent) {
-        this(fragment, activityClass, intent, null /*arguments*/);
-    }
-
-    private FragmentController(
-            F fragment, Class<? extends FragmentActivity> activityClass, Bundle arguments) {
-        this(fragment, activityClass, null /*intent*/, arguments);
-    }
-
-    private FragmentController(
-            F fragment,
-            Class<? extends FragmentActivity> activityClass,
-            Intent intent,
-            Bundle arguments) {
-        super(fragment, intent);
-        this.mFragment = fragment;
-        if (arguments != null) {
-            this.mFragment.setArguments(arguments);
-        }
-        this.mActivityController =
-                ActivityController.of(ReflectionHelpers.callConstructor(activityClass), intent);
-    }
-
-    /**
-     * Generate the {@link FragmentController} for specific fragment.
-     *
-     * @param fragment the fragment which you'd like to drive lifecycle
-     * @return {@link FragmentController}
-     */
-    public static <F extends Fragment> FragmentController<F> of(F fragment) {
-        return new FragmentController<>(fragment, FragmentControllerActivity.class);
-    }
-
-    /**
-     * Generate the {@link FragmentController} for specific fragment and intent.
-     *
-     * @param fragment the fragment which you'd like to drive lifecycle
-     * @param intent   the intent which will be retained by activity
-     * @return {@link FragmentController}
-     */
-    public static <F extends Fragment> FragmentController<F> of(F fragment, Intent intent) {
-        return new FragmentController<>(fragment, FragmentControllerActivity.class, intent);
-    }
-
-    /**
-     * Generate the {@link FragmentController} for specific fragment and arguments.
-     *
-     * @param fragment  the fragment which you'd like to drive lifecycle
-     * @param arguments the arguments which will be retained by fragment
-     * @return {@link FragmentController}
-     */
-    public static <F extends Fragment> FragmentController<F> of(F fragment, Bundle arguments) {
-        return new FragmentController<>(fragment, FragmentControllerActivity.class, arguments);
-    }
-
-    /**
-     * Generate the {@link FragmentController} for specific fragment and activity class.
-     *
-     * @param fragment      the fragment which you'd like to drive lifecycle
-     * @param activityClass the activity which will be attached by fragment
-     * @return {@link FragmentController}
-     */
-    public static <F extends Fragment> FragmentController<F> of(
-            F fragment, Class<? extends FragmentActivity> activityClass) {
-        return new FragmentController<>(fragment, activityClass);
-    }
-
-    /**
-     * Generate the {@link FragmentController} for specific fragment, intent and arguments.
-     *
-     * @param fragment  the fragment which you'd like to drive lifecycle
-     * @param intent    the intent which will be retained by activity
-     * @param arguments the arguments which will be retained by fragment
-     * @return {@link FragmentController}
-     */
-    public static <F extends Fragment> FragmentController<F> of(
-            F fragment, Intent intent, Bundle arguments) {
-        return new FragmentController<>(fragment, FragmentControllerActivity.class, intent,
-                arguments);
-    }
-
-    /**
-     * Generate the {@link FragmentController} for specific fragment, activity class and intent.
-     *
-     * @param fragment      the fragment which you'd like to drive lifecycle
-     * @param activityClass the activity which will be attached by fragment
-     * @param intent        the intent which will be retained by activity
-     * @return {@link FragmentController}
-     */
-    public static <F extends Fragment> FragmentController<F> of(
-            F fragment, Class<? extends FragmentActivity> activityClass, Intent intent) {
-        return new FragmentController<>(fragment, activityClass, intent);
-    }
-
-    /**
-     * Generate the {@link FragmentController} for specific fragment, activity class and arguments.
-     *
-     * @param fragment      the fragment which you'd like to drive lifecycle
-     * @param activityClass the activity which will be attached by fragment
-     * @param arguments     the arguments which will be retained by fragment
-     * @return {@link FragmentController}
-     */
-    public static <F extends Fragment> FragmentController<F> of(
-            F fragment, Class<? extends FragmentActivity> activityClass, Bundle arguments) {
-        return new FragmentController<>(fragment, activityClass, arguments);
-    }
-
-    /**
-     * Generate the {@link FragmentController} for specific fragment, activity class, intent and
-     * arguments.
-     *
-     * @param fragment      the fragment which you'd like to drive lifecycle
-     * @param activityClass the activity which will be attached by fragment
-     * @param intent        the intent which will be retained by activity
-     * @param arguments     the arguments which will be retained by fragment
-     * @return {@link FragmentController}
-     */
-    public static <F extends Fragment> FragmentController<F> of(
-            F fragment,
-            Class<? extends FragmentActivity> activityClass,
-            Intent intent,
-            Bundle arguments) {
-        return new FragmentController<>(fragment, activityClass, intent, arguments);
-    }
-
-    /**
-     * Sets up the given fragment by attaching it to an activity, calling its onCreate() through
-     * onResume() lifecycle methods, and then making it visible. Note that the fragment will be
-     * added
-     * to the view with ID 1.
-     */
-    public static <F extends Fragment> F setupFragment(F fragment) {
-        return FragmentController.of(fragment).create().start().resume().visible().get();
-    }
-
-    /**
-     * Sets up the given fragment by attaching it to an activity, calling its onCreate() through
-     * onResume() lifecycle methods, and then making it visible. Note that the fragment will be
-     * added
-     * to the view with ID 1.
-     */
-    public static <F extends Fragment> F setupFragment(
-            F fragment, Class<? extends FragmentActivity> fragmentActivityClass) {
-        return FragmentController.of(fragment, fragmentActivityClass)
-                .create()
-                .start()
-                .resume()
-                .visible()
-                .get();
-    }
-
-    /**
-     * Sets up the given fragment by attaching it to an activity created with the given bundle,
-     * calling its onCreate() through onResume() lifecycle methods, and then making it visible. Note
-     * that the fragment will be added to the view with ID 1.
-     */
-    public static <F extends Fragment> F setupFragment(
-            F fragment, Class<? extends FragmentActivity> fragmentActivityClass, Bundle bundle) {
-        return FragmentController.of(fragment, fragmentActivityClass)
-                .create(bundle)
-                .start()
-                .resume()
-                .visible()
-                .get();
-    }
-
-    /**
-     * Sets up the given fragment by attaching it to an activity created with the given bundle and
-     * container id, calling its onCreate() through onResume() lifecycle methods, and then making it
-     * visible.
-     */
-    public static <F extends Fragment> F setupFragment(
-            F fragment,
-            Class<? extends FragmentActivity> fragmentActivityClass,
-            int containerViewId,
-            Bundle bundle) {
-        return FragmentController.of(fragment, fragmentActivityClass)
-                .create(containerViewId, bundle)
-                .start()
-                .resume()
-                .visible()
-                .get();
-    }
-
-    /**
-     * Creates the activity with {@link Bundle} and adds the fragment to the view with ID {@code
-     * contentViewId}.
-     */
-    public FragmentController<F> create(final int contentViewId, final Bundle bundle) {
-        shadowMainLooper.runPaused(
-                new Runnable() {
-                    @Override
-                    public void run() {
-                        mActivityController
-                                .create(bundle)
-                                .get()
-                                .getSupportFragmentManager()
-                                .beginTransaction()
-                                .add(contentViewId, mFragment)
-                                .commit();
-                    }
-                });
-        return this;
-    }
-
-    /**
-     * Creates the activity with {@link Bundle} and adds the fragment to it. Note that the fragment
-     * will be added to the view with ID 1.
-     */
-    public FragmentController<F> create(final Bundle bundle) {
-        return create(1, bundle);
-    }
-
-    /**
-     * Creates the {@link Fragment} in a newly initialized state and hence will receive a null
-     * savedInstanceState {@link Bundle parameter}
-     */
-    @Override
-    public FragmentController<F> create() {
-        return create(null);
-    }
-
-    /** Drive lifecycle of activity to Start lifetime */
-    public FragmentController<F> start() {
-        shadowMainLooper.runPaused(
-                new Runnable() {
-                    @Override
-                    public void run() {
-                        mActivityController.start();
-                    }
-                });
-        return this;
-    }
-
-    /** Drive lifecycle of activity to Resume lifetime */
-    public FragmentController<F> resume() {
-        shadowMainLooper.runPaused(
-                new Runnable() {
-                    @Override
-                    public void run() {
-                        mActivityController.resume();
-                    }
-                });
-        return this;
-    }
-
-    /** Drive lifecycle of activity to Pause lifetime */
-    public FragmentController<F> pause() {
-        shadowMainLooper.runPaused(
-                new Runnable() {
-                    @Override
-                    public void run() {
-                        mActivityController.pause();
-                    }
-                });
-        return this;
-    }
-
-    /** Drive lifecycle of activity to Stop lifetime */
-    public FragmentController<F> stop() {
-        shadowMainLooper.runPaused(
-                new Runnable() {
-                    @Override
-                    public void run() {
-                        mActivityController.stop();
-                    }
-                });
-        return this;
-    }
-
-    /** Drive lifecycle of activity to Destroy lifetime */
-    @Override
-    public FragmentController<F> destroy() {
-        shadowMainLooper.runPaused(
-                new Runnable() {
-                    @Override
-                    public void run() {
-                        mActivityController.destroy();
-                    }
-                });
-        return this;
-    }
-
-    /** Let activity can be visible lifetime */
-    public FragmentController<F> visible() {
-        shadowMainLooper.runPaused(
-                new Runnable() {
-                    @Override
-                    public void run() {
-                        mActivityController.visible();
-                    }
-                });
-        return this;
-    }
-
-    private static class FragmentControllerActivity extends FragmentActivity {
-
-        @Override
-        protected void onCreate(Bundle savedInstanceState) {
-            super.onCreate(savedInstanceState);
-            LinearLayout view = new LinearLayout(this);
-            view.setId(1);
-
-            setContentView(view);
-        }
-    }
-}
diff --git a/packages/SettingsLib/tests/robotests/fragment/src/test/AndroidManifest.xml b/packages/SettingsLib/tests/robotests/fragment/src/test/AndroidManifest.xml
deleted file mode 100644
index 8493c02..0000000
--- a/packages/SettingsLib/tests/robotests/fragment/src/test/AndroidManifest.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="org.robolectric.shadows.androidx.fragment">
-
-    <uses-sdk android:targetSdkVersion="28"/>
-</manifest>
diff --git a/packages/SettingsLib/tests/robotests/fragment/src/test/java/org/robolectric/shadows/androidx/fragment/FragmentControllerTest.java b/packages/SettingsLib/tests/robotests/fragment/src/test/java/org/robolectric/shadows/androidx/fragment/FragmentControllerTest.java
deleted file mode 100644
index ef63058..0000000
--- a/packages/SettingsLib/tests/robotests/fragment/src/test/java/org/robolectric/shadows/androidx/fragment/FragmentControllerTest.java
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.robolectric.shadows.androidx.fragment;
-
-import static android.os.Looper.getMainLooper;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.robolectric.Shadows.shadowOf;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentActivity;
-
-import org.junit.After;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** Tests for {@link FragmentController} */
-@RunWith(RobolectricTestRunner.class)
-public class FragmentControllerTest {
-
-    @After
-    public void tearDown() {
-        TranscriptFragment.clearLifecycleEvents();
-    }
-
-    @Test
-    public void initialNotAttached() {
-        final FragmentController<TranscriptFragment> controller =
-                FragmentController.of(new TranscriptFragment());
-
-        assertThat(controller.get().getView()).isNull();
-        assertThat(controller.get().getActivity()).isNull();
-        assertThat(controller.get().isAdded()).isFalse();
-    }
-
-    @Test
-    public void initialNotAttached_customActivity() {
-        final FragmentController<TranscriptFragment> controller =
-                FragmentController.of(new TranscriptFragment(), TestActivity.class);
-
-        assertThat(controller.get().getView()).isNull();
-        assertThat(controller.get().getActivity()).isNull();
-        assertThat(controller.get().isAdded()).isFalse();
-    }
-
-    @Test
-    public void attachedAfterCreate() {
-        final FragmentController<TranscriptFragment> controller =
-                FragmentController.of(new TranscriptFragment());
-
-        controller.create();
-        shadowOf(getMainLooper()).idle();
-
-        assertThat(controller.get().getActivity()).isNotNull();
-        assertThat(controller.get().isAdded()).isTrue();
-        assertThat(controller.get().isResumed()).isFalse();
-    }
-
-    @Test
-    public void attachedAfterCreate_customActivity() {
-        final FragmentController<TranscriptFragment> controller =
-                FragmentController.of(new TranscriptFragment(), TestActivity.class);
-
-        controller.create();
-        shadowOf(getMainLooper()).idle();
-
-        assertThat(controller.get().getActivity()).isNotNull();
-        assertThat(controller.get().getActivity()).isInstanceOf(TestActivity.class);
-        assertThat(controller.get().isAdded()).isTrue();
-        assertThat(controller.get().isResumed()).isFalse();
-    }
-
-    @Test
-    public void attachedAfterCreate_customizedViewId() {
-        final FragmentController<TranscriptFragment> controller =
-                FragmentController.of(new TranscriptFragment(), CustomizedViewIdTestActivity.class);
-
-        controller.create(R.id.custom_activity_view, null).start();
-
-        assertThat(controller.get().getView()).isNotNull();
-        assertThat(controller.get().getActivity()).isNotNull();
-        assertThat(controller.get().isAdded()).isTrue();
-        assertThat(controller.get().isResumed()).isFalse();
-        assertThat((TextView) controller.get().getView().findViewById(R.id.tacos)).isNotNull();
-    }
-
-    @Test
-    public void hasViewAfterStart() {
-        final FragmentController<TranscriptFragment> controller =
-                FragmentController.of(new TranscriptFragment());
-
-        controller.create().start();
-
-        assertThat(controller.get().getView()).isNotNull();
-    }
-
-    @Test
-    public void isResumed() {
-        final FragmentController<TranscriptFragment> controller =
-                FragmentController.of(new TranscriptFragment(), TestActivity.class);
-
-        controller.create().start().resume();
-
-        assertThat(controller.get().getView()).isNotNull();
-        assertThat(controller.get().getActivity()).isNotNull();
-        assertThat(controller.get().isAdded()).isTrue();
-        assertThat(controller.get().isResumed()).isTrue();
-        assertThat((TextView) controller.get().getView().findViewById(R.id.tacos)).isNotNull();
-    }
-
-    @Test
-    public void isPaused() {
-        final FragmentController<TranscriptFragment> controller =
-                FragmentController.of(new TranscriptFragment(), TestActivity.class);
-
-        controller.create().start().resume().pause();
-
-        assertThat(controller.get().getView()).isNotNull();
-        assertThat(controller.get().getActivity()).isNotNull();
-        assertThat(controller.get().isAdded()).isTrue();
-        assertThat(controller.get().isResumed()).isFalse();
-        assertThat(controller.get().getLifecycleEvents())
-                .containsExactly("onCreate", "onStart", "onResume", "onPause")
-                .inOrder();
-    }
-
-    @Test
-    public void isStopped() {
-        final FragmentController<TranscriptFragment> controller =
-                FragmentController.of(new TranscriptFragment(), TestActivity.class);
-
-        controller.create().start().resume().pause().stop();
-
-        assertThat(controller.get().getView()).isNotNull();
-        assertThat(controller.get().getActivity()).isNotNull();
-        assertThat(controller.get().isAdded()).isTrue();
-        assertThat(controller.get().isResumed()).isFalse();
-        assertThat(controller.get().getLifecycleEvents())
-                .containsExactly("onCreate", "onStart", "onResume", "onPause", "onStop")
-                .inOrder();
-    }
-
-    @Test
-    public void withIntent() {
-        final Intent intent = generateTestIntent();
-        final FragmentController<TranscriptFragment> controller =
-                FragmentController.of(new TranscriptFragment(), TestActivity.class, intent);
-
-        controller.create();
-        shadowOf(getMainLooper()).idle();
-        final Intent intentInFragment = controller.get().getActivity().getIntent();
-
-        assertThat(intentInFragment.getAction()).isEqualTo("test_action");
-        assertThat(intentInFragment.getExtras().getString("test_key")).isEqualTo("test_value");
-    }
-
-    @Test
-    public void withArguments() {
-        final Bundle bundle = generateTestBundle();
-        final FragmentController<TranscriptFragment> controller =
-                FragmentController.of(new TranscriptFragment(), TestActivity.class, bundle);
-
-        controller.create();
-        final Bundle args = controller.get().getArguments();
-
-        assertThat(args.getString("test_key")).isEqualTo("test_value");
-    }
-
-    @Test
-    public void withIntentAndArguments() {
-        final Bundle bundle = generateTestBundle();
-        final Intent intent = generateTestIntent();
-        final FragmentController<TranscriptFragment> controller =
-                FragmentController.of(new TranscriptFragment(), TestActivity.class, intent, bundle);
-
-        controller.create();
-        shadowOf(getMainLooper()).idle();
-        final Intent intentInFragment = controller.get().getActivity().getIntent();
-        final Bundle args = controller.get().getArguments();
-
-        assertThat(intentInFragment.getAction()).isEqualTo("test_action");
-        assertThat(intentInFragment.getExtras().getString("test_key")).isEqualTo("test_value");
-        assertThat(args.getString("test_key")).isEqualTo("test_value");
-    }
-
-    @Test
-    public void visible() {
-        final FragmentController<TranscriptFragment> controller =
-                FragmentController.of(new TranscriptFragment(), TestActivity.class);
-
-        controller.create().start().resume();
-
-        assertThat(controller.get().isVisible()).isFalse();
-
-        controller.visible();
-
-        assertThat(controller.get().isVisible()).isTrue();
-    }
-
-    @Test
-    public void setupFragmentWithFragment_fragmentHasCorrectLifecycle() {
-        TranscriptFragment fragment = FragmentController.setupFragment(new TranscriptFragment());
-
-        assertThat(fragment.getLifecycleEvents())
-                .containsExactly("onCreate", "onStart", "onResume")
-                .inOrder();
-        assertThat(fragment.isVisible()).isTrue();
-    }
-
-    @Test
-    public void setupFragmentWithFragmentAndActivity_fragmentHasCorrectLifecycle() {
-        TranscriptFragment fragment =
-                FragmentController.setupFragment(new TranscriptFragment(), TestActivity.class);
-
-        assertThat(fragment.getLifecycleEvents())
-                .containsExactly("onCreate", "onStart", "onResume")
-                .inOrder();
-        assertThat(fragment.isVisible()).isTrue();
-    }
-
-    @Test
-    public void setupFragmentWithFragmentAndActivityAndBundle_HasCorrectLifecycle() {
-        Bundle testBundle = generateTestBundle();
-        TranscriptFragment fragment =
-                FragmentController.setupFragment(new TranscriptFragment(), TestActivity.class,
-                        testBundle);
-
-        assertThat(fragment.getLifecycleEvents())
-                .containsExactly("onCreate", "onStart", "onResume")
-                .inOrder();
-        assertThat(fragment.isVisible()).isTrue();
-    }
-
-    @Test
-    public void
-            setupFragmentWithFragment_Activity_ContainViewIdAndBundle_HasCorrectLifecycle() {
-        Bundle testBundle = generateTestBundle();
-        TranscriptFragment fragment =
-                FragmentController.setupFragment(
-                        new TranscriptFragment(),
-                        CustomizedViewIdTestActivity.class,
-                        R.id.custom_activity_view,
-                        testBundle);
-
-        assertThat(fragment.getLifecycleEvents())
-                .containsExactly("onCreate", "onStart", "onResume")
-                .inOrder();
-        assertThat(fragment.isVisible()).isTrue();
-    }
-
-    private Intent generateTestIntent() {
-        final Intent testIntent = new Intent("test_action").putExtra("test_key", "test_value");
-        return testIntent;
-    }
-
-    private Bundle generateTestBundle() {
-        final Bundle testBundle = new Bundle();
-        testBundle.putString("test_key", "test_value");
-
-        return testBundle;
-    }
-
-    /** A Fragment which can record lifecycle status for test. */
-    public static class TranscriptFragment extends Fragment {
-
-        public static final List<String> sLifecycleEvents = new ArrayList<>();
-
-        @Override
-        public void onCreate(Bundle savedInstanceState) {
-            super.onCreate(savedInstanceState);
-            sLifecycleEvents.add("onCreate");
-        }
-
-        @Override
-        public void onStart() {
-            super.onStart();
-            sLifecycleEvents.add("onStart");
-        }
-
-        @Override
-        public void onResume() {
-            super.onResume();
-            sLifecycleEvents.add("onResume");
-        }
-
-        @Override
-        public void onPause() {
-            super.onPause();
-            sLifecycleEvents.add("onPause");
-        }
-
-        @Override
-        public void onStop() {
-            super.onStop();
-            sLifecycleEvents.add("onStop");
-        }
-
-        @Override
-        public View onCreateView(
-                LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-            return inflater.inflate(R.layout.fragment_contents, container, false);
-        }
-
-        public List<String> getLifecycleEvents() {
-            return sLifecycleEvents;
-        }
-
-        public static void clearLifecycleEvents() {
-            sLifecycleEvents.clear();
-        }
-    }
-
-    /** A Activity which set a default view for test. */
-    public static class TestActivity extends FragmentActivity {
-        @Override
-        protected void onCreate(Bundle savedInstanceState) {
-            super.onCreate(savedInstanceState);
-            LinearLayout view = new LinearLayout(this);
-            view.setId(1);
-
-            setContentView(view);
-        }
-    }
-
-    /** A Activity which has a custom view for test. */
-    public static class CustomizedViewIdTestActivity extends FragmentActivity {
-        @Override
-        protected void onCreate(Bundle savedInstanceState) {
-            super.onCreate(savedInstanceState);
-            setContentView(R.layout.custom_activity_view);
-        }
-    }
-}
diff --git a/packages/SettingsLib/tests/robotests/fragment/src/test/resources/res/layout/custom_activity_view.xml b/packages/SettingsLib/tests/robotests/fragment/src/test/resources/res/layout/custom_activity_view.xml
deleted file mode 100644
index c074f30..0000000
--- a/packages/SettingsLib/tests/robotests/fragment/src/test/resources/res/layout/custom_activity_view.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/custom_activity_view"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
-    android:orientation="vertical">
-
-</LinearLayout>
diff --git a/packages/SettingsLib/tests/robotests/fragment/src/test/resources/res/layout/fragment_contents.xml b/packages/SettingsLib/tests/robotests/fragment/src/test/resources/res/layout/fragment_contents.xml
deleted file mode 100644
index 425b2bb..0000000
--- a/packages/SettingsLib/tests/robotests/fragment/src/test/resources/res/layout/fragment_contents.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
-    android:orientation="vertical">
-
-  <TextView
-      android:id="@+id/tacos"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:text="TACOS"/>
-
-  <TextView
-      android:id="@+id/burritos"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:text="BURRITOS"/>
-
-</LinearLayout>
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
index bb72375..4a913c8 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
@@ -25,6 +25,7 @@
 import static org.mockito.Mockito.when;
 
 import android.app.ActivityManager;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
@@ -57,10 +58,12 @@
 import org.robolectric.shadows.ShadowSettings;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 @RunWith(RobolectricTestRunner.class)
-@Config(shadows = {UtilsTest.ShadowLocationManager.class})
+@Config(shadows = {UtilsTest.ShadowSecure.class, UtilsTest.ShadowLocationManager.class})
 public class UtilsTest {
     private static final double[] TEST_PERCENTAGES = {0, 0.4, 0.5, 0.6, 49, 49.3, 49.8, 50, 100};
     private static final String TAG = "UtilsTest";
@@ -91,7 +94,7 @@
         mContext = spy(RuntimeEnvironment.application);
         when(mContext.getSystemService(Context.LOCATION_SERVICE)).thenReturn(mLocationManager);
         when(mContext.getSystemService(UsbManager.class)).thenReturn(mUsbManager);
-        ShadowSettings.ShadowSecure.reset();
+        ShadowSecure.reset();
         mAudioManager = mContext.getSystemService(AudioManager.class);
     }
 
@@ -108,16 +111,15 @@
                 Settings.Secure.LOCATION_CHANGER_QUICK_SETTINGS);
 
         assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
-                Settings.Secure.LOCATION_CHANGER,
-                Settings.Secure.LOCATION_CHANGER_UNKNOWN)).isEqualTo(
-                Settings.Secure.LOCATION_CHANGER_QUICK_SETTINGS);
+                Settings.Secure.LOCATION_CHANGER, Settings.Secure.LOCATION_CHANGER_UNKNOWN))
+                .isEqualTo(Settings.Secure.LOCATION_CHANGER_QUICK_SETTINGS);
     }
 
     @Test
     public void testFormatPercentage_RoundTrue_RoundUpIfPossible() {
-        final String[] expectedPercentages =
-                {PERCENTAGE_0, PERCENTAGE_0, PERCENTAGE_1, PERCENTAGE_1, PERCENTAGE_49,
-                        PERCENTAGE_49, PERCENTAGE_50, PERCENTAGE_50, PERCENTAGE_100};
+        final String[] expectedPercentages = {PERCENTAGE_0, PERCENTAGE_0, PERCENTAGE_1,
+                PERCENTAGE_1, PERCENTAGE_49, PERCENTAGE_49, PERCENTAGE_50, PERCENTAGE_50,
+                PERCENTAGE_100};
 
         for (int i = 0, size = TEST_PERCENTAGES.length; i < size; i++) {
             final String percentage = Utils.formatPercentage(TEST_PERCENTAGES[i], true);
@@ -127,9 +129,9 @@
 
     @Test
     public void testFormatPercentage_RoundFalse_NoRound() {
-        final String[] expectedPercentages =
-                {PERCENTAGE_0, PERCENTAGE_0, PERCENTAGE_0, PERCENTAGE_0, PERCENTAGE_49,
-                        PERCENTAGE_49, PERCENTAGE_49, PERCENTAGE_50, PERCENTAGE_100};
+        final String[] expectedPercentages = {PERCENTAGE_0, PERCENTAGE_0, PERCENTAGE_0,
+                PERCENTAGE_0, PERCENTAGE_49, PERCENTAGE_49, PERCENTAGE_49, PERCENTAGE_50,
+                PERCENTAGE_100};
 
         for (int i = 0, size = TEST_PERCENTAGES.length; i < size; i++) {
             final String percentage = Utils.formatPercentage(TEST_PERCENTAGES[i], false);
@@ -141,7 +143,12 @@
     public void testGetDefaultStorageManagerDaysToRetain_storageManagerDaysToRetainUsesResources() {
         Resources resources = mock(Resources.class);
         when(resources.getInteger(
-                eq(com.android.internal.R.integer.config_storageManagerDaystoRetainDefault)))
+                eq(
+                        com.android
+                                .internal
+                                .R
+                                .integer
+                                .config_storageManagerDaystoRetainDefault)))
                 .thenReturn(60);
         assertThat(Utils.getDefaultStorageManagerDaysToRetain(resources)).isEqualTo(60);
     }
@@ -156,6 +163,31 @@
         return intent -> TextUtils.equals(expected, intent.getAction());
     }
 
+    @Implements(value = Settings.Secure.class)
+    public static class ShadowSecure extends ShadowSettings.ShadowSecure {
+        private static Map<String, Integer> map = new HashMap<>();
+
+        @Implementation
+        public static boolean putIntForUser(ContentResolver cr, String name, int value,
+                int userHandle) {
+            map.put(name, value);
+            return true;
+        }
+
+        @Implementation
+        public static int getIntForUser(ContentResolver cr, String name, int def, int userHandle) {
+            if (map.containsKey(name)) {
+                return map.get(name);
+            } else {
+                return def;
+            }
+        }
+
+        public static void reset() {
+            map.clear();
+        }
+    }
+
     @Implements(value = LocationManager.class)
     public static class ShadowLocationManager {
 
@@ -305,8 +337,9 @@
 
     @Test
     public void getBatteryStatus_statusIsFull_returnFullString() {
-        final Intent intent = new Intent().putExtra(BatteryManager.EXTRA_LEVEL, 100).putExtra(
-                BatteryManager.EXTRA_SCALE, 100);
+        final Intent intent = new Intent()
+                .putExtra(BatteryManager.EXTRA_LEVEL, 100)
+                .putExtra(BatteryManager.EXTRA_SCALE, 100);
         final Resources resources = mContext.getResources();
 
         assertThat(Utils.getBatteryStatus(mContext, intent, /* compactStatus= */ false)).isEqualTo(
@@ -315,8 +348,9 @@
 
     @Test
     public void getBatteryStatus_statusIsFullAndUseCompactStatus_returnFullyChargedString() {
-        final Intent intent = new Intent().putExtra(BatteryManager.EXTRA_LEVEL, 100).putExtra(
-                BatteryManager.EXTRA_SCALE, 100);
+        final Intent intent = new Intent()
+                .putExtra(BatteryManager.EXTRA_LEVEL, 100)
+                .putExtra(BatteryManager.EXTRA_SCALE, 100);
         final Resources resources = mContext.getResources();
 
         assertThat(Utils.getBatteryStatus(mContext, intent, /* compactStatus= */ true)).isEqualTo(
@@ -482,6 +516,7 @@
         when(mUsbPort.getStatus()).thenReturn(mUsbPortStatus);
         when(mUsbPort.supportsComplianceWarnings()).thenReturn(true);
         when(mUsbPortStatus.isConnected()).thenReturn(true);
-        when(mUsbPortStatus.getComplianceWarnings()).thenReturn(new int[]{complianceWarningType});
+        when(mUsbPortStatus.getComplianceWarnings())
+                .thenReturn(new int[]{complianceWarningType});
     }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/accessibility/AccessibilityUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/accessibility/AccessibilityUtilsTest.java
index 3de8446..44fdaec 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/accessibility/AccessibilityUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/accessibility/AccessibilityUtilsTest.java
@@ -23,17 +23,13 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 
-import com.android.settingslib.testutils.shadow.ShadowSecure;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
 
 @RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowSecure.class})
 public class AccessibilityUtilsTest {
 
     private Context mContext;
@@ -50,7 +46,7 @@
 
     @Test
     public void getEnabledServicesFromSettings_badFormat_emptyResult() {
-        ShadowSecure.putStringForUser(
+        Settings.Secure.putStringForUser(
                 mContext.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
                 ":",
                 UserHandle.myUserId());
@@ -61,7 +57,7 @@
     @Test
     public void getEnabledServicesFromSettings_1Service_1result() {
         final ComponentName cn = new ComponentName("pkg", "serv");
-        ShadowSecure.putStringForUser(
+        Settings.Secure.putStringForUser(
                 mContext.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
                 cn.flattenToString() + ":",
                 UserHandle.myUserId());
@@ -74,7 +70,7 @@
     public void getEnabledServicesFromSettings_2Services_2results() {
         final ComponentName cn1 = new ComponentName("pkg", "serv");
         final ComponentName cn2 = new ComponentName("pkg", "serv2");
-        ShadowSecure.putStringForUser(
+        Settings.Secure.putStringForUser(
                 mContext.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
                 cn1.flattenToString() + ":" + cn2.flattenToString(),
                 UserHandle.myUserId());
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/RecentAppOpsAccessesTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/RecentAppOpsAccessesTest.java
index f9505dd..cb62a73 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/RecentAppOpsAccessesTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/RecentAppOpsAccessesTest.java
@@ -37,8 +37,6 @@
 import android.os.UserManager;
 import android.util.LongSparseArray;
 
-import com.android.settingslib.testutils.shadow.ShadowPermissionChecker;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -47,6 +45,7 @@
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowPermissionChecker;
 
 import java.time.Clock;
 import java.util.ArrayList;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java
index a2e8c59..dd8d54a 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java
@@ -38,7 +38,6 @@
 import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.LooperMode;
 import org.robolectric.util.ReflectionHelpers;
 
 import java.util.ArrayList;
@@ -168,7 +167,6 @@
     }
 
     @Test
-    @LooperMode(LooperMode.Mode.PAUSED)
     public void getAttribution_notSet_shouldReturnUnknown() {
         final Activity activity = Robolectric.setupActivity(Activity.class);
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SettingsJankMonitorTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SettingsJankMonitorTest.java
index 25833b3..d67d44b 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SettingsJankMonitorTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SettingsJankMonitorTest.java
@@ -36,7 +36,6 @@
 
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.jank.InteractionJankMonitor.CujType;
-import com.android.settingslib.testutils.OverpoweredReflectionHelper;
 import com.android.settingslib.testutils.shadow.ShadowInteractionJankMonitor;
 
 import org.junit.Before;
@@ -52,6 +51,7 @@
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
 import org.robolectric.annotation.Resetter;
+import org.robolectric.util.ReflectionHelpers;
 
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
@@ -83,10 +83,8 @@
     public void setUp() {
         ShadowInteractionJankMonitor.reset();
         when(ShadowInteractionJankMonitor.MOCK_INSTANCE.begin(any())).thenReturn(true);
-        OverpoweredReflectionHelper
-                .setStaticField(SettingsJankMonitor.class,
-                        "scheduledExecutorService",
-                        mScheduledExecutorService);
+        ReflectionHelpers.setStaticField(SettingsJankMonitor.class, "scheduledExecutorService",
+                mScheduledExecutorService);
     }
 
     @Test
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/HideNonSystemOverlayMixinTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/HideNonSystemOverlayMixinTest.java
index 471dac0..cf702b53 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/HideNonSystemOverlayMixinTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/HideNonSystemOverlayMixinTest.java
@@ -37,10 +37,8 @@
 import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.android.controller.ActivityController;
-import org.robolectric.annotation.LooperMode;
 
 @RunWith(RobolectricTestRunner.class)
-@LooperMode(LooperMode.Mode.PAUSED)
 public class HideNonSystemOverlayMixinTest {
 
     private ActivityController<TestActivity> mActivityController;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/DevelopmentSettingsEnablerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/DevelopmentSettingsEnablerTest.java
index b009abd..3475ff7 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/DevelopmentSettingsEnablerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/DevelopmentSettingsEnablerTest.java
@@ -22,14 +22,13 @@
 import android.os.UserManager;
 import android.provider.Settings;
 
-import com.android.settingslib.testutils.shadow.ShadowUserManager;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowUserManager;
 
 @RunWith(RobolectricTestRunner.class)
 public class DevelopmentSettingsEnablerTest {
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java
index 0cabab2..8e33ca3 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java
@@ -21,7 +21,6 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.LooperMode;
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.ByteArrayInputStream;
@@ -270,7 +269,6 @@
     }
 
     @Test
-    @LooperMode(LooperMode.Mode.PAUSED)
     public void testGenerateHtmlWithCustomHeading() throws Exception {
         List<File> xmlFiles = new ArrayList<>();
         Map<String, Map<String, Set<String>>> fileNameToLibraryToContentIdMap = new HashMap<>();
@@ -294,7 +292,6 @@
     }
 
     @Test
-    @LooperMode(LooperMode.Mode.PAUSED)
     public void testGenerateNewHtmlWithCustomHeading() throws Exception {
         List<File> xmlFiles = new ArrayList<>();
         Map<String, Map<String, Set<String>>> fileNameToLibraryToContentIdMap = new HashMap<>();
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AnimatedImageViewTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AnimatedImageViewTest.java
index faec02f7..d41d511 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AnimatedImageViewTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AnimatedImageViewTest.java
@@ -27,7 +27,6 @@
 import org.junit.runner.RunWith;
 import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.LooperMode;
 
 @RunWith(RobolectricTestRunner.class)
 public class AnimatedImageViewTest {
@@ -41,7 +40,6 @@
     }
 
     @Test
-    @LooperMode(LooperMode.Mode.PAUSED)
     public void testAnimation_ViewVisible_AnimationRunning() {
         mAnimatedImageView.setVisibility(View.VISIBLE);
         mAnimatedImageView.setAnimating(true);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java
index 0d88913..0a48f19 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java
@@ -41,8 +41,6 @@
 import androidx.preference.PreferenceViewHolder;
 import androidx.preference.R;
 
-import com.android.settingslib.testutils.OverpoweredReflectionHelper;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -504,18 +502,14 @@
     private void assumeAndroidR() {
         ReflectionHelpers.setStaticField(Build.VERSION.class, "SDK_INT", 30);
         ReflectionHelpers.setStaticField(Build.VERSION.class, "CODENAME", "R");
-        OverpoweredReflectionHelper
-                .setStaticField(BannerMessagePreference.class, "IS_AT_LEAST_S", false);
+        ReflectionHelpers.setStaticField(BannerMessagePreference.class, "IS_AT_LEAST_S", false);
         // Reset view holder to use correct layout.
     }
 
-
-
     private void assumeAndroidS() {
         ReflectionHelpers.setStaticField(Build.VERSION.class, "SDK_INT", 31);
         ReflectionHelpers.setStaticField(Build.VERSION.class, "CODENAME", "S");
-        OverpoweredReflectionHelper
-                .setStaticField(BannerMessagePreference.class, "IS_AT_LEAST_S", true);
+        ReflectionHelpers.setStaticField(BannerMessagePreference.class, "IS_AT_LEAST_S", true);
         // Re-inflate view to update layout.
         setUpViewHolder();
     }
diff --git a/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/OverpoweredReflectionHelper.java b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/OverpoweredReflectionHelper.java
deleted file mode 100644
index 4fcc5a1..0000000
--- a/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/OverpoweredReflectionHelper.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settingslib.testutils;
-
-import org.robolectric.util.ReflectionHelpers;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-
-public class OverpoweredReflectionHelper extends ReflectionHelpers {
-
-    /**
-     * Robolectric upstream does not rely on or encourage this behaviour.
-     *
-     * @param field
-     */
-    private static void makeFieldVeryAccessible(Field field) {
-        field.setAccessible(true);
-        // remove 'final' modifier if present
-        if ((field.getModifiers() & Modifier.FINAL) == Modifier.FINAL) {
-            Field modifiersField = getModifiersField();
-            modifiersField.setAccessible(true);
-            try {
-                modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
-            } catch (IllegalAccessException e) {
-
-                throw new AssertionError(e);
-            }
-        }
-    }
-
-    private static Field getModifiersField() {
-        try {
-            return Field.class.getDeclaredField("modifiers");
-        } catch (NoSuchFieldException e) {
-            try {
-                Method getFieldsMethod =
-                        Class.class.getDeclaredMethod("getDeclaredFields0", boolean.class);
-                getFieldsMethod.setAccessible(true);
-                Field[] fields = (Field[]) getFieldsMethod.invoke(Field.class, false);
-                for (Field modifiersField : fields) {
-                    if ("modifiers".equals(modifiersField.getName())) {
-                        return modifiersField;
-                    }
-                }
-            } catch (ReflectiveOperationException innerE) {
-                throw new AssertionError(innerE);
-            }
-        }
-        throw new AssertionError();
-    }
-
-    /**
-     * Reflectively set the value of a static field.
-     *
-     * @param field Field object.
-     * @param fieldNewValue The new value.
-     */
-    public static void setStaticField(Field field, Object fieldNewValue) {
-        try {
-            makeFieldVeryAccessible(field);
-            field.setAccessible(true);
-            field.set(null, fieldNewValue);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Reflectively set the value of a static field.
-     *
-     * @param clazz Target class.
-     * @param fieldName The field name.
-     * @param fieldNewValue The new value.
-     */
-    public static void setStaticField(Class<?> clazz, String fieldName, Object fieldNewValue) {
-        try {
-            setStaticField(clazz.getDeclaredField(fieldName), fieldNewValue);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-}
diff --git a/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowActivityManager.java b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowActivityManager.java
index 0b9ba8d..924eb04 100644
--- a/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowActivityManager.java
+++ b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowActivityManager.java
@@ -16,27 +16,23 @@
 
 package com.android.settingslib.testutils.shadow;
 
-import static android.os.Build.VERSION_CODES.O;
-
 import android.app.ActivityManager;
-import android.app.IActivityManager;
 
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
 import org.robolectric.annotation.Resetter;
 import org.robolectric.shadow.api.Shadow;
-import org.robolectric.util.ReflectionHelpers;
 
 @Implements(ActivityManager.class)
 public class ShadowActivityManager {
     private static int sCurrentUserId = 0;
-    private static int sUserSwitchedTo = -1;
+    private int mUserSwitchedTo = -1;
 
     @Resetter
-    public static void reset() {
+    public void reset() {
         sCurrentUserId = 0;
-        sUserSwitchedTo = 0;
+        mUserSwitchedTo = 0;
     }
 
     @Implementation
@@ -46,21 +42,16 @@
 
     @Implementation
     protected boolean switchUser(int userId) {
-        sUserSwitchedTo = userId;
+        mUserSwitchedTo = userId;
         return true;
     }
 
-    @Implementation(minSdk = O)
-    protected static IActivityManager getService() {
-        return ReflectionHelpers.createNullProxy(IActivityManager.class);
-    }
-
     public boolean getSwitchUserCalled() {
-        return sUserSwitchedTo != -1;
+        return mUserSwitchedTo != -1;
     }
 
     public int getUserSwitchedTo() {
-        return sUserSwitchedTo;
+        return mUserSwitchedTo;
     }
 
     public static void setCurrentUser(int userId) {
diff --git a/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowDefaultDialerManager.java b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowDefaultDialerManager.java
index bbfdb7f..2c0792f 100644
--- a/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowDefaultDialerManager.java
+++ b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowDefaultDialerManager.java
@@ -29,7 +29,7 @@
     private static String sDefaultDialer;
 
     @Resetter
-    public static void reset() {
+    public void reset() {
         sDefaultDialer = null;
     }
 
diff --git a/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowPermissionChecker.java b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowPermissionChecker.java
deleted file mode 100644
index fae3aea..0000000
--- a/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowPermissionChecker.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settingslib.testutils.shadow;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.AttributionSource;
-import android.content.Context;
-import android.content.PermissionChecker;
-
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-
-import java.util.HashMap;
-import java.util.Map;
-/** Shadow class of {@link PermissionChecker}. */
-@Implements(PermissionChecker.class)
-public class ShadowPermissionChecker {
-    private static final Map<String, Map<String, Integer>> RESULTS = new HashMap<>();
-    /** Set the result of permission check for a specific permission. */
-    public static void setResult(String packageName, String permission, int result) {
-        if (!RESULTS.containsKey(packageName)) {
-            RESULTS.put(packageName, new HashMap<>());
-        }
-        RESULTS.get(packageName).put(permission, result);
-    }
-    /** Check the permission of calling package. */
-    @Implementation
-    public static int checkCallingPermissionForDataDelivery(
-            Context context,
-            String permission,
-            String packageName,
-            String attributionTag,
-            String message) {
-        return RESULTS.containsKey(packageName) && RESULTS.get(packageName).containsKey(permission)
-                ? RESULTS.get(packageName).get(permission)
-                : PermissionChecker.checkCallingPermissionForDataDelivery(
-                        context, permission, packageName, attributionTag, message);
-    }
-    /** Check general permission. */
-    @Implementation
-    public static int checkPermissionForDataDelivery(
-            Context context,
-            String permission,
-            int pid,
-            int uid,
-            String packageName,
-            String attributionTag,
-            String message) {
-        return RESULTS.containsKey(packageName) && RESULTS.get(packageName).containsKey(permission)
-                ? RESULTS.get(packageName).get(permission)
-                : PermissionChecker.checkPermissionForDataDelivery(
-                        context, permission, pid, uid, packageName, attributionTag, message);
-    }
-    /** Check general permission. */
-    @Implementation
-    public static int checkPermissionForPreflight(@NonNull Context context,
-            @NonNull String permission, int pid, int uid, @Nullable String packageName) {
-        return checkPermissionForPreflight(context, permission, new AttributionSource(
-                uid, packageName, null /*attributionTag*/));
-    }
-    /** Check general permission. */
-    @Implementation
-    public static int checkPermissionForPreflight(@NonNull Context context,
-            @NonNull String permission, @NonNull AttributionSource attributionSource) {
-        final String packageName = attributionSource.getPackageName();
-        return RESULTS.containsKey(packageName) && RESULTS.get(packageName).containsKey(permission)
-                ? RESULTS.get(packageName).get(permission)
-                : PermissionChecker.checkPermissionForPreflight(
-                        context, permission, attributionSource);
-    }
-}
diff --git a/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowSecure.java b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowSecure.java
deleted file mode 100644
index 70ebc67..0000000
--- a/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowSecure.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settingslib.testutils.shadow;
-
-import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
-
-import android.content.ContentResolver;
-import android.provider.Settings;
-
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-import org.robolectric.shadows.ShadowSettings;
-
-@Implements(value = Settings.Secure.class)
-public class ShadowSecure extends ShadowSettings.ShadowSecure {
-    @Implementation(minSdk = JELLY_BEAN_MR1)
-    public static boolean putStringForUser(ContentResolver cr, String name, String value,
-            int userHandle) {
-        return putString(cr, name, value);
-    }
-}
diff --git a/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowSmsApplication.java b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowSmsApplication.java
index 5ac0a87..381d072 100644
--- a/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowSmsApplication.java
+++ b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowSmsApplication.java
@@ -31,7 +31,7 @@
     private static ComponentName sDefaultSmsApplication;
 
     @Resetter
-    public static void reset() {
+    public void reset() {
         sDefaultSmsApplication = null;
     }
 
diff --git a/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowUserManager.java b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowUserManager.java
index 60d7721..ca1eefc 100644
--- a/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowUserManager.java
+++ b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowUserManager.java
@@ -16,28 +16,20 @@
 
 package com.android.settingslib.testutils.shadow;
 
-import static android.os.Build.VERSION_CODES.N_MR1;
-
 import android.annotation.UserIdInt;
 import android.content.Context;
 import android.content.pm.UserInfo;
-import android.content.pm.UserProperties;
-import android.os.UserHandle;
 import android.os.UserManager;
 
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
-import org.robolectric.shadows.ShadowBuild;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 @Implements(value = UserManager.class)
 public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager {
     private List<UserInfo> mUserInfos = addProfile(0, "Owner");
-    private final Map<Integer, UserProperties> mUserPropertiesMap = new HashMap<>();
 
     @Implementation
     protected static UserManager get(Context context) {
@@ -70,37 +62,4 @@
     protected List<UserInfo> getProfiles(@UserIdInt int userHandle) {
         return getProfiles();
     }
-
-    /**
-     * @return {@code false} by default, or the value specified via {@link #setIsAdminUser(boolean)}
-     */
-    @Implementation(minSdk = N_MR1)
-    public boolean isAdminUser() {
-        return getUserInfo(UserHandle.myUserId()).isAdmin();
-    }
-
-    /**
-     * Sets that the current user is an admin user; controls the return value of
-     * {@link UserManager#isAdminUser}.
-     */
-    public void setIsAdminUser(boolean isAdminUser) {
-        UserInfo userInfo = getUserInfo(UserHandle.myUserId());
-        if (isAdminUser) {
-            userInfo.flags |= UserInfo.FLAG_ADMIN;
-        } else {
-            userInfo.flags &= ~UserInfo.FLAG_ADMIN;
-        }
-    }
-
-    public void setupUserProperty(int userId, int showInSettings) {
-        UserProperties userProperties = new UserProperties(new UserProperties.Builder()
-                .setShowInSettings(showInSettings).build());
-        mUserPropertiesMap.putIfAbsent(userId, userProperties);
-    }
-
-    @Implementation(minSdk = ShadowBuild.UPSIDE_DOWN_CAKE)
-    protected UserProperties getUserProperties(UserHandle user) {
-        return mUserPropertiesMap.getOrDefault(user.getIdentifier(),
-            new UserProperties(new UserProperties.Builder().build()));
-    }
 }
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 73fb0f0..7be6043 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -123,6 +123,7 @@
     ],
     static_libs: [
         "SystemUISharedLib",
+        "SystemUICustomizationLib",
         "SettingsLib",
         "androidx.leanback_leanback",
         "androidx.slice_slice-core",
@@ -272,7 +273,6 @@
         "tests/src/com/android/systemui/dock/DockManagerFake.java",
         "tests/src/com/android/systemui/dump/LogBufferHelper.kt",
         "tests/src/com/android/systemui/statusbar/phone/FakeKeyguardStateController.java",
-        "tests/src/com/android/systemui/keyguard/domain/quickaffordance/FakeKeyguardQuickAffordanceRegistry.kt",
 
         /* Biometric converted tests */
         "tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt",
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
index 240bace..d83596e 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
@@ -99,7 +99,10 @@
         horizontalAlignment = Alignment.CenterHorizontally,
         verticalArrangement = Arrangement.spacedBy(60.dp),
         modifier =
-            modifier.background(MaterialTheme.colorScheme.surface).fillMaxSize().padding(32.dp)
+            modifier
+                .fillMaxSize()
+                .background(MaterialTheme.colorScheme.surface)
+                .padding(start = 32.dp, top = 92.dp, end = 32.dp, bottom = 32.dp)
     ) {
         Crossfade(
             targetState = message,
diff --git a/packages/SystemUI/compose/testing/Android.bp b/packages/SystemUI/compose/testing/Android.bp
deleted file mode 100644
index 555f42e..0000000
--- a/packages/SystemUI/compose/testing/Android.bp
+++ /dev/null
@@ -1,43 +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 {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_packages_SystemUI_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_packages_SystemUI_license"],
-}
-
-android_library {
-    name: "SystemUIComposeTesting",
-    manifest: "AndroidManifest.xml",
-
-    srcs: [
-        "src/**/*.kt",
-    ],
-
-    static_libs: [
-        "PlatformComposeCore",
-        "SystemUIScreenshotLib",
-
-        "androidx.compose.runtime_runtime",
-        "androidx.compose.material3_material3",
-        "androidx.compose.ui_ui-test-junit4",
-        "androidx.compose.ui_ui-test-manifest",
-    ],
-
-    kotlincflags: ["-Xjvm-default=all"],
-}
diff --git a/packages/SystemUI/compose/testing/AndroidManifest.xml b/packages/SystemUI/compose/testing/AndroidManifest.xml
deleted file mode 100644
index b1f7c3b..0000000
--- a/packages/SystemUI/compose/testing/AndroidManifest.xml
+++ /dev/null
@@ -1,25 +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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    package="com.android.systemui.testing.compose">
-    <application
-        android:appComponentFactory="androidx.core.app.AppComponentFactory"
-        tools:replace="android:appComponentFactory">
-    </application>
-</manifest>
diff --git a/packages/SystemUI/compose/testing/src/com/android/systemui/testing/compose/ComposeScreenshotTestRule.kt b/packages/SystemUI/compose/testing/src/com/android/systemui/testing/compose/ComposeScreenshotTestRule.kt
deleted file mode 100644
index cb9e53c..0000000
--- a/packages/SystemUI/compose/testing/src/com/android/systemui/testing/compose/ComposeScreenshotTestRule.kt
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.testing.compose
-
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Surface
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.platform.ViewRootForTest
-import androidx.compose.ui.test.junit4.createAndroidComposeRule
-import androidx.compose.ui.test.onRoot
-import com.android.compose.theme.PlatformTheme
-import com.android.systemui.testing.screenshot.ScreenshotActivity
-import com.android.systemui.testing.screenshot.SystemUIGoldenImagePathManager
-import com.android.systemui.testing.screenshot.UnitTestBitmapMatcher
-import com.android.systemui.testing.screenshot.drawIntoBitmap
-import org.junit.rules.RuleChain
-import org.junit.rules.TestRule
-import org.junit.runner.Description
-import org.junit.runners.model.Statement
-import platform.test.screenshot.DeviceEmulationRule
-import platform.test.screenshot.DeviceEmulationSpec
-import platform.test.screenshot.MaterialYouColorsRule
-import platform.test.screenshot.ScreenshotTestRule
-import platform.test.screenshot.getEmulatedDevicePathConfig
-
-/** A rule for Compose screenshot diff tests. */
-class ComposeScreenshotTestRule(
-    emulationSpec: DeviceEmulationSpec,
-    assetPathRelativeToBuildRoot: String
-) : TestRule {
-    private val colorsRule = MaterialYouColorsRule()
-    private val deviceEmulationRule = DeviceEmulationRule(emulationSpec)
-    private val screenshotRule =
-        ScreenshotTestRule(
-            SystemUIGoldenImagePathManager(
-                getEmulatedDevicePathConfig(emulationSpec),
-                assetPathRelativeToBuildRoot
-            )
-        )
-    private val composeRule = createAndroidComposeRule<ScreenshotActivity>()
-    private val delegateRule =
-        RuleChain.outerRule(colorsRule)
-            .around(deviceEmulationRule)
-            .around(screenshotRule)
-            .around(composeRule)
-    private val matcher = UnitTestBitmapMatcher
-
-    override fun apply(base: Statement, description: Description): Statement {
-        return delegateRule.apply(base, description)
-    }
-
-    /**
-     * Compare [content] with the golden image identified by [goldenIdentifier] in the context of
-     * [testSpec].
-     */
-    fun screenshotTest(
-        goldenIdentifier: String,
-        content: @Composable () -> Unit,
-    ) {
-        // Make sure that the activity draws full screen and fits the whole display instead of the
-        // system bars.
-        val activity = composeRule.activity
-        activity.mainExecutor.execute { activity.window.setDecorFitsSystemWindows(false) }
-
-        // Set the content using the AndroidComposeRule to make sure that the Activity is set up
-        // correctly.
-        composeRule.setContent {
-            PlatformTheme {
-                Surface(
-                    color = MaterialTheme.colorScheme.background,
-                ) {
-                    content()
-                }
-            }
-        }
-        composeRule.waitForIdle()
-
-        val view = (composeRule.onRoot().fetchSemanticsNode().root as ViewRootForTest).view
-        screenshotRule.assertBitmapAgainstGolden(view.drawIntoBitmap(), goldenIdentifier, matcher)
-    }
-}
diff --git a/packages/SystemUI/customization/res/values-h800dp/dimens.xml b/packages/SystemUI/customization/res/values-h800dp/dimens.xml
index 60afc8a..cb49945 100644
--- a/packages/SystemUI/customization/res/values-h800dp/dimens.xml
+++ b/packages/SystemUI/customization/res/values-h800dp/dimens.xml
@@ -17,4 +17,7 @@
 <resources>
     <!-- Large clock maximum font size (dp is intentional, to prevent any further scaling) -->
     <dimen name="large_clock_text_size">200dp</dimen>
+
+    <!-- With the large clock, move up slightly from the center -->
+    <dimen name="keyguard_large_clock_top_margin">-112dp</dimen>
 </resources>
diff --git a/packages/SystemUI/customization/res/values/dimens.xml b/packages/SystemUI/customization/res/values/dimens.xml
index ba8f284..8eb8132 100644
--- a/packages/SystemUI/customization/res/values/dimens.xml
+++ b/packages/SystemUI/customization/res/values/dimens.xml
@@ -24,4 +24,12 @@
     <item name="keyguard_clock_line_spacing_scale" type="dimen" format="float">.7</item>
     <!-- Burmese line spacing multiplier between hours and minutes of the keyguard clock -->
     <item name="keyguard_clock_line_spacing_scale_burmese" type="dimen" format="float">1</item>
+
+    <!-- With the large clock, move up slightly from the center -->
+    <dimen name="keyguard_large_clock_top_margin">-60dp</dimen>
+
+    <!-- additional offset for clock switch area items -->
+    <dimen name="small_clock_height">114dp</dimen>
+    <dimen name="small_clock_padding_top">28dp</dimen>
+    <dimen name="clock_padding_start">28dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
index d208404..b9d6643 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
@@ -33,8 +33,8 @@
 import com.android.systemui.animation.GlyphCallback
 import com.android.systemui.animation.TextAnimator
 import com.android.systemui.customization.R
-import com.android.systemui.log.LogBuffer
-import com.android.systemui.log.core.LogLevel.DEBUG
+import com.android.systemui.log.core.Logger
+import com.android.systemui.log.core.MessageBuffer
 import java.io.PrintWriter
 import java.util.Calendar
 import java.util.Locale
@@ -51,7 +51,12 @@
     defStyleAttr: Int = 0,
     defStyleRes: Int = 0
 ) : TextView(context, attrs, defStyleAttr, defStyleRes) {
-    var logBuffer: LogBuffer? = null
+    var messageBuffer: MessageBuffer? = null
+        set(value) {
+            logger = if (value != null) Logger(value, TAG) else null
+        }
+
+    private var logger: Logger? = null
 
     private val time = Calendar.getInstance()
 
@@ -129,7 +134,7 @@
 
     override fun onAttachedToWindow() {
         super.onAttachedToWindow()
-        logBuffer?.log(TAG, DEBUG, "onAttachedToWindow")
+        logger?.d("onAttachedToWindow")
         refreshFormat()
     }
 
@@ -145,39 +150,32 @@
         time.timeInMillis = timeOverrideInMillis ?: System.currentTimeMillis()
         contentDescription = DateFormat.format(descFormat, time)
         val formattedText = DateFormat.format(format, time)
-        logBuffer?.log(TAG, DEBUG,
-                { str1 = formattedText?.toString() },
-                { "refreshTime: new formattedText=$str1" }
-        )
+        logger?.d({ "refreshTime: new formattedText=$str1" }) { str1 = formattedText?.toString() }
         // Setting text actually triggers a layout pass (because the text view is set to
         // wrap_content width and TextView always relayouts for this). Avoid needless
         // relayout if the text didn't actually change.
         if (!TextUtils.equals(text, formattedText)) {
             text = formattedText
-            logBuffer?.log(TAG, DEBUG,
-                    { str1 = formattedText?.toString() },
-                    { "refreshTime: done setting new time text to: $str1" }
-            )
+            logger?.d({ "refreshTime: done setting new time text to: $str1" }) {
+                str1 = formattedText?.toString()
+            }
             // Because the TextLayout may mutate under the hood as a result of the new text, we
             // notify the TextAnimator that it may have changed and request a measure/layout. A
             // crash will occur on the next invocation of setTextStyle if the layout is mutated
             // without being notified TextInterpolator being notified.
             if (layout != null) {
                 textAnimator?.updateLayout(layout)
-                logBuffer?.log(TAG, DEBUG, "refreshTime: done updating textAnimator layout")
+                logger?.d("refreshTime: done updating textAnimator layout")
             }
             requestLayout()
-            logBuffer?.log(TAG, DEBUG, "refreshTime: after requestLayout")
+            logger?.d("refreshTime: after requestLayout")
         }
     }
 
     fun onTimeZoneChanged(timeZone: TimeZone?) {
         time.timeZone = timeZone
         refreshFormat()
-        logBuffer?.log(TAG, DEBUG,
-                { str1 = timeZone?.toString() },
-                { "onTimeZoneChanged newTimeZone=$str1" }
-        )
+        logger?.d({ "onTimeZoneChanged newTimeZone=$str1" }) { str1 = timeZone?.toString() }
     }
 
     @SuppressLint("DrawAllocation")
@@ -191,7 +189,7 @@
         } else {
             animator.updateLayout(layout)
         }
-        logBuffer?.log(TAG, DEBUG, "onMeasure")
+        logger?.d("onMeasure")
     }
 
     override fun onDraw(canvas: Canvas) {
@@ -203,12 +201,12 @@
         } else {
             super.onDraw(canvas)
         }
-        logBuffer?.log(TAG, DEBUG, "onDraw")
+        logger?.d("onDraw")
     }
 
     override fun invalidate() {
         super.invalidate()
-        logBuffer?.log(TAG, DEBUG, "invalidate")
+        logger?.d("invalidate")
     }
 
     override fun onTextChanged(
@@ -218,10 +216,7 @@
             lengthAfter: Int
     ) {
         super.onTextChanged(text, start, lengthBefore, lengthAfter)
-        logBuffer?.log(TAG, DEBUG,
-                { str1 = text.toString() },
-                { "onTextChanged text=$str1" }
-        )
+        logger?.d({ "onTextChanged text=$str1" }) { str1 = text.toString() }
     }
 
     fun setLineSpacingScale(scale: Float) {
@@ -235,7 +230,7 @@
     }
 
     fun animateColorChange() {
-        logBuffer?.log(TAG, DEBUG, "animateColorChange")
+        logger?.d("animateColorChange")
         setTextStyle(
             weight = lockScreenWeight,
             textSize = -1f,
@@ -257,7 +252,7 @@
     }
 
     fun animateAppearOnLockscreen() {
-        logBuffer?.log(TAG, DEBUG, "animateAppearOnLockscreen")
+        logger?.d("animateAppearOnLockscreen")
         setTextStyle(
             weight = dozingWeight,
             textSize = -1f,
@@ -283,7 +278,7 @@
         if (isAnimationEnabled && textAnimator == null) {
             return
         }
-        logBuffer?.log(TAG, DEBUG, "animateFoldAppear")
+        logger?.d("animateFoldAppear")
         setTextStyle(
             weight = lockScreenWeightInternal,
             textSize = -1f,
@@ -310,7 +305,7 @@
             // Skip charge animation if dozing animation is already playing.
             return
         }
-        logBuffer?.log(TAG, DEBUG, "animateCharge")
+        logger?.d("animateCharge")
         val startAnimPhase2 = Runnable {
             setTextStyle(
                 weight = if (isDozing()) dozingWeight else lockScreenWeight,
@@ -334,7 +329,7 @@
     }
 
     fun animateDoze(isDozing: Boolean, animate: Boolean) {
-        logBuffer?.log(TAG, DEBUG, "animateDoze")
+        logger?.d("animateDoze")
         setTextStyle(
             weight = if (isDozing) dozingWeight else lockScreenWeight,
             textSize = -1f,
@@ -453,10 +448,7 @@
             isSingleLineInternal && !use24HourFormat -> Patterns.sClockView12
             else -> DOUBLE_LINE_FORMAT_12_HOUR
         }
-        logBuffer?.log(TAG, DEBUG,
-                { str1 = format?.toString() },
-                { "refreshFormat format=$str1" }
-        )
+        logger?.d({ "refreshFormat format=$str1" }) { str1 = format?.toString() }
 
         descFormat = if (use24HourFormat) Patterns.sClockView24 else Patterns.sClockView12
         refreshTime()
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 12f7452..d65edae 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
@@ -23,10 +23,11 @@
 import android.provider.Settings
 import android.util.Log
 import androidx.annotation.OpenForTesting
-import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.LogMessageImpl
 import com.android.systemui.log.core.LogLevel
 import com.android.systemui.log.core.LogMessage
+import com.android.systemui.log.core.Logger
+import com.android.systemui.log.core.MessageBuffer
 import com.android.systemui.log.core.MessageInitializer
 import com.android.systemui.log.core.MessagePrinter
 import com.android.systemui.plugins.ClockController
@@ -75,7 +76,7 @@
 
 private val TMP_MESSAGE: LogMessage by lazy { LogMessageImpl.Factory.create() }
 
-private inline fun LogBuffer?.tryLog(
+private inline fun Logger?.tryLog(
     tag: String,
     level: LogLevel,
     messageInitializer: MessageInitializer,
@@ -84,7 +85,7 @@
 ) {
     if (this != null) {
         // Wrap messagePrinter to convert it from crossinline to noinline
-        this.log(tag, level, messageInitializer, messagePrinter, ex)
+        this.log(level, messagePrinter, ex, messageInitializer)
     } else {
         messageInitializer(TMP_MESSAGE)
         val msg = messagePrinter(TMP_MESSAGE)
@@ -110,7 +111,7 @@
     val handleAllUsers: Boolean,
     defaultClockProvider: ClockProvider,
     val fallbackClockId: ClockId = DEFAULT_CLOCK_ID,
-    val logBuffer: LogBuffer? = null,
+    messageBuffer: MessageBuffer? = null,
     val keepAllLoaded: Boolean,
     subTag: String,
     var isTransitClockEnabled: Boolean = false,
@@ -124,6 +125,7 @@
         fun onAvailableClocksChanged() {}
     }
 
+    private val logger: Logger? = if (messageBuffer != null) Logger(messageBuffer, TAG) else null
     private val availableClocks = ConcurrentHashMap<ClockId, ClockInfo>()
     private val clockChangeListeners = mutableListOf<ClockChangeListener>()
     private val settingObserver =
@@ -150,7 +152,7 @@
 
                 val knownClocks = KNOWN_PLUGINS.get(manager.getPackage())
                 if (knownClocks == null) {
-                    logBuffer.tryLog(
+                    logger.tryLog(
                         TAG,
                         LogLevel.WARNING,
                         { str1 = manager.getPackage() },
@@ -159,7 +161,7 @@
                     return true
                 }
 
-                logBuffer.tryLog(
+                logger.tryLog(
                     TAG,
                     LogLevel.INFO,
                     { str1 = manager.getPackage() },
@@ -176,7 +178,7 @@
                         }
 
                     if (manager != info.manager) {
-                        logBuffer.tryLog(
+                        logger.tryLog(
                             TAG,
                             LogLevel.ERROR,
                             { str1 = id },
@@ -216,7 +218,7 @@
                         }
 
                     if (manager != info.manager) {
-                        logBuffer.tryLog(
+                        logger.tryLog(
                             TAG,
                             LogLevel.ERROR,
                             { str1 = id },
@@ -244,7 +246,7 @@
                     val id = clock.clockId
                     val info = availableClocks[id]
                     if (info?.manager != manager) {
-                        logBuffer.tryLog(
+                        logger.tryLog(
                             TAG,
                             LogLevel.ERROR,
                             { str1 = id },
@@ -319,7 +321,7 @@
 
                 ClockSettings.deserialize(json)
             } catch (ex: Exception) {
-                logBuffer.tryLog(TAG, LogLevel.ERROR, {}, { "Failed to parse clock settings" }, ex)
+                logger.tryLog(TAG, LogLevel.ERROR, {}, { "Failed to parse clock settings" }, ex)
                 null
             }
         settings = result
@@ -348,7 +350,7 @@
                 )
             }
         } catch (ex: Exception) {
-            logBuffer.tryLog(TAG, LogLevel.ERROR, {}, { "Failed to set clock settings" }, ex)
+            logger.tryLog(TAG, LogLevel.ERROR, {}, { "Failed to set clock settings" }, ex)
         }
         settings = value
     }
@@ -508,9 +510,9 @@
     }
 
     private fun onConnected(clockId: ClockId) {
-        logBuffer.tryLog(TAG, LogLevel.DEBUG, { str1 = clockId }, { "Connected $str1" })
+        logger.tryLog(TAG, LogLevel.DEBUG, { str1 = clockId }, { "Connected $str1" })
         if (currentClockId == clockId) {
-            logBuffer.tryLog(
+            logger.tryLog(
                 TAG,
                 LogLevel.INFO,
                 { str1 = clockId },
@@ -520,10 +522,10 @@
     }
 
     private fun onLoaded(clockId: ClockId) {
-        logBuffer.tryLog(TAG, LogLevel.DEBUG, { str1 = clockId }, { "Loaded $str1" })
+        logger.tryLog(TAG, LogLevel.DEBUG, { str1 = clockId }, { "Loaded $str1" })
 
         if (currentClockId == clockId) {
-            logBuffer.tryLog(
+            logger.tryLog(
                 TAG,
                 LogLevel.INFO,
                 { str1 = clockId },
@@ -534,10 +536,10 @@
     }
 
     private fun onUnloaded(clockId: ClockId) {
-        logBuffer.tryLog(TAG, LogLevel.DEBUG, { str1 = clockId }, { "Unloaded $str1" })
+        logger.tryLog(TAG, LogLevel.DEBUG, { str1 = clockId }, { "Unloaded $str1" })
 
         if (currentClockId == clockId) {
-            logBuffer.tryLog(
+            logger.tryLog(
                 TAG,
                 LogLevel.WARNING,
                 { str1 = clockId },
@@ -548,10 +550,10 @@
     }
 
     private fun onDisconnected(clockId: ClockId) {
-        logBuffer.tryLog(TAG, LogLevel.DEBUG, { str1 = clockId }, { "Disconnected $str1" })
+        logger.tryLog(TAG, LogLevel.DEBUG, { str1 = clockId }, { "Disconnected $str1" })
 
         if (currentClockId == clockId) {
-            logBuffer.tryLog(
+            logger.tryLog(
                 TAG,
                 LogLevel.WARNING,
                 { str1 = clockId },
@@ -597,22 +599,17 @@
         if (isEnabled && clockId.isNotEmpty()) {
             val clock = createClock(clockId)
             if (clock != null) {
-                logBuffer.tryLog(
-                    TAG,
-                    LogLevel.INFO,
-                    { str1 = clockId },
-                    { "Rendering clock $str1" }
-                )
+                logger.tryLog(TAG, LogLevel.INFO, { str1 = clockId }, { "Rendering clock $str1" })
                 return clock
             } else if (availableClocks.containsKey(clockId)) {
-                logBuffer.tryLog(
+                logger.tryLog(
                     TAG,
                     LogLevel.WARNING,
                     { str1 = clockId },
                     { "Clock $str1 not loaded; using default" }
                 )
             } else {
-                logBuffer.tryLog(
+                logger.tryLog(
                     TAG,
                     LogLevel.ERROR,
                     { str1 = clockId },
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 e557c8e..e539c95 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
@@ -24,7 +24,7 @@
 import android.widget.FrameLayout
 import androidx.annotation.VisibleForTesting
 import com.android.systemui.customization.R
-import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.MessageBuffer
 import com.android.systemui.plugins.ClockAnimations
 import com.android.systemui.plugins.ClockConfig
 import com.android.systemui.plugins.ClockController
@@ -108,10 +108,10 @@
 
         override val config = ClockFaceConfig()
 
-        override var logBuffer: LogBuffer?
-            get() = view.logBuffer
+        override var messageBuffer: MessageBuffer?
+            get() = view.messageBuffer
             set(value) {
-                view.logBuffer = value
+                view.messageBuffer = value
             }
 
         override var animations: DefaultClockAnimations = DefaultClockAnimations(view, 0f, 0f)
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 537b7a4..d962732 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
@@ -18,7 +18,7 @@
 import android.graphics.drawable.Drawable
 import android.view.View
 import com.android.internal.annotations.Keep
-import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.MessageBuffer
 import com.android.systemui.plugins.annotations.ProvidesInterface
 import java.io.PrintWriter
 import java.util.Locale
@@ -95,7 +95,7 @@
     val animations: ClockAnimations
 
     /** Some clocks may log debug information */
-    var logBuffer: LogBuffer?
+    var messageBuffer: MessageBuffer?
 }
 
 /** Events that should call when various rendering parameters change */
diff --git a/packages/SystemUI/proguard_common.flags b/packages/SystemUI/proguard_common.flags
index 1f47e72..9bd26ab1 100644
--- a/packages/SystemUI/proguard_common.flags
+++ b/packages/SystemUI/proguard_common.flags
@@ -65,15 +65,7 @@
 # The plugins, log & common subpackages act as shared libraries that might be referenced in
 # dynamically-loaded plugin APKs.
 -keep class com.android.systemui.plugins.** { *; }
--keep class com.android.systemui.log.ConstantStringsLoggerImpl { *; }
--keep class com.android.systemui.log.ConstantStringsLogger { *; }
--keep class com.android.systemui.log.LogBuffer { *; }
--keep class com.android.systemui.log.LogcatEchoTrackerDebug { *; }
--keep class com.android.systemui.log.LogcatEchoTracker { *; }
--keep class com.android.systemui.log.LogcatEchoTrackerProd { *; }
--keep class com.android.systemui.log.LogLevel { *; }
--keep class com.android.systemui.log.LogMessageImpl { *; }
--keep class com.android.systemui.log.LogMessage { *; }
+-keep class com.android.systemui.log.core.** { *; }
 -keep class com.android.systemui.fragments.FragmentService$FragmentCreator {
     *;
 }
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_lock_locked.xml b/packages/SystemUI/res-keyguard/drawable/ic_lock_locked.xml
new file mode 100644
index 0000000..e572985
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/ic_lock_locked.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+  <path
+      android:pathData="M17,8H18C19.1,8 20,8.9 20,10V20C20,21.1 19.1,22 18,22H6C4.9,22 4,21.1 4,20V10C4,8.9 4.9,8 6,8H7V6C7,3.24 9.24,1 12,1C14.76,1 17,3.24 17,6V8ZM12,3C10.34,3 9,4.34 9,6V8H15V6C15,4.34 13.66,3 12,3ZM6,20V10H18V20H6ZM14,15C14,16.1 13.1,17 12,17C10.9,17 10,16.1 10,15C10,13.9 10.9,13 12,13C13.1,13 14,13.9 14,15Z"
+      android:fillColor="#5F6368"
+      android:fillType="evenOdd"/>
+</vector>
diff --git a/packages/SystemUI/res-keyguard/layout/status_bar_mobile_signal_group_inner.xml b/packages/SystemUI/res-keyguard/layout/status_bar_mobile_signal_group_inner.xml
index c85449d0..8f1323d 100644
--- a/packages/SystemUI/res-keyguard/layout/status_bar_mobile_signal_group_inner.xml
+++ b/packages/SystemUI/res-keyguard/layout/status_bar_mobile_signal_group_inner.xml
@@ -30,12 +30,13 @@
 
         <FrameLayout
             android:id="@+id/inout_container"
-            android:layout_height="17dp"
+            android:layout_height="@dimen/status_bar_mobile_inout_container_size"
             android:layout_width="wrap_content"
             android:layout_gravity="center_vertical">
             <ImageView
                 android:id="@+id/mobile_in"
-                android:layout_height="wrap_content"
+                android:layout_height="@dimen/status_bar_mobile_signal_size"
+                android:adjustViewBounds="true"
                 android:layout_width="wrap_content"
                 android:src="@drawable/ic_activity_down"
                 android:visibility="gone"
@@ -43,7 +44,8 @@
                 />
             <ImageView
                 android:id="@+id/mobile_out"
-                android:layout_height="wrap_content"
+                android:layout_height="@dimen/status_bar_mobile_signal_size"
+                android:adjustViewBounds="true"
                 android:layout_width="wrap_content"
                 android:src="@drawable/ic_activity_up"
                 android:paddingEnd="2dp"
@@ -52,11 +54,12 @@
         </FrameLayout>
         <ImageView
             android:id="@+id/mobile_type"
-            android:layout_height="wrap_content"
+            android:layout_height="@dimen/status_bar_mobile_signal_size"
             android:layout_width="wrap_content"
             android:layout_gravity="center_vertical"
-            android:paddingStart="2.5dp"
-            android:paddingEnd="1dp"
+            android:adjustViewBounds="true"
+            android:paddingStart="2.5sp"
+            android:paddingEnd="1sp"
             android:visibility="gone" />
         <Space
             android:id="@+id/mobile_roaming_space"
@@ -70,14 +73,14 @@
             android:layout_gravity="center_vertical">
             <com.android.systemui.statusbar.AnimatedImageView
                 android:id="@+id/mobile_signal"
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
+                android:layout_height="@dimen/status_bar_mobile_signal_size"
+                android:layout_width="@dimen/status_bar_mobile_signal_size"
                 systemui:hasOverlappingRendering="false"
                 />
             <ImageView
                 android:id="@+id/mobile_roaming"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
+                android:layout_width="@dimen/status_bar_mobile_signal_size"
+                android:layout_height="@dimen/status_bar_mobile_signal_size"
                 android:layout_gravity="top|start"
                 android:src="@drawable/stat_sys_roaming"
                 android:contentDescription="@string/data_connection_roaming"
diff --git a/packages/SystemUI/res-keyguard/values-nl/strings.xml b/packages/SystemUI/res-keyguard/values-nl/strings.xml
index c394fb6..366ee57 100644
--- a/packages/SystemUI/res-keyguard/values-nl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nl/strings.xml
@@ -113,7 +113,7 @@
     <string name="kg_prompt_reason_restart_pin" msgid="2672166323886110512">"Pincode is vereist na opnieuw opstarten apparaat"</string>
     <string name="kg_prompt_reason_restart_password" msgid="3967993994418885887">"Wachtwoord is vereist na opnieuw opstarten apparaat"</string>
     <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"Gebruik in plaats daarvan het patroon voor extra beveiliging"</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"Gebruik in plaats daarvan de pincode voor extra beveiliging"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"Gebruik de pincode voor extra beveiliging"</string>
     <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"Gebruik in plaats daarvan het wachtwoord voor extra beveiliging"</string>
     <string name="kg_prompt_reason_device_admin" msgid="6961159596224055685">"Apparaat vergrendeld door beheerder"</string>
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Apparaat is handmatig vergrendeld"</string>
diff --git a/packages/SystemUI/res-keyguard/values-uk/strings.xml b/packages/SystemUI/res-keyguard/values-uk/strings.xml
index a147d07..546f31b 100644
--- a/packages/SystemUI/res-keyguard/values-uk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uk/strings.xml
@@ -81,7 +81,7 @@
     <string name="kg_prompt_password_auth_timeout" msgid="5809110458491920871">"Потрібен додатковий захист. Пароль довго не використовувався."</string>
     <string name="kg_prompt_pattern_auth_timeout" msgid="1860605401869262178">"Потрібен додатковий захист. Ключ довго не використовувався."</string>
     <string name="kg_prompt_auth_timeout" msgid="6620679830980315048">"Потрібен додатковий захист. Пристрій довго не розблоковувався."</string>
-    <string name="kg_face_locked_out" msgid="2751559491287575">"Не розблоковано (фейсконтроль). Забагато спроб."</string>
+    <string name="kg_face_locked_out" msgid="2751559491287575">"Не розблоковано (фейс-контроль). Забагато спроб."</string>
     <string name="kg_fp_locked_out" msgid="6228277682396768830">"Не розблоковано (відбиток пальця). Забагато спроб."</string>
     <string name="kg_trust_agent_disabled" msgid="5400691179958727891">"Довірчий агент недоступний"</string>
     <string name="kg_primary_auth_locked_out_pin" msgid="5492230176361601475">"Неправильний PIN-код введено забагато разів"</string>
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index 39dd90e..8c81733 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -95,9 +95,6 @@
     <dimen name="num_pad_key_margin_end">12dp</dimen>
 
     <!-- additional offset for clock switch area items -->
-    <dimen name="small_clock_height">114dp</dimen>
-    <dimen name="small_clock_padding_top">28dp</dimen>
-    <dimen name="clock_padding_start">28dp</dimen>
     <dimen name="below_clock_padding_start">32dp</dimen>
     <dimen name="below_clock_padding_end">16dp</dimen>
     <dimen name="below_clock_padding_start_icons">28dp</dimen>
diff --git a/packages/SystemUI/res-product/values-af/strings.xml b/packages/SystemUI/res-product/values-af/strings.xml
index 1fab1d4..c1a6803 100644
--- a/packages/SystemUI/res-product/values-af/strings.xml
+++ b/packages/SystemUI/res-product/values-af/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Jy het die foon <xliff:g id="NUMBER">%d</xliff:g> keer verkeerd probeer ontsluit. Die werkprofiel sal verwyder word, wat alle profieldata sal uitvee."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd geteken. Na nóg <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings sal jy gevra word om jou e-posrekening te gebruik om jou tablet te ontsluit.\n\n Probeer weer oor <xliff:g id="NUMBER_2">%3$d</xliff:g> sekondes."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd geteken. Na nóg <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings sal jy gevra word om jou e-posrekening te gebruik om jou foon te ontsluit.\n\n Probeer weer oor <xliff:g id="NUMBER_2">%3$d</xliff:g> sekondes."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Foon het afgeskakel weens hitte"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Toestel het afgeskakel weens hitte"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tablet het afgeskakel weens hitte"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Jou foon werk nou normaal.\nTik vir meer inligting"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Jou toestel werk nou normaal.\nTik vir meer inligting"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Jou tablet werk nou normaal.\nTik vir meer inligting"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Jou foon was te warm en het afgeskakel om af te koel. Jou foon werk nou normaal.\n\nJou foon sal dalk te warm word as jy:\n	• Hulpbronintensiewe apps (soos dobbel-, video- of navigasieapps) gebruik\n	• Groot lêers af- of oplaai\n	• Jou foon in hoë temperature gebruik"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Jou toestel was te warm en het afgeskakel om af te koel. Jou toestel werk nou normaal.\n\nJou toestel sal dalk te warm word as jy:\n	• Hulpbronintensiewe apps (soos dobbel-, video- of navigasieapps) gebruik\n	• Groot lêers af- of oplaai\n	• Jou toestel in hoë temperature gebruik"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Jou tablet was te warm en het afgeskakel om af te koel. Jou tablet werk nou normaal.\n\nJou tablet sal dalk te warm word as jy:\n	• Hulpbronintensiewe apps (soos dobbel-, video- of navigasieapps) gebruik\n	• Groot lêers af- of oplaai\n	• Jou tablet in hoë temperature gebruik"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Foon word warm"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Toestel word warm"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Tablet word warm"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Sommige kenmerke word beperk terwyl die foon besig is om af te koel.\nTik vir meer inligting"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Sommige kenmerke word beperk terwyl die toestel besig is om af te koel.\nTik vir meer inligting"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Sommige kenmerke word beperk terwyl die tablet besig is om af te koel.\nTik vir meer inligting"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Jou foon sal outomaties probeer afkoel. Jy kan steeds jou foon gebruik, maar dit sal dalk stadiger werk.\n\nJou foon sal normaal werk nadat dit afgekoel het."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Jou toestel sal outomaties probeer afkoel. Jy kan steeds jou toestel gebruik, maar dit sal dalk stadiger werk.\n\nJou toestel sal normaal werk nadat dit afgekoel het."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Jou tablet sal outomaties probeer afkoel. Jy kan steeds jou tablet gebruik, maar dit sal dalk stadiger werk.\n\nJou tablet sal normaal werk nadat dit afgekoel het."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Die vingerafdruksensor is op die aan/af-skakelaar. Dit is die plat knoppie langs die verhewe volumeknoppie aan die kant van die tablet."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Die vingerafdruksensor is op die aan/af-skakelaar. Dit is die plat knoppie langs die verhewe volumeknoppie aan die kant van die toestel."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Die vingerafdruksensor is op die aan/af-skakelaar. Dit is die plat knoppie langs die verhewe volumeknoppie aan die kant van die foon."</string>
diff --git a/packages/SystemUI/res-product/values-am/strings.xml b/packages/SystemUI/res-product/values-am/strings.xml
index ab55d22..b8b2df8 100644
--- a/packages/SystemUI/res-product/values-am/strings.xml
+++ b/packages/SystemUI/res-product/values-am/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"ስልኩን <xliff:g id="NUMBER">%d</xliff:g> ጊዜ ትክክል ባልሆነ መልኩ ለመክፈት ሞክረዋል። የስራ መገለጫው ይወገዳል፣ ይህም ሁሉንም የመገለጫ ውሂብ ይሰርዛል።"</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%1$d</xliff:g> ጊዜ በትክክል አልሳሉትም። ከ<xliff:g id="NUMBER_1">%2$d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ጡባዊዎን እንዲከፍቱ ይጠየቃሉ።\n\n ከ<xliff:g id="NUMBER_2">%3$d</xliff:g> ከሰከንዶች በኋላ እንደገና ይሞክሩ።"</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%1$d</xliff:g> ጊዜ በትክክል አልሳሉትም። ከ<xliff:g id="NUMBER_1">%2$d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ስልክዎን እንዲከፍቱ ይጠየቃሉ።\n\nእባክዎ ከ<xliff:g id="NUMBER_2">%3$d</xliff:g> ሰከንዶች በኋላ እንደገና ይሞክሩ።"</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"ስልክ በሙቀት ምክንያት ጠፍቷል"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"መሣሪያ በሙቀት ምክንያት ጠፍቷል"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"ጡባዊ በሙቀት ምክንያት ጠፍቷል"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"የእርስዎ ስልክ በመደበኛነት በማሄድ ላይ ነው።\nለተጨማሪ መረጃ መታ ያድርጉ"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"የእርስዎ ጡባዊ በመደበኛነት በማሄድ ላይ ነው።\nለተጨማሪ መረጃ መታ ያድርጉ"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"የእርስዎ ጡባዊ በመደበኛነት በማሄድ ላይ ነው።\nለተጨማሪ መረጃ መታ ያድርጉ"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"የእርስዎ ስልክ በጣም ግሎ ነበር ስለዚህ እንዲቀዘቅዝ ጠፍቷል። የእርስዎ ስልክ አሁን በመደበኛነት በማሄድ ላይ ነው።\n\nየሚከተሉትን ካደረጉ የእርስዎ ስልክ በጣም ሊግል ይችላል፦\n	• ኃይል በጣም የሚጠቀሙ መተግበሪያዎችን (እንደ ጨዋታ፣ ቪድዮ ወይም የአሰሳ መተግበሪያዎች ያሉ) ከተጠቀሙ\n	• ትልልቅ ፋይሎችን ካወረዱ ወይም ከሰቀሉ\n	• ስልክዎን በከፍተኛ ሙቀት ውስጥ ከተጠቀሙ"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"የእርስዎ መሣሪያ በጣም ግሎ ነበር ስለዚህ እንዲቀዘቅዝ ጠፍቷል። የእርስዎ መሣሪያ አሁን በመደበኛነት በማሄድ ላይ ነው።\n\nየሚከተሉትን ካደረጉ የእርስዎ መሣሪያ በጣም ሊግል ይችላል፦\n	• ኃይል በጣም የሚጠቀሙ መተግበሪያዎችን (እንደ ጨዋታ፣ ቪድዮ ወይም የአሰሳ መተግበሪያዎች ያሉ) ከተጠቀሙ\n	• ትልልቅ ፋይሎችን ካወረዱ ወይም ከሰቀሉ\n	• መሣሪያዎን በከፍተኛ ሙቀት ውስጥ ከተጠቀሙ"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"የእርስዎ ጡባዊ በጣም ግሎ ነበር ስለዚህ እንዲቀዘቅዝ ጠፍቷል። የእርስዎ ጡባዊ አሁን በመደበኛነት በማሄድ ላይ ነው።\n\nየሚከተሉትን ካደረጉ የእርስዎ ጡባዊ በጣም ሊግል ይችላል፦\n	• ኃይል በጣም የሚጠቀሙ መተግበሪያዎችን (እንደ ጨዋታ፣ ቪድዮ ወይም የአሰሳ መተግበሪያዎች ያሉ) ከተጠቀሙ\n	• ትልልቅ ፋይሎችን ካወረዱ ወይም ከሰቀሉ\n	• ጡባዊዎን በከፍተኛ ሙቀት ውስጥ ከተጠቀሙ"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"የስልክ ሙቀት እየጨመረ ነው"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"የመሣሪያ ሙቀት እየጨመረ ነው"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"የጡባዊ ሙቀት እየጨመረ ነው"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"ስልክ እየቀዘቀዘ ሳለ አንዳንድ ባህሪያት ይገደባሉ።\nለተጨማሪ መረጃ መታ ያድርጉ"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"መሣሪያ እየቀዘቀዘ ሳለ አንዳንድ ባህሪያት ይገደባሉ።\nለተጨማሪ መረጃ መታ ያድርጉ"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"ጡባዊ እየቀዘቀዘ ሳለ አንዳንድ ባህሪያት ይገደባሉ።\nለተጨማሪ መረጃ መታ ያድርጉ"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"የእርስዎ ስልክ በራስ-ሰር ለመቀዝቀዝ ይሞክራል። አሁንም ስልክዎን መጠቀም ይችላሉ ነገር ግን ቀትፋፋ ሆኖ ሊያሄድ ይችላል።\n\nአንዴ ስልክዎ ከቀዘቀዘ በኋላ በመደበኛነት ያሄዳል።"</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"መሣሪያዎ በራስ-ሰር ለመቀዝቀዝ ይሞክራል። አሁንም መሣሪያዎን መጠቀም ይችላሉ ነገር ግን ቀርፋፋ ሆኖ ሊያሄድ ይችላል።\n\nአንዴ መሣሪያዎ ከቀዘቀዘ በኋላ በመደበኛነት ያሄዳል"</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"ጡባዊዎ በራስ-ሰር ለመቀዝቀዝ ይሞክራል። አሁንም ጡባዊዎን መጠቀም ይችላሉ ነገር ግን ቀርፋፋ ሆኖ ሊያሄድ ይችላል።\n\nአንዴ ጡባዊዎ ከቀዘቀዘ በኋላ በመደበኛነት ያሄዳል።"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"የጣት አሻራ ዳሳሹ የማብሪያ/ማጥፊያ ቁልፉ ላይ ነው። በጡባዊው ጫፍ ላይ ከፍ ካለው የድምፅ አዝራር ቀጥሎ ያለው ጠፍጣፋ አዝራር ነው።"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"የጣት አሻራ ዳሳሹ የማብሪያ/ማጥፊያ ቁልፉ ላይ ነው። በመሣሪያው ጫፍ ላይ ከፍ ካለው የድምፅ አዝራር ቀጥሎ ያለው ጠፍጣፋ አዝራር ነው።"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"የጣት አሻራ ዳሳሹ የማብሪያ/ማጥፊያ ቁልፉ ላይ ነው። በስልኩ ጫፍ ላይ ከፍ ካለው የድምፅ አዝራር ቀጥሎ ያለው ጠፍጣፋ አዝራር ነው።"</string>
diff --git a/packages/SystemUI/res-product/values-ar/strings.xml b/packages/SystemUI/res-product/values-ar/strings.xml
index 1664d6f..4d4d8d0 100644
--- a/packages/SystemUI/res-product/values-ar/strings.xml
+++ b/packages/SystemUI/res-product/values-ar/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"أخطأت في محاولة فتح قفل الهاتف <xliff:g id="NUMBER">%d</xliff:g> مرة. ستتم إزالة الملف الشخصي للعمل، ومن ثم يتم حذف جميع بياناته."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"رسمت نقش فتح القفل بشكل غير صحيح <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%2$d</xliff:g> محاولة غير ناجحة أخرى، ستُطالَب بفتح قفل الجهاز اللوحي باستخدام معلومات حساب بريد إلكتروني.\n\n يُرجى إعادة المحاولة خلال <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانية."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"رسمت نقش فتح القفل بشكل غير صحيح <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%2$d</xliff:g> محاولة غير ناجحة أخرى، ستُطالَب بفتح قفل الهاتف باستخدام حساب بريد إلكتروني.\n\n يُرجى إعادة المحاولة خلال <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانية."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"تم إطفاء الهاتف بسبب ارتفاع درجة حرارته"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"تم إطفاء الجهاز بسبب ارتفاع درجة حرارته"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"تم إطفاء الجهاز اللوحي لارتفاع حرارته"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"يعمل هاتفك الآن بشكل طبيعي.\nانقر للحصول على مزيد من المعلومات."</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"يعمل جهازك الآن بشكل طبيعي.\nانقر للحصول على مزيد من المعلومات."</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"يعمل جهازك اللوحي الآن بشكل طبيعي.\nانقر للحصول على مزيد من المعلومات."</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"ارتفعت درجة حرارة هاتفك بشدة، لذا تم إطفاؤه لخفض درجة حرارته. يعمل هاتفك الآن بشكل طبيعي.\n\nقد ترتفع درجة حرارة هاتفك بشدة إذا:\n	• استخدمت تطبيقات تستهلك موارد الجهاز بصورة كبيرة (مثل تطبيقات الألعاب أو الفيديو أو التنقل)\n	• نزَّلت أو حمَّلت ملفات كبيرة الحجم\n	• استخدمت هاتفك وسط أجواء مرتفعة الحرارة"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"ارتفعت درجة حرارة جهازك بشدة، لذا تم إطفاؤه لخفض درجة حرارته. يعمل جهازك الآن بشكل طبيعي.\n\nقد ترتفع درجة حرارة جهازك بشدة إذا:\n	• استخدمت تطبيقات تستهلك موارد الجهاز بصورة كبيرة (مثل تطبيقات الألعاب أو الفيديو أو التنقل)\n	• نزَّلت أو حمَّلت ملفات كبيرة الحجم\n	• استخدمت جهازك وسط أجواء مرتفعة الحرارة"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"ارتفعت درجة حرارة جهازك اللوحي بشدة، لذا تم إطفاؤه لخفض درجة حرارته. يعمل جهازك اللوحي الآن بشكل طبيعي.\n\nقد ترتفع درجة حرارة جهازك اللوحي بشدة إذا:\n	• استخدمت تطبيقات تستهلك موارد الجهاز بصورة كبيرة (مثل تطبيقات الألعاب أو الفيديو أو التنقل)\n	• نزَّلت أو حمَّلت ملفات كبيرة الحجم\n	• استخدمت جهازك اللوحي وسط أجواء مرتفعة الحرارة"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"تزداد درجة حرارة الهاتف"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"تزداد درجة حرارة الجهاز"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"تزداد درجة حرارة الجهاز اللوحي"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"سيتم فرض قيود على بعض الميزات إلى أن تنخفض درجة حرارة الهاتف.\nانقر للحصول على مزيد من المعلومات."</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"سيتم فرض قيود على بعض الميزات إلى أن تنخفض درجة حرارة الجهاز.\nانقر للحصول على مزيد من المعلومات."</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"سيتم فرض قيود على بعض الميزات إلى أن تنخفض درجة حرارة الجهاز اللوحي.\nانقر للحصول على مزيد من المعلومات."</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"سيحاول الهاتف تخفيض درجة حرارته تلقائيًا. سيظل بإمكانك استخدام هاتفك، ولكنه قد يعمل بشكل أبطأ.\n\nبعد أن تنخفض درجة حرارة الهاتف، سيستعيد سرعته المعتادة."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"سيحاول جهازك تخفيض درجة حرارته تلقائيًا. سيظل بإمكانك استخدام جهازك، ولكنه قد يعمل بشكل أبطأ.\n\nبعد أن تنخفض درجة حرارة الجهاز، سيستعيد سرعته المعتادة."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"سيحاول جهازك اللوحي تخفيض درجة حرارته تلقائيًا. سيظل بإمكانك استخدام جهازك اللوحي، ولكنه قد يعمل بشكل أبطأ.\n\nبعد أن تنخفض درجة حرارة الجهاز اللوحي، سيستعيد سرعته المعتادة."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"توجد أداة استشعار بصمة الإصبع على زر التشغيل. زر التشغيل هو الزر المسطّح بجانب زرَّي التحكّم بمستوى الصوت البارزَين في الجزء الجانبي من الجهاز اللوحي."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"توجد أداة استشعار بصمة الإصبع على زر التشغيل. زر التشغيل هو الزر المسطّح بجانب زرَّي التحكّم بمستوى الصوت البارزَين في الجزء الجانبي من الجهاز."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"توجد أداة استشعار بصمة الإصبع على زر التشغيل. زر التشغيل هو الزر المسطّح بجانب زرَّي التحكّم بمستوى الصوت البارزَين في الجزء الجانبي من الهاتف."</string>
diff --git a/packages/SystemUI/res-product/values-as/strings.xml b/packages/SystemUI/res-product/values-as/strings.xml
index 05c69b8..40aab2f 100644
--- a/packages/SystemUI/res-product/values-as/strings.xml
+++ b/packages/SystemUI/res-product/values-as/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"আপুনি ফ’নটো আনলক কৰিবলৈ <xliff:g id="NUMBER">%d</xliff:g> বাৰ ভুলকৈ প্ৰয়াস কৰিছে। কৰ্মস্থানৰ প্ৰ’ফাইলটো আঁতৰোৱা হ’ব, যিয়ে প্ৰ’ফাইলটোৰ আটাইবোৰ ডেটা মচি পেলাব।"</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"আপুনি নিজৰ আনলক কৰা আৰ্হিটো <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুলকৈ আঁকিছে। আৰু <xliff:g id="NUMBER_1">%2$d</xliff:g> বাৰ ভুলকৈ প্ৰয়াস কৰাৰ পাছত আপোনাক নিজৰ টেবলেটটো এটা ইমেইল একাউণ্টৰ জৰিয়তে আনলক কৰিবলৈ কোৱা হ’ব।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ছেকেণ্ডৰ পাছত পুনৰ চেষ্টা কৰক।"</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"আপুনি নিজৰ আনলক কৰা আৰ্হিটো <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুলকৈ আঁকিছে। আৰু <xliff:g id="NUMBER_1">%2$d</xliff:g> বাৰ ভুলকৈ প্ৰয়াস কৰাৰ পাছত আপোনাক নিজৰ ফ’নটো এটা ইমেইল একাউণ্টৰ জৰিয়তে আনলক কৰিবলৈ কোৱা হ’ব।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ছেকেণ্ডৰ পাছত পুনৰ চেষ্টা কৰক।"</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"ফ’নটো গৰম হোৱাৰ কাৰণে অফ হৈছিল"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"ডিভাইচটো গৰম হোৱাৰ কাৰণে অফ হৈছিল"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"টেবলেটটো গৰম হোৱাৰ কাৰণে অফ হৈছিল"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"আপোনাৰ ফ’নটো এতিয়া স্বাভাৱিকভাৱে চলি আছে।\nঅধিক তথ্যৰ বাবে টিপক"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"আপোনাৰ ডিভাইচটো এতিয়া স্বাভাৱিকভাৱে চলি আছে।\nঅধিক তথ্যৰ বাবে টিপক"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"আপোনাৰ টেবলেটটো এতিয়া স্বাভাৱিকভাৱে চলি আছে।\nঅধিক তথ্যৰ বাবে টিপক"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"আপোনাৰ ফ’নটো অত্যধিক গৰম হোৱাৰ বাবে সেইটো ঠাণ্ডা কৰিবলৈ অফ হৈছিল। আপোনাৰ ফ’নটো এতিয়া স্বাভাৱিকভাৱে চলি আছে।\n\nআপোনাৰ ফ’নটো গৰম হ’ব পাৰে, যদিহে আপুনি:\n	• ফ’নটোৰ হাৰ্ডৱেৰ অত্যধিক মাত্ৰাত ব্যৱহাৰ কৰা এপ্‌ (যেনে- ভিডিঅ’ গে’ম, ভিডিঅ’, দিক্-নিৰ্দেশনাৰ এপ্‌) ব্যৱহাৰ কৰে\n	• ডাঙৰ আকাৰৰ ফাইল আপল’ড অথবা ডাউনল’ড কৰে\n	• আপোনাৰ ফ’নটো উচ্চ তাপমাত্ৰাৰ পৰিৱেশত ব্যৱহাৰ কৰে"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"আপোনাৰ ডিভাইচটো অত্যধিক গৰম হোৱাৰ বাবে সেইটো ঠাণ্ডা কৰিবলৈ অফ হৈছিল। আপোনাৰ ডিভাইচটো এতিয়া স্বাভাৱিকভাৱে চলি আছে।\n\nআপোনাৰ ডিভাইচটো গৰম হ’ব পাৰে, যদিহে আপুনি:\n	• ডিভাইচটোৰ হাৰ্ডৱেৰ অত্যধিক মাত্ৰাত ব্যৱহাৰ কৰা এপ্‌ (যেনে- ভিডিঅ’ গে’ম, ভিডিঅ’, দিক্-নিৰ্দেশনাৰ এপ্‌) ব্যৱহাৰ কৰে\n	• ডাঙৰ আকাৰৰ ফাইল আপল’ড অথবা ডাউনল’ড কৰে\n	• আপোনাৰ ডিভাইচটো উচ্চ তাপমাত্ৰাৰ পৰিৱেশত ব্যৱহাৰ কৰে"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"আপোনাৰ টেবলেটটো অত্যধিক গৰম হোৱাৰ বাবে সেইটো ঠাণ্ডা কৰিবলৈ অফ হৈছিল। আপোনাৰ টেবলেটটো এতিয়া স্বাভাৱিকভাৱে চলি আছে।\n\nআপোনাৰ টেবলেটটো গৰম হ’ব পাৰে, যদিহে আপুনি:\n	• টেবলেটটোৰ হাৰ্ডৱেৰ অত্যধিক মাত্ৰাত ব্যৱহাৰ কৰা এপ্‌ (যেনে- ভিডিঅ’ গে’ম, ভিডিঅ’, দিক্-নিৰ্দেশনাৰ এপ্‌) ব্যৱহাৰ কৰে\n	• ডাঙৰ আকাৰৰ ফাইল আপল’ড অথবা ডাউনল’ড কৰে\n	• আপোনাৰ টেবলেটটো উচ্চ তাপমাত্ৰাৰ পৰিৱেশত ব্যৱহাৰ কৰে"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"ফ’নটো গৰম হ’বলৈ ধৰিছে"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"ডিভাইচটো গৰম হবলৈ ধৰিছে"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"টেবলেটটো গৰম হবলৈ ধৰিছে"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"ফ’নটো ঠাণ্ডা হ’বলৈ ধৰোঁতে কিছুমান সুবিধা উপলব্ধ নহয়।\nঅধিক তথ্যৰ বাবে টিপক"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"ডিভাইচটো ঠাণ্ডা হ’বলৈ ধৰোঁতে কিছুমান সুবিধা উপলব্ধ নহয়।\nঅধিক তথ্যৰ বাবে টিপক"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"টেবলেটটো ঠাণ্ডা হ’বলৈ ধৰোঁতে কিছুমান সুবিধা উপলব্ধ নহয়।\nঅধিক তথ্যৰ বাবে টিপক"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"আপোনাৰ ফ’নটোৱে নিজে নিজে ঠাণ্ডা হ’বলৈ স্বয়ংক্ৰিয়ভাৱে চেষ্টা কৰিব। আপুনি ফ’নটো ব্যৱহাৰ কৰি থাকিব পাৰে কিন্তু ই লাহে লাহে চলিব পাৰে।\n\nফ’নটো ঠাণ্ডা হোৱাৰ পাছত ই আগৰ নিচিনাকৈ চলিব।"</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"আপোনাৰ ডিভাইচটোৱে নিজে নিজে ঠাণ্ডা হ’বলৈ স্বয়ংক্ৰিয়ভাৱে চেষ্টা কৰিব। আপুনি ডিভাইচটো ব্যৱহাৰ কৰি থাকিব পাৰে কিন্তু ই লাহে লাহে চলিব পাৰে।\n\nআপোনাৰ ডিভাইচটো ঠাণ্ডা হোৱাৰ পাছত ই আগৰ নিচিনাকৈ চলিব।"</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"আপোনাৰ টেবলেটটোৱে নিজে নিজে ঠাণ্ডা হ’বলৈ স্বয়ংক্ৰিয়ভাৱে চেষ্টা কৰিব। আপুনি টেবলেটটো ব্যৱহাৰ কৰি থাকিব পাৰে কিন্তু ই লাহে লাহে চলিব পাৰে।\n\nআপোনাৰ টেবলেটটো ঠাণ্ডা হোৱাৰ পাছত ই আগৰ নিচিনাকৈ চলিব।"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰটো পাৱাৰ বুটামটোত আছে। এইটো হৈছে টেবলেটটোৰ প্ৰান্তত থকা উঠঙা ভলিউমৰ বুটামটোৰ কাষত থকা চেপেটা বুটামটো।"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰটো পাৱাৰ বুটামটোত আছে। এইটো হৈছে ডিভাইচটোৰ প্ৰান্তত থকা উঠঙা ভলিউমৰ বুটামটোৰ কাষত থকা চেপেটা বুটামটো।"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰটো পাৱাৰ বুটামটোত আছে। এইটো হৈছে ফ’নটোৰ প্ৰান্তত থকা উঠঙা ভলিউমৰ বুটামটোৰ কাষত থকা চেপেটা বুটামটো।"</string>
diff --git a/packages/SystemUI/res-product/values-az/strings.xml b/packages/SystemUI/res-product/values-az/strings.xml
index 3cc7d8c..b7e93fd 100644
--- a/packages/SystemUI/res-product/values-az/strings.xml
+++ b/packages/SystemUI/res-product/values-az/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Telefonun kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> dəfə yanlış cəhd etmisiniz. İş profili silinəcək və bütün data ləğv ediləcək."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Kilid açma modelini <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış çəkmisiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra planşet kilidini e-poçt hesabınızla açmaq tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə sonra cəhd edin."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Kilid açma modelini artıq <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış çəkmisiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra telefon kilidini e-poçt hesabınızla açmaq tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə sonra cəhd edin."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Telefon qızdığı üçün söndü"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Cihaz qızdığı üçün söndü"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Planşet qızdığı üçün söndü"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Hazırda telefon normal işləyir.\nƏtraflı məlumat üçün toxunun"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Hazırda cihaz normal işləyir.\nƏtraflı məlumat üçün toxunun"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Hazırda planşet normal işləyir.\nƏtraflı məlumat üçün toxunun"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Telefon çox isti idi və soyumaq üçün söndü. Hazırda telefon normal işləyir.\n\nTelefon bu hallarda çox isinə bilər:\n	• Çoxresurslu tətbiq (oyun, video və ya naviqasiya tətbiqi kimi) istifadə etsəniz\n	• Böyük fayl endirsəniz və ya yükləsəniz\n	• Telefonu yüksək temperaturda istifadə etsəniz"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Cihaz çox isti idi və soyumaq üçün söndü. Hazırda cihaz normal işləyir.\n\nCihaz bu hallarda çox isinə bilər:\n	• Çoxresurslu tətbiq (oyun, video və ya naviqasiya tətbiqi kimi) istifadə etsəniz\n	• Böyük fayl endirsəniz və ya yükləsəniz\n	• Cihazı yüksək temperaturda istifadə etsəniz"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Planşet çox isti idi və soyumaq üçün söndü. Hazırda planşet normal işləyir.\n\nPlanşet bu hallarda çox isinə bilər:\n	• Çoxresurslu tətbiq (oyun, video və ya naviqasiya tətbiqi kimi) istifadə etsəniz\n	• Böyük fayl endirsəniz və ya yükləsəniz\n	• Planşeti yüksək temperaturda istifadə etsəniz"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Telefon isinir"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Cihaz isinir"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Planşet isinir"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Telefon soyuyarkən bəzi funksiyalar məhdudlaşdırılır.\nƏtraflı məlumat üçün toxunun"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Cihaz soyuyarkən bəzi funksiyalar məhdudlaşdırılır.\nƏtraflı məlumat üçün toxunun"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Planşet soyuyarkən bəzi funksiyalar məhdudlaşdırılır.\nƏtraflı məlumat üçün toxunun"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Telefon avtomatik soyuyacaq. Telefondan istifadə mümkündür, lakin asta işləyə bilər.\n\nSoyuduqdan sonra normal işləyəcək."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Cihaz avtomatik soyuyacaq. Cihazdan istifadə mümkündür, lakin asta işləyə bilər.\n\nSoyuduqdan sonra normal işləyəcək."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Planşet avtomatik soyuyacaq. Planşetdən istifadə mümkündür, lakin asta işləyə bilər.\n\nSoyuduqdan sonra normal işləyəcək."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Barmaq izi sensoru enerji düyməsinin üzərindədir. Bu, planşetin kənarındakı qabarıq səs düyməsinin yanındakı yastı düymədir."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Barmaq izi sensoru enerji düyməsinin üzərindədir. Bu, cihazın kənarındakı qabarıq səs düyməsinin yanındakı yastı düymədir."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Barmaq izi sensoru enerji düyməsinin üzərindədir. Bu, telefonun kənarındakı qabarıq səs düyməsinin yanındakı yastı düymədir."</string>
diff --git a/packages/SystemUI/res-product/values-b+sr+Latn/strings.xml b/packages/SystemUI/res-product/values-b+sr+Latn/strings.xml
index 07d8c94..067c16b 100644
--- a/packages/SystemUI/res-product/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res-product/values-b+sr+Latn/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Pogrešno ste pokušali da otključate telefon <xliff:g id="NUMBER">%d</xliff:g> puta. Uklonićemo poslovni profil, čime se brišu svi podaci sa profila."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Netačno ste nacrtali šablon za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta, zatražićemo da otključate tablet pomoću imejl naloga.\n\n Probajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Netačno ste nacrtali šablon za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta, zatražićemo da otključate telefon pomoću imejl naloga.\n\n Probajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Telefon se isključio zbog toplote"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Uređaj se isključio zbog toplote"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tablet se isključio zbog toplote"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Telefon sada funkcioniše normalno.\nDodirnite za više informacija"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Uređaj sada funkcioniše normalno.\nDodirnite za više informacija"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Tablet sada funkcioniše normalno.\nDodirnite za više informacija"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Telefon je bio prevruć, pa se isključio da se ohladi. Sada radi normalno.\n\nTelefon može previše da se ugreje ako:\n	• koristite aplikacije koje zahtevaju puno resursa (npr. video igre, video ili aplikacije za navigaciju)\n	• preuzimate ili otpremate velike fajlove\n	• koristite telefon na visokoj temperaturi"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Uređaj je bio prevruć, pa se isključio da se ohladi. Sada radi normalno.\n\nUređaj može previše da se ugreje ako:\n	• koristite aplikacije koje zahtevaju puno resursa (npr. video igre, video ili aplikacije za navigaciju)\n	• preuzimate ili otpremate velike fajlove\n	• koristite uređaj na visokoj temperaturi"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Tablet je bio prevruć, pa se isključio da se ohladi. Sada radi normalno.\n\nTablet može previše da se ugreje ako:\n	• koristite aplikacije koje zahtevaju puno resursa (npr. video igre, video ili aplikacije za navigaciju)\n	• preuzimate ili otpremate velike fajlove\n	• koristite tablet na visokoj temperaturi"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Telefon se zagrejao"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Uređaj se zagrejao"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Tablet se zagrejao"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Neke funkcije su ograničene dok se telefon ne ohladi.\nDodirnite za više informacija"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Neke funkcije su ograničene dok se uređaj ne ohladi.\nDodirnite za više informacija"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Neke funkcije su ograničene dok se tablet ne ohladi.\nDodirnite za više informacija"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Telefon će automatski pokušati da se ohladi. I dalje možete da koristite telefon, ali će možda raditi sporije.\n\nKad se telefon ohladi, funkcionisaće normalno."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Uređaj će automatski pokušati da se ohladi. I dalje možete da koristite uređaj, ali će možda raditi sporije.\n\nKad se uređaj ohladi, funkcionisaće normalno."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Tablet će automatski pokušati da se ohladi. I dalje možete da koristite tablet, ali će možda raditi sporije.\n\nKad se tablet ohladi, funkcionisaće normalno."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Senzor za otisak prsta se nalazi na dugmetu za uključivanje. To je ravno dugme pored izdignutog dugmeta za jačinu zvuka na ivici tableta."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Senzor za otisak prsta se nalazi na dugmetu za uključivanje. To je ravno dugme pored izdignutog dugmeta za jačinu zvuka na ivici uređaja."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Senzor za otisak prsta se nalazi na dugmetu za uključivanje. To je ravno dugme pored izdignutog dugmeta za jačinu zvuka na ivici telefona."</string>
diff --git a/packages/SystemUI/res-product/values-be/strings.xml b/packages/SystemUI/res-product/values-be/strings.xml
index e9c491a..f9ef0d5 100644
--- a/packages/SystemUI/res-product/values-be/strings.xml
+++ b/packages/SystemUI/res-product/values-be/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Вы не змаглі разблакіраваць тэлефон столькі разоў: <xliff:g id="NUMBER">%d</xliff:g>. Працоўны профіль будзе выдалены, і гэта прывядзе да выдалення ўсіх даных у профілі."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Вы няправільна ўвялі ўзор разблакіроўкі столькі разоў: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Пасля яшчэ некалькіх няўдалых спроб (<xliff:g id="NUMBER_1">%2$d</xliff:g>) вам будзе прапанавана разблакіраваць планшэт, увайшоўшы ва ўліковы запіс электроннай пошты.\n\n Паўтарыце спробу праз <xliff:g id="NUMBER_2">%3$d</xliff:g> с."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Вы няправільна ўвялі ўзор разблакіроўкі столькі разоў: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Пасля яшчэ некалькіх няўдалых спроб (<xliff:g id="NUMBER_1">%2$d</xliff:g>) вам будзе прапанавана разблакіраваць тэлефон, увайшоўшы ва ўліковы запіс электроннай пошты.\n\n Паўтарыце спробу праз <xliff:g id="NUMBER_2">%3$d</xliff:g> с."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Тэлефон выключыўся з-за перагрэву"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Прылада выключылася з-за перагрэву"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Планшэт выключыўся з-за перагрэву"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Ваш тэлефон працуе ў звычайным рэжыме.\nНацісніце, каб даведацца больш"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Ваша прылада працуе ў звычайным рэжыме.\nНацісніце, каб даведацца больш"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Ваш планшэт працуе ў звычайным рэжыме.\nНацісніце, каб даведацца больш"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Ваш тэлефон пераграваўся, таму ён выключыўся, каб астыць. Зараз тэлефон працуе ў звычайным рэжыме.\n\nТэлефон можа перагравацца пры:\n	• выкарыстанні рэсурсаёмістых праграм (напрыклад, гульняў або праграм, звязаных з відэа або навігацыяй);\n	• спампоўванні або запампоўванні вялікіх файлаў;\n	• выкарыстанні тэлефона пры высокіх тэмпературах."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Ваша прылада перагравалася, таму яна выключылася, каб астыць. Зараз прылада працуе ў звычайным рэжыме.\n\nПрылада можа перагравацца пры:\n	• выкарыстанні рэсурсаёмістых праграм (напрыклад, гульняў або праграм, звязаных з відэа або навігацыяй);\n	• спампоўванні або запампоўванні вялікіх файлаў;\n	• выкарыстанні прылады пры высокіх тэмпературах."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Ваш планшэт пераграваўся, таму ён выключыўся, каб астыць. Зараз планшэт працуе ў звычайным рэжыме.\n\nПланшэт можа перагравацца пры:\n	• выкарыстанні рэсурсаёмістых праграм (напрыклад, гульняў або праграм, звязаных з відэа або навігацыяй);\n	• спампоўванні або запампоўванні вялікіх файлаў;\n	• выкарыстанні планшэта пры высокіх тэмпературах."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Тэлефон награваецца"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Прылада награваецца"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Планшэт награваецца"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Некаторыя функцыі абмежаваны, пакуль тэлефон не астыне.\nНацісніце, каб даведацца больш"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Некаторыя функцыі абмежаваны, пакуль прылада не астыне.\nНацісніце, каб даведацца больш"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Некаторыя функцыі абмежаваны, пакуль планшэт не астыне.\nНацісніце, каб даведацца больш"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Ваш тэлефон будзе астываць аўтаматычна. Вы можаце і далей ім карыстацца, але ён можа працаваць больш павольна.\n\nПасля таго як тэлефон астыне, ён будзе працаваць у звычайным рэжыме."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Ваша прылада будзе астываць аўтаматычна. Вы можаце і далей ёй карыстацца, але яна можа працаваць больш павольна.\n\nПасля таго як прылада астыне, яна будзе працаваць у звычайным рэжыме."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Ваш планшэт будзе астываць аўтаматычна. Вы можаце і далей ім карыстацца, але ён можа працаваць больш павольна.\n\nПасля таго як планшэт астыне, ён будзе працаваць у звычайным рэжыме."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Сканер адбіткаў пальцаў знаходзіцца на кнопцы сілкавання. Гэта плоская кнопка побач з выпуклай кнопкай гучнасці на бакавой грані планшэта."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Сканер адбіткаў пальцаў знаходзіцца на кнопцы сілкавання. Гэта плоская кнопка побач з выпуклай кнопкай гучнасці на бакавой грані прылады."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Сканер адбіткаў пальцаў знаходзіцца на кнопцы сілкавання. Гэта плоская кнопка побач з выпуклай кнопкай гучнасці на бакавой грані тэлефона."</string>
diff --git a/packages/SystemUI/res-product/values-bg/strings.xml b/packages/SystemUI/res-product/values-bg/strings.xml
index 3542558..40140c4 100644
--- a/packages/SystemUI/res-product/values-bg/strings.xml
+++ b/packages/SystemUI/res-product/values-bg/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Опитахте да отключите телефона и сбъркахте <xliff:g id="NUMBER">%d</xliff:g> пъти. Служебният потребителски профил ще бъде премахнат, при което ще се изтрият всички данни за него."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%1$d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни опита ще бъдете помолени да отключите таблета си посредством имейл адрес.\n\n Опитайте отново след <xliff:g id="NUMBER_2">%3$d</xliff:g> секунди."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%1$d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни опита ще бъдете помолени да отключите телефона посредством имейл адрес.\n\n Опитайте отново след <xliff:g id="NUMBER_2">%3$d</xliff:g> секунди."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Телефонът се изключи поради загряване"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Устройството се изключи поради загряване"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Таблетът се изключи поради загряване"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Телефонът ви вече работи нормално.\nДокоснете за още информация"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Устройството ви вече работи нормално.\nДокоснете за още информация"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Таблетът ви вече работи нормално.\nДокоснете за още информация"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Телефонът ви бе твърде горещ, затова се изключи с цел охлаждане. Вече работи нормално.\n\nТелефонът ви може да стане твърде горещ, ако:\n	• използвате натоварващи приложения (като например игри или приложения за видео или за навигация);\n	• изтегляте или качвате големи файлове;\n	• използвате устройството си при високи температури."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Устройството ви бе твърде горещо, затова се изключи с цел охлаждане. Вече работи нормално.\n\nУстройството ви може да стане твърде горещо, ако:\n	• използвате натоварващи приложения (като например игри или приложения за видео или за навигация);\n	• изтегляте или качвате големи файлове;\n	• използвате устройството си при високи температури."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Таблетът ви бе твърде горещ, затова се изключи с цел охлаждане. Вече работи нормално.\n\nТаблетът ви може да стане твърде горещ, ако:\n	• използвате натоварващи приложения (като например игри или приложения за видео или за навигация);\n	• изтегляте или качвате големи файлове;\n	• използвате устройството си при високи температури."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Телефонът загрява"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Устройството загрява"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Таблетът загрява"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Някои функции са ограничени, докато телефонът се охлажда.\nДокоснете за още информация"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Някои функции са ограничени, докато устройството се охлажда.\nДокоснете за още информация"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Някои функции са ограничени, докато таблетът се охлажда.\nДокоснете за още информация"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Телефонът ви автоматично ще направи опит да се охлади. Пак можете да го използвате, но той може да работи по-бавно.\n\nСлед като се охлади, ще работи нормално."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Устройството ви автоматично ще направи опит да се охлади. Пак можете да го използвате, но то може да работи по-бавно.\n\nСлед като се охлади, ще работи нормално."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Таблетът ви автоматично ще направи опит да се охлади. Пак можете да го използвате, но той може да работи по-бавно.\n\nСлед като се охлади, ще работи нормално."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Сензорът за отпечатъци се намира върху бутона за захранване. Този бутон е плосък и е разположен на ръба на таблета до повдигнатия бутон за силата на звука."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Сензорът за отпечатъци се намира върху бутона за захранване. Този бутон е плосък и е разположен на ръба на устройството до повдигнатия бутон за силата на звука."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Сензорът за отпечатъци се намира върху бутона за захранване. Този бутон е плосък и е разположен на ръба на телефона до повдигнатия бутон за силата на звука."</string>
diff --git a/packages/SystemUI/res-product/values-bn/strings.xml b/packages/SystemUI/res-product/values-bn/strings.xml
index 0984de2..19165ef 100644
--- a/packages/SystemUI/res-product/values-bn/strings.xml
+++ b/packages/SystemUI/res-product/values-bn/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"আপনি <xliff:g id="NUMBER">%d</xliff:g> বার ভুল পদ্ধতিতে ফোন আনলক করার চেষ্টা করেছেন। অফিস প্রোফাইলটি সরিয়ে দেওয়া হবে, যার ফলে প্রোফাইলের সমস্ত ডেটা মুছে যাবে।"</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল পদ্ধতিতে প্যাটার্ন আনলক করার চেষ্টা করেছেন। আরও <xliff:g id="NUMBER_1">%2$d</xliff:g> বার এটি করলে আপনাকে প্যাটার্ন আনলক করতে একটি ইমেল অ্যাকাউন্ট ব্যবহার করতে বলা হবে।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> সেকেন্ড পরে আবার চেষ্টা করুন।"</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল পদ্ধতিতে প্যাটার্ন আনলক করার চেষ্টা করেছেন। আরও <xliff:g id="NUMBER_1">%2$d</xliff:g> বার এটি করলে আপনাকে প্যাটার্ন আনলক করতে একটি ইমেল অ্যাকাউন্ট ব্যবহারের করতে বলা হবে।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> সেকেন্ড পরে আবার চেষ্টা করুন।"</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"ফোন গরম হওয়ার জন্য বন্ধ হয়ে গেছে"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"ডিভাইস গরম হওয়ার জন্য বন্ধ হয়ে গেছে"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"ট্যাবলেট গরম হওয়ার জন্য বন্ধ হয়ে গেছে"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"আপনার ফোন এখন ভালভাবে কাজ করছে।\nআরও তথ্যের জন্য ট্যাপ করুন"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"আপনার ডিভাইস এখন ভালভাবে কাজ করছে।\nআরও তথ্যের জন্য ট্যাপ করুন"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"আপনার ট্যাবলেট এখন ভালভাবে কাজ করছে।\nআরও তথ্যের জন্য ট্যাপ করুন"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"আপনার ফোন খুব বেশি গরম হয়ে যায়, তাই ঠাণ্ডা হওয়ার জন্য বন্ধ হয়ে গেছে। আপনার ফোন এখন ভালভাবে কাজ করছে।\n\nআপনার ফোন খুব বেশি গরম হয়ে যেতে পারে যদি আপনি:\n	•এমন অ্যাপ ব্যবহার করেন যেটি আপনার ফোনের রিসোর্স বেশি ব্যবহার করে (যেমন গেমিং, ভিডিও বা নেভিগেশন অ্যাপ)\n	• বড় ফাইল ডাউনলোড বা আপলোড করেন\n	• অনেক বেশি তাপমাত্রায় ফোন ব্যবহার করেন"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"আপনার ডিভাইস খুব বেশি গরম হয়ে যায়, তাই ঠাণ্ডা হওয়ার জন্য বন্ধ হয়ে গেছে। আপনার ডিভাইস এখন ভালভাবে কাজ করছে।\n\nআপনার ডিভাইস খুব বেশি গরম হয়ে যেতে পারে যদি আপনি:\n	•এমন অ্যাপ ব্যবহার করেন যেটি আপনার ডিভাইসের রিসোর্স বেশি ব্যবহার করে (যেমন গেমিং, ভিডিও বা নেভিগেশন অ্যাপ)\n	• বড় ফাইল ডাউনলোড বা আপলোড করেন\n	• অনেক বেশি তাপমাত্রায় ডিভাইস ব্যবহার করেন"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"আপনার ট্যাবলেট খুব বেশি গরম হয়ে যায়, তাই ঠাণ্ডা হওয়ার জন্য বন্ধ হয়ে গেছে। আপনার ট্যাবলেট এখন ভালভাবে কাজ করছে।\n\nআপনার ট্যাবলেট খুব বেশি গরম হয়ে যেতে পারে যদি আপনি:\n	•এমন অ্যাপ ব্যবহার করেন যেটি আপনার ট্যাবলেটের রিসোর্স বেশি ব্যবহার করে (যেমন গেমিং, ভিডিও বা নেভিগেশন অ্যাপ)\n	• বড় ফাইল ডাউনলোড বা আপলোড করেন\n	• অনেক বেশি তাপমাত্রায় ট্যাবলেট ব্যবহার করেন"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"ফোন গরম হয়ে গেছে"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"ডিভাইস গরম হয়ে গেছে"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"ট্যাবলেট গরম হয়ে গেছে"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"ফোন ঠাণ্ডা না হওয়া পর্যন্ত কিছু ফিচার কাজ করতে পারে না।\nআরও তথ্যের জন্য ট্যাপ করুন"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"ডিভাইস ঠাণ্ডা না হওয়া পর্যন্ত কিছু ফিচার কাজ করতে পারে না।\nআরও তথ্যের জন্য ট্যাপ করুন"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"ট্যাবলেট ঠাণ্ডা না হওয়া পর্যন্ত কিছু ফিচার কাজ করতে পারে না।\nআরও তথ্যের জন্য ট্যাপ করুন"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"আপনার ফোনটি অটোমেটিক ঠাণ্ডা হওয়ার চেষ্টা করবে। আপনি তবুও ফোন ব্যবহার করতে পারেন, কিন্তু এটি একটু ধীরে চলতে পারে।\n\nফোন পুরোপুরি ঠাণ্ডা হয়ে গেলে, এটি ভালভাবে চলবে।"</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"আপনার ডিভাইস অটোমেটিক ঠাণ্ডা হওয়ার চেষ্টা করবে। আপনি তবুও ডিভাইস ব্যবহার করতে পারবেন, কিন্তু এটি একটু ধীরে চলতে পারে।\n\nডিভাইস পুরোপুরি ঠাণ্ডা হয়ে গেলে, এটি ভালভাবে চলবে।"</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"আপনার ট্যাবলেট অটোমেটিক ঠাণ্ডা হওয়ার চেষ্টা করবে। আপনি তবুও ট্যাবলেট ব্যবহার করতে পারবেন, কিন্তু এটি একটু ধীরে চলতে পারে।\n\nট্যাবলেট পুরোপুরি ঠাণ্ডা হয়ে গেলে, এটি ভালভাবে চলবে।"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"\'পাওয়ার\' বোতামের উপরে ফিঙ্গারপ্রিন্ট সেন্সর দেওয়া হয়েছে। ট্যাবলেটের প্রান্তে একটু বাইরে বেরিয়ে থাকা ভলিউমের বোতামের ঠিক পাশে এই ফ্ল্যাট বোতামটি আপনি খুঁজে পাবেন।"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"\'পাওয়ার\' বোতামের উপরে ফিঙ্গারপ্রিন্ট সেন্সর দেওয়া হয়েছে। ডিভাইসের সাইডে একটু বাইরে বেরিয়ে থাকা ভলিউমের বোতামের ঠিক পাশে এই ফ্ল্যাট বোতামটি আপনি খুঁজে পাবেন।"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"\'পাওয়ার\' বোতামের উপরে ফিঙ্গারপ্রিন্ট সেন্সর দেওয়া হয়েছে। ফোনের প্রান্তে একটু বাইরে বেরিয়ে থাকা ভলিউমের বোতামের ঠিক পাশে এই ফ্ল্যাট বোতামটি আপনি খুঁজে পাবেন।"</string>
diff --git a/packages/SystemUI/res-product/values-bs/strings.xml b/packages/SystemUI/res-product/values-bs/strings.xml
index 576fac4..1c1316f 100644
--- a/packages/SystemUI/res-product/values-bs/strings.xml
+++ b/packages/SystemUI/res-product/values-bs/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Pokušali ste neispravno otključati telefon <xliff:g id="NUMBER">%d</xliff:g> puta. Radni profil će se ukloniti i svi podaci s profila će se izbrisati."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Pogrešno ste nacrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, od vas će se tražiti da otključate tablet pomoću računa e-pošte. \n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Pogrešno ste nacrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, od vas će se tražiti da otključate telefon pomoću računa e-pošte. \n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Telefon se isključio zbog pregrijavanja"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Uređaj se isključio zbog pregrijavanja"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tablet se isključio zbog pregrijavanja"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Vaš telefon sada radi normalno.\nDodirnite za više informacija"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Vaš uređaj sada radi normalno.\nDodirnite za više informacija"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Vaš tablet sada radi normalno.\nDodirnite za više informacija"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Vaš telefon se pregrijao, pa se isključio da se ohladi. Telefon sada radi normalno.\n\nTelefon se može pregrijati ako:\n	• koristite aplikacije koje troše puno resursa (kao što su aplikacije za igranje, videozapise ili navigaciju)\n	• preuzimate ili otpremate velike fajlove\n	• koristite telefon na visokim temperaturama"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Vaš uređaj se pregrijao, pa se isključio da se ohladi. Uređaj sada radi normalno.\n\nUređaj se može pregrijati ako:\n	• koristite aplikacije koje troše puno resursa (kao što su aplikacije za igranje, videozapise ili navigaciju)\n	• preuzimate ili otpremate velike fajlove\n	• koristite uređaj na visokim temperaturama"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Vaš tablet se pregrijao, pa se isključio da se ohladi. Tablet sada radi normalno.\n\nTablet se može pregrijati ako:\n	• koristite aplikacije koje troše puno resursa (kao što su aplikacije za igranje, videozapise ili navigaciju)\n	• preuzimate ili otpremate velike fajlove\n	• koristite tablet na visokim temperaturama"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Telefon se zagrijava"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Uređaj se zagrijava"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Tablet se zagrijava"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Neke funkcije su ograničene dok se telefon hladi.\nDodirnite za više informacija"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Neke funkcije su ograničene dok se uređaj hladi.\nDodirnite za više informacija"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Neke funkcije su ograničene dok se tablet hladi.\nDodirnite za više informacija"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Vaš telefon će se automatski pokušati ohladiti. I dalje možete koristiti telefon, ali će možda sporije raditi.\n\nNakon što se ohladi, telefon će raditi normalno."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Uređaj će se automatski pokušati ohladiti. I dalje možete koristiti uređaj, ali će možda sporije raditi.\n\nNakon što se ohladi, uređaj će raditi normalno."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Tablet će se automatski pokušati ohladiti. I dalje možete koristiti tablet, ali će možda sporije raditi.\n\nNakon što se ohladi, tablet će raditi normalno."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Senzor za otisak prsta je na dugmetu za uključivanje. To je ravno dugme pored izdignutog dugmeta za jačinu zvuka na rubu tableta."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Senzor za otisak prsta je na dugmetu za uključivanje. To je ravno dugme pored izdignutog dugmeta za jačinu zvuka na rubu uređaja."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Senzor za otisak prsta je na dugmetu za uključivanje. To je ravno dugme pored izdignutog dugmeta za jačinu zvuka na rubu telefona."</string>
diff --git a/packages/SystemUI/res-product/values-ca/strings.xml b/packages/SystemUI/res-product/values-ca/strings.xml
index d8d4a47..4b84a6b 100644
--- a/packages/SystemUI/res-product/values-ca/strings.xml
+++ b/packages/SystemUI/res-product/values-ca/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. El perfil de treball se suprimirà, juntament amb totes les dades que contingui."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, se\'t demanarà que desbloquegis la tauleta amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%3$d</xliff:g> segons."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, se\'t demanarà que desbloquegis el telèfon amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%3$d</xliff:g> segons."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"El telèfon s\'ha apagat per la calor"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"El dispositiu s\'ha apagat per la calor"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"La tauleta s\'ha apagat per la calor"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Ara el telèfon funciona amb normalitat.\nToca per obtenir més informació."</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Ara el dispositiu funciona amb normalitat.\nToca per obtenir més informació."</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Ara la tauleta funciona amb normalitat.\nToca per obtenir més informació."</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"El telèfon s\'havia sobreescalfat i s\'ha apagat per refredar-se. Ara funciona amb normalitat.\n\nEs pot sobreescalfar si:\n	• Utilitzes aplicacions que consumeixen molts recursos (com ara, videojocs, vídeos o aplicacions de navegació).\n	• Baixes o penges fitxers grans.\n	• L\'utilitzes amb temperatures altes."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"El dispositiu s\'havia sobreescalfat i s\'ha apagat per refredar-se. Ara funciona amb normalitat.\n\nEs pot sobreescalfar si:\n	• Utilitzes aplicacions que consumeixen molts recursos (com ara videojocs, vídeos o aplicacions de navegació).\n	• Baixes o penges fitxers grans.\n	• L\'utilitzes amb temperatures altes."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"La tauleta s\'havia sobreescalfat i s\'ha apagat per refredar-se. Ara funciona amb normalitat.\n\nEs pot sobreescalfar si:\n	• Utilitzes aplicacions que consumeixen molts recursos (com ara videojocs, vídeos o aplicacions de navegació).\n	• Baixes o penges fitxers grans.\n	• L\'utilitzes amb temperatures altes."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"El telèfon s\'està escalfant"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"El dispositiu s\'està escalfant"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"La tauleta s\'està escalfant"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Algunes funcions estan limitades mentre el telèfon es refreda.\nToca per obtenir més informació."</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Algunes funcions estan limitades mentre el dispositiu es refreda.\nToca per obtenir més informació."</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Algunes funcions estan limitades mentre la tauleta es refreda.\nToca per obtenir més informació."</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"El telèfon provarà de refredar-se automàticament. Podràs continuar utilitzant-lo, però és possible que funcioni més lentament.\n\nUn cop s\'hagi refredat, funcionarà amb normalitat."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"El dispositiu provarà de refredar-se automàticament. Pots continuar utilitzant-lo, però és possible que funcioni més lentament.\n\nUn cop s\'hagi refredat, funcionarà amb normalitat."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"La tauleta provarà de refredar-se automàticament. Pots continuar utilitzant-la, però és possible que funcioni més lentament.\n\nUn cop s\'hagi refredat, funcionarà amb normalitat."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"El sensor d\'empremtes digitals es troba al botó d\'engegada. És el botó pla situat al costat del botó de volum amb relleu al lateral de la tauleta."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"El sensor d\'empremtes digitals es troba al botó d\'engegada. És el botó pla situat al costat del botó de volum amb relleu al lateral del dispositiu."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"El sensor d\'empremtes digitals es troba al botó d\'engegada. És el botó pla situat al costat del botó de volum amb relleu al lateral del telèfon."</string>
diff --git a/packages/SystemUI/res-product/values-cs/strings.xml b/packages/SystemUI/res-product/values-cs/strings.xml
index 47881bd..ffefb98 100644
--- a/packages/SystemUI/res-product/values-cs/strings.xml
+++ b/packages/SystemUI/res-product/values-cs/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Již <xliff:g id="NUMBER">%d</xliff:g>krát jste se pokusili odemknout telefon nesprávným způsobem. Pracovní profil bude odstraněn, čímž budou smazána všechna jeho data."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Již <xliff:g id="NUMBER_0">%1$d</xliff:g>krát jste nesprávně zadali své bezpečnostní gesto. Po <xliff:g id="NUMBER_1">%2$d</xliff:g>dalších neúspěšných pokusech budete požádáni o odemčení tabletu pomocí e-mailového účtu.\n\n Zkuste to znovu za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Již <xliff:g id="NUMBER_0">%1$d</xliff:g>krát jste nesprávně zadali své bezpečnostní gesto. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> dalších neúspěšných pokusech budete požádáni o odemčení telefonu pomocí e-mailového účtu.\n\n Zkuste to znovu za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Telefon se vypnul z důvodu zahřátí"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Zařízení se vypnulo z důvodu zahřátí"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tablet se vypnul z důvodu zahřátí"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Nyní telefon funguje jako obvykle.\nKlepnutím zobrazíte další informace"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Nyní zařízení funguje jako obvykle.\nKlepnutím zobrazíte další informace"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Nyní tablet funguje jako obvykle.\nKlepnutím zobrazíte další informace"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Telefon byl příliš zahřátý, proto se vypnul, aby vychladl. Nyní telefon funguje jako obvykle.\n\nTelefon se může příliš zahřát v těchto případech:\n	• používání náročných aplikací (např. her, videí nebo navigace),\n	• stahování nebo nahrávání velkých souborů,\n	• používání telefonu při vysokých teplotách."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Zařízení bylo příliš zahřáté, proto se vypnulo, aby vychladlo. Nyní zařízení funguje jako obvykle.\n\nZařízení se může příliš zahřát v těchto případech:\n	• používání náročných aplikací (např. her, videí nebo navigace),\n	• stahování nebo nahrávání velkých souborů,\n	• používání zařízení při vysokých teplotách."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Tablet byl příliš zahřátý, proto se vypnul, aby vychladl. Nyní tablet funguje jako obvykle.\n\nTablet se může příliš zahřát v těchto případech:\n	• používání náročných aplikací (např. her, videí nebo navigace),\n	• stahování nebo nahrávání velkých souborů,\n	• používání tabletu při vysokých teplotách."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Telefon se zahřívá"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Zařízení se zahřívá"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Tablet se zahřívá"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Některé funkce jsou při chladnutí telefonu omezeny.\nKlepnutím zobrazíte další informace"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Některé funkce jsou při chladnutí zařízení omezeny.\nKlepnutím zobrazíte další informace"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Některé funkce jsou při chladnutí tabletu omezeny.\nKlepnutím zobrazíte další informace"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Telefon se automaticky pokusí vychladnout. Lze jej nadále používat, ale může být pomalejší.\n\nAž telefon vychladne, bude fungovat normálně."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Zařízení se automaticky pokusí vychladnout. Lze jej nadále používat, ale může být pomalejší.\n\nAž zařízení vychladne, bude fungovat normálně."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Tablet se automaticky pokusí vychladnout. Lze jej nadále používat, ale může být pomalejší.\n\nAž tablet vychladne, bude fungovat normálně."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Snímač otisků prstů je na vypínači. Je to ploché tlačítko vedle vystouplého tlačítka hlasitosti na hraně tabletu."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Snímač otisků prstů je na vypínači. Je to ploché tlačítko vedle vystouplého tlačítka hlasitosti na hraně zařízení."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Snímač otisků prstů je na vypínači. Je to ploché tlačítko vedle vystouplého tlačítka hlasitosti na hraně telefonu."</string>
diff --git a/packages/SystemUI/res-product/values-da/strings.xml b/packages/SystemUI/res-product/values-da/strings.xml
index 47531e7..9bed837 100644
--- a/packages/SystemUI/res-product/values-da/strings.xml
+++ b/packages/SystemUI/res-product/values-da/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Du har forsøgt at låse telefonen op med den forkerte adgangskode <xliff:g id="NUMBER">%d</xliff:g> gange. Arbejdsprofilen fjernes, hvilket sletter alle profildata."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter endnu <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøg bliver du bedt om at låse din tablet op ved hjælp af en mailkonto.\n\n Prøv igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter endnu <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøg bliver du bedt om at låse din telefon op ved hjælp af en mailkonto.\n\n Prøv igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Telefonen slukkede pga. varme"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Enheden slukkede pga. varme"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Din tablet slukkede pga. varme"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Din telefon kører nu normalt.\nTryk for at få flere oplysninger"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Din enhed kører nu normalt.\nTryk for at få flere oplysninger"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Din tablet kører nu normalt.\nTryk for at få flere oplysninger"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Din telefon var blevet for varm, så den slukkede for at køle ned. Din telefon kører nu igen normalt. \n\nDin telefon kan blive for varm, hvis du:\n	• Bruger ressourcekrævende apps (f.eks. spil, video eller navigation)\n	• Downloader eller uploader store filer\n	• Bruger din telefon i varme omgivelser"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Din enhed var blevet for varm, så den slukkede for at køle ned. Din enhed kører nu igen normalt. \n\nDin enhed kan blive for varm, hvis du:\n	• Bruger ressourcekrævende apps (f.eks. spil, video eller navigation)\n	• Downloader eller uploader store filer\n	• Bruger din enhed i varme omgivelser"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Din tablet var blevet for varm, så den slukkede for at køle ned. Din tablet kører nu igen normalt. \n\nDin tablet kan blive for varm, hvis du:\n	• Bruger ressourcekrævende apps (f.eks. spil, video eller navigation)\n	• Downloader eller uploader store filer\n	• Bruger din tablet i varme omgivelser"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Telefonen er ved at blive varm"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Enheden er ved at blive varm"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Tabletten er ved at blive varm"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Nogle funktioner er begrænsede, mens telefonen køler ned.\nTryk for at få flere oplysninger"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Nogle funktioner er begrænsede, mens enheden køler ned.\nTryk for at få flere oplysninger"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Nogle funktioner er begrænsede, mens din tablet køler ned.\nTryk for at få flere oplysninger"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Din telefon forsøger automatisk at køle sig selv ned. Du kan stadig bruge telefonen, men den kører muligvis langsommere end normalt.\n\nNår din telefon er kølet ned, fungerer den normalt igen."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Din enhed forsøger automatisk at køle sig selv ned. Du kan stadig bruge din enhed, men den kører muligvis langsommere end normalt.\n\nNår din enhed er kølet ned, fungerer den normalt igen."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Din tablet forsøger automatisk at køle sig selv ned. Du kan stadig bruge din tablet, men den kører muligvis langsommere end normalt.\n\nNår din tablet er kølet ned, fungerer den normalt igen."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Fingeraftrykssensoren sidder på afbryderknappen. Det er den flade knap ved siden af den hævede lydstyrkeknap på siden af din tablet."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Fingeraftrykssensoren sidder på afbryderknappen. Det er den flade knap ved siden af den hævede lydstyrkeknap på siden af enheden."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Fingeraftrykssensoren sidder på afbryderknappen. Det er den flade knap ved siden af den hævede lydstyrkeknap på siden af telefonen."</string>
diff --git a/packages/SystemUI/res-product/values-de/strings.xml b/packages/SystemUI/res-product/values-de/strings.xml
index 9c0b768..80389a4 100644
--- a/packages/SystemUI/res-product/values-de/strings.xml
+++ b/packages/SystemUI/res-product/values-de/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Du hast <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Smartphone zu entsperren. Das Arbeitsprofil wird nun entfernt und alle Profildaten werden gelöscht."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Du hast dein Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wirst du aufgefordert, dein Tablet mithilfe eines E-Mail-Kontos zu entsperren.\n\n Versuche es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden noch einmal."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Du hast dein Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wirst du aufgefordert, dein Smartphone mithilfe eines E-Mail-Kontos zu entsperren.\n\n Versuche es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden noch einmal."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Smartphone wegen Überhitzung ausgeschaltet"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Gerät wegen Überhitzung ausgeschaltet"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tablet wegen Überhitzung ausgeschaltet"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Dein Smartphone funktioniert jetzt wieder normal.\nFür mehr Informationen tippen."</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Dein Gerät funktioniert jetzt wieder normal.\nFür mehr Informationen tippen."</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Dein Tablet funktioniert jetzt wieder normal.\nFür mehr Informationen tippen."</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Dein Smartphone war zu heiß und wurde zum Abkühlen ausgeschaltet. Nun funktioniert es wieder normal.\n\nMögliche Ursachen:\n	• Verwendung ressourcenintensiver Apps, z. B. Spiele-, Video- oder Navigations-Apps\n	• Download oder Upload großer Dateien\n	• Verwendung des Smartphones bei hohen Temperaturen"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Dein Gerät war zu heiß und wurde zum Abkühlen ausgeschaltet. Nun funktioniert es wieder normal.\n\nMögliche Ursachen:\n	• Verwendung ressourcenintensiver Apps, z. B. Spiele-, Video- oder Navigations-Apps\n	• Download oder Upload großer Dateien\n	• Verwendung des Geräts bei hohen Temperaturen"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Dein Tablet war zu heiß und wurde zum Abkühlen ausgeschaltet. Nun funktioniert es wieder normal.\n\nMögliche Ursachen:\n	• Verwendung ressourcenintensiver Apps, z. B. Spiele-, Video- oder Navigations-Apps\n	• Download oder Upload großer Dateien\n	• Verwendung des Tablets bei hohen Temperaturen"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Smartphone wird warm"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Gerät wird warm"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Tablet wird warm"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Einige Funktionen sind während der Abkühlphase des Smartphones eingeschränkt.\nFür mehr Informationen tippen."</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Einige Funktionen sind während der Abkühlphase des Geräts eingeschränkt.\nFür mehr Informationen tippen."</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Einige Funktionen sind während der Abkühlphase des Tablets eingeschränkt.\nFür mehr Informationen tippen."</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Dein Smartphone kühlt sich automatisch ab. Du kannst es weiterhin nutzen, aber es reagiert möglicherweise langsamer.\n\nSobald dein Smartphone abgekühlt ist, funktioniert es wieder normal."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Dein Gerät kühlt sich automatisch ab. Du kannst es weiterhin nutzen, aber es reagiert möglicherweise langsamer.\n\nSobald dein Gerät abgekühlt ist, funktioniert es wieder normal."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Dein Tablet kühlt sich automatisch ab. Du kannst es weiterhin nutzen, aber es reagiert möglicherweise langsamer.\n\nSobald dein Tablet abgekühlt ist, funktioniert es wieder normal."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Der Fingerabdrucksensor befindet sich auf der Ein-/Aus-Taste. Das ist die flache Taste neben der erhöhten Lautstärketaste am Rand des Tablets."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Der Fingerabdrucksensor befindet sich auf der Ein-/Aus-Taste. Das ist die flache Taste neben der erhöhten Lautstärketaste am Rand des Geräts."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Der Fingerabdrucksensor befindet sich auf der Ein-/Aus-Taste. Das ist die flache Taste neben der erhöhten Lautstärketaste am Rand des Smartphones."</string>
diff --git a/packages/SystemUI/res-product/values-el/strings.xml b/packages/SystemUI/res-product/values-el/strings.xml
index 139fa04..67bdbcf 100644
--- a/packages/SystemUI/res-product/values-el/strings.xml
+++ b/packages/SystemUI/res-product/values-el/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Δοκιμάσατε να ξεκλειδώσετε το τηλέφωνο <xliff:g id="NUMBER">%d</xliff:g> φορές χωρίς επιτυχία. Το προφίλ εργασίας θα καταργηθεί και θα διαγραφούν όλα τα δεδομένα προφίλ."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%1$d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%2$d</xliff:g> ακόμα ανεπιτυχείς προσπάθειες, θα σας ζητηθεί να ξεκλειδώσετε το tablet με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου.\n\n Δοκιμάστε να συνδεθείτε ξανά σε <xliff:g id="NUMBER_2">%3$d</xliff:g> δευτερόλεπτα."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%1$d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%2$d</xliff:g> ακόμα ανεπιτυχείς προσπάθειες, θα σας ζητηθεί να ξεκλειδώσετε το τηλέφωνό σας με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου.\n\n Δοκιμάστε ξανά σε <xliff:g id="NUMBER_2">%3$d</xliff:g> δευτερόλεπτα."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Το τηλέφωνο απενεργοποιήθηκε λόγω ζέστης"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Η συσκευή απενεργοποιήθηκε λόγω ζέστης"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Το tablet απενεργοποιήθηκε λόγω ζέστης"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Το τηλέφωνο λειτουργεί πλέον κανονικά.\nΠατήστε για περισσότερες πληροφορίες"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Η συσκευή λειτουργεί πλέον κανονικά.\nΠατήστε για περισσότερες πληροφορίες"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Το tablet λειτουργεί πλέον κανονικά.\nΠατήστε για περισσότερες πληροφορίες"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Η θερμοκρασία του τηλεφώνου είναι πολύ υψηλή και απενεργοποιήθηκε για να κρυώσει. Πλέον, το τηλέφωνο λειτουργεί κανονικά.\n\nΗ θερμοκρασία του τηλεφώνου ενδέχεται να ανέβει κατά τη:\n	• Χρήση εφαρμογών υψηλής κατανάλωσης πόρων (όπως gaming, βίντεο ή περιήγησης)\n	• Λήψη ή μεταφόρτωση μεγάλων αρχείων\n	• Χρήση του τηλεφώνου σε υψηλές θερμοκρασίες"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Η θερμοκρασία της συσκευής είναι πολύ υψηλή και απενεργοποιήθηκε για να κρυώσει. Πλέον, η συσκευή λειτουργεί κανονικά.\n\nΗ θερμοκρασία της συσκευής ενδέχεται να ανέβει κατά τη:\n	• Χρήση εφαρμογών υψηλής κατανάλωσης πόρων (όπως gaming, βίντεο ή περιήγησης)\n	• Λήψη ή μεταφόρτωση μεγάλων αρχείων\n	• Χρήση της συσκευής σε υψηλές θερμοκρασίες"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Η θερμοκρασία του tablet είναι πολύ υψηλή και απενεργοποιήθηκε για να κρυώσει. Πλέον, το tablet λειτουργεί κανονικά.\n\nΗ θερμοκρασία του tablet ενδέχεται να ανέβει κατά τη:\n	• Χρήση εφαρμογών υψηλής κατανάλωσης πόρων (όπως gaming, βίντεο ή περιήγησης)\n	• Λήψη ή μεταφόρτωση μεγάλων αρχείων\n	• Χρήση του tablet σε υψηλές θερμοκρασίες"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Το τηλέφωνο θερμαίνεται"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Η συσκευή θερμαίνεται"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Το tablet θερμαίνεται"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Ορισμένες λειτουργίες περιορίζονται κατά τη μείωση της θερμοκρασίας του τηλεφώνου.\nΠατήστε για περισσότερες πληροφορίες"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Ορισμένες λειτουργίες περιορίζονται κατά τη μείωση της θερμοκρασίας της συσκευής.\nΠατήστε για περισσότερες πληροφορίες"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Ορισμένες λειτουργίες περιορίζονται κατά τη μείωση της θερμοκρασίας του tablet.\nΠατήστε για περισσότερες πληροφορίες"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Το τηλέφωνό σας θα προσπαθήσει αυτόματα να κρυώσει. Μπορείτε να εξακολουθήσετε να το χρησιμοποιείτε, αλλά είναι πιθανό να λειτουργεί πιο αργά.\n\nΜόλις μειωθεί η θερμοκρασία του τηλεφώνου σας, θα λειτουργεί ξανά κανονικά."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Η συσκευή σας θα προσπαθήσει αυτόματα να κρυώσει. Μπορείτε να εξακολουθήσετε να τη χρησιμοποιείτε, αλλά είναι πιθανό να λειτουργεί πιο αργά.\n\nΜόλις μειωθεί η θερμοκρασία της συσκευής σας, θα λειτουργεί ξανά κανονικά."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Το tablet σας θα προσπαθήσει αυτόματα να κρυώσει. Μπορείτε να εξακολουθήσετε να το χρησιμοποιείτε, αλλά είναι πιθανό να λειτουργεί πιο αργά.\n\nΜόλις μειωθεί η θερμοκρασία του tablet σας, θα λειτουργεί ξανά κανονικά."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Ο αισθητήρας δακτυλικών αποτυπωμάτων βρίσκεται στο κουμπί λειτουργίας. Είναι το επίπεδο κουμπί δίπλα στο ανυψωμένο κουμπί έντασης ήχου στο άκρο του tablet."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Ο αισθητήρας δακτυλικών αποτυπωμάτων βρίσκεται στο κουμπί λειτουργίας. Είναι το επίπεδο κουμπί δίπλα στο ανυψωμένο κουμπί έντασης ήχου στο άκρο της συσκευής."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Ο αισθητήρας δακτυλικών αποτυπωμάτων βρίσκεται στο κουμπί λειτουργίας. Είναι το επίπεδο κουμπί δίπλα στο ανυψωμένο κουμπί έντασης ήχου στο άκρο του τηλεφώνου."</string>
diff --git a/packages/SystemUI/res-product/values-en-rAU/strings.xml b/packages/SystemUI/res-product/values-en-rAU/strings.xml
index 6356fc2..1373251 100644
--- a/packages/SystemUI/res-product/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res-product/values-en-rAU/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Phone turned off due to heat"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Device turned off due to heat"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tablet turned off due to heat"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Your phone is now running normally.\nTap for more info"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Your device is now running normally.\nTap for more info"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Your tablet is now running normally.\nTap for more info"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Your phone was too hot, so it turned off to cool down. Your phone is now running normally.\n\nYour phone may get too hot if you:\n	• Use resource-intensive apps (such as gaming, video or navigation apps)\n	• Download or upload large files\n	• Use your phone in high temperatures"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Your device was too hot, so it turned off to cool down. Your device is now running normally.\n\nYour device may get too hot if you:\n	• Use resource-intensive apps (such as gaming, video or navigation apps)\n	• Download or upload large files\n	• Use your device in high temperatures"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Your tablet was too hot, so it turned off to cool down. Your tablet is now running normally.\n\nYour tablet may get too hot if you:\n	• Use resource-intensive apps (such as gaming, video or navigation apps)\n	• Download or upload large files\n	• Use your tablet in high temperatures"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Phone is getting warm"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Device is getting warm"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Tablet is getting warm"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Some features limited while phone cools down.\nTap for more info"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Some features limited while device cools down.\nTap for more info"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Some features limited while tablet cools down.\nTap for more info"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Your phone will automatically try to cool down. You can still use your phone, but it may run more slowly.\n\nOnce your phone has cooled down, it will run normally."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Your device will automatically try to cool down. You can still use your device, but it may run slower.\n\nOnce your device has cooled down, it will run normally."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Your tablet will automatically try to cool down. You can still use your tablet, but it may run slower.\n\nOnce your tablet has cooled down, it will run normally."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the tablet."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the device."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the phone."</string>
diff --git a/packages/SystemUI/res-product/values-en-rCA/strings.xml b/packages/SystemUI/res-product/values-en-rCA/strings.xml
index fb7aa72..eaa5de0 100644
--- a/packages/SystemUI/res-product/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res-product/values-en-rCA/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Phone turned off due to heat"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Device turned off due to heat"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tablet turned off due to heat"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Your phone is now running normally.\nTap for more info"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Your device is now running normally.\nTap for more info"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Your tablet is now running normally.\nTap for more info"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Your phone was too hot, so it turned off to cool down. Your phone is now running normally.\n\nYour phone may get too hot if you:\n	• Use resource-intensive apps (such as gaming, video, or navigation apps)\n	• Download or upload large files\n	• Use your phone in high temperatures"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Your device was too hot, so it turned off to cool down. Your device is now running normally.\n\nYour device may get too hot if you:\n	• Use resource-intensive apps (such as gaming, video, or navigation apps)\n	• Download or upload large files\n	• Use your device in high temperatures"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Your tablet was too hot, so it turned off to cool down. Your tablet is now running normally.\n\nYour tablet may get too hot if you:\n	• Use resource-intensive apps (such as gaming, video, or navigation apps)\n	• Download or upload large files\n	• Use your tablet in high temperatures"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Phone is getting warm"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Device is getting warm"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Tablet is getting warm"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Some features limited while phone cools down.\nTap for more info"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Some features limited while device cools down.\nTap for more info"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Some features limited while tablet cools down.\nTap for more info"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Your phone will automatically try to cool down. You can still use your phone, but it may run slower.\n\nOnce your phone has cooled down, it will run normally."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Your device will automatically try to cool down. You can still use your device, but it may run slower.\n\nOnce your device has cooled down, it will run normally."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Your tablet will automatically try to cool down. You can still use your tablet, but it may run slower.\n\nOnce your tablet has cooled down, it will run normally."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"The fingerprint sensor is on the power button. It\'s the flat button next to the raised volume button on the edge of the tablet."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"The fingerprint sensor is on the power button. It\'s the flat button next to the raised volume button on the edge of the device."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"The fingerprint sensor is on the power button. It\'s the flat button next to the raised volume button on the edge of the phone."</string>
diff --git a/packages/SystemUI/res-product/values-en-rGB/strings.xml b/packages/SystemUI/res-product/values-en-rGB/strings.xml
index 6356fc2..1373251 100644
--- a/packages/SystemUI/res-product/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res-product/values-en-rGB/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Phone turned off due to heat"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Device turned off due to heat"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tablet turned off due to heat"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Your phone is now running normally.\nTap for more info"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Your device is now running normally.\nTap for more info"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Your tablet is now running normally.\nTap for more info"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Your phone was too hot, so it turned off to cool down. Your phone is now running normally.\n\nYour phone may get too hot if you:\n	• Use resource-intensive apps (such as gaming, video or navigation apps)\n	• Download or upload large files\n	• Use your phone in high temperatures"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Your device was too hot, so it turned off to cool down. Your device is now running normally.\n\nYour device may get too hot if you:\n	• Use resource-intensive apps (such as gaming, video or navigation apps)\n	• Download or upload large files\n	• Use your device in high temperatures"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Your tablet was too hot, so it turned off to cool down. Your tablet is now running normally.\n\nYour tablet may get too hot if you:\n	• Use resource-intensive apps (such as gaming, video or navigation apps)\n	• Download or upload large files\n	• Use your tablet in high temperatures"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Phone is getting warm"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Device is getting warm"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Tablet is getting warm"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Some features limited while phone cools down.\nTap for more info"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Some features limited while device cools down.\nTap for more info"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Some features limited while tablet cools down.\nTap for more info"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Your phone will automatically try to cool down. You can still use your phone, but it may run more slowly.\n\nOnce your phone has cooled down, it will run normally."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Your device will automatically try to cool down. You can still use your device, but it may run slower.\n\nOnce your device has cooled down, it will run normally."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Your tablet will automatically try to cool down. You can still use your tablet, but it may run slower.\n\nOnce your tablet has cooled down, it will run normally."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the tablet."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the device."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the phone."</string>
diff --git a/packages/SystemUI/res-product/values-en-rIN/strings.xml b/packages/SystemUI/res-product/values-en-rIN/strings.xml
index 6356fc2..1373251 100644
--- a/packages/SystemUI/res-product/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res-product/values-en-rIN/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Phone turned off due to heat"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Device turned off due to heat"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tablet turned off due to heat"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Your phone is now running normally.\nTap for more info"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Your device is now running normally.\nTap for more info"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Your tablet is now running normally.\nTap for more info"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Your phone was too hot, so it turned off to cool down. Your phone is now running normally.\n\nYour phone may get too hot if you:\n	• Use resource-intensive apps (such as gaming, video or navigation apps)\n	• Download or upload large files\n	• Use your phone in high temperatures"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Your device was too hot, so it turned off to cool down. Your device is now running normally.\n\nYour device may get too hot if you:\n	• Use resource-intensive apps (such as gaming, video or navigation apps)\n	• Download or upload large files\n	• Use your device in high temperatures"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Your tablet was too hot, so it turned off to cool down. Your tablet is now running normally.\n\nYour tablet may get too hot if you:\n	• Use resource-intensive apps (such as gaming, video or navigation apps)\n	• Download or upload large files\n	• Use your tablet in high temperatures"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Phone is getting warm"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Device is getting warm"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Tablet is getting warm"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Some features limited while phone cools down.\nTap for more info"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Some features limited while device cools down.\nTap for more info"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Some features limited while tablet cools down.\nTap for more info"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Your phone will automatically try to cool down. You can still use your phone, but it may run more slowly.\n\nOnce your phone has cooled down, it will run normally."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Your device will automatically try to cool down. You can still use your device, but it may run slower.\n\nOnce your device has cooled down, it will run normally."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Your tablet will automatically try to cool down. You can still use your tablet, but it may run slower.\n\nOnce your tablet has cooled down, it will run normally."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the tablet."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the device."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the phone."</string>
diff --git a/packages/SystemUI/res-product/values-en-rXC/strings.xml b/packages/SystemUI/res-product/values-en-rXC/strings.xml
index 4a7d0ad..b1a5613 100644
--- a/packages/SystemUI/res-product/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res-product/values-en-rXC/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‏‏‎‎‎‎‎‎‎‏‏‏‏‎‎‎‏‏‎‏‎‏‏‎‎‏‏‎‎‎‎‎‏‎‎‏‏‎‏‏‎‎You have incorrectly attempted to unlock the phone ‎‏‎‎‏‏‎<xliff:g id="NUMBER">%d</xliff:g>‎‏‎‎‏‏‏‎ times. The work profile will be removed, which will delete all profile data.‎‏‎‎‏‎"</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‎‎‎‎‏‏‏‎‎‏‏‎‎‏‏‎‎‎‏‎‎‎‏‏‎‏‎‏‏‏‎‎‎‏‏‎‎‎‏‎‏‎‏‏‏‏‏‎‎‎‎You have incorrectly drawn your unlock pattern ‎‏‎‎‏‏‎<xliff:g id="NUMBER_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ times. After ‎‏‎‎‏‏‎<xliff:g id="NUMBER_1">%2$d</xliff:g>‎‏‎‎‏‏‏‎ more unsuccessful attempts, you will be asked to unlock your tablet using an email account.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎ Try again in ‎‏‎‎‏‏‎<xliff:g id="NUMBER_2">%3$d</xliff:g>‎‏‎‎‏‏‏‎ seconds.‎‏‎‎‏‎"</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‎‎‏‏‏‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‎‎‎‏‏‎‎‎‏‏‏‎‏‏‎‎‎‎‎‏‏‏‏‎‎‏‏‏‎‏‏‎‏‎You have incorrectly drawn your unlock pattern ‎‏‎‎‏‏‎<xliff:g id="NUMBER_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ times. After ‎‏‎‎‏‏‎<xliff:g id="NUMBER_1">%2$d</xliff:g>‎‏‎‎‏‏‏‎ more unsuccessful attempts, you will be asked to unlock your phone using an email account.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎ Try again in ‎‏‎‎‏‏‎<xliff:g id="NUMBER_2">%3$d</xliff:g>‎‏‎‎‏‏‏‎ seconds.‎‏‎‎‏‎"</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‏‎‎‏‎‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎‏‏‏‏‎‎‏‎‏‎‏‏‎‏‎‎‎‏‎Phone turned off due to heat‎‏‎‎‏‎"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‎‎‏‎‎‎‏‎‎‏‎‏‎‎‏‎‏‏‎‏‎‏‎‏‏‎‎‏‏‏‎‏‏‏‎‏‏‎Device turned off due to heat‎‏‎‎‏‎"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‏‏‏‎‏‏‏‎‏‎‎‏‏‏‏‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‏‏‎‏‎‏‏‏‎‏‏‏‏‏‎‏‎Tablet turned off due to heat‎‏‎‎‏‎"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‏‎‏‎‎‎‎‎‏‎‏‏‎‎‎‏‎‏‎‎‎‏‏‎‎‏‎‏‏‏‏‏‎‎‎‏‏‎‏‎‎‎‎‎Your phone is now running normally.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Tap for more info‎‏‎‎‏‎"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‎‏‏‏‏‎‎‎‏‏‎‎‎‏‏‎‎‏‎‏‎‏‎‏‏‏‏‎‎‎‏‏‎‎‏‎‏‎‏‎‎‏‏‏‎‏‏‎‎‏‏‏‎‎Your device is now running normally.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Tap for more info‎‏‎‎‏‎"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‏‎‏‏‎‏‏‎‏‎‎‏‎‎‎‎‏‎‎‏‎‏‎‏‏‏‏‏‎‎‎‏‎‎‏‎‏‏‎‏‎‏‎‎‏‏‎‎‏‏‏‏‎‏‎‎Your tablet is now running normally.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Tap for more info‎‏‎‎‏‎"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‎‏‎‏‎‏‎‏‏‎‏‎‎‏‏‏‎‏‏‎‎‏‎‏‏‏‎‏‏‏‏‏‎‏‏‎‎‎‏‎‏‏‏‎‎‎‏‏‎‏‎‏‎‎Your phone was too hot, so it turned off to cool down. Your phone is now running normally.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Your phone may get too hot if you:‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎	• Use resource-intensive apps (such as gaming, video, or navigation apps)‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎	• Download or upload large files‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎	• Use your phone in high temperatures‎‏‎‎‏‎"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‎‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‎‏‎‎‎‏‏‎‏‏‏‎‎‏‎‏‎‎‎‏‎‏‎Your device was too hot, so it turned off to cool down. Your device is now running normally.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Your device may get too hot if you:‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎	• Use resource-intensive apps (such as gaming, video, or navigation apps)‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎	• Download or upload large files‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎	• Use your device in high temperatures‎‏‎‎‏‎"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‎‏‏‏‎‎‎‏‎‏‏‎‏‎‎‏‏‎‎‏‎‏‎‎‎‎‏‎‏‎‎‎‎‎‏‏‏‎‏‎‏‎‏‎‏‎‏‎‏‎Your tablet was too hot, so it turned off to cool down. Your tablet is now running normally.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Your tablet may get too hot if you:‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎	• Use resource-intensive apps (such as gaming, video, or navigation apps)‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎	• Download or upload large files‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎	• Use your tablet in high temperatures‎‏‎‎‏‎"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‏‏‏‎‏‏‏‎‎‏‎‏‏‏‏‎‏‏‏‏‎‏‎‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‏‎‎‏‏‎Phone is getting warm‎‏‎‎‏‎"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‏‏‎‎‎‎‏‏‎‏‎‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‏‎‎‏‎‎‏‏‎‎‏‏‏‏‎‎‎‎‏‎‎‎‎‎Device is getting warm‎‏‎‎‏‎"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‏‎‎‏‎‏‎‏‏‏‏‎‏‎‎‏‎‏‎‏‏‏‏‎‎‏‏‎‎‏‏‏‎‎‎‎‏‎‎‎‎‎‎‏‏‎‎‎‎Tablet is getting warm‎‏‎‎‏‎"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‎‎‏‏‎‎‏‏‎‏‏‎‏‎‏‎‏‏‎‎‎‎‎‎‏‏‎‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‏‎‏‏‎‏‏‎‎‎Some features limited while phone cools down.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Tap for more info‎‏‎‎‏‎"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‏‎‎‏‏‏‎‎‎‎‏‏‏‎‎‎‏‎‏‎‏‏‏‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‎‎Some features limited while device cools down.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Tap for more info‎‏‎‎‏‎"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‏‎‎‏‏‎‏‏‎‎‎‏‏‎‏‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‏‎‎Some features limited while tablet cools down.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Tap for more info‎‏‎‎‏‎"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‎‎‏‏‎‎‎‏‎‏‎‎‏‏‏‏‏‎‏‎‏‎‏‎‏‎‏‏‎‎‎‏‏‎‎‏‏‎‎‏‎‎‏‎‏‎‎‏‏‎‏‎‎‏‎Your phone will automatically try to cool down. You can still use your phone, but it may run slower.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Once your phone has cooled down, it will run normally.‎‏‎‎‏‎"</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‎‏‎‎‏‎‏‏‎‏‏‎‏‎‎‎‎‏‎‏‎‎‎‏‏‏‏‏‎‎‎‎‎‏‏‎‎‎‏‏‏‎‏‎‏‎‎‏‏‎‏‏‎‎Your device will automatically try to cool down. You can still use your device, but it may run slower.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Once your device has cooled down, it will run normally.‎‏‎‎‏‎"</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‏‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‏‏‏‎‎‏‎‏‏‎‏‎‏‎‎‏‎‏‎‎‎‏‏‎‏‏‎‏‎‏‏‎‎‎‏‎Your tablet will automatically try to cool down. You can still use your tablet, but it may run slower.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Once your tablet has cooled down, it will run normally.‎‏‎‎‏‎"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‏‏‎‎‎‏‏‎‏‏‏‎‏‏‏‎‎‎‎‎‎‎‎‎‎‏‏‎‎‏‏‏‏‏‎‎‎‎‏‎‎‏‏‎‎‏‏‎‎‏‎‎‏‎The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the tablet.‎‏‎‎‏‎"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‎‏‎‎‏‏‏‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‎‎‏‏‎‏‏‎‎‎‎‏‏‎‎‎‏‏‎‏‎‎‎‏‏‏‎‎‎‏‎‏‎The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the device.‎‏‎‎‏‎"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‏‎‏‏‎‎‏‎‏‏‎‎‎‏‏‎‏‎‎‏‏‏‏‎‎‎‏‎‎‎‎‏‏‏‎The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the phone.‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res-product/values-es-rUS/strings.xml b/packages/SystemUI/res-product/values-es-rUS/strings.xml
index 3a22304..7ee96b2 100644
--- a/packages/SystemUI/res-product/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res-product/values-es-rUS/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Intentaste desbloquear el teléfono <xliff:g id="NUMBER">%d</xliff:g> veces de manera incorrecta. Se quitará el perfil de trabajo, lo que borrará todos los datos asociados."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Dibujaste el patrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de manera incorrecta. Después de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees la tablet mediante una cuenta de correo electrónico.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Dibujaste el patrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de manera incorrecta. Después de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees el dispositivo mediante una cuenta de correo electrónico.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Se apagó el tel. debido a alta temp."</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Se apagó el disp. debido a alta temp."</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Se apagó la tablet debido a alta temp."</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Tu teléfono ahora se ejecuta con normalidad.\nPresiona para obtener más información"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Tu dispositivo ahora se ejecuta con normalidad.\nPresiona para obtener más información"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Tu tablet ahora se ejecuta con normalidad.\nPresiona para obtener más información"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Tu teléfono estaba muy caliente y se apagó para enfriarse. Ya funciona correctamente.\n\nTu teléfono puede calentarse en los siguientes casos:\n	• Si usas apps que consumen muchos recursos (como juegos, videos o navegación).\n	• Si subes o descargas archivos grandes.\n	• Si usas el teléfono en condiciones de temperatura alta."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Tu dispositivo estaba muy caliente y se apagó para enfriarse. Ya funciona correctamente.\n\nTu dispositivo puede calentarse en los siguientes casos:\n	• Si usas apps que consumen muchos recursos (como juegos, videos o navegación).\n	• Si subes o descargas archivos grandes.\n	• Si usas el dispositivo en condiciones de temperatura alta."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Tu tablet estaba muy caliente y se apagó para enfriarse. Ya funciona correctamente.\n\nTu tablet puede calentarse en los siguientes casos:\n	• Si usas apps que consumen muchos recursos (como juegos, videos o navegación).\n	• Si subes o descargas archivos grandes.\n	• Si usas la tablet en condiciones de temperatura alta."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"El teléfono se está calentando"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"El disp. se está calentando"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"La tablet se está calentando"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Algunas funciones se limitan durante el enfriamiento del teléfono.\nPresiona para obtener más información"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Algunas funciones se limitan durante el enfriamiento del dispositivo.\nPresiona para obtener más información"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Algunas funciones se limitan durante el enfriamiento de la tablet.\nPresiona para obtener más información"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Tu teléfono intentará enfriarse automáticamente. Podrás usarlo, pero es posible que funcione más lento.\n\nUna vez que se haya enfriado, volverá a funcionar con normalidad."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Tu dispositivo intentará enfriarse automáticamente. Podrás usarlo, pero es posible que funcione más lento.\n\nUna vez que se haya enfriado, volverá a funcionar con normalidad."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Tu tablet intentará enfriarse automáticamente. Podrás usarla, pero es posible que funcione más lenta.\n\nUna vez que se haya enfriado, volverá a funcionar con normalidad."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"El sensor de huellas dactilares está en el botón de encendido. Es el botón plano que está junto al botón de volumen en relieve, en el borde de la tablet."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"El sensor de huellas dactilares está en el botón de encendido. Es el botón plano que está junto al botón de volumen en relieve, en el borde del dispositivo."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"El sensor de huellas dactilares está en el botón de encendido. Es el botón plano que está junto al botón de volumen en relieve, en el borde del teléfono."</string>
diff --git a/packages/SystemUI/res-product/values-es/strings.xml b/packages/SystemUI/res-product/values-es/strings.xml
index 744761d..d39c6ed 100644
--- a/packages/SystemUI/res-product/values-es/strings.xml
+++ b/packages/SystemUI/res-product/values-es/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Has intentado desbloquear el teléfono de forma incorrecta <xliff:g id="NUMBER">%d</xliff:g> veces. Se quitará este perfil de trabajo y se eliminarán todos sus datos."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Has dibujado un patrón de desbloqueo incorrecto <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Si se producen <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se te pedirá que desbloquees el tablet con una cuenta de correo electrónico.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Has dibujado un patrón de desbloqueo incorrecto <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Si se producen <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se te pedirá que desbloquees el teléfono con una cuenta de correo electrónico.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Teléfono apagado por calor"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Dispositivo apagado por calor"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tablet apagada por calor"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"El teléfono ya funciona con normalidad.\nToca para ver más información."</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"El dispositivo ya funciona con normalidad.\nToca para ver más información."</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"La tablet ya funciona con normalidad.\nToca para ver más información."</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"El teléfono se calentó demasiado, así que se apagó para enfriarse. Ahora funciona con normalidad.\n\nTu teléfono puede calentarse demasiado si:\n	• Usas aplicaciones que consumen muchos recursos (como aplicaciones de juegos, vídeos o navegación)\n	• Descargas o subes archivos de gran tamaño\n	• Lo usas a altas temperaturas"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"El dispositivo se calentó demasiado, así que se apagó para enfriarse. Ahora funciona con normalidad.\n\nTu dispositivo puede calentarse demasiado si:\n	• Usas aplicaciones que consumen muchos recursos (como aplicaciones de juegos, vídeos o navegación)\n	• Descargas o subes archivos de gran tamaño\n	• Lo usas a altas temperaturas"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"La tablet se calentó demasiado, así que se apagó para enfriarse. Ahora funciona con normalidad.\n\nTu tablet puede calentarse demasiado si:\n	• Usas aplicaciones que consumen muchos recursos (como aplicaciones de juegos, vídeos o navegación)\n	• Descargas o subes archivos de gran tamaño\n	• La usas a altas temperaturas"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"El teléfono se está calentando"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"El dispositivo se está calentando"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"La tablet se está calentando"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Se han limitado algunas funciones mientras el teléfono se enfría.\nToca para ver más información."</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Se han limitado algunas funciones mientras el dispositivo se enfría.\nToca para ver más información."</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Se han limitado algunas funciones mientras la tablet se enfría.\nToca para ver más información."</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"El teléfono intentará enfriarse automáticamente. Puedes seguir usándolo, pero es posible que funcione más lento.\n\nUna vez que el teléfono se haya enfriado, funcionará con normalidad."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"El dispositivo intentará enfriarse automáticamente. Puedes seguir usándolo, pero es posible que funcione más lento.\n\nUna vez que el dispositivo se haya enfriado, funcionará con normalidad."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"La tablet intentará enfriarse automáticamente. Puedes seguir usándola, pero es posible que funcione más lenta.\n\nUna vez que la tablet se haya enfriado, funcionará con normalidad."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"El sensor de huellas digitales está en el botón de encendido. Es el botón plano situado junto al botón de volumen con relieve cerca de una de la esquinas de la tablet."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"El sensor de huellas digitales está en el botón de encendido. Es el botón plano situado junto al botón de volumen con relieve en el lateral del dispositivo."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"El sensor de huellas digitales está en el botón de encendido. Es el botón plano situado junto al botón de volumen con relieve en el lateral del teléfono."</string>
diff --git a/packages/SystemUI/res-product/values-et/strings.xml b/packages/SystemUI/res-product/values-et/strings.xml
index 4d8af24..8cd4ae6 100644
--- a/packages/SystemUI/res-product/values-et/strings.xml
+++ b/packages/SystemUI/res-product/values-et/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Olete püüdnud <xliff:g id="NUMBER">%d</xliff:g> korda telefoni valesti avada. Tööprofiil eemaldatakse ja kõik profiiliandmed kustutatakse."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> ebaõnnestunud katset palutakse teil tahvelarvuti avada meilikontoga.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundi pärast."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> ebaõnnestunud katset palutakse teil telefon avada meilikontoga.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundi pärast."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Telefon lülitati kuuma tõttu välja"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Seade lülitati kuuma tõttu välja"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tahvelarvuti lülitati kuuma tõttu välja"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Telefon töötab nüüd tavapäraselt.\nPuudutage lisateabe saamiseks."</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Seade töötab nüüd tavapäraselt.\nPuudutage lisateabe saamiseks."</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Tahvelarvuti töötab nüüd tavapäraselt.\nPuudutage lisateabe saamiseks."</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Telefon oli liiga kuum, seetõttu lülitus see jahtumiseks välja. Telefon töötab nüüd tavapäraselt.\n\nTelefon võib kuumaks minna:\n	• ressursse koormavate rakenduste kasutamisel (nt mängu-, video- või navigatsioonirakendused)\n	• suurte failide alla-/üleslaadimisel\n	• telefoni kasutamisel kõrgel temperatuuril"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Seade oli liiga kuum, seetõttu lülitus see jahtumiseks välja. Seade töötab nüüd tavapäraselt.\n\nSeade võib kuumaks minna:\n	• ressursse koormavate rakenduste kasutamisel (nt mängu-, video- või navigatsioonirakendused)\n	• suurte failide alla-/üleslaadimisel\n	• seadme kasutamisel kõrgel temperatuuril"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Tahvelarvuti oli liiga kuum, seetõttu lülitus see jahtumiseks välja. Tahvelarvuti töötab nüüd tavapäraselt.\n\nTahvelarvuti võib kuumaks minna:\n	• ressursse koormavate rakenduste kasutamisel (nt mängu-, video- või navigatsioonirakendused)\n	• suurte failide alla-/üleslaadimisel\n	• tahvelarvuti kasutamisel kõrgel temperatuuril"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Telefon soojeneb"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Seade soojeneb"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Tahvelarvuti soojeneb"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Mõned funktsioonid on piiratud, kuni telefon jahtub.\nPuudutage lisateabe saamiseks."</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Mõned funktsioonid on piiratud, kuni seade jahtub.\nPuudutage lisateabe saamiseks."</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Mõned funktsioonid on piiratud, kuni tahvelarvuti jahtub.\nPuudutage lisateabe saamiseks."</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Teie telefon proovib automaatselt maha jahtuda. Saate telefoni ikka kasutada, kuid see võib olla aeglasem.\n\nKui telefon on jahtunud, töötab see tavapäraselt."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Teie seade proovib automaatselt maha jahtuda. Saate seadet ikka kasutada, kuid see võib olla aeglasem.\n\nKui seade on jahtunud, töötab see tavapäraselt."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Teie tahvelarvuti proovib automaatselt maha jahtuda. Saate tahvelarvutit ikka kasutada, kuid see võib olla aeglasem.\n\nKui tahvelarvuti on jahtunud, töötab see tavapäraselt."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Sõrmejäljeandur asub toitenupul. See on tahvelarvuti küljel helitugevuse kõrgendatud nupu kõrval olev lame nupp."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Sõrmejäljeandur asub toitenupul. See on seadme küljel helitugevuse kõrgendatud nupu kõrval olev lame nupp."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Sõrmejäljeandur asub toitenupul. See on telefoni küljel helitugevuse kõrgendatud nupu kõrval olev lame nupp."</string>
diff --git a/packages/SystemUI/res-product/values-eu/strings.xml b/packages/SystemUI/res-product/values-eu/strings.xml
index dcb1ead..032811c 100644
--- a/packages/SystemUI/res-product/values-eu/strings.xml
+++ b/packages/SystemUI/res-product/values-eu/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"<xliff:g id="NUMBER">%d</xliff:g> aldiz saiatu zara telefonoa desblokeatzen, baina huts egin duzu denetan. Laneko profila kendu egingo da eta, ondorioz, profileko datu guztiak ezabatuko dira."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Desblokeatzeko eredua oker marraztu duzu <xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz oker marrazten baduzu, tableta posta-kontu baten bidez desblokeatzeko eskatuko dizugu.\n\n Saiatu berriro <xliff:g id="NUMBER_2">%3$d</xliff:g> segundo barru."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Desblokeatzeko eredua oker marraztu duzu <xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz oker marrazten baduzu, telefonoa posta-kontu baten bidez desblokeatzeko eskatuko dizugu.\n\n Saiatu berriro <xliff:g id="NUMBER_2">%3$d</xliff:g> segundo barru."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Gehiegi berotu delako itzali da telefonoa"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Gehiegi berotu delako itzali da gailua"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Gehiegi berotu delako itzali da tableta"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Orain, ohi bezala funtzionatzen du telefonoak.\nInformazio gehiago lortzeko, sakatu hau"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Orain, ohi bezala funtzionatzen du gailuak.\nInformazio gehiago lortzeko, sakatu hau"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Orain, ohi bezala funtzionatzen du tabletak.\nInformazio gehiago lortzeko, sakatu hau"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Telefonoa gehiegi berotu denez, itzali egin da hoztu ahal izateko. Orain, ohi bezala funtzionatzen du.\n\nBerotzeko arrazoi posibleak:\n	• Baliabide asko behar dituzten aplikazioak erabiltzea (adibidez, jokoak, bideoak edo nabigazio-aplikazioak).\n	• Fitxategi handiak deskargatzea edo kargatzea.\n	• Telefonoa tenperatura altuak daudenean erabiltzea."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Gailua gehiegi berotu denez, itzali egin da hoztu ahal izateko. Orain, ohi bezala funtzionatzen du.\n\nBerotzeko arrazoi posibleak:\n	• Baliabide asko behar dituzten aplikazioak erabiltzea (adibidez, jokoak, bideoak edo nabigazio-aplikazioak).\n	• Fitxategi handiak deskargatzea edo kargatzea.\n	• Gailua tenperatura altuak daudenean erabiltzea."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Tableta gehiegi berotu denez, itzali egin da hoztu ahal izateko. Orain, ohi bezala funtzionatzen du.\n\nBerotzeko arrazoi posibleak:\n	• Baliabide asko behar dituzten aplikazioak erabiltzea (adibidez, jokoak, bideoak edo nabigazio-aplikazioak).\n	• Fitxategi handiak deskargatzea edo kargatzea.\n	• Tableta tenperatura altuak daudenean erabiltzea."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Telefonoa berotzen ari da"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Gailua berotzen ari da"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Tableta berotzen ari da"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Eginbide batzuk ezingo dira erabili telefonoa hozten den arte.\nInformazio gehiago lortzeko, sakatu hau"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Eginbide batzuk ezingo dira erabili gailua hozten den arte.\nInformazio gehiago lortzeko, sakatu hau"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Eginbide batzuk ezingo dira erabili tableta hozten den arte.\nInformazio gehiago lortzeko, sakatu hau"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Telefonoa automatikoki saiatuko da hozten. Hoztu bitartean, erabiltzen jarrai dezakezu, baina baliteke mantsoago funtzionatzea.\n\nHozten denean, ohi bezala funtzionatuko du."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Gailua automatikoki saiatuko da hozten. Hoztu bitartean, erabiltzen jarrai dezakezu, baina baliteke mantsoago funtzionatzea.\n\nHozten denean, ohi bezala funtzionatuko du."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Tableta automatikoki saiatuko da hozten. Hoztu bitartean, erabiltzen jarrai dezakezu, baina baliteke mantsoago funtzionatzea.\n\nHozten denean, ohi bezala funtzionatuko du."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Hatz-marken sentsorea etengailuan dago. Tabletaren ertzeko bolumen-botoi goratuaren ondoan dagoen botoi laua da."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Hatz-marken sentsorea etengailuan dago. Gailuaren ertzeko bolumen-botoi goratuaren ondoan dagoen botoi laua da."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Hatz-marken sentsorea etengailuan dago. Telefonoaren ertzeko bolumen-botoi goratuaren ondoan dagoen botoi laua da."</string>
diff --git a/packages/SystemUI/res-product/values-fa/strings.xml b/packages/SystemUI/res-product/values-fa/strings.xml
index a861261..30121cc 100644
--- a/packages/SystemUI/res-product/values-fa/strings.xml
+++ b/packages/SystemUI/res-product/values-fa/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"<xliff:g id="NUMBER">%d</xliff:g> تلاش ناموفق برای باز کردن قفل تلفن داشته‌اید. نمایه کاری پاک می‌شود که با آن همه داده‌های نمایه حذف می‌شود."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"‏الگوی بازگشایی قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیده‌اید. بعداز <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته می‌‎شود که بااستفاده از یک حساب ایمیل قفل رایانه لوحی‌تان را باز کنید.\n\n لطفاً پس‌از <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"الگوی بازگشایی قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیده‌اید. پس‌از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته می‌شود که بااستفاده از یک حساب ایمیل قفل تلفن را باز کنید.\n\n لطفاً پس‌از <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"تلفن به‌علت گرم شدن خاموش شد"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"دستگاه به‌علت گرم شدن خاموش شد"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"رایانه لوحی به‌علت گرم شدن خاموش شد"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"اکنون عملکرد تلفنتان به حالت عادی برگشته است.\nبرای اطلاعات بیشتر ضربه بزنید"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"اکنون عملکرد دستگاهتان به حالت عادی برگشته است.\nبرای اطلاعات بیشتر ضربه بزنید"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"اکنون عملکرد رایانه لوحی‌تان به حالت عادی برگشته است.\nبرای اطلاعات بیشتر ضربه بزنید"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"تلفنتان خیلی گرم شده بود، بنابراین خاموش شد تا خنک شود. اکنون تلفنتان عملکرد معمولش را دارد.\n\nتلفنتان ممکن است خیلی گرم شود، اگر:\n	• از برنامه‌های نیازمند پردازش زیاد (مثل بازی، ویدیو، یا برنامه‌های ناوبری) استفاده کنید\n	• فایل‌های بزرگ بارگیری یا بارگذاری کنید\n	• در دماهای بالا از تلفنتان استفاده کنید"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"دستگاهتان خیلی گرم شده بود، بنابراین خاموش شد تا خنک شود. اکنون دستگاهتان عملکرد معمولش را دارد.\n\nدستگاهتان ممکن است خیلی گرم شود، اگر:\n	• از برنامه‌های نیازمند پردازش زیاد (مثل بازی، ویدیو، یا برنامه‌های ناوبری) استفاده کنید\n	• فایل‌های بزرگ بارگیری یا بارگذاری کنید\n	• در دماهای بالا از دستگاهتان استفاده کنید"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"رایانه لوحی‌تان خیلی گرم شده بود، بنابراین خاموش شد تا خنک شود. اکنون رایانه لوحی‌تان عملکرد معمولش را دارد.\n\nرایانه لوحی‌تان ممکن است خیلی گرم شود، اگر:\n	• از برنامه‌های نیازمند پردازش زیاد (مثل بازی، ویدیو، یا برنامه‌های ناوبری) استفاده کنید\n	• فایل‌های بزرگ بارگیری یا بارگذاری کنید\n	• در دماهای بالا از رایانه لوحی‌تان استفاده کنید"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"تلفن درحال گرم شدن است"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"دستگاه درحال گرم شدن است"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"رایانه لوحی درحال گرم شدن است"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"وقتی تلفن درحال خنک شدن است، بعضی‌از ویژگی‌ها محدود می‌شوند.\nبرای اطلاعات بیشتر ضربه بزنید"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"وقتی دستگاه درحال خنک شدن است، بعضی‌از ویژگی‌ها محدود می‌شوند.\nبرای اطلاعات بیشتر ضربه بزنید"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"وقتی رایانه لوحی درحال خنک شدن است، بعضی‌از ویژگی‌ها محدود می‌شوند.\nبرای اطلاعات بیشتر ضربه بزنید"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"تلفنتان به‌طور خودکار سعی می‌کند خنک شود. همچنان می‌توانید از تلفنتان استفاده کنید، اما ممکن است کندتر عمل کند.\n\nوقتی تلفن خنک شد، عملکرد عادی‌اش از سرگرفته می‌شود."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"دستگاهتان به‌طور خودکار سعی می‌کند خنک شود. همچنان می‌توانید از دستگاهتان استفاده کنید، اما ممکن است کندتر عمل کند.\n\nوقتی دستگاه خنک شد، عملکرد عادی‌اش از سرگرفته می‌شود."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"رایانه لوحی‌تان به‌طور خودکار سعی می‌کند خنک شود. همچنان می‌توانید از رایانه لوحی‌تان استفاده کنید، اما ممکن است کندتر عمل کند.\n\nوقتی رایانه لوحی خنک شد، عملکرد عادی‌اش از سرگرفته می‌شود."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"حسگر اثر انگشت روی دکمه روشن/خاموش قرار دارد. این همان دکمه مسطحی است که در کنار دکمه برآمده صدا در لبه رایانه لوحی قرار دارد."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"حسگر اثر انگشت روی دکمه روشن/خاموش قرار دارد. این همان دکمه مسطحی است که در کنار دکمه برآمده صدا در لبه دستگاه قرار دارد."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"حسگر اثر انگشت روی دکمه روشن/خاموش قرار دارد. این همان دکمه مسطحی است که در کنار دکمه برآمده صدا در لبه تلفن قرار دارد."</string>
diff --git a/packages/SystemUI/res-product/values-fi/strings.xml b/packages/SystemUI/res-product/values-fi/strings.xml
index c6db4fe..3ed7f6d 100644
--- a/packages/SystemUI/res-product/values-fi/strings.xml
+++ b/packages/SystemUI/res-product/values-fi/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Yritit avata puhelimen lukituksen virheellisillä tiedoilla <xliff:g id="NUMBER">%d</xliff:g> kertaa. Työprofiili ja kaikki sen data poistetaan."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%2$d</xliff:g> kertaa, sinua pyydetään avaamaan tabletin lukitus sähköpostitilin avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunnin kuluttua."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%2$d</xliff:g> kertaa, sinua pyydetään avaamaan puhelimesi lukitus sähköpostitilin avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunnin kuluttua."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Puhelin sammui kuumuuden takia"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Laite sammui kuumuuden takia"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tabletti sammui kuumuuden takia"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Puhelimesi toimii nyt normaalisti.\nLue lisää napauttamalla"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Laitteesi toimii nyt normaalisti.\nLue lisää napauttamalla"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Tablettisi toimii nyt normaalisti.\nLue lisää napauttamalla"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Puhelimesi oli liian kuuma, joten se sammui. Puhelimesi toimii nyt normaalisti.\n\nPuhelimesi voi kuumentua liikaa, jos\n	• käytät paljon resursseja vaativia sovelluksia (esim. pelejä, videoita tai navigointisovelluksia)\n	• lataat tai lähetät suuria tiedostoja\n	• käytät puhelintasi korkeissa lämpötiloissa."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Laitteesi oli liian kuuma, joten se sammui. Laitteesi toimii nyt normaalisti.\n\nLaitteesi voi kuumentua liikaa, jos\n	• käytät paljon resursseja vaativia sovelluksia (esim. pelejä, videoita tai navigointisovelluksia)\n	• lataat tai lähetät suuria tiedostoja\n	• käytät laitetta korkeissa lämpötiloissa."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Tablettisi oli liian kuuma, joten se sammui. Tablettisi toimii nyt normaalisti.\n\nTablettisi voi kuumentua liikaa, jos\n	• käytät paljon resursseja vaativia sovelluksia (esim. pelejä, videoita tai navigointisovelluksia)\n	• lataat tai lähetät suuria tiedostoja\n	• käytät tablettia korkeissa lämpötiloissa."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Puhelin lämpenee"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Laite lämpenee"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Tabletti lämpenee"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Joidenkin ominaisuuksien käyttöä on rajoitettu puhelimen jäähtymisen aikana.\nLue lisää napauttamalla"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Joidenkin ominaisuuksien käyttöä on rajoitettu laitteen jäähtymisen aikana.\nLue lisää napauttamalla"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Joidenkin ominaisuuksien käyttöä on rajoitettu tabletin jäähtymisen aikana.\nLue lisää napauttamalla"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Puhelimesi yrittää automaattisesti jäähdyttää itsensä. Voit silti käyttää puhelinta, mutta se voi toimia hitaammin.\n\nKun puhelin on jäähtynyt, se toimii normaalisti."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Laitteesi yrittää jäähtyä automaattisesti. Voit silti käyttää laitetta, mutta se voi toimia hitaammin.\n\nKun laite on jäähtynyt, se toimii normaalisti."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Tablettisi yrittää jäähtyä automaattisesti. Voit silti käyttää tablettia, mutta se voi toimia hitaammin.\n\nKun tabletti on jäähtynyt, se toimii normaalisti."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Sormenjälkitunnistin on virtapainikkeessa. Se on litteä painike koholla olevan äänenvoimakkuuspainikkeen vieressä tabletin sivussa."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Sormenjälkitunnistin on virtapainikkeessa. Se on litteä painike koholla olevan äänenvoimakkuuspainikkeen vieressä laitteen sivussa."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Sormenjälkitunnistin on virtapainikkeessa. Se on litteä painike koholla olevan äänenvoimakkuuspainikkeen vieressä puhelimen sivussa."</string>
diff --git a/packages/SystemUI/res-product/values-fr-rCA/strings.xml b/packages/SystemUI/res-product/values-fr-rCA/strings.xml
index 3862796..1b6c6099 100644
--- a/packages/SystemUI/res-product/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res-product/values-fr-rCA/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Vous avez tenté de déverrouiller ce téléphone à <xliff:g id="NUMBER">%d</xliff:g> reprises. Le profil professionnel sera supprimé, ce qui entraîne la suppression de toutes ses données."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre tablette à l\'aide d\'un compte de courriel.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de courriel.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Le téléphone s\'est éteint; surchauffage."</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"L\'appareil s\'est éteint; surchauffage."</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"La tablette s\'est éteinte; surchauffage."</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Votre téléphone fonctionne normalement maintenant.\nTouchez pour en savoir plus"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Votre appareil fonctionne normalement maintenant.\nTouchez pour en savoir plus"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Votre tablette fonctionne normalement maintenant.\nTouchez pour en savoir plus."</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Votre téléphone surchauffait et s\'est éteint afin de se refroidir. Il fonctionne normalement maintenant.\n\nIl peut surchauffer si vous :\n	• utilisez. des applications qui utilisent beaucoup de ressources (jeux, vidéo, navigation, etc.)\n	• téléchargez ou téléversez des fichiers lourds \n	• si vous l\'utilisez lors de températures élevées."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Votre téléphone surchauffait et s\'est éteint afin de se refroidir. Il fonctionne normalement maintenant.\n\nIl peut surchauffer si vous :\n	• utilisez. des applications qui utilisent beaucoup de ressources (jeux, vidéo, navigation, etc.)\n	• téléchargez ou téléversez des fichiers lourds \n	• ou si vous l\'utilisez lors de températures élevées."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Votre tablette surchauffait et s\'est éteinte afin de se refroidir. Elle fonctionne normalement maintenant.\n\nElle peut surchauffer si vous :\n	• utilisez. des applications qui utilisent beaucoup de ressources (jeux, vidéo, navigation, etc.)\n	• téléchargez ou téléversez des fichiers lourds \n	• si vous l\'utilisez lors de températures élevées."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Le téléphone surchauffe"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"L\'appareil surchauffe"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"La tablette surchauffe"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Certaines fonctionnalités sont limitées lors du refroidissement du téléphone.\nTouchez pour en savoir plus"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Certaines fonctionnalités sont limitées lors du refroidissement du téléphone.\nTouchez pour en savoir plus"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Certaines fonctionnalités sont limitées lors du refroidissement du téléphone.\nTouchez pour en savoir plus"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Votre téléphone va se refroidir automatiquement. Vous pouvez toujours l\'utiliser, mais il risque d\'être plus lent.\n\nUne fois refroidi, il va fonctionner normalement."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Votre téléphone va se refroidir automatiquement. Vous pouvez toujours utiliser votre téléphone, mais il risque d\'être plus lent.\n\nUne fois refroidi, il fonctionnera normalement."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Votre tablette va se refroidir automatiquement. Vous pouvez toujours utiliser votre tablette, mais elle risque d\'être plus lente.\n\nUne fois refroidie, elle va fonctionner normalement."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Le capteur d\'empreintes digitales est situé sur l\'interrupteur. Il s\'agit du bouton plat situé à côté du bouton de volume surélevé, sur le bord de la tablette."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Le capteur d\'empreintes digitales est situé sur l\'interrupteur. Il s\'agit du bouton plat situé à côté du bouton de volume surélevé, sur le bord de l\'appareil."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Le capteur d\'empreintes digitales est situé sur l\'interrupteur. Il s\'agit du bouton plat situé à côté du bouton de volume surélevé, sur le bord du téléphone."</string>
diff --git a/packages/SystemUI/res-product/values-fr/strings.xml b/packages/SystemUI/res-product/values-fr/strings.xml
index d874882..eedc182 100644
--- a/packages/SystemUI/res-product/values-fr/strings.xml
+++ b/packages/SystemUI/res-product/values-fr/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Vous avez tenté de déverrouiller le téléphone à <xliff:g id="NUMBER">%d</xliff:g> reprises. Le profil professionnel et toutes les données associées vont être supprimés."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre tablette à l\'aide d\'un compte de messagerie électronique.\n\nRéessayez dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de messagerie électronique.\n\nRéessayez dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Téléphone éteint car il surchauffait"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Appareil éteint car il surchauffait"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tablette éteinte car elle surchauffait"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"À présent, votre téléphone fonctionne normalement.\nAppuyer pour en savoir plus"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"À présent, votre appareil fonctionne normalement.\nAppuyer pour en savoir plus"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"À présent, votre tablette fonctionne normalement.\nAppuyer pour en savoir plus"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Votre téléphone s\'est éteint, car il surchauffait. Il s\'est refroidi et fonctionne normalement.\n\nIl peut surchauffer si vous :\n	• exécutez des applis utilisant beaucoup de ressources (jeux, vidéo, navigation, etc.) ;\n	• téléchargez ou importez de gros fichiers ;\n	• utilisez votre téléphone à des températures élevées."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Votre appareil s\'est éteint, car il surchauffait. Il s\'est refroidi et fonctionne normalement.\n\nIl peut surchauffer si vous :\n	• exécutez des applis utilisant beaucoup de ressources (jeux, vidéo, navigation, etc.) ;\n	• téléchargez ou importez de gros fichiers ;\n	• utilisez votre appareil à des températures élevées."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Votre tablette s\'est éteinte, car elle surchauffait. Elle s\'est refroidie et fonctionne normalement.\n\nElle peut surchauffer si vous :\n	• exécutez des applis utilisant beaucoup de ressources (jeux, vidéo, navigation, etc.) ;\n	• téléchargez ou importez de gros fichiers ;\n	• utilisez votre tablette à des températures élevées."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Le téléphone chauffe"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"L\'appareil chauffe"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"La tablette chauffe"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Fonctionnalités limitées pendant le refroidissement du téléphone.\nAppuyer pour en savoir plus"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Fonctionnalités limitées pendant le refroidissement de l\'appareil.\nAppuyer pour en savoir plus"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Fonctionnalités limitées pendant le refroidissement de la tablette.\nAppuyer pour en savoir plus"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Votre téléphone va essayer de se refroidir automatiquement. Vous pouvez toujours l\'utiliser, mais il risque d\'être plus lent.\n\nUne fois refroidi, il fonctionnera normalement."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Votre appareil va essayer de se refroidir automatiquement. Vous pouvez toujours l\'utiliser, mais il risque d\'être plus lent.\n\nUne fois refroidi, il fonctionnera normalement."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Votre tablette va essayer de se refroidir automatiquement. Vous pouvez toujours l\'utiliser, mais elle risque d\'être plus lente.\n\nUne fois refroidie elle fonctionnera normalement."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Le lecteur d\'empreinte digitale est sur le bouton Marche/Arrêt. C\'est le bouton plat à côté du bouton de volume en relief sur un bord de la tablette."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Le lecteur d\'empreinte digitale est sur le bouton Marche/Arrêt. C\'est le bouton plat à côté du bouton de volume en relief sur un bord de l\'appareil."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Le lecteur d\'empreinte digitale est sur le bouton Marche/Arrêt. C\'est le bouton plat à côté du bouton de volume en relief sur un bord du téléphone."</string>
diff --git a/packages/SystemUI/res-product/values-gl/strings.xml b/packages/SystemUI/res-product/values-gl/strings.xml
index b3e03ca..67be4b2 100644
--- a/packages/SystemUI/res-product/values-gl/strings.xml
+++ b/packages/SystemUI/res-product/values-gl/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Tentaches desbloquear o teléfono <xliff:g id="NUMBER">%d</xliff:g> veces de forma incorrecta. Quitarase o perfil de traballo e, por conseguinte, todos os seus datos."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Debuxaches o padrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de forma incorrecta. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, terás que desbloquear a tableta a través dunha conta de correo electrónico.\n\n Téntao de novo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Debuxaches o padrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de forma incorrecta. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, terás que desbloquear o teléfono a través dunha conta de correo electrónico.\n\n Téntao de novo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"O teléfono apagouse pola calor"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"O dispositivo apagouse pola calor"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"A tableta apagouse pola calor"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"O teléfono funciona con normalidade.\nToca para obter máis información"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"O dispositivo funciona con normalidade.\nToca para obter máis información"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"A tableta funciona con normalidade.\nToca para obter máis información"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Como teléfono estaba demasiado quente, apagouse para arrefriar. Agora funciona con normalidade.\n\nÉ posible que se quente demasiado se:\n	• Usas aplicacións que requiran moitos recursos (como aplicacións de navegación, vídeos ou xogos).\n	• Descargas ou cargas ficheiros grandes.\n	• Utilizas o teléfono en ambientes con temperatura elevada."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Como o dispositivo estaba demasiado quente, apagouse para arrefriar. Agora funciona con normalidade.\n\nÉ posible que se quente demasiado se:\n	• Usas aplicacións que requiran moitos recursos (como aplicacións de navegación, vídeos ou xogos).\n	• Descargas ou cargas ficheiros grandes.\n	• Utilizas o dispositivo en ambientes con temperatura elevada."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Como a tableta estaba demasiado quente, apagouse para arrefriar. Agora funciona con normalidade.\n\nÉ posible que se quente demasiado se:\n	• Usas aplicacións que requiran moitos recursos (como aplicacións de navegación, vídeos ou xogos).\n	• Descargas ou cargas ficheiros grandes.\n	• Utilizas a tableta en ambientes con temperatura elevada."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"O teléfono estase quentando"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"O dispositivo estase quentando"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"A tableta estase quentando"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Algunhas funcións estarán limitadas mentres arrefría o teléfono.\nToca para obter máis información"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Algunhas funcións estarán limitadas mentres arrefría o dispositivo.\nToca para obter máis información"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Algunhas funcións estarán limitadas mentres arrefría a tableta.\nToca para obter máis información"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"O teléfono tentará arrefriar automaticamente. Podes utilizalo igual, pero quizais vaia máis lento.\n\nUnha vez que arrefríe, funcionará con normalidade."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"O dispositivo tentará arrefriar automaticamente. Podes utilizalo igual, pero quizais vaia máis lento.\n\nUnha vez que arrefríe, funcionará con normalidade."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"A tableta tentará arrefriar automaticamente. Podes utilizala igual, pero quizais vaia máis lenta.\n\nUnha vez que arrefríe, funcionará con normalidade."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"O sensor de impresión dixital está no botón de acendido. É o botón plano que se atopa a carón do botón de volume con relevo, no lateral da tableta."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"O sensor de impresión dixital está no botón de acendido. É o botón plano que se atopa a carón do botón de volume con relevo, no lateral do dispositivo."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"O sensor de impresión dixital está no botón de acendido. É o botón plano que se atopa a carón do botón de volume con relevo, no lateral do teléfono."</string>
diff --git a/packages/SystemUI/res-product/values-gu/strings.xml b/packages/SystemUI/res-product/values-gu/strings.xml
index 4621be3..d43c3d3 100644
--- a/packages/SystemUI/res-product/values-gu/strings.xml
+++ b/packages/SystemUI/res-product/values-gu/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"તમે ફોનને <xliff:g id="NUMBER">%d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. આ કાર્યાલયની પ્રોફાઇલ કાઢી નાખવામાં આવશે, જે તમામ પ્રોફાઇલ ડેટાને ડિલીટ કરી દેશે."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"તમે તમારી અનલૉક પૅટર્ન <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે દોરી છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> અસફળ પ્રયાસો પછી, તમને એક ઇમેઇલ એકાઉન્ટનો ઉપયોગ કરીને તમારા ટૅબ્લેટને અનલૉક કરવાનું કહેવામાં આવશે.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> સેકન્ડમાં ફરી પ્રયાસ કરો."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"તમે તમારી અનલૉક પૅટર્ન <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે દોરી છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> અસફળ પ્રયાસો પછી, તમને ઇમેઇલ એકાઉન્ટનો ઉપયોગ કરીને તમારા ફોનને અનલૉક કરવાનું કહેવામાં આવશે.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> સેકન્ડમાં ફરીથી પ્રયાસ કરો."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"ગરમ થવાના કારણે ફોન બંધ થઇ ગયો છે"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"ગરમ થવાના કારણે ડિવાઇસ બંધ થઈ ગયું છે"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"ગરમ થવાના કારણે ટૅબ્લેટ બંધ થઈ ગયું છે"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"તમારો ફોન હવે સામાન્ય રીતે કાર્ય કરી રહ્યો છે.\nવધુ માહિતી માટે ટૅપ કરો"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"તમારું ડિવાઇસ હવે સામાન્ય રીતે કાર્ય કરી રહ્યું છે.\nવધુ માહિતી માટે ટૅપ કરો"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"તમારું ટૅબ્લેટ હવે સામાન્ય રીતે કાર્ય કરી રહ્યું છે.\nવધુ માહિતી માટે ટૅપ કરો"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"તમારો ફોન અત્યંત ગરમ હતો, તેથી તે ઠંડો થવા ઑટોમૅટિક રીતે બંધ થઈ ગયો છે. તમારો ફોન હવે સામાન્ય રીતે કાર્ય કરી રહ્યો છે.\n\nતમારો ફોન અત્યંત ગરમ થઈ શકે છે, જો તમે:\n	• એવી ઍપ વાપરતા હો જે સંસાધન સઘન રીતે વાપરતી હોય (જેમ કે ગેમિંગ, વીડિયો, અથવા નેવિગેટ કરતી ઍપ)\n	• મોટી ફાઇલો અપલોડ અથવા ડાઉનલોડ કરતા હો\n	• તમારા ફોનનો ઉપયોગ ઉચ્ચ તાપમાનમાં કરતા હો"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"તમારું ડિવાઇસ અત્યંત ગરમ હતું, તેથી તે ઠંડું થવા ઑટોમૅટિક રીતે બંધ થઈ ગયું છે. તમારું ડિવાઇસ હવે સામાન્ય રીતે કાર્ય કરી રહ્યું છે.\n\nતમારું ડિવાઇસ અત્યંત ગરમ થઈ શકે છે, જો તમે:\n	• એવી ઍપ વાપરતા હો જે સંસાધન સઘન રીતે વાપરતી હોય (જેમ કે ગેમિંગ, વીડિયો, અથવા નેવિગેટ કરતી ઍપ)\n	• મોટી ફાઇલો અપલોડ અથવા ડાઉનલોડ કરતા હો\n	• તમારા ડિવાઇસનો ઉપયોગ ઉચ્ચ તાપમાનમાં કરતા હો"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"તમારું ટૅબ્લેટ અત્યંત ગરમ હતું, તેથી તે ઠંડું થવા ઑટોમૅટિક રીતે બંધ થઈ ગયું છે. તમારું ટૅબ્લેટ હવે સામાન્ય રીતે કાર્ય કરી રહ્યું છે.\n\nતમારું ટૅબ્લેટ અત્યંત ગરમ થઈ શકે છે, જો તમે:\n	• એવી ઍપ વાપરતા હો જે સંસાધન સઘન રીતે વાપરતી હોય (જેમ કે ગેમિંગ, વીડિયો, અથવા નેવિગેટ કરતી ઍપ)\n	• મોટી ફાઇલો અપલોડ અથવા ડાઉનલોડ કરતા હો\n	• તમારા ટૅબ્લેટનો ઉપયોગ ઉચ્ચ તાપમાનમાં કરતા હો"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"ફોન ગરમ થવા લાગ્યો છે"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"ડિવાઇસ ગરમ થવા લાગ્યું છે"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"ટૅબ્લેટ ગરમ થવા લાગ્યું છે"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"ફોન ઠંડો થાય ત્યાં સુધી અમુક સુવિધાઓ મર્યાદિત હોય છે.\nવધુ માહિતી માટે ટૅપ કરો"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"ડિવાઇસ ઠંડું થાય ત્યાં સુધી અમુક સુવિધાઓ મર્યાદિત હોય છે.\nવધુ માહિતી માટે ટૅપ કરો"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"ટૅબ્લેટ ઠંડું થાય ત્યાં સુધી અમુક સુવિધાઓ મર્યાદિત હોય છે.\nવધુ માહિતી માટે ટૅપ કરો"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"તમારો ફોન ઑટોમૅટિક રીતે ઠંડો થવાનો પ્રયાસ કરશે. તમે હજી પણ તમારા ફોનનો ઉપયોગ કરી શકો છો, પરંતુ તે કદાચ થોડો ધીમો ચાલે.\n\nએકવાર તમારો ફોન ઠંડો થઈ ગયા પછી, તે સામાન્ય રીતે ચાલશે."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"તમારું ડિવાઇસ ઑટોમૅટિક રીતે ઠંડુ થવાનો પ્રયાસ કરશે. તમે હજી પણ તમારા ડિવાઇસનો ઉપયોગ કરી શકો છો, પરંતુ તે કદાચ થોડું ધીમું કાર્ય કરે.\n\nએકવાર તમારું ડિવાઇસ ઠંડું થઈ ગયા પછી, તે સામાન્ય રીતે કાર્ય કરશે."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"તમારું ટૅબ્લેટ ઑટોમૅટિક રીતે ઠંડું થવાનો પ્રયાસ કરશે. તમે હજી પણ તમારા ટૅબ્લેટનો ઉપયોગ કરી શકો છો, પરંતુ તે કદાચ થોડું ધીમું ચાલે.\n\nએકવાર તમારું ટૅબ્લેટ ઠંડું થઈ ગયા પછી, તે સામાન્ય રીતે કાર્ય કરશે."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"ફિંગરપ્રિન્ટ સેન્સર પાવર બટન પર છે. તે ટૅબ્લેટની કિનારીએ આવેલા ઉપસેલા વૉલ્યૂમ બટનની બાજુમાં આવેલું સપાટ બટન છે."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"ફિંગરપ્રિન્ટ સેન્સર પાવર બટન પર છે. તે ડિવાઇસની કિનારીએ આવેલા ઉપસેલા વૉલ્યૂમ બટનની બાજુમાં આવેલું સપાટ બટન છે."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"ફિંગરપ્રિન્ટ સેન્સર પાવર બટન પર છે. તે ફોનની કિનારીએ આવેલા ઉપસેલા વૉલ્યૂમ બટનની બાજુમાં આવેલું સપાટ બટન છે."</string>
diff --git a/packages/SystemUI/res-product/values-hi/strings.xml b/packages/SystemUI/res-product/values-hi/strings.xml
index 4c69df50..dab5f57 100644
--- a/packages/SystemUI/res-product/values-hi/strings.xml
+++ b/packages/SystemUI/res-product/values-hi/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"आप फ़ोन को अनलॉक करने के लिए <xliff:g id="NUMBER">%d</xliff:g> बार गलत पासवर्ड डाल चुके हैं. इसकी वजह से वर्क प्रोफ़ाइल को हटा दिया जाएगा जिससे उपयोगकर्ता की प्रोफ़ाइल का सारा डेटा मिट जाएगा."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"आपने लॉक खोलने के पैटर्न को <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से बनाया है. इसलिए, <xliff:g id="NUMBER_1">%2$d</xliff:g> और गलत पैटर्न बनाने के बाद, टैबलेट को अनलॉक करने के लिए आपसे ईमेल खाते का इस्तेमाल करने को कहा जाएगा.\n\n अनलॉक करने के लिए <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंड में फिर से कोशिश करें."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"आपने लॉक खोलने के पैटर्न को <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से बनाया है. इसलिए, <xliff:g id="NUMBER_1">%2$d</xliff:g> और गलत पैटर्न बनाने के बाद, आपसे फ़ोन को अनलॉक करने के लिए ईमेल खाते का इस्तेमाल करने को कहा जाएगा.\n\n अनलॉक करने के लिए <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंड में फिर से कोशिश करें."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"गर्म होने की वजह से फ़ोन बंद हो गया"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"गर्म होने की वजह से डिवाइस बंद हो गया"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"गर्म होने की वजह से टैबलेट बंद हो गया"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"आपका फ़ोन अब सामान्य रूप से काम कर रहा है.\nज़्यादा जानकारी के लिए टैप करें"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"आपका डिवाइस अब सामान्य रूप से काम कर रहा है.\nज़्यादा जानकारी के लिए टैप करें"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"आपका टैबलेट अब सामान्य रूप से काम कर रहा है.\nज़्यादा जानकारी के लिए टैप करें"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"आपका फ़ोन बहुत गर्म हो गया था. इसलिए, यह ठंडा होने के लिए बंद हो गया. फ़ोन अब सामान्य रूप से काम कर रहा है.\n\nफ़ोन बहुत गर्म हो सकता है, अगर:\n	• ज़्यादा रिसॉर्स का इस्तेमाल करने वाले ऐप्लिकेशन चलाए जाते हैं. जैसे, गेमिंग, वीडियो या नेविगेशन ऐप्लिकेशन\n	• बड़ी फ़ाइलें डाउनलोड या अपलोड की जाती हैं\n	• ज़्यादा तापमान में फ़ोन का इस्तेमाल किया जाता है"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"आपका डिवाइस बहुत गर्म हो गया था. इसलिए, यह ठंडा होने के लिए बंद हो गया. डिवाइस अब सामान्य रूप से काम कर रहा है.\n\nडिवाइस बहुत गर्म हो सकता है, अगर:\n	• ज़्यादा रिसॉर्स का इस्तेमाल करने वाले ऐप्लिकेशन चलाए जाते हैं. जैसे, गेमिंग, वीडियो या नेविगेशन ऐप्लिकेशन\n	• बड़ी फ़ाइलें डाउनलोड या अपलोड की जाती हैं\n	• ज़्यादा तापमान में डिवाइस का इस्तेमाल किया जाता है"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"आपका टैबलेट बहुत गर्म हो गया था. इसलिए, यह ठंडा होने के लिए बंद हो गया. टैबलेट अब सामान्य रूप से काम कर रहा है.\n\nटैबलेट बहुत गर्म हो सकता है, अगर:\n	• ज़्यादा रिसॉर्स का इस्तेमाल करने वाले ऐप्लिकेशन चलाए जाते हैं. जैसे, गेमिंग, वीडियो या नेविगेशन ऐप्लिकेशन\n	• बड़ी फ़ाइलें डाउनलोड या अपलोड की जाती हैं\n	• ज़्यादा तापमान में टैबलेट का इस्तेमाल किया जाता है"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"फ़ोन गर्म हो रहा है"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"डिवाइस गर्म हो रहा है"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"टैबलेट गर्म हो रहा है"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"फ़ोन के ठंडा होने तक कुछ सुविधाएं काम नहीं करतीं.\nज़्यादा जानकारी के लिए टैप करें"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"डिवाइस के ठंडा होने तक कुछ सुविधाएं काम नहीं करतीं.\nज़्यादा जानकारी के लिए टैप करें"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"टैबलेट के ठंडा होने तक कुछ सुविधाएं काम नहीं करतीं.\nज़्यादा जानकारी के लिए टैप करें"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"आपका फ़ोन अपने-आप ठंडा हो जाएगा. इस दौरान भी अपने फ़ोन का इस्तेमाल किया जा सकता है. हालांकि, ऐसे में फ़ोन शायद धीमा काम करे.\n\nठंडा हो जाने के बाद, यह पहले की तरह काम करेगा."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"आपका डिवाइस अपने-आप ठंडा हो जाएगा. इस दौरान भी अपने डिवाइस का इस्तेमाल किया जा सकता है. हालांकि, ऐसे में डिवाइस शायद धीमा काम करे.\n\nठंडा हो जाने के बाद, यह पहले की तरह काम करेगा."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"आपका टैबलेट अपने-आप ठंडा हो जाएगा. इस दौरान भी अपने टैबलेट का इस्तेमाल किया जा सकता है. हालांकि, ऐसे में टैबलेट शायद धीमा काम करे.\n\nठंडा हो जाने के बाद, यह पहले की तरह काम करेगा."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"फ़िंगरप्रिंट सेंसर, पावर बटन पर होता है. यह टैबलेट के किनारे पर मौजूद एक फ़्लैट बटन होता है, जो कि आपको आवाज़ कम या ज़्यादा करने वाले उभरे हुए बटन के बगल में मिलेगा."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"फ़िंगरप्रिंट सेंसर, पावर बटन पर होता है. यह डिवाइस के किनारे पर मौजूद एक फ़्लैट बटन होता है, जो कि आपको आवाज़ कम या ज़्यादा करने वाले उभरे हुए बटन के बगल में मिलेगा."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"फ़िंगरप्रिंट सेंसर, पावर बटन पर होता है. यह फ़ोन के किनारे पर मौजूद एक फ़्लैट बटन होता है, जो कि आपको आवाज़ कम या ज़्यादा करने वाले उभरे हुए बटन के बगल में मिलेगा."</string>
diff --git a/packages/SystemUI/res-product/values-hr/strings.xml b/packages/SystemUI/res-product/values-hr/strings.xml
index a7bd4b0..8be9a22 100644
--- a/packages/SystemUI/res-product/values-hr/strings.xml
+++ b/packages/SystemUI/res-product/values-hr/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Neuspješno ste pokušali otključati telefon <xliff:g id="NUMBER">%d</xliff:g> put/a. Radni će se profil ukloniti, a time će se izbrisati i svi njegovi podaci."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. Nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja morat ćete otključati tablet pomoću računa e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. Nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja morat ćete otključati telefon pomoću računa e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Telefon se isključio zbog vrućine"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Uređaj se isključio zbog vrućine"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tablet se isključio zbog vrućine"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Telefon sad radi normalno.\nDodirnite za više informacija."</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Uređaj sad radi normalno.\nDodirnite za više informacija."</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Tablet sad radi normalno.\nDodirnite za više informacija."</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Telefon se pregrijao, stoga se isključio kako bi se ohladio Telefon sada radi normalno.\n\nTelefon se može pregrijati ako:\n	• Upotrebljavate zahtjevne aplikacije (kao što su igre, aplikacije za videozapise ili navigaciju).\n	• Preuzimate ili prenosite velike datoteke.\n	• Upotrebljavate telefon na visokim temperaturama."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Uređaj se pregrijao, stoga se isključio kako bi se ohladio Uređaj sada radi normalno.\n\nUređaj se može pregrijati ako:\n	• Upotrebljavate zahtjevne aplikacije (kao što su igre, aplikacije za videozapise ili navigaciju).\n	• Preuzimate ili prenosite velike datoteke.\n	• Upotrebljavate uređaj na visokim temperaturama."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Tablet se pregrijao, stoga se isključio kako bi se ohladio Tablet sada radi normalno.\n\nTablet se može pregrijati ako:\n	• Upotrebljavate zahtjevne aplikacije (kao što su igre, aplikacije za videozapise ili navigaciju).\n	• Preuzimate ili prenosite velike datoteke.\n	• Upotrebljavate tablet na visokim temperaturama."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Telefon se zagrijava"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Uređaj se zagrijava"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Tablet se zagrijava"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Neke su značajke ograničene dok se telefon ne ohladi.\nDodirnite za više informacija"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Neke su značajke ograničene dok se uređaj ne ohladi.\nDodirnite za više informacija"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Neke su značajke ograničene dok se tablet ne ohladi.\nDodirnite za više informacija"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Telefon će se automatski pokušati ohladiti. Možete ga nastaviti koristiti, no mogao bi raditi sporije.\n\nKad se ohladi, radit će normalno."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Uređaj će se automatski pokušati ohladiti. Možete ga nastaviti koristiti, no mogao bi raditi sporije.\n\nKad se ohladi, radit će normalno."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Tablet će se automatski pokušati ohladiti. Možete ga nastaviti koristiti, no mogao bi raditi sporije.\n\nKad se ohladi, radit će normalno."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Senzor otiska prsta nalazi se na tipki za uključivanje/isključivanje. To je ravni gumb pored izdignutog gumba za glasnoću na rubu tableta."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Senzor otiska prsta nalazi se na tipki za uključivanje/isključivanje. To je ravni gumb pored izdignutog gumba za glasnoću na rubu uređaja."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Senzor otiska prsta nalazi se na tipki za uključivanje/isključivanje. To je ravni gumb pored izdignutog gumba za glasnoću na rubu telefona."</string>
diff --git a/packages/SystemUI/res-product/values-hu/strings.xml b/packages/SystemUI/res-product/values-hu/strings.xml
index 75c10e9..34f20a0 100644
--- a/packages/SystemUI/res-product/values-hu/strings.xml
+++ b/packages/SystemUI/res-product/values-hu/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"<xliff:g id="NUMBER">%d</xliff:g> alkalommal próbálkozott sikertelenül a telefon zárolásának feloldásával. A rendszer eltávolítja a munkaprofilt, és ezzel a profil összes adata törlődik."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%2$d</xliff:g> sikertelen kísérlet után e-mail-fiók használatával kell feloldania táblagépét.\n\nPróbálja újra <xliff:g id="NUMBER_2">%3$d</xliff:g> másodperc múlva."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%2$d</xliff:g> sikertelen kísérlet után e-mail-fiók használatával kell feloldania telefonját.\n\nPróbálja újra <xliff:g id="NUMBER_2">%3$d</xliff:g> másodperc múlva."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"A telefon a meleg miatt kikapcsolt"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Az eszköz a meleg miatt kikapcsolt"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"A táblagép a meleg miatt kikapcsolt"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Telefonja most már megfelelően működik.\nKoppintson, ha további információra van szüksége."</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Eszköze most már megfelelően működik.\nKoppintson, ha további információra van szüksége."</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Táblagépe most már megfelelően működik.\nKoppintson, ha további információra van szüksége."</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Telefonja túlmelegedett, így kikapcsolt, hogy lehűlhessen. Most már megfelelően működik.\n\nA telefon akkor melegedhet túl, ha Ön:\n	• Energiaigényes alkalmazásokat használ (például játékokat, videókat vagy navigációs alkalmazásokat)\n	• Nagy fájlokat tölt le vagy fel\n	• Melegben használja a telefonját"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Eszköze túlmelegedett, így kikapcsolt, hogy lehűlhessen. Most már megfelelően működik.\n\nAz eszköz akkor melegedhet túl, ha Ön:\n	• Energiaigényes alkalmazásokat használ (például játékokat, videókat vagy navigációs alkalmazásokat)\n	• Nagy fájlokat tölt le vagy fel\n	• Melegben használja eszközét"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Táblagépe túlmelegedett, így kikapcsolt, hogy lehűlhessen. Most már megfelelően működik.\n\nA táblagép akkor melegedhet túl, ha Ön:\n	• Energiaigényes alkalmazásokat használ (például játékokat, videókat vagy navigációs alkalmazásokat)\n	• Nagy fájlokat tölt le vagy fel\n	• Melegben használja a táblagépet"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"A telefon melegszik"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Az eszköz melegszik"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"A táblagép melegszik"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Bizonyos funkciók korlátozottan működnek a telefon lehűlése közben.\nKoppintson, ha további információra van szüksége."</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Bizonyos funkciók korlátozottan működnek az eszköz lehűlése közben.\nKoppintson, ha további információra van szüksége."</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Bizonyos funkciók korlátozottan működnek a táblagép lehűlése közben.\nKoppintson, ha további információra van szüksége."</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"A telefon automatikusan megpróbál lehűlni. Továbbra is tudja használni a telefont, de elképzelhető, hogy működése lelassul.\n\nAmint a telefon lehűl, újra a szokásos módon működik majd."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Az eszköz automatikusan megpróbál lehűlni. Továbbra is tudja használni, de elképzelhető, hogy működése lelassul.\n\nAmint az eszköz lehűl, újra a szokásos módon működik majd."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"A táblagép automatikusan megpróbál lehűlni. Továbbra is tudja használni, de elképzelhető, hogy működése lelassul.\n\nAmint a táblagép lehűl, újra a szokásos módon működik majd."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Az ujjlenyomat-érzékelő a bekapcsológombon található. Ez a kiemelkedő hangerőgomb melletti lapos gomb a táblagép szélén."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Az ujjlenyomat-érzékelő a bekapcsológombon található. Ez a kiemelkedő hangerőgomb melletti lapos gomb az eszköz szélén."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Az ujjlenyomat-érzékelő a bekapcsológombon található. Ez a kiemelkedő hangerőgomb melletti lapos gomb a telefon szélén."</string>
diff --git a/packages/SystemUI/res-product/values-hy/strings.xml b/packages/SystemUI/res-product/values-hy/strings.xml
index acee335..f527eab 100644
--- a/packages/SystemUI/res-product/values-hy/strings.xml
+++ b/packages/SystemUI/res-product/values-hy/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Դուք կատարել եք հեռախոսն ապակողպելու <xliff:g id="NUMBER">%d</xliff:g> անհաջող փորձ: Աշխատանքային պրոֆիլը կհեռացվի, և պրոֆիլի բոլոր տվյալները կջնջվեն:"</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Դուք կատարել եք ապակողպման նախշը մուտքագրելու <xliff:g id="NUMBER_0">%1$d</xliff:g> անհաջող փորձ: Եվս <xliff:g id="NUMBER_1">%2$d</xliff:g> անհաջող փորձից հետո ձեզանից կպահանջվի ապակողպել պլանշետը էլփոստի հաշվի միջոցով։\n\n Խնդրում ենք կրկին փորձել <xliff:g id="NUMBER_2">%3$d</xliff:g> վայրկյանից:"</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Դուք <xliff:g id="NUMBER_0">%1$d</xliff:g> անգամ սխալ եք հավաքել ձեր ապակողպման նմուշը: Եվս <xliff:g id="NUMBER_1">%2$d</xliff:g> անհաջող փորձից հետո ձեզ կառաջարկվի ապակողպել հեռախոսը` օգտագործելով էլփոստի հաշիվ:\n\n Կրկին փորձեք <xliff:g id="NUMBER_2">%3$d</xliff:g> վայրկյանից:"</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Հեռախոսն անջատվել էր տաքանալու պատճառով"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Սարքն անջատվել էր տաքանալու պատճառով"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Պլանշետն անջատվել էր տաքանալու պատճառով"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Ձեր հեռախոսն այժմ նորմալ է աշխատում։\nՀպեք՝ ավելին իմանալու համար"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Ձեր սարքն այժմ նորմալ է աշխատում։\nՀպեք՝ ավելին իմանալու համար"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Ձեր պլանշետն այժմ նորմալ է աշխատում։\nՀպեք՝ ավելին իմանալու համար"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Ձեր հեռախոսը չափազանց տաք էր, այդ պատճառով այն անջատվել է՝ հովանալու համար։ Հեռախոսն այժմ նորմալ աշխատում է։\n\nՀեռախոսը կարող է տաքանալ, եթե՝\n	• Օգտագործում եք ռեսուրսատար հավելվածներ (օրինակ՝ խաղեր, տեսանյութեր կամ նավիգացիայի հավելվածներ)\n	• Ներբեռնում կամ վերբեռնում եք ծանր ֆայլեր\n	• Օգտագործում եք ձեր հեռախոսը բարձր ջերմային պայմաններում"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Ձեր սարքը չափազանց տաք էր, այդ պատճառով այն անջատվել է՝ հովանալու համար։ Սարքն այժմ նորմալ աշխատում է։\n\nՍարքը կարող է տաքանալ, եթե՝\n	• Օգտագործում եք ռեսուրսատար հավելվածներ (օրինակ՝ խաղեր, տեսանյութեր կամ նավիգացիայի հավելվածներ)\n	• Ներբեռնում կամ վերբեռնում եք ծանր ֆայլեր\n	• Օգտագործում եք ձեր սարքը բարձր ջերմային պայմաններում"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Ձեր պլանշետը չափազանց տաք էր, այդ պատճառով այն անջատվել է՝ հովանալու համար: Պլանշետը այժմ նորմալ աշխատում է:\n\nՊլանշետը կարող է տաքանալ, եթե՝\n	• Օգտագործում եք ռեսուրսատար հավելվածներ (օրինակ՝ խաղեր, տեսանյութեր կամ նավիգացիայի հավելվածներ)\n	• Ներբեռնում կամ վերբեռնում եք ծանր ֆայլեր\n	• Օգտագործում եք ձեր պլանշետը բարձր ջերմային պայմաններում"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Հեռախոսը տաքանում է"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Սարքը տաքանում է"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Պլանշետը տաքանում է"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Հովանալու ընթացքում հեռախոսի որոշ գործառույթներ սահմանափակված են։\nՀպեք՝ ավելին իմանալու համար"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Հովանալու ընթացքում սարքի որոշ գործառույթներ սահմանափակված են։\nՀպեք՝ ավելին իմանալու համար"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Հովանալու ընթացքում պլանշետի որոշ գործառույթներ սահմանափակված են։\nՀպեք՝ ավելին իմանալու համար"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Ձեր հեռախոսն ավտոմատ կերպով կփորձի hովանալ։ Կարող եք շարունակել օգտագործել հեռախոսը, սակայն հնարավոր է, որ այն ավելի դանդաղ աշխատի։\n\nՀովանալուց հետո հեռախոսը կաշխատի կանոնավոր կերպով։"</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Ձեր սարքը ավտոմատ կերպով կփորձի hովանալ։ Կարող եք շարունակել օգտագործել սարքը, սակայն հնարավոր է, որ այն ավելի դանդաղ աշխատի:\n\nՀովանալուց հետո սարքը կաշխատի կանոնավոր կերպով։"</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Ձեր պլանշետը ավտոմատ կերպով կփորձի hովանալ։ Կարող եք շարունակել օգտագործել պլանշետը, սակայն հնարավոր է, որ այն ավելի դանդաղ աշխատի:\n\nՀովանալուց հետո պլանշետը կաշխատի կանոնավոր կերպով։"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Մատնահետքերի սկաները սնուցման կոճակի վրա է։ Այն հարթ կոճակ է ձայնի ուժգնության ուռուցիկ կոճակի կողքին՝ պլանշետի կողային մասում։"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Մատնահետքերի սկաները սնուցման կոճակի վրա է։ Այն հարթ կոճակ է ձայնի ուժգնության ուռուցիկ կոճակի կողքին՝ սարքի կողային մասում։"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Մատնահետքերի սկաները սնուցման կոճակի վրա է։ Այն հարթ կոճակ է ձայնի ուժգնության ուռուցիկ կոճակի կողքին՝ հեռախոսի կողային մասում։"</string>
diff --git a/packages/SystemUI/res-product/values-in/strings.xml b/packages/SystemUI/res-product/values-in/strings.xml
index af1895c..2224810 100644
--- a/packages/SystemUI/res-product/values-in/strings.xml
+++ b/packages/SystemUI/res-product/values-in/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali berupaya membuka kunci ponsel dengan tidak benar. Profil kerja akan dihapus, sehingga semua data profil akan dihapus."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, Anda akan diminta membuka kunci tablet menggunakan akun email.\n\n Coba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, Anda akan diminta membuka kunci ponsel menggunakan akun email.\n\n Coba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Ponsel dimatikan karena panas"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Perangkat dimatikan karena panas"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tablet dimatikan karena panas"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Ponsel kini berfungsi normal.\nKetuk untuk info selengkapnya"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Perangkat kini berfungsi normal.\nKetuk untuk info selengkapnya"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Tablet kini berfungsi normal.\nKetuk untuk info selengkapnya"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Ponsel terlalu panas, jadi dimatikan agar mendingin. Ponsel kini berfungsi normal.\n\nPonsel dapat menjadi terlalu panas jika Anda:\n	• Menggunakan aplikasi yang menggunakan sumber daya secara intensif (seperti aplikasi game, video, atau navigasi)\n	• Mendownload atau mengupload file besar\n	• Menggunakan ponsel dalam suhu tinggi"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Perangkat terlalu panas, jadi dimatikan agar mendingin. Perangkat kini berfungsi normal.\n\nPerangkat dapat menjadi terlalu panas jika Anda:\n	• Menggunakan aplikasi yang menggunakan sumber daya secara intensif (seperti aplikasi game, video, atau navigasi)\n	• Mendownload atau mengupload file besar\n	• Menggunakan perangkat dalam suhu tinggi"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Tablet terlalu panas, jadi dimatikan agar mendingin. Tablet kini berfungsi normal.\n\nTablet dapat menjadi terlalu panas jika Anda:\n	• Menggunakan aplikasi yang menggunakan sumber daya secara intensif (seperti aplikasi game, video, atau navigasi)\n	• Mendownload atau mengupload file besar\n	• Menggunakan tablet dalam suhu tinggi"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Ponsel menjadi panas"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Perangkat menjadi panas"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Tablet menjadi panas"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Beberapa fitur dibatasi saat ponsel mendingin.\nKetuk untuk info selengkapnya"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Beberapa fitur dibatasi saat perangkat mendingin.\nKetuk untuk info selengkapnya"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Beberapa fitur dibatasi saat tablet mendingin.\nKetuk untuk info selengkapnya"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Ponsel akan otomatis mencoba mendingin. Anda tetap dapat menggunakan ponsel, tetapi mungkin berjalan lebih lambat.\n\nSetelah dingin, ponsel akan berjalan seperti biasa."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Perangkat akan otomatis mencoba mendingin. Anda tetap dapat menggunakan perangkat, tetapi mungkin berjalan lebih lambat.\n\nSetelah dingin, perangkat akan berjalan seperti biasa."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Tablet akan otomatis mencoba mendingin. Anda tetap dapat menggunakan tablet, tetapi mungkin berjalan lebih lambat.\n\nSetelah dingin, tablet akan berjalan seperti biasa."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Sensor sidik jari ada di tombol daya. Tombol ini berupa tombol datar di samping tombol volume timbul di tepi tablet."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Sensor sidik jari ada di tombol daya. Tombol ini berupa tombol datar di samping tombol volume timbul di tepi perangkat."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Sensor sidik jari ada di tombol daya. Tombol ini berupa tombol datar di samping tombol volume timbul di tepi ponsel."</string>
diff --git a/packages/SystemUI/res-product/values-is/strings.xml b/packages/SystemUI/res-product/values-is/strings.xml
index 1e42255..0f3f71c 100644
--- a/packages/SystemUI/res-product/values-is/strings.xml
+++ b/packages/SystemUI/res-product/values-is/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Þú hefur gert <xliff:g id="NUMBER">%d</xliff:g> árangurslausar tilraunir til að opna símann. Vinnusniðið verður fjarlægt, með þeim afleiðingum að öllum gögnum þess verður eytt."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Þú hefur teiknað rangt opnunarmynstur <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verðurðu beðin(n) um að opna spjaldtölvuna með tölvupóstreikningi.\n\n Reyndu aftur eftir <xliff:g id="NUMBER_2">%3$d</xliff:g> sekúndur."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Þú hefur teiknað rangt opnunarmynstur <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verðurðu beðin(n) um að opna símann með tölvupóstreikningi.\n\n Reyndu aftur eftir <xliff:g id="NUMBER_2">%3$d</xliff:g> sekúndur."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Slökkt var á símanum vegna hita"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Slökkt var á tækinu vegna hita"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Slökkt var á spjaldtölvunni vegna hita"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Síminn virkar nú eins og venjulega.\nÝttu til að fá frekari upplýsingar"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Tækið virkar nú eins og venjulega.\nÝttu til að fá frekari upplýsingar"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Spjaldtölvan virkar nú eins og venjulega.\nÝttu til að fá frekari upplýsingar"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Síminn varð of heitur og því var slökkt á honum til að kæla hann. Síminn virkar núna sem skyldi.\n\nSíminn getur orðið of heitur ef þú:\n	• Notar plássfrek forrit (t.d. leikja-, myndbands- eða leiðsagnarforrit\n	• Sækir eða hleður upp stórum skrám\n	• Notar símann í miklum hita"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Tækið varð of heitt og því var slökkt á því til að kæla það. Tækið virkar núna sem skyldi.\n\nTækið getur orðið of heitt ef þú:\n	• Notar plássfrek forrit (t.d. leikja-, myndbands- eða leiðsagnarforrit\n	• Sækir eða hleður upp stórum skrám\n	• Notar tækið í miklum hita"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Spjaldtölvan varð of heit og því var slökkt á henni til að kæla hana. Spjaldtölvan virkar núna sem skyldi.\n\nSpjaldtölvan getur orðið of heit ef þú:\n	• Notar plássfrek forrit (t.d. leikja-, myndbands- eða leiðsagnarforrit\n	• Sækir eða hleður upp stórum skrám\n	• Notar spjaldtölvuna í miklum hita"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Síminn er að hitna"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Tækið er að hitna"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Spjaldtölvan er að hitna"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Sumir eiginleikar eru takmarkaðir á meðan síminn kælir sig.\nÝttu til að fá frekari upplýsingar"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Sumir eiginleikar eru takmarkaðir á meðan tækið kælir sig.\nÝttu til að fá frekari upplýsingar"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Sumir eiginleikar eru takmarkaðir á meðan spjaldtölvan kælir sig.\nÝttu til að fá frekari upplýsingar"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Síminn reynir að kæla sig sjálfkrafa. Þú getur áfram notað símann en hann gæti verið hægvirkari.\n\nÞegar síminn hefur kælt sig mun hann virka eðlilega."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Tækið reynir að kæla sig sjálfkrafa. Þú getur áfram notað tækið en það gæti verið hægvirkara.\n\nÞegar tækið hefur kælt sig mun það virka eðlilega."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Spjaldtölvan reynir að kæla sig sjálfkrafa. Þú getur áfram notað spjaldtölvuna en hún gæti verið hægvirkari.\n\nÞegar spjaldtölvan hefur kælt sig mun hún virka eðlilega."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Fingrafaralesarinn er á aflrofanum. Það er flati hnappurinn við hliðina á upphleypta hljóðstyrkshnappnum á hlið spjaldtölvunnar."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Fingrafaralesarinn er á aflrofanum. Það er flati hnappurinn við hliðina á upphleypta hljóðstyrkshnappnum á hlið tækisins."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Fingrafaralesarinn er á aflrofanum. Það er flati hnappurinn við hliðina á upphleypta hljóðstyrkshnappnum á hlið símans."</string>
diff --git a/packages/SystemUI/res-product/values-it/strings.xml b/packages/SystemUI/res-product/values-it/strings.xml
index 0b3bb3d..a9fd80b 100644
--- a/packages/SystemUI/res-product/values-it/strings.xml
+++ b/packages/SystemUI/res-product/values-it/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Hai tentato di sbloccare il telefono senza riuscirci per <xliff:g id="NUMBER">%d</xliff:g> volte. Il profilo di lavoro verrà rimosso e verranno quindi eliminati tutti i dati associati."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"<xliff:g id="NUMBER_0">%1$d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il tablet con un account email.\n\n Riprova tra <xliff:g id="NUMBER_2">%3$d</xliff:g> secondi."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"<xliff:g id="NUMBER_0">%1$d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il telefono con un account email.\n\n Riprova tra <xliff:g id="NUMBER_2">%3$d</xliff:g> secondi."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Lo smartphone si è spento per il calore"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Il dispositivo si è spento per il calore"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Il tablet si è spento per il calore"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Ora lo smartphone funziona normalmente.\nTocca per maggiori informazioni"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Ora il dispositivo funziona normalmente.\nTocca per maggiori informazioni"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Ora il tablet funziona normalmente.\nTocca per maggiori informazioni"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Lo smartphone era surriscaldato e si è spento per raffreddarsi. Ora funziona normalmente.\n\nLo smartphone può surriscaldarsi se:\n	• Utilizzi app che consumano molte risorse (ad esempio app di navigazione, giochi o video)\n	• Scarichi o carichi grandi file\n	• Lo utilizzi in presenza di alte temperature"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Il dispositivo era surriscaldato e si è spento per raffreddarsi. Ora funziona normalmente.\n\nIl dispositivo può surriscaldarsi se:\n	• Utilizzi app che consumano molte risorse (ad esempio app di navigazione, giochi o video)\n	• Scarichi o carichi grandi file\n	• Lo utilizzi in presenza di alte temperature"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Il tablet era surriscaldato e si è spento per raffreddarsi. Ora funziona normalmente.\n\nIl tablet può surriscaldarsi se:\n	• Utilizzi app che consumano molte risorse (ad esempio app di navigazione, giochi o video)\n	• Scarichi o carichi grandi file\n	• Lo utilizzi in presenza di alte temperature"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Surriscaldamento smartphone"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Surriscaldamento dispositivo"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Surriscaldamento tablet"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Alcune funzionalità sono state limitate durante il raffreddamento dello smartphone.\nTocca per maggiori informazioni"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Alcune funzionalità sono state limitate durante il raffreddamento del dispositivo.\nTocca per maggiori informazioni"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Alcune funzionalità sono state limitate durante il raffreddamento del tablet.\nTocca per maggiori informazioni"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Lo smartphone cercherà automaticamente di raffreddarsi. Puoi comunque usarlo, ma potrebbe essere più lento.\n\nUna volta raffreddato, lo smartphone funzionerà normalmente."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Il dispositivo cercherà automaticamente di raffreddarsi. Puoi comunque usarlo, ma potrebbe essere più lento.\n\nUna volta raffreddato, il dispositivo funzionerà normalmente."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Il tablet cercherà automaticamente di raffreddarsi. Puoi comunque usarlo, ma potrebbe essere più lento.\n\nUna volta raffreddato, il tablet funzionerà normalmente."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Il sensore di impronte digitali si trova sul tasto di accensione. Si tratta del tasto piatto accanto al tasto del volume in rilievo sul bordo del tablet."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Il sensore di impronte digitali si trova sul tasto di accensione. Si tratta del tasto piatto accanto al tasto del volume in rilievo sulla parte laterale del dispositivo."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Il sensore di impronte digitali si trova sul tasto di accensione. Si tratta del tasto piatto accanto al tasto del volume in rilievo sulla parte laterale dello smartphone."</string>
diff --git a/packages/SystemUI/res-product/values-iw/strings.xml b/packages/SystemUI/res-product/values-iw/strings.xml
index 71779f30..9365dd9 100644
--- a/packages/SystemUI/res-product/values-iw/strings.xml
+++ b/packages/SystemUI/res-product/values-iw/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"ניסית לבטל את נעילת הטלפון <xliff:g id="NUMBER">%d</xliff:g> פעמים. פרופיל העבודה יוסר וכל נתוני הפרופיל יימחקו."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"שרטטת קו ביטול נעילה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, ,תישלח אליך בקשה לבטל את נעילת הטאבלט באמצעות חשבון אימייל‏.\n\n יש לנסות שוב בעוד <xliff:g id="NUMBER_2">%3$d</xliff:g> שניות."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"שרטטת קו ביטול נעילה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, תישלח אליך בקשה לבטל את נעילת הטלפון באמצעות חשבון אימייל‏.\n\n יש לנסות שוב בעוד <xliff:g id="NUMBER_2">%3$d</xliff:g> שניות."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"הטלפון כבה בגלל התחממות"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"המכשיר כבה בגלל התחממות"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"הטאבלט כבה בגלל התחממות"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"הטלפון פועל כרגיל עכשיו.\nיש להקיש כדי להציג מידע נוסף"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"המכשיר פועל כרגיל עכשיו.\nיש להקיש כדי להציג מידע נוסף"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"הטאבלט פועל כרגיל עכשיו.\nיש להקיש כדי להציג מידע נוסף"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"הטלפון שלך התחמם יותר מדי וכבה כדי להתקרר. הטלפון פועל כרגיל עכשיו.\n\nייתכן שהטלפון יתחמם יותר מדי אם:\n	• משתמשים באפליקציות עתירות משאבים (כמו משחקים, אפליקציות וידאו או אפליקציות ניווט).\n	• מורידים או מעלים קבצים גדולים.\n	• משתמשים בטלפון בסביבה עם טמפרטורות גבוהות."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"המכשיר שלך התחמם יותר מדי וכבה כדי להתקרר. המכשיר פועל כרגיל עכשיו.\n\nייתכן שהמכשיר יתחמם יותר מדי אם:\n	• משתמשים באפליקציות עתירות משאבים (כמו משחקים, אפליקציות וידאו או אפליקציות ניווט).\n	• מורידים או מעלים קבצים גדולים.\n	• משתמשים במכשיר בסביבה עם טמפרטורות גבוהות."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"הטאבלט שלך התחמם יותר מדי וכבה כדי להתקרר. הטאבלט פועל כרגיל עכשיו.\n\nייתכן שהטאבלט יתחמם יותר מדי אם:\n	• משתמשים באפליקציות עתירות משאבים (כמו משחקים, אפליקציות וידאו או אפליקציות ניווט).\n	• מורידים או מעלים קבצים גדולים.\n	• משתמשים בטאבלט בסביבה עם טמפרטורות גבוהות."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"הטלפון מתחמם"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"המכשיר מתחמם"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"הטאבלט מתחמם"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"חלק מהתכונות מוגבלות כל עוד הטלפון מתקרר.\nיש להקיש כדי להציג מידע נוסף"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"חלק מהתכונות מוגבלות כל עוד המכשיר מתקרר.\nיש להקיש כדי להציג מידע נוסף"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"חלק מהתכונות מוגבלות כל עוד הטאבלט מתקרר.\nיש להקיש כדי להציג מידע נוסף"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"קירור הטלפון ייעשה באופן אוטומטי. אפשר עדיין להשתמש בטלפון, אבל ייתכן שהוא יפעל לאט יותר.\n\nהטלפון יחזור לפעול כרגיל לאחר שיתקרר."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"קירור המכשיר ייעשה באופן אוטומטי. אפשר עדיין להשתמש במכשיר אבל ייתכן שהוא יפעל לאט יותר.\n\nהמכשיר יחזור לפעול כרגיל לאחר שיתקרר."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"קירור הטאבלט ייעשה באופן אוטומטי. אפשר עדיין להשתמש בטאבלט אבל ייתכן שהוא יפעל לאט יותר.\n\nהטאבלט יחזור לפעול כרגיל לאחר שיתקרר."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"חיישן טביעות האצבע נמצא על לחצן ההפעלה. זה הלחצן השטוח ליד הלחצן הבולט של עוצמת הקול בשולי הטאבלט."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"חיישן טביעות האצבע נמצא על לחצן ההפעלה. זה הלחצן השטוח ליד הלחצן הבולט של עוצמת הקול בשולי המכשיר."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"חיישן טביעות האצבע נמצא על לחצן ההפעלה. זה הלחצן השטוח ליד הלחצן הבולט של עוצמת הקול בשולי הטלפון."</string>
diff --git a/packages/SystemUI/res-product/values-ja/strings.xml b/packages/SystemUI/res-product/values-ja/strings.xml
index 68f030b..1fc8775 100644
--- a/packages/SystemUI/res-product/values-ja/strings.xml
+++ b/packages/SystemUI/res-product/values-ja/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"スマートフォンのロック解除に <xliff:g id="NUMBER">%d</xliff:g> 回失敗しました。仕事用プロファイルは削除され、プロファイルのデータはすべて消去されます。"</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"ロック解除パターンの入力を <xliff:g id="NUMBER_0">%1$d</xliff:g> 回間違えました。あと <xliff:g id="NUMBER_1">%2$d</xliff:g> 回間違えると、タブレットのロック解除にメール アカウントが必要になります。\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後にもう一度お試しください。"</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"ロック解除パターンの入力を <xliff:g id="NUMBER_0">%1$d</xliff:g> 回間違えました。あと <xliff:g id="NUMBER_1">%2$d</xliff:g> 回間違えると、スマートフォンのロック解除にメール アカウントが必要になります。\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後にもう一度お試しください。"</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"温度上昇により電源が OFF になりました"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"温度上昇により電源が OFF になりました"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"温度上昇により電源が OFF になりました"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"お使いのスマートフォンは現在、正常に動作しています。\nタップして詳細を表示"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"お使いのデバイスは現在、正常に動作しています。\nタップして詳細を表示"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"お使いのタブレットは現在、正常に動作しています。\nタップして詳細を表示"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"スマートフォンが熱くなりすぎたため電源が OFF になりました。現在は正常に動作しています。\n\nスマートフォンは以下の場合に熱くなる場合があります。\n	• リソースを集中的に使用する機能やアプリ(ゲームアプリ、動画アプリ、ナビアプリなど)を使用\n	• サイズの大きいファイルをダウンロードまたはアップロード\n	• 高温の場所で使用"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"デバイスが熱くなりすぎたため電源が OFF になりました。現在は正常に動作しています。\n\nデバイスは以下の場合に熱くなる場合があります。\n	• リソースを集中的に使用する機能やアプリ(ゲームアプリ、動画アプリ、ナビアプリなど)を使用\n	• サイズの大きいファイルをダウンロードまたはアップロード\n	• 高温の場所で使用"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"タブレットが熱くなりすぎたため電源が OFF になりました。現在は正常に動作しています。\n\nタブレットは以下の場合に熱くなる場合があります。\n	• リソースを集中的に使用する機能やアプリ(ゲームアプリ、動画アプリ、ナビアプリなど)を使用\n	• サイズの大きいファイルをダウンロードまたはアップロード\n	• 高温の場所で使用"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"スマートフォンの温度が上昇中"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"デバイスの温度が上昇中"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"タブレットの温度が上昇中"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"スマートフォンのクールダウン中は一部の機能が制限されます。\nタップして詳細を表示"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"デバイスのクールダウン中は一部の機能が制限されます。\nタップして詳細を表示"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"タブレットのクールダウン中は一部の機能が制限されます。\nタップして詳細を表示"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"スマートフォンは自動的にクールダウンを行います。その間もスマートフォンを使用できますが、動作が遅くなる可能性があります。\n\nクールダウンが完了すると、通常どおり動作します。"</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"デバイスは自動的にクールダウンを行います。その間もデバイスを使用できますが、動作が遅くなる可能性があります。\n\nクールダウンが完了すると、通常どおり動作します。"</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"タブレットは自動的にクールダウンを行います。その間もタブレットを使用できますが、動作が遅くなる可能性があります。\n\nクールダウンが完了すると、通常どおり動作します。"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"指紋認証センサーは電源ボタンに内蔵されています。タブレット側面のボタンのうち、音量ボタンの横にあるフラットなボタンです。"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"指紋認証センサーは電源ボタンに内蔵されています。デバイス側面のボタンのうち、音量ボタンの横にあるフラットなボタンです。"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"指紋認証センサーは電源ボタンに内蔵されています。スマートフォン側面のボタンのうち、音量ボタンの横にあるフラットなボタンです。"</string>
diff --git a/packages/SystemUI/res-product/values-ka/strings.xml b/packages/SystemUI/res-product/values-ka/strings.xml
index 34fc24c..f007c4a 100644
--- a/packages/SystemUI/res-product/values-ka/strings.xml
+++ b/packages/SystemUI/res-product/values-ka/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"თქვენ არასწორად ცადეთ ტელეფონის განბლოკვა <xliff:g id="NUMBER">%d</xliff:g>-ჯერ. ამის გამო, სამსახურის პროფილი ამოიშლება, რაც პროფილის ყველა მონაცემის წაშლას გამოიწვევს."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"თქვენ არასწორად დახატეთ თქვენი განბლოკვის ნიმუში <xliff:g id="NUMBER_0">%1$d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%2$d</xliff:g> წარუმატებელი მცდელობის შემდეგ მოგთხოვთ, ტაბლეტი თქვენი ელფოსტის ანგარიშის მეშვეობით განბლოკოთ.\n\n ცადეთ ხელახლა <xliff:g id="NUMBER_2">%3$d</xliff:g> წამში."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"თქვენ არასწორად დახატეთ თქვენი განბლოკვის ნიმუში <xliff:g id="NUMBER_0">%1$d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%2$d</xliff:g> წარუმატებელი მცდელობის შემდეგ მოგთხოვთ, ტელეფონი თქვენი ელფოსტის ანგარიშის მეშვეობით განბლოკოთ.\n\n ცადეთ ხელახლა <xliff:g id="NUMBER_2">%3$d</xliff:g> წამში."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"ტელეფონი გამოირთო გაცხელების გამო"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"მოწყობილობა გამოირთო გაცხელების გამო"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"ტაბლეტი გამოირთო გაცხელების გამო"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"თქვენი ტელეფონი უკვე ნორმალურად მუშაობს.\nშეეხეთ დამატებითი ინფორმაციის მისაღებად"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"თქვენი მოწყობილობა უკვე ნორმალურად მუშაობს.\nშეეხეთ დამატებითი ინფორმაციის მისაღებად"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"თქვენი ტაბლეტი უკვე ნორმალურად მუშაობს.\nშეეხეთ დამატებითი ინფორმაციის მისაღებად"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"თქვენი ტელეფონი გამოირთო გასაგრილებლად, რადგან ის მეტისმეტად გაცხელდა. ახლა ის ჩვეულებრივად მუშაობს.\n\nტელეფონის გაცხელების მიზეზებია:\n	• რესურსტევადი აპების გამოყენება (მაგ.: სათამაშო, ვიდეო ან ნავიგაციის აპების)\n	• დიდი ფაილების ჩამოტვირთვა ან ატვირთვა\n	• მოწყობილობის გამოყენება მაღალი ტემპერატურისას"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"თქვენი მოწყობილობა გამოირთო გასაგრილებლად, რადგან ის მეტისმეტად გაცხელდა. ახლა ის ჩვეულებრივად მუშაობს.\n\nმოწყობილობის გაცხელების მიზეზებია:\n	• რესურსტევადი აპების გამოყენება (მაგ.: სათამაშო, ვიდეო ან ნავიგაციის აპების)\n	• დიდი ფაილების ჩამოტვირთვა ან ატვირთვა\n	• მოწყობილობის გამოყენება მაღალი ტემპერატურისას"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"თქვენი ტაბლეტი გამოირთო გასაგრილებლად, რადგან ის მეტისმეტად გაცხელდა. ახლა ის ჩვეულებრივად მუშაობს.\n\nტაბლეტის გაცხელების მიზეზებია:\n	• რესურსტევადი აპების გამოყენება (მაგ.: სათამაშო, ვიდეო ან ნავიგაციის აპების)\n	• დიდი ფაილების ჩამოტვირთვა ან ატვირთვა\n	• მოწყობილობის გამოყენება მაღალი ტემპერატურისას"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"ტელეფონი ცხელდება"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"მოწყობილობა ცხელდება"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"ტაბლეტი ცხელდება"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"ზოგიერთი ფუნქცია შეზღუდული იქნება, სანამ ტელეფონი გაგრილდება.\nშეეხეთ დამატებითი ინფორმაციის მისაღებად"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"ზოგიერთი ფუნქცია შეზღუდული იქნება, სანამ მოწყობილობა გაგრილდება.\nშეეხეთ დამატებითი ინფორმაციის მისაღებად"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"ზოგიერთი ფუნქცია შეზღუდული იქნება, სანამ ტაბლეტი გაგრილდება.\nშეეხეთ დამატებითი ინფორმაციის მისაღებად"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"თქვენი ტელეფონი გაგრილებას ავტომატურად შეეცდება. შეგიძლიათ გააგრძელოთ მისით სარგებლობა, თუმცა ტელეფონმა შეიძლება უფრო ნელა იმუშაოს.\n\nგაგრილების შემდგომ ის ჩვეულებრივად იმუშავებს."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"თქვენი მოწყობილობა გაგრილებას ავტომატურად შეეცდება. შეგიძლიათ გააგრძელოთ მისით სარგებლობა, თუმცა ტელეფონმა შეიძლება უფრო ნელა იმუშაოს.\n\nგაგრილების შემდგომ ის ჩვეულებრივად იმუშავებს."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"თქვენი ტაბლეტი გაგრილებას ავტომატურად შეეცდება. შეგიძლიათ გააგრძელოთ თქვენი ტაბლეტით სარგებლობა, თუმცა მან შეიძლება უფრო ნელა იმუშაოს.\n\nგაგრილების შემდგომ ის ჩვეულებრივად იმუშავებს."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"თითის ანაბეჭდის სენსორი ჩართვის ღილაკზეა. ეს არის ბრტყელი ღილაკი ხმის აწევის ღილაკის გვერდით, ტაბლეტის კიდეში."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"თითის ანაბეჭდის სენსორი ჩართვის ღილაკზეა. ეს არის ბრტყელი ღილაკი ხმის აწევის ღილაკის გვერდით, მოწყობილობის კიდეში."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"თითის ანაბეჭდის სენსორი ჩართვის ღილაკზეა. ეს არის ბრტყელი ღილაკი ხმის აწევის ღილაკის გვერდით, ტელეფონის კიდეში."</string>
diff --git a/packages/SystemUI/res-product/values-kk/strings.xml b/packages/SystemUI/res-product/values-kk/strings.xml
index 73b637e..83b2351 100644
--- a/packages/SystemUI/res-product/values-kk/strings.xml
+++ b/packages/SystemUI/res-product/values-kk/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Телефон құлпын ашуға <xliff:g id="NUMBER">%d</xliff:g> рет сәтсіз әрекет жасалды. Жұмыс профилі өшіріліп, оның бүкіл деректері жойылады."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Құлыпты ашу өрнегі <xliff:g id="NUMBER_0">%1$d</xliff:g> рет қате енгізілді. <xliff:g id="NUMBER_1">%2$d</xliff:g> әрекет қалды. Одан кейін планшетті аккаунт арқылы ашу сұралады. \n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундтан кейін әрекетті қайталаңыз."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Құлыпты ашу өрнегі <xliff:g id="NUMBER_0">%1$d</xliff:g> рет қате енгізілді. <xliff:g id="NUMBER_1">%2$d</xliff:g> әрекет қалды. Одан кейін телефонды аккаунт арқылы ашу сұралады. \n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундтан кейін әрекетті қайталаңыз."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Телефон қызып кеткендіктен өшірілді"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Құрылғы қызып кеткендіктен өшірілді"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Планшет қызып кеткендіктен өшірілді"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Телефоныңыз қалыпты жұмыс істеп тұр.\nТолық ақпарат алу үшін түртіңіз."</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Құрылғыңыз қалыпты жұмыс істеп тұр.\nТолық ақпарат алу үшін түртіңіз."</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Планшетіңіз қалыпты жұмыс істеп тұр.\nТолық ақпарат алу үшін түртіңіз."</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Телефоныңыз қатты қызып кеткендіктен өшірілген еді. Ал қазір қалыпты жұмыс істеп тұр.\n\nОл мына жағдайларда қызып кетуі мүмкін:\n	• ресурстарды көп көлемде қажет ететін қолданбаларды (ойын, бейне немесе навигация қолданбалары) пайдалану\n	• үлкен көлемді файлдарды жүктеу немесе жүктеп салу;\n	• телефонды жоғары температурада пайдалану."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Құрылғыңыз қатты қызып кеткендіктен өшірілген еді. Ал қазір қалыпты жұмыс істеп тұр.\n\nОл мына жағдайларда қызып кетуі мүмкін:\n	• ресурстарды көп көлемде қажет ететін қолданбаларды (ойын, бейне немесе навигация қолданбалары) пайдалану;\n	• үлкен көлемді файлдарды жүктеу немесе жүктеп салу;\n	• құрылғыны жоғары температурада пайдалану."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Планшетіңіз қатты қызып кеткендіктен өшірілген еді. Ал қазір қалыпты жұмыс істеп тұр.\n\nОл мына жағдайларда қызып кетуі мүмкін:\n	• ресурстарды көп көлемде қажет ететін қолданбаларды (ойын, бейне немесе навигация қолданбалары) пайдалану;\n	• үлкен көлемді файлдарды жүктеу немесе жүктеп салу;\n	• планшетті жоғары температурада пайдалану."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Телефон қызып бара жатыр"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Құрылғы қызып бара жатыр"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Планшет қызып бара жатыр"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Телефон толық суығанға дейін, кейбір функцияның жұмысы шектеледі.\nТолық ақпарат үшін түртіңіз."</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Құрылғы толық суығанға дейін, кейбір функцияның жұмысы шектеледі.\nТолық ақпарат үшін түртіңіз."</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Планшет толық суығанға дейін, кейбір функцияның жұмысы шектеледі.\nТолық ақпарат үшін түртіңіз."</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Телефон автоматты түрде суи бастайды. Оны пайдалана бере аласыз, бірақ ол баяуырақ жұмыс істеуі мүмкін.\n\nСуығаннан кейін, оның жұмысы қалпына келеді."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Құрылғы автоматты түрде суи бастайды. Оны пайдалана бере аласыз, бірақ ол баяуырақ жұмыс істеуі мүмкін.\n\nСуығаннан кейін, оның жұмысы қалпына келеді."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Планшет автоматты түрде суи бастайды. Оны пайдалана бере аласыз, бірақ ол баяуырақ жұмыс істеуі мүмкін.\n\nСуығаннан кейін, оның жұмысы қалпына келеді."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Саусақ ізін оқу сканері қуат түймесінде орналасқан. Ол – планшет шетіндегі шығыңқы дыбыс деңгейі түймесінің жанында орналасқан жалпақ түйме."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Саусақ ізін оқу сканері қуат түймесінде орналасқан. Ол – құрылғы шетіндегі шығыңқы дыбыс деңгейі түймесінің жанында орналасқан жалпақ түйме."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Саусақ ізін оқу сканері қуат түймесінде орналасқан. Ол – телефон шетіндегі шығыңқы дыбыс деңгейі түймесінің жанында орналасқан жалпақ түйме."</string>
diff --git a/packages/SystemUI/res-product/values-km/strings.xml b/packages/SystemUI/res-product/values-km/strings.xml
index 611ee94..34189d4 100644
--- a/packages/SystemUI/res-product/values-km/strings.xml
+++ b/packages/SystemUI/res-product/values-km/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"អ្នក​បាន​ព្យាយាម​ដោះសោ​ទូរសព្ទ​នេះ​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER">%d</xliff:g> ដង​ហើយ។ កម្រង​ព័ត៌មាន​ការងារ​នេះ​នឹង​ត្រូវ​បាន​លុប ហើយ​វា​នឹង​លុប​ទិន្នន័យ​កម្រង​ព័ត៌មាន​ទាំងអស់។"</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"អ្នក​បាន​គូរ​លំនាំ​ដោះ​សោ​របស់​អ្នក​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%1$d</xliff:g> ដង​ហើយ។ បន្ទាប់ពីមានការ​ព្យាយាម​ដោះ​សោ​ចំនួន <xliff:g id="NUMBER_1">%2$d</xliff:g> ដងទៀត​មិន​ទទួល​បាន​ជោគជ័យ អ្នក​នឹង​ត្រូវ​បាន​ស្នើ​ឱ្យ​ដោះ​សោ​ថេប្លេត​របស់​អ្នក​ ដោយ​ប្រើ​គណនី​អ៊ីមែល។\n\n សូមព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_2">%3$d</xliff:g> វិនាទី​ទៀត។"</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"អ្នកបានគូរលំនាំ​ដោះសោ​របស់អ្នក​មិន​ត្រឹមត្រូវចំនួន <xliff:g id="NUMBER_0">%1$d</xliff:g> ដងហើយ។ បន្ទាប់ពីមាន​ការព្យាយាម​ដោះសោចំនួន <xliff:g id="NUMBER_1">%2$d</xliff:g> ដងទៀតមិនទទួលបាន​ជោគជ័យ អ្នកនឹង​ត្រូវបាន​ស្នើឱ្យ​ដោះសោ​ទូរសព្ទ​របស់​អ្នកដោយ​ប្រើគណនី​អ៊ីមែល។\n\n សូមព្យាយាម​ម្ដងទៀតក្នុង​រយៈពេល <xliff:g id="NUMBER_2">%3$d</xliff:g> វិនាទីទៀត។"</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"ទូរសព្ទបានបិទដោយសារកម្ដៅ"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"ឧបករណ៍បានបិទដោយសារកម្ដៅ"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"ថេប្លេតបានបិទដោយសារកម្ដៅ"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"ឥឡូវនេះ ទូរសព្ទ​របស់អ្នក​កំពុងដំណើរការ​ជាធម្មតា។\nសូមចុច​ដើម្បីទទួលបាន​ព័ត៌មានបន្ថែម"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"ឥឡូវនេះ ឧបករណ៍​របស់អ្នក​កំពុងដំណើរការ​ជាធម្មតា។\nសូមចុច​ដើម្បីទទួលបាន​ព័ត៌មានបន្ថែម"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"ឥឡូវនេះ ថេប្លេត​របស់អ្នក​កំពុងដំណើរការ​ជាធម្មតា។\nសូមចុច​ដើម្បីទទួលបាន​ព័ត៌មានបន្ថែម"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"ទូរសព្ទ​របស់អ្នក​ក្តៅពេក ដូច្នេះ​វាបាន​បិទ​ដើម្បី​បន្ថយ​កម្តៅ។ ឥឡូវនេះ ​ទូរសព្ទ​របស់អ្នក​កំពុង​ដំណើរការ​ធម្មតា។\n\nទូរសព្ទ​របស់អ្នក​អាចនឹង​ឡើង​កម្តៅ​ខ្លាំងជ្រុល ប្រសិន​បើអ្នក៖\n	• ប្រើប្រាស់​កម្មវិធី​ដែល​ប្រើប្រាស់ទិន្នន័យច្រើនក្នុងរយៈពេលខ្លី (ដូចជាហ្គេម វីដេអូ ឬកម្មវិធីរុករក)\n	• ទាញយក ឬ​បង្ហោះ​ឯកសារដែលមានទំហំធំ\n	• ប្រើប្រាស់​ទូរសព្ទ​របស់អ្នក​នៅកន្លែង​មានសីតុណ្ហភាព​ខ្ពស់"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"ឧបករណ៍​របស់អ្នក​ក្តៅពេក ដូច្នេះ​វាបាន​បិទ​ដើម្បី​បន្ថយ​កម្តៅ។ ឥឡូវនេះ ​ឧបករណ៍​របស់អ្នក​កំពុង​ដំណើរការ​ធម្មតា។\n\nឧបករណ៍​របស់អ្នក​អាចនឹង​ឡើង​កម្តៅ​ខ្លាំងជ្រុល ប្រសិន​បើអ្នក៖\n	• ប្រើប្រាស់​កម្មវិធី​ដែល​ប្រើប្រាស់ទិន្នន័យច្រើនក្នុងរយៈពេលខ្លី (ដូចជាហ្គេម វីដេអូ ឬកម្មវិធីរុករក)\n	• ទាញយក ឬ​បង្ហោះ​ឯកសារដែលមានទំហំធំ\n	• ប្រើប្រាស់​ឧបករណ៍​របស់អ្នក​នៅកន្លែង​មានសីតុណ្ហភាព​ខ្ពស់"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"ថេប្លេត​របស់អ្នក​ក្តៅពេក ដូច្នេះ​វាបាន​បិទ​ដើម្បី​បន្ថយ​កម្តៅ។ ឥឡូវនេះ ​ថេប្លេតរបស់អ្នក​កំពុង​ដំណើរការ​ធម្មតា។\n\nថេប្លេត​របស់អ្នក​អាចនឹង​ឡើង​កម្តៅ​ខ្លាំងជ្រុល ប្រសិន​បើអ្នក៖\n	• ប្រើប្រាស់​កម្មវិធី​ដែល​ប្រើប្រាស់ទិន្នន័យច្រើនក្នុងរយៈពេលខ្លី (ដូចជាហ្គេម វីដេអូ ឬកម្មវិធីរុករក)\n	• ទាញយក ឬ​បង្ហោះ​ឯកសារដែលមានទំហំធំ\n	• ប្រើប្រាស់​ថេប្លេត​របស់អ្នក​នៅកន្លែង​មានសីតុណ្ហភាព​ខ្ពស់"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"ទូរសព្ទ​កំពុងកើនកម្តៅ"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"ឧបករណ៍​កំពុងកើនកម្ដៅ"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"ថេប្លេត​កំពុងកើនកម្តៅ"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"មុខងារ​មួយចំនួន​នឹងមិនអាច​ប្រើបានពេញលេញ​នោះទេ ខណៈពេល​ដែលទូរសព្ទ​កំពុងបញ្ចុះកម្ដៅ។\nសូមចុច​ដើម្បីទទួលបាន​ព័ត៌មានបន្ថែម"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"មុខងារមួយចំនួន​នឹងមិនអាចប្រើបានពេញលេញនោះទេ ខណៈពេលដែល​ឧបករណ៍​កំពុងបញ្ចុះកម្ដៅ។\nសូមចុចដើម្បីទទួលបាន​ព័ត៌មានបន្ថែម"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"មុខងារ​មួយចំនួន​នឹងមិនអាច​ប្រើបានពេញលេញ​នោះទេ ខណៈពេល​ដែលថេប្លេត​កំពុងបញ្ចុះកម្ដៅ។\nសូមចុច​ដើម្បីទទួលបាន​ព័ត៌មានបន្ថែម"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"ទូរសព្ទ​របស់អ្នក​នឹង​ព្យាយាម​បញ្ចុះ​កម្តៅ​ដោយ​ស្វ័យប្រវត្តិ។ អ្នក​នៅតែ​អាច​ប្រើ​ទូរសព្ទ​របស់អ្នក​បាន​ដដែល​ ប៉ុន្តែ​ទូរសព្ទនេះ​អាចដំណើរការ​យឺតជាងមុន។\n\nនៅពេល​ទូរសព្ទ​របស់អ្នកចុះ​ត្រជាក់​​ហើយ ទូរសព្ទនេះ​នឹង​ដំណើរការធម្មតា។"</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"ឧបករណ៍របស់អ្នក​នឹងព្យាយាមបញ្ចុះកម្ដៅ​ដោយស្វ័យប្រវត្តិ។ អ្នកនៅតែ​អាចប្រើឧបករណ៍​របស់អ្នកបានដដែល ប៉ុន្តែឧបករណ៍នេះ​អាចដំណើរការ​យឺតជាងមុន។\n\nនៅពេលឧបករណ៍​របស់អ្នកចុះ​ត្រជាក់​ហើយ ឧបករណ៍នេះនឹង​ដំណើរការ​ធម្មតា។"</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"ថេប្លេតរបស់អ្នក​នឹងព្យាយាមបញ្ចុះកម្ដៅ​ដោយស្វ័យប្រវត្តិ។ អ្នកនៅតែ​អាចប្រើថេប្លេត​របស់អ្នកបានដដែល ប៉ុន្តែថេប្លេតនេះ​អាចដំណើរការ​យឺតជាងមុន។\n\nនៅពេលថេប្លេត​របស់អ្នកចុះត្រជាក់ហើយ ថេប្លេតនេះនឹង​ដំណើរការ​ធម្មតា។"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"សេនស័រចាប់ស្នាមម្រាមដៃ​ស្ថិតនៅលើប៊ូតុង​ថាមពល។ វាជាប៊ូតុងរាបស្មើនៅជាប់នឹងប៊ូតុងកម្រិតសំឡេងដែលលៀនចេញមកនៅលើគែមថេប្លេត។"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"សេនស័រចាប់ស្នាមម្រាមដៃ​ស្ថិតនៅលើប៊ូតុង​ថាមពល។ វាជាប៊ូតុងរាបស្មើនៅជាប់នឹងប៊ូតុងកម្រិតសំឡេងដែលលៀនចេញមកនៅលើគែមឧបករណ៍។"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"សេនស័រចាប់ស្នាមម្រាមដៃ​ស្ថិតនៅលើប៊ូតុង​ថាមពល។ វាជាប៊ូតុងរាបស្មើនៅជាប់នឹងប៊ូតុងកម្រិតសំឡេងដែលលៀនចេញមកនៅលើគែមទូរសព្ទ។"</string>
diff --git a/packages/SystemUI/res-product/values-kn/strings.xml b/packages/SystemUI/res-product/values-kn/strings.xml
index 4fbf76f..4532d83 100644
--- a/packages/SystemUI/res-product/values-kn/strings.xml
+++ b/packages/SystemUI/res-product/values-kn/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"ಫೋನ್ ಅನ್ನು ಅನ್‌ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ ಅನ್ನು ತೆಗೆದುಹಾಕಲಾಗುತ್ತದೆ, ಇದು ಪ್ರೊಫೈಲ್‌ನ ಎಲ್ಲಾ ಡೇಟಾವನ್ನು ಅಳಿಸುತ್ತದೆ."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"ನಿಮ್ಮ ಅನ್‍‍ಲಾಕ್ ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಡ್ರಾ ಮಾಡಿರುವಿರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ಬಳಿಕ, ನಿಮ್ಮ ಇಮೇಲ್ ಖಾತೆಯನ್ನು ಬಳಸಿ ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ನಿಮ್ಮನ್ನು ಕೇಳಲಾಗುತ್ತದೆ.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ಸೆಕೆಂಡ್‌ಗಳಲ್ಲಿ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"ನಿಮ್ಮ ಅನ್‍‍ಲಾಕ್ ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಡ್ರಾ ಮಾಡಿರುವಿರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ಬಳಿಕ, ಇಮೇಲ್ ಖಾತೆಯನ್ನು ಬಳಸಿ ನಿಮ್ಮ ಫೋನ್ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ನಿಮ್ಮನ್ನು ಕೇಳಲಾಗುತ್ತದೆ.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ಸೆಕೆಂಡ್‌ಗಳಲ್ಲಿ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"ಫೋನ್ ಬಿಸಿಯಾದ ಕಾರಣದಿಂದಾಗಿ ಆಫ್ ಆಗಿದೆ"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"ಸಾಧನ ಬಿಸಿಯಾದ ಕಾರಣದಿಂದಾಗಿ ಆಫ್ ಆಗಿದೆ"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"ಟ್ಯಾಬ್ಲೆಟ್‌‌ ಬಿಸಿಯಾದ ಕಾರಣ ಆಫ್ ಆಗಿದೆ"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"ನಿಮ್ಮ ಫೋನ್ ಈಗ ಎಂದಿನಂತೆ ರನ್ ಆಗುತ್ತಿದೆ.\nಇನ್ನಷ್ಟು ಮಾಹಿತಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"ನಿಮ್ಮ ಸಾಧನವು ಈಗ ಎಂದಿನಂತೆ ರನ್ ಆಗುತ್ತಿದೆ.\nಇನ್ನಷ್ಟು ಮಾಹಿತಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್‌‌ ಈಗ ಎಂದಿನಂತೆ ರನ್ ಆಗುತ್ತಿದೆ.\nಇನ್ನಷ್ಟು ಮಾಹಿತಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"ನಿಮ್ಮ ಫೋನ್ ತುಂಬಾ ಬಿಸಿಯಾದ ಕಾರಣ ಅದನ್ನು ತಣ್ಣಗಾಗಿಸಲು ಆಫ್ ಮಾಡಲಾಗಿದೆ. ನಿಮ್ಮ ಫೋನ್ ಈಗ ಸಾಮಾನ್ಯ ರೀತಿಯಲ್ಲಿ ರನ್ ಆಗುತ್ತಿದೆ.\n\nನಿಮ್ಮ ಫೋನ್ ಈ ಕೆಳಗಿನ ಕಾರಣಗಳಿಂದ ತುಂಬಾ ಬಿಸಿಯಾಗಬಹುದು:\n	• ಹೆಚ್ಚು ಸಂಪನ್ಮೂಲಗಳನ್ನು ಬಳಸಿಕೊಳ್ಳುವ ಆ್ಯಪ್‌ಗಳ ಬಳಕೆ (ಉದಾಹರಣೆಗೆ ಗೇಮಿಂಗ್, ವೀಡಿಯೊ ಅಥವಾ ನ್ಯಾವಿಗೇಶನ್ ಆ್ಯಪ್‌ಗಳು)\n	• ದೊಡ್ಡ ಫೈಲ್‌ಗಳನ್ನು ಡೌನ್‌ಲೋಡ್ ಅಥವಾ ಅಪ್‌ಲೋಡ್ ಮಾಡುವುದು\n	• ಅಧಿಕ ತಾಪಮಾನದಲ್ಲಿ ಫೋನ್‌ ಬಳಸುವುದು"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"ನಿಮ್ಮ ಸಾಧನವು ತುಂಬಾ ಬಿಸಿಯಾದ ಕಾರಣ ಅದನ್ನು ತಣ್ಣಗಾಗಿಸಲು ಆಫ್ ಮಾಡಲಾಗಿದೆ. ನಿಮ್ಮ ಸಾಧನವು ಈಗ ಸಾಮಾನ್ಯ ರೀತಿಯಲ್ಲಿ ರನ್ ಆಗುತ್ತಿದೆ.\n\nನಿಮ್ಮ ಸಾಧನವು ಈ ಕೆಳಗಿನ ಕಾರಣಗಳಿಂದ ತುಂಬಾ ಬಿಸಿಯಾಗಬಹುದು:\n	• ಹೆಚ್ಚು ಸಂಪನ್ಮೂಲಗಳನ್ನು ಬಳಸಿಕೊಳ್ಳುವ ಆ್ಯಪ್‌ಗಳ ಬಳಕೆ (ಉದಾಹರಣೆಗೆ ಗೇಮಿಂಗ್, ವೀಡಿಯೊ ಅಥವಾ ನ್ಯಾವಿಗೇಶನ್ ಆ್ಯಪ್‌ಗಳು)\n	• ದೊಡ್ಡ ಫೈಲ್‌ಗಳನ್ನು ಡೌನ್‌ಲೋಡ್ ಅಥವಾ ಅಪ್‌ಲೋಡ್ ಮಾಡುವುದು\n	• ಅಧಿಕ ತಾಪಮಾನದಲ್ಲಿ ಸಾಧನವನ್ನು ಬಳಸುವುದು"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್‌‌ ತುಂಬಾ ಬಿಸಿಯಾದ ಕಾರಣ ಅದನ್ನು ತಣ್ಣಗಾಗಿಸಲು ಆಫ್ ಮಾಡಲಾಗಿದೆ. ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್‌‌ ಈಗ ಸಾಮಾನ್ಯ ರೀತಿಯಲ್ಲಿ ರನ್ ಆಗುತ್ತಿದೆ.\n\nನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್‌‌ ಈ ಕೆಳಗಿನ ಕಾರಣಗಳಿಂದ ತುಂಬಾ ಬಿಸಿಯಾಗಬಹುದು:\n	• ಹೆಚ್ಚು ಸಂಪನ್ಮೂಲಗಳನ್ನು ಬಳಸಿಕೊಳ್ಳುವ ಆ್ಯಪ್‌ಗಳ ಬಳಕೆ (ಉದಾಹರಣೆಗೆ ಗೇಮಿಂಗ್, ವೀಡಿಯೊ ಅಥವಾ ನ್ಯಾವಿಗೇಶನ್ ಆ್ಯಪ್‌ಗಳು)\n	• ದೊಡ್ಡ ಫೈಲ್‌ಗಳನ್ನು ಡೌನ್‌ಲೋಡ್ ಅಥವಾ ಅಪ್‌ಲೋಡ್ ಮಾಡುವುದು\n	• ಅಧಿಕ ತಾಪಮಾನದಲ್ಲಿ ಟ್ಯಾಬ್ಲೆಟ್‌‌ ಬಳಸುವುದು"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"ಫೋನ್ ಬಿಸಿಯಾಗುತ್ತಿದೆ"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"ಸಾಧನವು ಬಿಸಿಯಾಗುತ್ತಿದೆ"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"ಟ್ಯಾಬ್ಲೆಟ್‌‌ ಬಿಸಿಯಾಗುತ್ತಿದೆ"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"ಫೋನ್ ತಣ್ಣಗಾಗುವವರೆಗೂ ಕೆಲವು ಫೀಚರ್‌ಗಳನ್ನು ಸೀಮಿತಗೊಳಿಸಲಾಗುತ್ತದೆ.\nಇನ್ನಷ್ಟು ಮಾಹಿತಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"ಸಾಧನವು ತಣ್ಣಗಾಗುವವರೆಗೂ ಕೆಲವು ಫೀಚರ್‌ಗಳು ಸೀಮಿತಗೊಳಿಸಲಾಗುತ್ತದೆ.\nಇನ್ನಷ್ಟು ಮಾಹಿತಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"ಟ್ಯಾಬ್ಲೆಟ್‌‌ ತಣ್ಣಗಾಗುವವರೆಗೂ ಕೆಲವು ಫೀಚರ್‌ಗಳನ್ನು ಸೀಮಿತಗೊಳಿಸಲಾಗುತ್ತದೆ.\nಇನ್ನಷ್ಟು ಮಾಹಿತಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"ನಿಮ್ಮ ಫೋನ್ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ತಣ್ಣಗಾಗಲು ಪ್ರಯತ್ನಿಸುತ್ತದೆ. ನಿಮ್ಮ ಫೋನ್ ಅನ್ನು ನೀವು ಈಗಲೂ ಬಳಸಬಹುದು, ಆದರೆ ಅದು ನಿಧಾನವಾಗಿ ರನ್‌ ಆಗಬಹುದು.\n\nಫೋನ್ ತಣ್ಣಗಾದ ನಂತರ ಇದು ಸಾಮಾನ್ಯ ರೀತಿಯಲ್ಲಿ ರನ್‌ ಆಗುತ್ತದೆ."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"ನಿಮ್ಮ ಸಾಧನವು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ತಣ್ಣಗಾಗಲು ಪ್ರಯತ್ನಿಸುತ್ತದೆ. ನಿಮ್ಮ ಸಾಧನವನ್ನು ನೀವು ಈಗಲೂ ಬಳಸಬಹುದು, ಆದರೆ ಅದು ನಿಧಾನವಾಗಿ ರನ್‌ ಆಗಬಹುದು.\n\nಸಾಧನವು ತಣ್ಣಗಾದ ನಂತರ, ಇದು ಸಾಮಾನ್ಯ ರೀತಿಯಲ್ಲಿ ರನ್‌ ಆಗುತ್ತದೆ."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್‌‌ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ತಣ್ಣಗಾಗಲು ಪ್ರಯತ್ನಿಸುತ್ತದೆ. ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್‌‌ ಅನ್ನು ನೀವು ಈಗಲೂ ಬಳಸಬಹುದು, ಆದರೆ ಅದು ನಿಧಾನವಾಗಿ ರನ್‌ ಆಗಬಹುದು.\n\nಟ್ಯಾಬ್ಲೆಟ್‌‌ ತಣ್ಣಗಾದ ನಂತರ, ಇದು ಸಾಮಾನ್ಯ ರೀತಿಯಲ್ಲಿ ರನ್‌ ಆಗುತ್ತದೆ."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಪವರ್ ಬಟನ್‌ನಲ್ಲಿದೆ. ಇದು ಟ್ಯಾಬ್ಲೆಟ್‌ನ ಅಂಚಿನಲ್ಲಿರುವ ಎತ್ತರಿಸಿದ ವಾಲ್ಯೂಮ್ ಬಟನ್‌ನ ಪಕ್ಕದಲ್ಲಿರುವ ಫ್ಲ್ಯಾಟ್ ಬಟನ್ ಆಗಿದೆ."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಪವರ್ ಬಟನ್‌ನಲ್ಲಿದೆ. ಇದು ಸಾಧನದ ಅಂಚಿನಲ್ಲಿರುವ ಎತ್ತರಿಸಿದ ವಾಲ್ಯೂಮ್ ಬಟನ್‌ನ ಪಕ್ಕದಲ್ಲಿರುವ ಫ್ಲಾಟ್ ಬಟನ್ ಆಗಿದೆ."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಪವರ್ ಬಟನ್‌ನಲ್ಲಿದೆ. ಇದು ಫೋನ್‌ನ ಅಂಚಿನಲ್ಲಿರುವ ಎತ್ತರಿಸಿದ ವಾಲ್ಯೂಮ್ ಬಟನ್‌ನ ಪಕ್ಕದಲ್ಲಿರುವ ಫ್ಲ್ಯಾಟ್ ಬಟನ್ ಆಗಿದೆ."</string>
diff --git a/packages/SystemUI/res-product/values-ko/strings.xml b/packages/SystemUI/res-product/values-ko/strings.xml
index b262452..cb4a620 100644
--- a/packages/SystemUI/res-product/values-ko/strings.xml
+++ b/packages/SystemUI/res-product/values-ko/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"휴대전화 잠금 해제에 <xliff:g id="NUMBER">%d</xliff:g>번 실패했습니다. 직장 프로필과 모든 프로필 데이터가 삭제됩니다."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"잠금 해제 패턴을 <xliff:g id="NUMBER_0">%1$d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%2$d</xliff:g>회 더 실패하면 이메일 계정을 사용하여 태블릿을 잠금 해제해야 합니다.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g>초 후에 다시 시도해 주세요."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"잠금 해제 패턴을 <xliff:g id="NUMBER_0">%1$d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%2$d</xliff:g>회 더 실패하면 이메일 계정을 사용하여 휴대전화를 잠금 해제해야 합니다.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g>초 후에 다시 시도해 주세요."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"발열로 인해 휴대전화가 꺼짐"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"발열로 인해 기기가 꺼짐"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"발열로 인해 태블릿이 꺼짐"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"이제 휴대전화가 정상적으로 작동합니다.\n자세히 알아보려면 탭하세요."</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"이제 기기가 정상적으로 작동합니다.\n자세히 알아보려면 탭하세요."</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"이제 태블릿이 정상적으로 작동합니다.\n자세히 알아보려면 탭하세요."</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"휴대전화가 과열되어 온도를 낮추기 위해 전원이 종료되었습니다. 지금은 휴대전화가 정상적으로 작동합니다.\n\n휴대전화가 과열되는 이유는 다음과 같습니다.\n	• 리소스를 많이 사용하는 앱 사용(예: 게임, 동영상 또는 내비게이션 앱)\n	• 대용량 파일을 다운로드 또는 업로드\n	• 온도가 높은 곳에서 휴대전화 사용"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"기기가 과열되어 온도를 낮추기 위해 전원이 종료되었습니다. 지금은 기기가 정상적으로 작동합니다.\n\n기기가 과열되는 이유는 다음과 같습니다.\n	• 리소스를 많이 사용하는 앱 사용(예: 게임, 동영상 또는 내비게이션 앱)\n	• 대용량 파일을 다운로드 또는 업로드\n	• 온도가 높은 곳에서 기기 사용"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"태블릿이 과열되어 온도를 낮추기 위해 전원이 종료되었습니다. 지금은 태블릿이 정상적으로 작동합니다.\n\n태블릿이 과열되는 이유는 다음과 같습니다.\n	• 리소스를 많이 사용하는 앱 사용(예: 게임, 동영상 또는 내비게이션 앱)\n	• 대용량 파일을 다운로드 또는 업로드\n	• 온도가 높은 곳에서 태블릿 사용"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"휴대전화 온도가 높음"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"기기 온도가 높음"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"태블릿 온도가 높음"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"휴대전화 온도를 낮추는 동안 일부 기능이 제한됩니다.\n자세히 알아보려면 탭하세요."</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"기기 온도를 낮추는 동안 일부 기능이 제한됩니다.\n자세히 알아보려면 탭하세요."</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"태블릿 온도를 낮추는 동안 일부 기능이 제한됩니다.\n자세히 알아보려면 탭하세요."</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"휴대전화가 자동으로 온도를 낮추려고 시도합니다. 휴대전화를 계속 사용할 수는 있지만 작동이 느려질 수도 있습니다.\n\n휴대전화 온도가 낮아지면 정상적으로 작동됩니다."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"기기가 자동으로 온도를 낮추려고 시도합니다. 기기를 계속 사용할 수는 있지만 작동이 느려질 수도 있습니다.\n\n기기 온도가 낮아지면 정상적으로 작동됩니다."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"태블릿이 자동으로 온도를 낮추려고 시도합니다. 태블릿을 계속 사용할 수 있지만 작동이 느려질 수도 있습니다.\n\n태블릿 온도가 낮아지면 정상적으로 작동합니다."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"지문 센서는 전원 버튼에 있습니다. 태블릿 옆면에 있는 튀어나온 볼륨 버튼 옆의 평평한 버튼입니다."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"지문 센서는 전원 버튼에 있습니다. 기기 옆면에 있는 튀어나온 볼륨 버튼 옆의 평평한 버튼입니다."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"지문 센서는 전원 버튼에 있습니다. 휴대전화 옆면에 있는 튀어나온 볼륨 버튼 옆의 평평한 버튼입니다."</string>
diff --git a/packages/SystemUI/res-product/values-ky/strings.xml b/packages/SystemUI/res-product/values-ky/strings.xml
index 0f6acfc..8bd066f0 100644
--- a/packages/SystemUI/res-product/values-ky/strings.xml
+++ b/packages/SystemUI/res-product/values-ky/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Телефондун кулпусун <xliff:g id="NUMBER">%d</xliff:g> жолу туура эмес ачууга аракет жасадыңыз. Жумуш профили өчүрүлүп, андагы бардык нерселер өчүрүлөт."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> ийгиликсиз аракеттен кийин планшетиңизди бөгөттөн электрондук почтаңыз аркылуу чыгаруу талап кылынат.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секунддан кийин кайра аракеттениңиз."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> ийгиликсиз аракеттен кийин телефонуңузду бөгөттөн электрондук почтаңыз аркылуу чыгаруу талап кылынат.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секунддан кийин кайра аракеттениңиз."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Телефон ысыгандыктан өчүрүлдү"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Түзмөк ысыгандыктан өчүрүлдү"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Планшет ысыгандыктан өчүрүлдү"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Телефонуңуз кадимкидей иштеп жатат.\nКеңири маалымат алуу үчүн таптап коюңуз"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Түзмөгүңүз кадимкидей иштеп жатат.\nКеңири маалымат алуу үчүн таптап коюңуз"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Планшетиңиз кадимкидей иштеп жатат.\nКеңири маалымат алуу үчүн таптап коюңуз"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Телефонуңуз өтө ысып кеткендиктен, аны муздатуу үчүн өчүрүлдү. Эми телефонуңуз кадимкидей иштеп жатат.\n\nТелефонуңуз төмөнкү шарттарда ысып кетиши мүмкүн:\n	• Ашыкча ресурс короткон колдонмолорду (оюндар, видео же чабыттоо колдонмолору) пайдалансаңыз \n	• Ири көлөмдөгү файлдарды жүктөп алсаңыз же берсеңиз\n	• Телефонуңузду жогорку температураларда пайдалансаңыз"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Түзмөгүңүз өтө ысып кеткендиктен, аны муздатуу үчүн өчүрүлдү. Эми түзмөгүңүз кадимкидей иштеп жатат.\n\nТүзмөгүңүз төмөнкү шарттарда ысып кетиши мүмкүн:\n	• Ашыкча ресурс короткон колдонмолорду (оюндар, видео же чабыттоо колдонмолору) пайдалансаңыз \n	• Ири көлөмдөгү файлдарды жүктөп алсаңыз же берсеңиз\n	• Түзмөгүңүздү жогорку температураларда пайдалансаңыз"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Планшетиңиз өтө ысып кеткендиктен, аны муздатуу үчүн өчүрүлдү. Эми планшетиңиз кадимкидей иштеп жатат.\n\nПланшетиңиз төмөнкү шарттарда ысып кетиши мүмкүн:\n	• Ашыкча ресурс короткон колдонмолорду (оюндар, видео же чабыттоо колдонмолору) пайдалансаңыз \n	• Ири көлөмдөгү файлдарды жүктөп алсаңыз же берсеңиз\n	• Планшетиңизди жогорку температураларда пайдалансаңыз"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Телефон ысып баратат"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Түзмөк ысып баратат"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Планшет ысып баратат"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Телефон сууганча айрым элементтердин иши чектелген.\nКеңири маалымат алуу үчүн таптап коюңуз"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Түзмөк сууганча айрым элементтердин иши чектелген.\nКеңири маалымат алуу үчүн таптап коюңуз"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Планшет сууганча айрым элементтердин иши чектелген.\nКеңири маалымат алуу үчүн таптап коюңуз"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Телефонуңуз автоматтык түрдө сууйт. Аны колдоно берсеңиз болот, бирок ал жайыраак иштеп калат.\n\nТелефонуңуз суугандан кийин адаттагыдай эле иштеп баштайт."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Түзмөгүңүз автоматтык түрдө сууйт. Аны колдоно берсеңиз болот, бирок ал жайыраак иштеп калат.\n\nТүзмөгүңүз суугандан кийин адаттагыдай эле иштеп баштайт."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Планшетиңиз автоматтык түрдө сууйт. Аны колдоно берсеңиз болот, бирок ал жайыраак иштеп калат.\n\nПланшетиңиз суугандан кийин адаттагыдай эле иштеп баштайт."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Манжа изинин сенсору кубат баскычында жайгашкан. Бул планшеттин четиндеги үндү катуулатуу/акырындатуу баскычынын (көтөрүлгөн) жанындагы жалпак баскыч."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Манжа изинин сенсору кубат баскычында жайгашкан. Бул түзмөктүн четиндеги үндү катуулатуу/акырындатуу баскычынын (көтөрүлгөн) жанындагы жалпак баскыч."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Манжа изинин сенсору кубат баскычында жайгашкан. Бул телефондун четиндеги үндү катуулатуу/акырындатуу баскычынын (көтөрүлгөн) жанындагы жалпак баскыч."</string>
diff --git a/packages/SystemUI/res-product/values-lo/strings.xml b/packages/SystemUI/res-product/values-lo/strings.xml
index fee741d..958cf32 100644
--- a/packages/SystemUI/res-product/values-lo/strings.xml
+++ b/packages/SystemUI/res-product/values-lo/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"ທ່ານພະຍາຍາມປົດລັອກໂທລະສັບຜິດ <xliff:g id="NUMBER">%d</xliff:g> ເທື່ອແລ້ວ. ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກຈະຖືກລຶບອອກ, ເຊິ່ງຈະລຶບຂໍ້ມູນໂປຣໄຟລ໌ທັງໝົດອອກນຳ."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຜິດ <xliff:g id="NUMBER_0">%1$d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກແຕ້ມຜິດອີກ <xliff:g id="NUMBER_1">%2$d</xliff:g> ເທື່ອ, ທ່ານຈະຖືກຖາມໃຫ້ປົດລັອກແທັບເລັດຂອງທ່ານດ້ວຍການເຂົ້າສູ່ລະບົບໂດຍໃຊ້ອີເມວຂອງທ່ານ.\n\n ກະລຸນາລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_2">%3$d</xliff:g> ວິນາທີ."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຜິດ <xliff:g id="NUMBER_0">%1$d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກແຕ້ມຜິດອີກ <xliff:g id="NUMBER_1">%2$d</xliff:g> ເທື່ອ, ທ່ານຈະຖືກຖາມໃຫ້ປົດໂທລະສັບຂອງທ່ານດ້ວຍການເຂົ້າສູ່ລະບົບໂດຍໃຊ້ບັນຊີອີເມວ.\n\n ກະລຸນາລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_2">%3$d</xliff:g> ວິນາທີ."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"ໂທລະສັບປິດເຄື່ອງເນື່ອງຈາກຮ້ອນເກີນໄປ"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"ອຸປະກອນປິດເຄື່ອງເນື່ອງຈາກຮ້ອນເກີນໄປ"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"ແທັບເລັດປິດເຄື່ອງເນື່ອງຈາກຮ້ອນເກີນໄປ"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"ຕອນນີ້ໂທລະສັບຂອງທ່ານເຮັດວຽກຕາມປົກກະຕິແລ້ວ.\nແຕະເພື່ອເບິ່ງຂໍ້ມູນເພີ່ມເຕີມ"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"ຕອນນີ້ອຸປະກອນຂອງທ່ານເຮັດວຽກຕາມປົກກະຕິແລ້ວ.\nແຕະເພື່ອເບິ່ງຂໍ້ມູນເພີ່ມເຕີມ"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"ຕອນນີ້ແທັບເລັດຂອງທ່ານເຮັດວຽກຕາມປົກກະຕິແລ້ວ.\nແຕະເພື່ອເບິ່ງຂໍ້ມູນເພີ່ມເຕີມ"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"ໂທລະສັບຂອງທ່ານຮ້ອນເກີນໄປ, ດັ່ງນັ້ນຈຶ່ງຖືກປິດເຄື່ອງເພື່ອໃຫ້ເຢັນລົງ. ຕອນນີ້ໂທລະສັບຂອງທ່ານເຮັດວຽກຕາມປົກກະຕິແລ້ວ.\n\nໂທລະສັບຂອງທ່ານອາດຮ້ອນເກີນໄປ ຫາກທ່ານ:\n	• ໃຊ້ແອັບທີ່ກິນຊັບພະຍາກອນຫຼາຍ (ເຊັ່ນ: ເກມ, ວິດີໂອ ຫຼື ແອັບການນຳທາງ)\n	• ດາວໂຫຼດ ຫຼື ອັບໂຫຼດໄຟລ໌ຂະໜາດໃຫຍ່\n	• ໃຊ້ໂທລະສັບຂອງທ່ານໃນອຸນຫະພູມທີ່ສູງ"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"ອຸປະກອນຂອງທ່ານຮ້ອນເກີນໄປ, ດັ່ງນັ້ນຈຶ່ງຖືກປິດເຄື່ອງເພື່ອໃຫ້ເຢັນລົງ. ຕອນນີ້ອຸປະກອນຂອງທ່ານເຮັດວຽກຕາມປົກກະຕິແລ້ວ.\n\nອຸປະກອນຂອງທ່ານອາດຮ້ອນເກີນໄປ ຫາກທ່ານ:\n	• ໃຊ້ແອັບທີ່ກິນຊັບພະຍາກອນຫຼາຍ (ເຊັ່ນ: ເກມ, ວິດີໂອ ຫຼື ແອັບການນຳທາງ)\n	• ດາວໂຫຼດ ຫຼື ອັບໂຫຼດໄຟລ໌ຂະໜາດໃຫຍ່\n	• ໃຊ້ອຸປະກອນຂອງທ່ານໃນອຸນຫະພູມທີ່ສູງ"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"ແທັບເລັດຂອງທ່ານຮ້ອນເກີນໄປ, ດັ່ງນັ້ນຈຶ່ງຖືກປິດເຄື່ອງເພື່ອໃຫ້ເຢັນລົງ. ຕອນນີ້ແທັບເລັດຂອງທ່ານເຮັດວຽກຕາມປົກກະຕິແລ້ວ.\n\nແທັບເລັດຂອງທ່ານອາດຮ້ອນເກີນໄປ ຫາກທ່ານ:\n	• ໃຊ້ແອັບທີ່ກິນຊັບພະຍາກອນຫຼາຍ (ເຊັ່ນ: ເກມ, ວິດີໂອ ຫຼື ແອັບການນຳທາງ)\n	• ດາວໂຫຼດ ຫຼື ອັບໂຫຼດໄຟລ໌ຂະໜາດໃຫຍ່\n	• ໃຊ້ແທັບເລັດຂອງທ່ານໃນອຸນຫະພູມທີ່ສູງ"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"ໂທລະສັບເລີ່ມຮ້ອນຂຶ້ນ"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"ອຸປະກອນເລີ່ມຮ້ອນຂຶ້ນ"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"ແທັບເລັດເລີ່ມຮ້ອນຂຶ້ນ"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"ຄຸນສົມບັດບາງຢ່າງອາດໃຊ້ໄດ້ແບບຈຳກັດໃນລະຫວ່າງທີ່ໂທລະສັບເຢັນລົງ.\nແຕະເພື່ອເບິ່ງຂໍ້ມູນເພີ່ມເຕີມ"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"ຄຸນສົມບັດບາງຢ່າງອາດໃຊ້ໄດ້ແບບຈຳກັດໃນລະຫວ່າງທີ່ອຸປະກອນເຢັນລົງ.\nແຕະເພື່ອເບິ່ງຂໍ້ມູນເພີ່ມເຕີມ"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"ຄຸນສົມບັດບາງຢ່າງອາດໃຊ້ໄດ້ແບບຈຳກັດໃນລະຫວ່າງທີ່ແທັບເລັດເຢັນລົງ.\nແຕະເພື່ອເບິ່ງຂໍ້ມູນເພີ່ມເຕີມ"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"ໂທລະສັບຂອງທ່ານຈະພະຍາຍາມຫຼຸດອຸນຫະພູມລົງໂດຍອັດຕະໂນມັດ. ທ່ານຍັງສາມາດໃຊ້ໂທລະສັບຂອງທ່ານໄດ້ຢູ່, ແຕ່ໂທລະສັບອາດເຮັດວຽກຊ້າລົງ.\n\nໂທລະສັບຂອງທ່ານຈະກັບມາເຮັດວຽກຕາມປົກກະຕິເມື່ອເຢັນລົງແລ້ວ."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"ອຸປະກອນຂອງທ່ານຈະພະຍາຍາມເຮັດໃຫ້ເຢັນລົງໂດຍອັດຕະໂນມັດ. ທ່ານຍັງສາມາດໃຊ້ອຸປະກອນຂອງທ່ານໄດ້ຢູ່, ແຕ່ອຸປະກອນອາດເຮັດວຽກຊ້າລົງ.\n\nອຸປະກອນຂອງທ່ານຈະກັບມາເຮັດວຽກຕາມປົກກະຕິເມື່ອເຢັນລົງແລ້ວ."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"ແທັບເລັດຂອງທ່ານຈະພະຍາຍາມເຮັດໃຫ້ເຢັນລົງໂດຍອັດຕະໂນມັດ. ທ່ານຍັງສາມາດໃຊ້ແທັບເລັດຂອງທ່ານໄດ້ຢູ່, ແຕ່ແທັບເລັດອາດເຮັດວຽກຊ້າລົງ.\n\nແທັບເລັດຂອງທ່ານຈະກັບມາເຮັດວຽກຕາມປົກກະຕິເມື່ອເຢັນລົງແລ້ວ."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"ເຊັນເຊີລາຍນິ້ວມືແມ່ນຢູ່ປຸ່ມເປີດປິດ. ມັນເປັນປຸ່ມແປໆທີ່ຢູ່ຖັດຈາກປຸ່ມລະດັບສຽງຢູ່ຂອບຂອງແທັບເລັດ."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"ເຊັນເຊີລາຍນິ້ວມືແມ່ນຢູ່ປຸ່ມເປີດປິດ. ມັນເປັນປຸ່ມແປໆທີ່ຢູ່ຖັດຈາກປຸ່ມລະດັບສຽງຢູ່ຂອບຂອງອຸປະກອນ."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"ເຊັນເຊີລາຍນິ້ວມືແມ່ນຢູ່ປຸ່ມເປີດປິດ. ມັນເປັນປຸ່ມແປໆທີ່ຢູ່ຖັດຈາກປຸ່ມລະດັບສຽງຢູ່ຂອບຂອງໂທລະສັບ."</string>
diff --git a/packages/SystemUI/res-product/values-lt/strings.xml b/packages/SystemUI/res-product/values-lt/strings.xml
index 3035e4f..989e411 100644
--- a/packages/SystemUI/res-product/values-lt/strings.xml
+++ b/packages/SystemUI/res-product/values-lt/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"<xliff:g id="NUMBER">%d</xliff:g> kart. nesėkmingai bandėte atrakinti telefoną. Darbo profilis bus pašalintas ir visi profilio duomenys bus ištrinti."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"<xliff:g id="NUMBER_0">%1$d</xliff:g> kart. netinkamai nupiešėte atrakinimo piešinį. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. būsite paprašyti atrakinti planšetinį kompiuterį naudodami el. pašto paskyrą.\n\n Bandykite dar kartą po <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"<xliff:g id="NUMBER_0">%1$d</xliff:g> kart. netinkamai nupiešėte atrakinimo piešinį. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. būsite paprašyti atrakinti telefoną naudodami el. pašto paskyrą.\n\n Bandykite dar kartą po <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Telefonas išjungtas, nes įkaito"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Įrenginys išjungtas, nes įkaito"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Planšetinis komp. išjungtas, nes įkaito"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Telefonas dabar veikia įprastai.\nPalietę gausite daugiau informacijos"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Įrenginys dabar veikia įprastas.\nPalietę gausite daugiau informacijos"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Planšetinis kompiuteris dabar veikia įprastai.\nPalietę gausite daugiau informacijos"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Telefonas per daug įkaito, todėl buvo išjungtas, kad atvėstų. Dabar telefonas veikia įprastai.\n\nTelefonas gali per daug įkaisti, jei:\n	• esate įjungę daug išteklių naudojančių programų (pvz., žaidimų, vaizdo įrašų arba navigacijos programų);\n	• atsisiunčiate arba įkeliate didelius failus;\n	• telefoną naudojate esant aukštai temperatūrai."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Įrenginys per daug įkaito, todėl buvo išjungtas, kad atvėstų. Dabar įrenginys veikia įprastai.\n\nĮrenginys gali per daug įkaisti, jei:\n	• esate įjungę daug išteklių naudojančių programų (pvz., žaidimų, vaizdo įrašų arba navigacijos programų);\n	• atsisiunčiate arba įkeliate didelius failus;\n	• įrenginį naudojate esant aukštai temperatūrai."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Planšetinis kompiuteris per daug įkaito, todėl buvo išjungtas, kad atvėstų. Dabar planšetinis kompiuteris veikia įprastai.\n\nPlanšetinis kompiuteris gali per daug įkaisti, jei:\n	• esate įjungę daug išteklių naudojančių programų (pvz., žaidimų, vaizdo įrašų arba navigacijos programų);\n	• atsisiunčiate arba įkeliate didelius failus;\n	• planšetinį kompiuterį naudojate esant aukštai temperatūrai."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Telefonas kaista"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Įrenginys kaista"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Planšetinis kompiuteris kaista"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Kai kurios funkcijos gali neveikti, kol telefonas vėsta.\nPalietę gausite daugiau informacijos"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Kai kurios funkcijos gali neveikti, kol įrenginys vėsta.\nPalietę gausite daugiau informacijos"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Kai kurios funkcijos gali neveikti, kol planšetinis kompiuteris vėsta.\nPalietę gausite daugiau informacijos"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Telefonas automatiškai bandys atvėsti. Telefoną vis tiek galėsite naudoti, tačiau jis gali veikti lėčiau.\n\nKai telefonas atvės, jis veiks įprastai."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Įrenginys automatiškai bandys atvėsti. Įrenginį vis tiek galėsite naudoti, tačiau jis gali veikti lėčiau.\n\nKai įrenginys atvės, jis veiks įprastai."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Planšetinis kompiuteris automatiškai bandys atvėsti. Planšetinį kompiuterį vis tiek galėsite naudoti, tačiau jis gali veikti lėčiau.\n\nKai planšetinis kompiuteris atvės, jis veiks įprastai."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Piršto atspaudo jutiklis yra ant maitinimo mygtuko. Tai yra plokščias mygtukas šalia iškilusio garsumo mygtuko ant planšetinio kompiuterio krašto."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Piršto atspaudo jutiklis yra ant maitinimo mygtuko. Tai yra plokščias mygtukas šalia iškilusio garsumo mygtuko ant įrenginio krašto."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Piršto atspaudo jutiklis yra ant maitinimo mygtuko. Tai yra plokščias mygtukas šalia iškilusio garsumo mygtuko ant telefono krašto."</string>
diff --git a/packages/SystemUI/res-product/values-lv/strings.xml b/packages/SystemUI/res-product/values-lv/strings.xml
index 8e9c064d..a18076a 100644
--- a/packages/SystemUI/res-product/values-lv/strings.xml
+++ b/packages/SystemUI/res-product/values-lv/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Jūs <xliff:g id="NUMBER">%d</xliff:g> reizi(-es) nesekmīgi mēģinājāt atbloķēt tālruni. Darba profils tiks noņemts, kā arī visi profila dati tiks dzēsti."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Jūs <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es) nepareizi norādījāt atbloķēšanas kombināciju. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> neveiksmīga(-iem) mēģinājuma(-iem) planšetdators būs jāatbloķē, izmantojot e-pasta kontu.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundes(-ēm)."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Jūs <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es) nepareizi norādījāt atbloķēšanas kombināciju. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> nesekmīga(-iem) mēģinājuma(-iem) tālrunis būs jāatbloķē, izmantojot e-pasta kontu.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundes(-ēm)."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Tālrunis izslēgts karstuma dēļ"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Ierīce izslēgta karstuma dēļ"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Planšetdators izslēgts karstuma dēļ"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Tagad jūsu tālrunis darbojas normāli.\nPieskarieties, lai uzzinātu vairāk."</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Tagad jūsu ierīce darbojas normāli.\nPieskarieties, lai uzzinātu vairāk."</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Tagad jūsu planšetdators darbojas normāli.\nPieskarieties, lai uzzinātu vairāk."</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Jūsu tālrunis bija pārkarsis un tika izslēgts. Tagad tas darbojas normāli.\n\nTālrunis var sakarst, ja:\n	• tiek izmantotas lietotnes, kas patērē daudz enerģijas (piem., spēles, video lietotnes vai navigācija);\n	• tiek lejupielādēti/augšupielādēti lieli faili;\n	• tālrunis tiek lietots augstā temperatūrā."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Jūsu ierīce bija pārkarsusi un tika izslēgta. Tagad tā darbojas normāli.\n\nIerīce var sakarst, ja:\n	• tiek izmantotas lietotnes, kas patērē daudz enerģijas (piem., spēles, video lietotnes vai navigācija);\n	• tiek lejupielādēti/augšupielādēti lieli faili;\n	• ierīce tiek lietota augstā temperatūrā."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Jūsu planšetdators bija pārkarsis un tika izslēgts. Tagad tas darbojas normāli.\n\nPlanšetdators var sakarst, ja:\n	• tiek izmantotas lietotnes, kas patērē daudz enerģijas (piem., spēles, video lietotnes vai navigācija);\n	• tiek lejupielādēti/augšupielādēti lieli faili;\n	• planšetdators tiek lietots augstā temperatūrā."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Tālrunis kļūst silts"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Ierīce kļūst silta"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Planšetdators kļūst silts"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Dažas funkcijas ir ierobežotas, kamēr notiek tālruņa atdzišana.\nPieskarieties, lai uzzinātu vairāk."</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Dažas funkcijas ir ierobežotas, kamēr notiek ierīces atdzišana.\nPieskarieties, lai uzzinātu vairāk."</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Dažas funkcijas ir ierobežotas, kamēr notiek planšetdatora atdzišana.\nPieskarieties, lai uzzinātu vairāk."</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Jūsu tālrunis automātiski mēģinās atdzist. Jūs joprojām varat izmantot tālruni, taču tas, iespējams, darbosies lēnāk.\n\nTiklīdz tālrunis būs atdzisis, tas darbosies normāli."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Jūsu ierīce automātiski mēģinās atdzist. Jūs joprojām varat izmantot ierīci, taču tā, iespējams, darbosies lēnāk.\n\nTiklīdz ierīce būs atdzisusi, tā darbosies normāli."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Jūsu planšetdators automātiski mēģinās atdzist. Jūs joprojām varat izmantot planšetdatoru, taču tas, iespējams, darbosies lēnāk.\n\nTiklīdz planšetdators būs atdzisis, tas darbosies normāli."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Pirksta nospieduma sensors atrodas uz barošanas pogas. Tā ir plakanā poga, kas atrodas blakus augstākai skaļuma pogai planšetdatora sānos."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Pirksta nospieduma sensors atrodas uz barošanas pogas. Tā ir plakanā poga, kas atrodas blakus augstākai skaļuma pogai ierīces sānos."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Pirksta nospieduma sensors atrodas uz barošanas pogas. Tā ir plakanā poga, kas atrodas blakus augstākai skaļuma pogai tālruņa sānos."</string>
diff --git a/packages/SystemUI/res-product/values-mk/strings.xml b/packages/SystemUI/res-product/values-mk/strings.xml
index 6d34f97..bb58df2 100644
--- a/packages/SystemUI/res-product/values-mk/strings.xml
+++ b/packages/SystemUI/res-product/values-mk/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Погрешно се обидовте да го отклучите телефонот <xliff:g id="NUMBER">%d</xliff:g> пати. Работниот профил ќе се отстрани, со што ќе се избришат сите податоци на профилот."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Погрешно ја употребивте вашата шема на отклучување <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. По уште <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни обиди, ќе побараме да го отклучите таблетот со сметка на е-пошта.\n\n Обидете се повторно за <xliff:g id="NUMBER_2">%3$d</xliff:g> секунди."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Погрешно ја употребивте вашата шема на отклучување <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. По уште <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни обиди, ќе побараме да го отклучите телефонот со сметка на е-пошта.\n\n Обидете се повторно за <xliff:g id="NUMBER_2">%3$d</xliff:g> секунди."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Телефонот се исклучи поради загреаност"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Уредот се исклучи поради загреаност"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Таблетот се исклучи поради загреаност"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Сега телефонот работи нормално.\nДопрете за повеќе информации"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Сега уредот работи нормално.\nДопрете за повеќе информации"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Сега таблетот работи нормално.\nДопрете за повеќе информации"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Телефонот беше премногу загреан, така што се исклучи за да се олади. Сега работи нормално.\n\nТелефонот може премногу да се загрее ако:\n	• користите апликации што користат многу ресурси (како што се, на пример, апликациите за видеа, навигација или игри)\n	• преземате или поставувате големи датотеки\n	• го користите телефонот на високи температури"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Уредот беше премногу загреан, така што се исклучи за да се олади. Сега работи нормално.\n\nУредот може премногу да се загрее ако:\n	• користите апликации што користат многу ресурси (како што се, на пример, апликациите за видеа, навигација или игри)\n	• преземате или прикачувате големи датотеки\n	• го користите уредот на високи температури"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Таблетот беше премногу загреан, така што се исклучи за да се олади. Сега работи нормално.\n\nТаблетот може премногу да се загрее ако:\n	• користите апликации што користат многу ресурси (како што се, на пример, апликациите за видеа, навигација или игри)\n	• преземате или поставувате големи датотеки\n	• го користите таблетот на високи температури"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Телефонот се загрева"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Уредот се загрева"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Таблетот се загрева"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Некои функции се ограничени додека телефонот се лади.\nДопрете за повеќе информации"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Некои функции се ограничени додека уредот се лади.\nДопрете за повеќе информации"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Некои функции се ограничени додека таблетот се лади.\nДопрете за повеќе информации"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Телефонот автоматски ќе почне да се лади. Сѐ уште ќе може да го користите, но можно е да работи побавно.\n\nОткако ќе се олади, ќе работи нормално."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Уредот автоматски ќе почне да се лади. Сѐ уште ќе може да го користите, но можно е да работи побавно.\n\nОткако ќе се олади, ќе работи нормално."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Таблетот автоматски ќе почне да се лади. Сѐ уште ќе може да го користите, но можно е да работи побавно.\n\nОткако ќе се олади, ќе работи нормално."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Сензорот за отпечатоци се наоѓа на копчето за вклучување. Тоа е рамното копче веднаш до подигнатото копче за јачина на звук на работ од таблетот."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Сензорот за отпечатоци се наоѓа на копчето за вклучување. Тоа е рамното копче веднаш до подигнатото копче за јачина на звук на работ од уредот."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Сензорот за отпечатоци се наоѓа на копчето за вклучување. Тоа е рамното копче веднаш до подигнатото копче за јачина на звук на работ од телефонот."</string>
diff --git a/packages/SystemUI/res-product/values-ml/strings.xml b/packages/SystemUI/res-product/values-ml/strings.xml
index d1e7b4b..55cfd06 100644
--- a/packages/SystemUI/res-product/values-ml/strings.xml
+++ b/packages/SystemUI/res-product/values-ml/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"നിങ്ങൾ <xliff:g id="NUMBER">%d</xliff:g> തവണ തെറ്റായ രീതിയിൽ ഫോൺ അൺലോക്ക് ചെയ്യാൻ ശ്രമിച്ചു. ഔദ്യോഗിക പ്രൊഫൈൽ നീക്കം ചെയ്യപ്പെടുകയും, അതുവഴി എല്ലാ പ്രൊഫൈൽ ഡാറ്റയും ഇല്ലാതാകുകയും ചെയ്യും."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ തെറ്റായ രീതിയിൽ അൺലോക്ക് പാറ്റേൺ വരച്ചു. <xliff:g id="NUMBER_1">%2$d</xliff:g> ശ്രമങ്ങൾ കൂടി പരാജയപ്പെട്ടാൽ, ഒരു ഇമെയിൽ അക്കൗണ്ടുപയോഗിച്ച് ടാബ്‌ലെറ്റ് അൺലോക്ക് ചെയ്യാൻ നിങ്ങളോട് ആവശ്യപ്പെടും.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> സെക്കന്റ് കഴിഞ്ഞ് വീണ്ടും ശ്രമിക്കുക."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ തെറ്റായ രീതിയിൽ അൺലോക്ക് പാറ്റേൺ വരച്ചു. <xliff:g id="NUMBER_1">%2$d</xliff:g> ശ്രമങ്ങൾ കൂടി പരാജയപ്പെട്ടാൽ, ഒരു ഇമെയിൽ അക്കൗണ്ടുപയോഗിച്ച് ഫോൺ അൺലോക്ക് ചെയ്യാൻ നിങ്ങളോട് ആവശ്യപ്പെടും.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> സെക്കന്റ് കഴിഞ്ഞ് വീണ്ടും ശ്രമിക്കുക."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"ചൂട് കൂടിയതിനാൽ ഫോൺ ഓഫായി"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"ചൂട് കൂടിയതിനാൽ ഉപകരണം ഓഫായി"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"ചൂട് കൂടിയതിനാൽ ടാബ്‌ലെറ്റ് ഓഫായി"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"നിങ്ങളുടെ ഫോൺ ഇപ്പോൾ സാധാരണ ഗതിയിൽ പ്രവർത്തിക്കുന്നുണ്ട്.\nകൂടുതൽ വിവരങ്ങൾക്ക് ടാപ്പ് ചെയ്യുക"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"നിങ്ങളുടെ ഉപകരണം ഇപ്പോൾ സാധാരണ ഗതിയിൽ പ്രവർത്തിക്കുന്നുണ്ട്.\nകൂടുതൽ വിവരങ്ങൾക്ക് ടാപ്പ് ചെയ്യുക"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"നിങ്ങളുടെ ടാബ്‌ലെറ്റ് ഇപ്പോൾ സാധാരണ ഗതിയിൽ പ്രവർത്തിക്കുന്നുണ്ട്.\nകൂടുതൽ വിവരങ്ങൾക്ക് ടാപ്പ് ചെയ്യുക"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"ഫോൺ വളരെയധികം ചൂടായതിനാൽ തണുക്കാൻ വേണ്ടിയാണ് ഓഫായത്. ഫോൺ ഇപ്പോൾ സാധാരണഗതിയിൽ പ്രവർത്തിക്കുന്നുണ്ട്.\n\nഇനിപ്പറയുന്ന സാഹചര്യങ്ങളിൽ ഫോൺ വളരെയധികം ചൂടായേക്കാം:\n	• ഗെയിമിംഗ്, വീഡിയോ അല്ലെങ്കിൽ നാവിഗേഷൻ തുടങ്ങിയ കൂടുതൽ വിഭവങ്ങൾ ഉപയോഗിക്കുന്ന ആപ്പുകൾ ഉപയോഗിക്കുന്നത്\n	• വലിയ ഫയലുകൾ അപ്‌ലോഡോ ഡൗൺലോഡോ ചെയ്യുന്നത്\n	• ഉയർന്ന താപനിലയിൽ ഫോൺ ഉപയോഗിക്കുന്നത്"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"ഉപകരണം വളരെയധികം ചൂടായതിനാൽ തണുക്കാൻ വേണ്ടിയാണ് ഓഫായത്. ഉപകരണം ഇപ്പോൾ സാധാരണഗതിയിൽ പ്രവർത്തിക്കുന്നുണ്ട്.\n\nഇനിപ്പറയുന്ന സാഹചര്യങ്ങളിൽ ഉപകരണം വളരെയധികം ചൂടായേക്കാം:\n	• ഗെയിമിംഗ്, വീഡിയോ അല്ലെങ്കിൽ നാവിഗേഷൻ തുടങ്ങിയ കൂടുതൽ വിഭവങ്ങൾ ഉപയോഗിക്കുന്ന ആപ്പുകൾ ഉപയോഗിക്കുന്നത്\n	• വലിയ ഫയലുകൾ അപ്‌ലോഡോ ഡൗൺലോഡോ ചെയ്യുന്നത്\n	• ഉയർന്ന താപനിലയിൽ ഉപകരണം ഉപയോഗിക്കുന്നത്"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"ടാബ്‌ലെറ്റ് വളരെയധികം ചൂടായതിനാൽ തണുക്കാൻ വേണ്ടിയാണ് ഓഫായത്. ടാബ്‌ലെറ്റ് ഇപ്പോൾ സാധാരണഗതിയിൽ പ്രവർത്തിക്കുന്നുണ്ട്.\n\nഇനിപ്പറയുന്ന സാഹചര്യങ്ങളിൽ ടാബ്‌ലെറ്റ് വളരെയധികം ചൂടായേക്കാം:\n	• ഗെയിമിംഗ്, വീഡിയോ അല്ലെങ്കിൽ നാവിഗേഷൻ തുടങ്ങിയ കൂടുതൽ വിഭവങ്ങൾ ഉപയോഗിക്കുന്ന ആപ്പുകൾ ഉപയോഗിക്കുന്നത്\n	• വലിയ ഫയലുകൾ അപ്‌ലോഡോ ഡൗൺലോഡോ ചെയ്യുന്നത്\n	• ഉയർന്ന താപനിലയിൽ ടാബ്‌ലെറ്റ് ഉപയോഗിക്കുന്നത്"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"ഫോൺ ചൂടാകുന്നു"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"ഉപകരണം ചൂടാകുന്നു"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"ടാബ്‌ലെറ്റ് ചൂടാകുന്നു"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"ഫോൺ തണുത്തുകൊണ്ടിരിക്കുമ്പോൾ ചില ഫീച്ചറുകൾ പരിമിതപ്പെടുത്തും.\nകൂടുതൽ വിവരങ്ങൾക്ക് ടാപ്പ് ചെയ്യുക"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"ഉപകരണം തണുത്തുകൊണ്ടിരിക്കുമ്പോൾ ചില ഫീച്ചറുകൾ പരിമിതപ്പെടുത്തും.\nകൂടുതൽ വിവരങ്ങൾക്ക് ടാപ്പ് ചെയ്യുക"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"ടാബ്‌ലെറ്റ് തണുത്തുകൊണ്ടിരിക്കുമ്പോൾ ചില ഫീച്ചറുകൾ പരിമിതപ്പെടുത്തും.\nകൂടുതൽ വിവരങ്ങൾക്ക് ടാപ്പ് ചെയ്യുക"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"നിങ്ങളുടെ ഫോൺ സ്വയമേവ തണുക്കാൻ ശ്രമിക്കും. നിങ്ങൾക്ക് അപ്പോഴും ഫോൺ ഉപയോഗിക്കാമെങ്കിലും അതിന്റെ പ്രവർത്തനം മന്ദഗതിയിലായിരിക്കാം.\n\nതണുത്തുകഴിഞ്ഞാൽ ഫോൺ സാധാരണപോലെ പ്രവർത്തിക്കും."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"നിങ്ങളുടെ ഉപകരണം സ്വയമേവ തണുക്കാൻ ശ്രമിക്കും. നിങ്ങൾക്ക് അപ്പോഴും ഉപകരണം ഉപയോഗിക്കാമെങ്കിലും അതിന്റെ പ്രവർത്തനം മന്ദഗതിയിലായിരിക്കാം.\n\nതണുത്തുകഴിഞ്ഞാൽ ഉപകരണം സാധാരണപോലെ പ്രവർത്തിക്കും."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"നിങ്ങളുടെ ടാബ്‌ലെറ്റ് സ്വയമേവ തണുക്കാൻ ശ്രമിക്കും. നിങ്ങൾക്ക് അപ്പോഴും ടാബ്‌ലെറ്റ് ഉപയോഗിക്കാമെങ്കിലും അതിന്റെ പ്രവർത്തനം മന്ദഗതിയിലായിരിക്കാം.\n\nതണുത്തുകഴിഞ്ഞാൽ ടാബ്‌ലെറ്റ് സാധാരണപോലെ പ്രവർത്തിക്കും."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"പവർ ബട്ടണിലാണ് ഫിംഗർപ്രിന്റ് സെൻസർ ഉള്ളത്. ടാബ്‌ലെറ്റിന്റെ അറ്റത്ത് ഉയർന്ന് നിൽക്കുന്ന ശബ്ദ ബട്ടണിന്റെ അടുത്തുള്ള പരന്ന ബട്ടൺ ആണ് ഇത്."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"പവർ ബട്ടണിലാണ് ഫിംഗർപ്രിന്റ് സെൻസർ ഉള്ളത്. ഉപകരണത്തിന്റെ അറ്റത്ത് ഉയർന്ന് നിൽക്കുന്ന ശബ്ദ ബട്ടണിന്റെ അടുത്തുള്ള പരന്ന ബട്ടൺ ആണ് ഇത്."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"പവർ ബട്ടണിലാണ് ഫിംഗർപ്രിന്റ് സെൻസർ ഉള്ളത്. ഫോണിന്റെ അറ്റത്ത് ഉയർന്ന് നിൽക്കുന്ന ശബ്ദ ബട്ടണിന്റെ അടുത്തുള്ള പരന്ന ബട്ടൺ ആണ് ഇത്."</string>
diff --git a/packages/SystemUI/res-product/values-mn/strings.xml b/packages/SystemUI/res-product/values-mn/strings.xml
index 1cc1a1c..179e816 100644
--- a/packages/SystemUI/res-product/values-mn/strings.xml
+++ b/packages/SystemUI/res-product/values-mn/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Та утасны түгжээг тайлах оролдлогыг <xliff:g id="NUMBER">%d</xliff:g> удаа буруу хийсэн байна. Ажлын профайлыг устгах бөгөөд ингэснээр профайлын бүх өгөгдлийг устгах болно."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Та тайлах хээгээ <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу зурсан байна. Дахин <xliff:g id="NUMBER_1">%2$d</xliff:g> удаа буруу зурсны дараа та имэйл бүртгэл ашиглан таблетынхаа түгжээг тайлах шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундийн дараа дахин оролдоно уу."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Та тайлах хээгээ <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу зурсан байна. Дахин <xliff:g id="NUMBER_1">%2$d</xliff:g> удаа буруу зурсны дараа та имэйл бүртгэл ашиглан утасныхаа түгжээг тайлах шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундийн дараа дахин оролдоно уу."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Халсны улмаас утас унтарсан"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Халсны улмаас төхөөрөмж унтарсан"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Халсны улмаас таблет унтарсан"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Таны утас одоо хэвийн ажиллаж байна.\nДэлгэрэнгүй мэдээлэл авах бол товшино уу"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Таны төхөөрөмж одоо хэвийн ажиллаж байна.\nДэлгэрэнгүй мэдээлэл авах бол товшино уу"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Таны таблет одоо хэвийн ажиллаж байна.\nДэлгэрэнгүй мэдээлэл авах бол товшино уу"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Таны утас хэт халсан тул хөрөхөөр унтарсан. Таны утас одоо хэвийн ажиллаж байна.\n\nТа дараахыг хийсэн тохиолдолд утас тань хэт халж магадгүй:\n	• Нөөц их ашигладаг аппуудыг (тоглоом, видео эсвэл навигацын аппууд) ашиглах\n	• Том файлууд татах эсвэл байршуулах\n	• Утсаа өндөр температурт ашиглах"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Таны төхөөрөмж хэт халсан тул хөрөхөөр унтарсан. Таны төхөөрөмж одоо хэвийн ажиллаж байна.\n\nТа дараахыг хийсэн тохиолдолд төхөөрөмж тань хэт халж магадгүй:\n	• Нөөц их ашигладаг аппуудыг (тоглоом, видео эсвэл навигацын аппууд) ашиглах\n	• Том файлууд татах эсвэл байршуулах\n	• Төхөөрөмжөө өндөр температурт ашиглах"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Таны таблет хэт халсан тул хөрөхөөр унтарсан. Таны таблет одоо хэвийн ажиллаж байна.\n\nТа дараахыг хийсэн тохиолдолд таблет тань хэт халж магадгүй:\n	• Нөөц их ашигладаг аппуудыг (тоглоом, видео эсвэл навигацын аппууд) ашиглах\n	• Том файлууд татах эсвэл байршуулах\n	• Таблетаа өндөр температурт ашиглах"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Утас халж байна"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Төхөөрөмж халж байна"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Таблет халж байна"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Утсыг хөрөх үед зарим онцлогийг хязгаарлана.\nДэлгэрэнгүй мэдээлэл авах бол товшино уу"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Төхөөрөмжийг хөрөх үед зарим онцлогийг хязгаарлана.\nДэлгэрэнгүй мэдээлэл авах бол товшино уу"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Таблетыг хөрөх үед зарим онцлогийг хязгаарлана.\nДэлгэрэнгүй мэдээлэл авах бол товшино уу"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Таны утас хөрөхөөр автоматаар оролдоно. Та утсаа ашиглах боломжтой хэвээр байх хэдий ч энэ нь удаан ажиллаж магадгүй.\n\nТаны утас хөрснийхөө дараа хэвийн ажиллана."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Таны төхөөрөмж хөрөхөөр автоматаар оролдоно. Та төхөөрөмжөө ашиглах боломжтой хэвээр байх хэдий ч энэ нь удаан ажиллаж магадгүй.\n\nТаны төхөөрөмж хөрснийхөө дараа хэвийн ажиллана."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Таны таблет хөрөхөөр автоматаар оролдоно. Та таблетаа ашиглах боломжтой хэвээр байх хэдий ч энэ нь удаан ажиллаж магадгүй.\n\nТаны таблет хөрснийхөө дараа хэвийн ажиллана."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Хурууны хээ мэдрэгч асаах/унтраах товчин дээр байдаг. Энэ нь таблетын ирмэг дээрх дууны түвшний товгор товчлуурын хажууд байх хавтгай товчлуур юм."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Хурууны хээ мэдрэгч асаах/унтраах товчин дээр байдаг. Энэ нь төхөөрөмжийн ирмэг дээрх дууны түвшний товгор товчлуурын хажууд байх хавтгай товчлуур юм."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Хурууны хээ мэдрэгч асаах/унтраах товчин дээр байдаг. Энэ нь утасны ирмэг дээрх дууны түвшний товгор товчлуурын хажууд байх хавтгай товчлуур юм."</string>
diff --git a/packages/SystemUI/res-product/values-mr/strings.xml b/packages/SystemUI/res-product/values-mr/strings.xml
index 33c3eb4..821b303 100644
--- a/packages/SystemUI/res-product/values-mr/strings.xml
+++ b/packages/SystemUI/res-product/values-mr/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"तुम्ही फोन अनलॉक करण्याचा <xliff:g id="NUMBER">%d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. कार्य प्रोफाइल काढली जाईल, त्यामुळे सर्व प्रोफाइल डेटा हटवला जाईल."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"तुम्ही तुमचा अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने काढला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, तुम्हाला ईमेल खाते वापरून तुमचा टॅबलेट अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"तुम्ही तुमचा अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने काढला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, तुम्हाला ईमेल खाते वापरून तुमचा फोन अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"खूप गरम झाल्यामुळे फोन बंद झाला"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"खूप गरम झाल्यामुळे डिव्हाइस बंद झाले"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"खूप गरम झाल्यामुळे टॅबलेट बंद झाला"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"तुमचा फोन आता सामान्यपणे रन होत आहे.\nअधिक माहितीसाठी टॅप करा"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"तुमचे डिव्हाइस आता सामान्यपणे रन होत आहे.\nअधिक माहितीसाठी टॅप करा"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"तुमचा टॅबलेट आता सामान्यपणे रन होत आहे.\nअधिक माहितीसाठी टॅप करा"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"तुमचा फोन खूप गरम झाला होता, म्हणून तो थंड होण्यासाठी बंद झाला आहे. तुमचा फोन आता सामान्यपणे रन होत आहे.\n\nतुम्ही पुढील गोष्टी केल्यास तुमचा फोन खूप गरम होऊ शकतो:\n	•स्रोत इंटेन्सिव्ह अ‍ॅप्स वापरणे (जसे की गेमिंग, व्हिडिओ किंवा नेव्हिगेशन यांसारखी अ‍ॅप्स)\n	•मोठ्या फाइल डाउनलोड किंवा अपलोड करणे\n	•तुमचा फोन उच्च तापमानांमध्ये वापरणे"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"तुमचे डिव्हाइस खूप गरम झाले होते, म्हणून ते थंड होण्यासाठी बंद झाले आहे. तुमचे डिव्हाइस आता सामान्यपणे रन होत आहे.\n\nतुम्ही पुढील गोष्टी केल्यास तुमचे डिव्हाइस खूप गरम होऊ शकते:\n	•स्रोत इंटेन्सिव्ह अ‍ॅप्स वापरणे (जसे की गेमिंग, व्हिडिओ किंवा नेव्हिगेशन यांसारखी अ‍ॅप्स)\n	•मोठ्या फाइल डाउनलोड किंवा अपलोड करणे\n	•तुमचे डिव्हाइस उच्च तापमानांमध्ये वापरणे"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"तुमचा टॅबलेट खूप गरम झाला होता, म्हणून तो थंड होण्यासाठी बंद झाला आहे. तुमचा टॅबलेट आता सामान्यपणे रन होत आहे.\n\nतुम्ही पुढील गोष्टी केल्यास तुमचा टॅबलेट खूप गरम होऊ शकतो:\n	•स्रोत इंटेन्सिव्ह अ‍ॅप्स वापरणे (जसे की गेमिंग, व्हिडिओ किंवा नेव्हिगेशन यांसारखी अ‍ॅप्स)\n	•मोठ्या फाइल डाउनलोड किंवा अपलोड करणे\n	•तुमचा टॅबलेट उच्च तापमानांमध्ये वापरणे"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"फोन गरम होत आहे"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"डिव्हाइस गरम होत आहे"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"टॅबलेट गरम होत आहे"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"फोन थंड होईपर्यंत काही वैशिष्ट्ये मर्यादित केली आहेत.\nअधिक माहितीसाठी टॅप करा"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"डिव्हाइस थंड होईपर्यंत काही वैशिष्ट्ये मर्यादित केली आहेत.\nअधिक माहितीसाठी टॅप करा"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"टॅबलेट थंड होईपर्यंत काही वैशिष्ट्ये मर्यादित केली आहेत.\nअधिक माहितीसाठी टॅप करा"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"तुमचा फोन आपोआप थंड होण्याचा प्रयत्न करेल. तुम्ही तरीही तुमचा फोन वापरू शकता, पण तो कदाचित धीम्या गतीने रन होईल.\n\nतुमचा फोन थंड झाल्यानंतर तो सामान्यपणे काम करेल."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"तुमचे डिव्हाइस आपोआप थंड होण्याचा प्रयत्न करेल. तुम्ही तरीही तुमचे डिव्हाइस वापरू शकता, पण ते कदाचित धीम्या गतीने रन होईल.\n\nतुमचे डिव्हाइस थंड झाल्यानंतर ते सामान्यपणे काम करेल."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"तुमचा टॅबलेट आपोआप थंड होण्याचा प्रयत्न करेल. तुम्ही तरीही तुमचा टॅबलेट वापरू शकता, पण तो कदाचित धीम्या गतीने रन होईल.\n\nतुमचा टॅबलेट थंड झाल्यानंतर तो सामान्यपणे काम करेल."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"फिंगरप्रिंट सेन्सर हे पॉवर बटणावर आहे. टॅबलेटच्या कडेला वर आलेल्या व्हॉल्यूम बटणाच्या बाजूला असलेले सपाट बटण म्हणजे पॉवर बटण."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"फिंगरप्रिंट सेन्सर हे पॉवर बटणावर आहे. डिव्हाइसच्या कडेला वरती आलेल्या व्हॉल्यूम बटणाच्या बाजूला असलेले सपाट बटण म्हणजे पॉवर बटण."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"फिंगरप्रिंट सेन्सर हे पॉवर बटणावर आहे. फोनच्या कडेला वर आलेल्या व्हॉल्यूम बटणाच्या बाजूला असलेले सपाट बटण म्हणजे पॉवर बटण."</string>
diff --git a/packages/SystemUI/res-product/values-ms/strings.xml b/packages/SystemUI/res-product/values-ms/strings.xml
index e1e6976..ee10626 100644
--- a/packages/SystemUI/res-product/values-ms/strings.xml
+++ b/packages/SystemUI/res-product/values-ms/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Anda telah salah membuka kunci telefon sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Profil kerja ini akan dialih keluar sekali gus memadamkan semua data profil."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang gagal, anda akan diminta membuka kunci tablet anda menggunakan akaun e-mel.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> saat."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang gagal, anda akan diminta membuka kunci telefon anda menggunakan akaun e-mel.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> saat."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Telefon dimatikan kerana panas"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Peranti dimatikan kerana panas"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tablet dimatikan kerana panas"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Kini telefon anda berjalan seperti biasa.\nKetik untuk mendapatkan maklumat lanjut"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Kini peranti anda berjalan seperti biasa.\nKetik untuk mendapatkan maklumat lanjut"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Kini tablet anda berjalan seperti biasa.\nKetik untuk mendapatkan maklumat lanjut"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Telefon anda terlalu panas, oleh yang demikian telefon itu telah dimatikan untuk menyejuk. Sekarang, telefon anda berjalan seperti biasa.\n\nTelefon anda mungkin menjadi terlalu panas jika anda:\n	• Menggunakan apl intensif sumber (seperti permainan, video atau apl navigasi)\n	• Memuat turun atau memuat naik fail besar\n	• Menggunakan telefon anda dalam suhu tinggi"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Peranti anda terlalu panas, oleh yang demikian peranti itu telah dimatikan untuk menyejuk. Sekarang, peranti anda berjalan seperti biasa.\n\nPeranti anda mungkin menjadi terlalu panas jika anda:\n	• Menggunakan apl intensif sumber (seperti permainan, video atau apl navigasi)\n	• Memuat turun atau memuat naik fail besar\n	• Menggunakan peranti anda dalam suhu tinggi"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Tablet anda terlalu panas, oleh yang demikian tablet itu telah dimatikan untuk menyejuk. Sekarang, tablet anda berjalan seperti biasa.\n\nTablet anda mungkin menjadi terlalu panas jika anda:\n	• Menggunakan apl intensif sumber (seperti permainan, video atau apl navigasi)\n	• Memuat turun atau memuat naik fail besar\n	• Menggunakan tablet anda dalam suhu tinggi"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Telefon semakin panas"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Peranti semakin panas"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Tablet semakin panas"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Sesetengah ciri adalah terhad semasa telefon menyejuk.\nKetik untuk mendapatkan maklumat lanjut"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Sesetengah ciri adalah terhad semasa peranti menyejuk.\nKetik untuk mendapatkan maklumat lanjut"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Sesetengah ciri adalah terhad semasa tablet menyejuk.\nKetik untuk mendapatkan maklumat lanjut"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Telefon anda akan cuba menyejuk secara automatik. Anda masih dapat menggunakan telefon itu tetapi telefon tersebut mungkin berjalan lebih perlahan.\n\nSetelah telefon anda sejuk, telefon itu akan berjalan seperti biasa."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Peranti anda akan cuba menyejuk secara automatik. Anda masih dapat menggunakan peranti anda tetapi peranti tersebut mungkin berjalan lebih perlahan.\n\nSetelah peranti anda sejuk, peranti itu akan berjalan seperti biasa."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Tablet anda akan cuba menyejuk secara automatik. Anda masih dapat menggunakan tablet itu tetapi tablet tersebut mungkin berjalan lebih perlahan.\n\nSetelah tablet anda sejuk, tablet itu akan berjalan seperti biasa."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Penderia cap jari berada pada butang kuasa. Penderia cap jari ialah butang leper yang terletak bersebelahan butang kelantangan timbul pada bahagian tepi tablet."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Penderia cap jari berada pada butang kuasa. Penderia cap jari ialah butang leper yang terletak bersebelahan butang kelantangan timbul pada bahagian tepi peranti."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Penderia cap jari berada pada butang kuasa. Penderia cap jari ialah butang leper yang terletak bersebelahan butang kelantangan timbul pada bahagian tepi telefon."</string>
diff --git a/packages/SystemUI/res-product/values-my/strings.xml b/packages/SystemUI/res-product/values-my/strings.xml
index 68711e8..9a61692 100644
--- a/packages/SystemUI/res-product/values-my/strings.xml
+++ b/packages/SystemUI/res-product/values-my/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"ဖုန်းကို <xliff:g id="NUMBER">%d</xliff:g> ကြိမ် မှားယွင်းစွာ လော့ခ်ဖွင့်ရန် ကြိုးစားခဲ့ပါသည်။ အလုပ်ပရိုဖိုင်ကို ဖယ်ရှားလိုက်မည်ဖြစ်ပြီး ပရိုဖိုင်ဒေတာ အားလုံးကိုလည်း ဖျက်လိုက်ပါမည်။"</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"သင်သည် သင်၏ လော့ခ်ဖွင့်ခြင်းပုံစံကို <xliff:g id="NUMBER_0">%1$d</xliff:g> ကြိမ် မှားယွင်းစွာ ဆွဲခဲ့ပါသည်။ <xliff:g id="NUMBER_1">%2$d</xliff:g> ကြိမ် ထပ်မံမှားယွင်းပြီးသည့်နောက်တွင် သင့်အီးမေးလ်အကောင့်အား အသုံးပြု၍ တက်ဘလက်ကို လော့ခ်ဖွင့်ရန် တောင်းဆိုသွားပါမည်။\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> စက္ကန့်အကြာတွင် ထပ်စမ်းကြည့်ပါ။"</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"သင်သည် သင်၏ လော့ခ်ဖွင့်ခြင်းပုံစံကို <xliff:g id="NUMBER_0">%1$d</xliff:g> ကြိမ် မှားယွင်းစွာ ဆွဲခဲ့ပါသည်။ <xliff:g id="NUMBER_1">%2$d</xliff:g> ကြိမ် ထပ်မံမှားယွင်းပြီးသည့်နောက်တွင် သင့်အီးမေးလ်အကောင့်အား အသုံးပြု၍ ဖုန်းကို လော့ခ်ဖွင့်ရန် တောင်းဆိုသွားပါမည်။\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> စက္ကန့်အကြာတွင် ထပ်စမ်းကြည့်ပါ။"</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"အပူရှိန်ကြောင့် ဖုန်းပိတ်သွားသည်"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"အပူရှိန်ကြောင့် စက်ပစ္စည်းပိတ်သွားသည်"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"အပူရှိန်ကြောင့် တက်ဘလက်ပိတ်သွားသည်"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"သင့်ဖုန်းသည် ယခု ပုံမှန်လုပ်ဆောင်နေပါပြီ။\nနောက်ထပ်အချက်အလက်များအတွက် တို့ပါ"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"သင့်စက်ပစ္စည်းသည် ယခု ပုံမှန်လုပ်ဆောင်နေပါပြီ။\nနောက်ထပ်အချက်အလက်များအတွက် တို့ပါ"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"သင့်တက်ဘလက်သည် ယခု ပုံမှန်လုပ်ဆောင်နေပါပြီ။\nနောက်ထပ်အချက်အလက်များအတွက် တို့ပါ"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"သင့်ဖုန်းအလွန်ပူနေသည့်အတွက် အေးသွားစေရန် ပိတ်ထားပါသည်။ ယခုပုံမှန် လုပ်ဆောင်နေပါပြီ။\n\nအောက်ပါတို့ကိုသုံးလျှင် အလွန်ပူလာနိုင်သည်-\n	• ရင်းမြစ်အထူးစိုက်ထုတ်ရသော အက်ပ်များကို သုံးခြင်း (ဂိမ်းကစားခြင်း၊ ဗီဒီယို (သို့) လမ်းညွှန်အက်ပ်များ ကဲ့သို့)\n	• ကြီးမားသောဖိုင်များ ဒေါင်းလုဒ် (သို့) အပ်လုဒ်လုပ်ခြင်း\n	• အပူရှိန်မြင့်သောနေရာတွင် ဖုန်းကိုသုံးခြင်း"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"သင့်စက်ပစ္စည်း အလွန်ပူနေသည့်အတွက် အေးသွားစေရန် ပိတ်ထားပါသည်။ ယခုပုံမှန် လုပ်ဆောင်နေပါပြီ။\n\nအောက်ပါတို့ကိုသုံးလျှင် အလွန်ပူလာနိုင်သည်-\n	• ရင်းမြစ်အထူးစိုက်ထုတ်ရသော အက်ပ်များကို သုံးခြင်း (ဂိမ်းကစားခြင်း၊ ဗီဒီယို (သို့) လမ်းညွှန်အက်ပ်များကဲ့သို့)\n	• ကြီးမားသောဖိုင်များ ဒေါင်းလုဒ် (သို့) အပ်လုဒ်လုပ်ခြင်း\n	• အပူရှိန်မြင့်သောနေရာတွင် စက်ပစ္စည်းကိုသုံးခြင်း"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"သင့်တက်ဘလက်အလွန်ပူနေသည့်အတွက် အေးသွားစေရန် ပိတ်ထားပါသည်။ ယခုပုံမှန် လုပ်ဆောင်နေပါပြီ။\n\nအောက်ပါတို့ကိုသုံးလျှင် အလွန်ပူလာနိုင်သည်-\n	• ရင်းမြစ်အထူးစိုက်ထုတ်ရသော အက်ပ်များကို သုံးခြင်း (ဂိမ်းကစားခြင်း၊ ဗီဒီယို (သို့) လမ်းညွှန်အက်ပ်များကဲ့သို့)\n	• ကြီးမားသောဖိုင်များ ဒေါင်းလုဒ် (သို့) အပ်လုဒ်လုပ်ခြင်း\n	• အပူရှိန်မြင့်သောနေရာတွင် တက်ဘလက်ကိုသုံးခြင်း"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"ဖုန်း ပူနွေးလာပါပြီ"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"စက်ပစ္စည်း ပူနွေးလာပါပြီ"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"တက်ဘလက် ပူနွေးလာပါပြီ"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"ဖုန်း ပြန်အေးလာစဉ် အင်္ဂါရပ်အချို့ကို ကန့်သတ်ထားပါသည်။\nနောက်ထပ်အချက်အလက်များအတွက် တို့ပါ"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"စက်ပစ္စည်း ပြန်အေးလာစဉ် အင်္ဂါရပ်အချို့ကို ကန့်သတ်ထားပါသည်။\nနောက်ထပ်အချက်အလက်များအတွက် တို့ပါ"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"တက်ဘလက် ပြန်အေးလာစဉ် အင်္ဂါရပ်အချို့ကို ကန့်သတ်ထားပါသည်။\nနောက်ထပ်အချက်အလက်များအတွက် တို့ပါ"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"သင့်ဖုန်းသည် အလိုအလျောက် ပြန်အေးသွားပါမည်။ ဖုန်းကို အသုံးပြုနိုင်သေးသော်လည်း ပိုနှေးသွားနိုင်ပါသည်။\n\nဖုန်း အေးသွားသည့်အခါ ပုံမှန်အတိုင်း ပြန်လုပ်ဆောင်လိမ့်မည်။"</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"သင့်စက်ပစ္စည်းသည် အလိုအလျောက် ပြန်အေးသွားပါမည်။ စက်ပစ္စည်းကို အသုံးပြုနိုင်သေးသော်လည်း ပိုနှေးသွားနိုင်ပါသည်။\n\nစက်ပစ္စည်း အေးသွားသည့်အခါ ပုံမှန်အတိုင်း ပြန်လုပ်ဆောင်လိမ့်မည်။"</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"သင့်တက်ဘလက်သည် အလိုအလျောက် ပြန်အေးသွားပါမည်။ တက်ဘလက်ကို အသုံးပြုနိုင်သေးသော်လည်း ပိုနှေးသွားနိုင်ပါသည်။\n\nတက်ဘလက် အေးသွားသည့်အခါ ပုံမှန်အတိုင်း ပြန်လုပ်ဆောင်လိမ့်မည်။"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"လက်ဗွေ အာရုံခံကိရိယာသည် ဖွင့်ပိတ်ခလုတ်ပေါ်တွင် ရှိသည်။ တက်ဘလက်၏ဘေးဘက်ရှိ အသံထိန်းခလုတ်ဖုသီးနှင့် ကပ်လျက်မှ ခလုတ်ပြားဖြစ်သည်။"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"လက်ဗွေ အာရုံခံကိရိယာသည် ဖွင့်ပိတ်ခလုတ်ပေါ်တွင် ရှိသည်။ စက်၏ဘေးဘက်ရှိ အသံထိန်းခလုတ်ဖုသီးနှင့် ကပ်လျက်မှ ခလုတ်ပြားဖြစ်သည်။"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"လက်ဗွေ အာရုံခံကိရိယာသည် ဖွင့်ပိတ်ခလုတ်ပေါ်တွင် ရှိသည်။ ဖုန်း၏ဘေးဘက်ရှိ အသံထိန်းခလုတ်ဖုသီးနှင့် ကပ်လျက်မှ ခလုတ်ပြားဖြစ်သည်။"</string>
diff --git a/packages/SystemUI/res-product/values-nb/strings.xml b/packages/SystemUI/res-product/values-nb/strings.xml
index 4b16a43..533a9b8 100644
--- a/packages/SystemUI/res-product/values-nb/strings.xml
+++ b/packages/SystemUI/res-product/values-nb/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Du har gjort feil i forsøket på å låse opp telefonen <xliff:g id="NUMBER">%d</xliff:g> ganger. Jobbprofilen blir fjernet, og alle profildataene blir slettet."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Du har tegnet opplåsingsmønsteret feil <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%2$d</xliff:g> nye mislykkede forsøk blir du bedt om å låse opp nettbrettet via en e-postkonto.\n\n Prøv på nytt om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Du har tegnet opplåsingsmønsteret feil <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%2$d</xliff:g> nye mislykkede forsøk blir du bedt om å låse opp telefonen via en e-postkonto.\n\n Prøv på nytt om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Telefonen ble slått av på grunn av varme"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Enheten ble slått av på grunn av varme"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Nettbrett ble slått av på grunn av varme"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Telefonen kjører nå som normalt.\nTrykk for å se mer informasjon"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Enheten kjører nå som normalt.\nTrykk for å se mer informasjon"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Nettbrettet kjører nå som normalt.\nTrykk for å se mer informasjon"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Telefonen var for varm, så den ble slått av for å kjøles ned. Den kjører nå som normalt.\n\nTelefonen kan blir for varm hvis du\n	• bruker ressurskrevende apper (for eksempel spill-, video- eller navigeringsapper)\n	• laster store filer opp eller ned\n	• bruker den ved høy temperatur"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Enheten var for varm, så den ble slått av for å kjøles ned. Den kjører nå som normalt.\n\nEnheten kan blir for varm hvis du\n	• bruker ressurskrevende apper (for eksempel spill-, video- eller navigeringsapper)\n	• laster store filer opp eller ned\n	• bruker den ved høy temperatur"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Nettbrettet var for varmt, så det ble slått av for å kjøles ned. Det kjører nå som normalt.\n\nNettbrettet kan blir for varmt hvis du\n	• bruker ressurskrevende apper (for eksempel spill-, video- eller navigeringsapper)\n	• laster store filer opp eller ned\n	• bruker det ved høy temperatur"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Telefonen begynner å bli varm"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Enheten begynner å bli varm"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Nettbrett begynner å bli varmt"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Enkelte funksjoner er begrenset mens telefonen kjøles ned.\nTrykk for å se mer informasjon"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Enkelte funksjoner er begrenset mens enheten kjøles ned.\nTrykk for å se mer informasjon"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Enkelte funksjoner er begrenset mens nettbrettet kjøles ned.\nTrykk for å se mer informasjon"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Telefonen prøver automatisk å kjøle seg ned. Du kan fremdeles bruke den, men den kjører muligens saktere.\n\nNår telefonen har kjølt seg ned, kjører den som normalt."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Enheten prøver automatisk å kjøle seg ned. Du kan fremdeles bruke den, men den kjører muligens saktere.\n\nNår enheten har kjølt seg ned, kjører den som normalt."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Nettbrettet prøver automatisk å kjøle seg ned. Du kan fremdeles bruke det, men det kjører muligens saktere.\n\nNår nettbrettet har kjølt seg ned, kjører det som normalt."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Fingeravtrykkssensoren er på av/på-knappen. Det er den flate knappen ved siden av den hevede volumknappen på siden av nettbrettet."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Fingeravtrykkssensoren er på av/på-knappen. Det er den flate knappen ved siden av den hevede volumknappen på siden av enheten."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Fingeravtrykkssensoren er på av/på-knappen. Det er den flate knappen ved siden av den hevede volumknappen på siden av telefonen."</string>
diff --git a/packages/SystemUI/res-product/values-ne/strings.xml b/packages/SystemUI/res-product/values-ne/strings.xml
index 7276e23..274b72a 100644
--- a/packages/SystemUI/res-product/values-ne/strings.xml
+++ b/packages/SystemUI/res-product/values-ne/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"तपाईंले <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले फोन अनलक गर्ने प्रयास गर्नुभएको छ। कार्य प्रोफाइललाई यसका सबै डेटा मेटिने गरी हटाइने छ।"</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक आफ्नो अनलक गर्ने ढाँचा गलत रूपमा कोर्नुभयो। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> पटक असफल प्रयास गरेपछि, तपाईंलाई एउटा इमेल खाता प्रयोग गरेर आफ्नो ट्याब्लेट अनलक गर्न आग्रह गरिने छ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक आफ्नो अनलक गर्ने ढाँचा गलत रूपमा कोर्नुभयो। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> पटक असफल प्रयास गरेपछि, तपाईंलाई एउटा इमेल खाता प्रयोग गरेर आफ्नो फोन अनलक गर्न आग्रह गरिने छ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"तातिएका कारण फोन अफ भयो"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"तातिएका कारण डिभाइस अफ भयो"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"तातिएका कारण ट्याब्लेट अफ भयो"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"तपाईंको फोन अहिले सामान्य रूपमा चलिरहेको छ।\nथप जानकारीका लागि ट्याप गर्नुहोस्"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"तपाईंको डिभाइस अहिले सामान्य रूपमा चलिरहेको छ।\nथप जानकारीका लागि ट्याप गर्नुहोस्"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"तपाईंको ट्याब्लेट अहिले सामान्य रूपमा चलिरहेको छ।\nथप जानकारीका लागि ट्याप गर्नुहोस्"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"तपाईंको फोन अत्यधिक तातेका कारण सेलाउनका लागि अफ भयो। तपाईंको फोन अहिले सामान्य रूपमा चल्दै छ।\n\nतपाईंले निम्न कुरा गर्नुभयो भने तपाईंको फोन अत्यधिक तात्न सक्छ:\n	• धेरै स्रोत प्रयोग गर्ने एपहरू (गेमिङ, भिडियो वा नेभिगेसन एप जस्ता) प्रयोग गर्दा\n	• ठुला फाइलहरू डाउनलोड वा अपलोड गर्दा\n	• उच्च तापक्रममा फोन प्रयोग गर्दा"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"तपाईंको डिभाइस अत्यधिक तातेका कारण सेलाउनका लागि अफ भयो। तपाईंको डिभाइस अहिले सामान्य रूपमा चल्दै छ।\n\nतपाईंले निम्न कुरा गर्नुभयो भने तपाईंको डिभाइस अत्यधिक तात्न सक्छ:\n	• धेरै स्रोत प्रयोग गर्ने एपहरू (गेमिङ, भिडियो वा नेभिगेसन एप जस्ता) प्रयोग गर्दा\n	• ठुला फाइलहरू डाउनलोड वा अपलोड गर्दा\n	•उच्च तापक्रममा डिभाइस प्रयोग गर्दा"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"तपाईंको ट्याब्लेट अत्यधिक तातेका कारण सेलाउनका लागि अफ भयो। तपाईंको ट्याब्लेट अहिले सामान्य रूपमा चल्दै छ।\n\nतपाईंले निम्न कुरा गर्नुभयो भने तपाईंको ट्याब्लेट अत्यधिक तात्न सक्छ:\n	•धेरै स्रोत प्रयोग गर्ने एपहरू (गेमिङ, भिडियो वा नेभिगेसन एप जस्ता) प्रयोग गर्दा \n	• ठुला फाइलहरू डाउनलोड वा अपलोड गर्दा\n	• उच्च तापक्रममा ट्याब्लेट प्रयोग गर्दा"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"फोन तात्न थालेको छ"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"डिभाइस तात्न थालेको छ"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"ट्याब्लेट तात्न थालेको छ"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"फोन सेलाउने क्रममा गर्दा केही सुविधाहरू उपलब्ध हुँदैनन्।\nथप जानकारीका लागि ट्याप गर्नुहोस्"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"डिभाइस सेलाउने क्रममा केही सुविधाहरू उपलब्ध हुँदैनन्।\nथप जानकारीका लागि ट्याप गर्नुहोस्"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"ट्याब्लेट सेलाउने क्रममा केही सुविधाहरू उपलब्ध हुँदैनन्।\nथप जानकारीका लागि ट्याप गर्नुहोस्"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"तपाईंको फोनले स्वतः सेलाउने प्रयास गर्ने छ। तपाईं अझै पनि आफ्नो फोन प्रयोग गर्न सक्नुहुन्छ तर उक्त फोन अलि सुस्त चल्न सक्छ।\n\nसेलाइसकेपछि भने तपाईंको फोन पहिले जस्तै राम्ररी चल्न थाल्ने छ।"</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"तपाईंको डिभाइसले स्वतः सेलाउने प्रयास गर्ने छ। तपाईं अझै पनि आफ्नो डिभाइस प्रयोग गर्न सक्नुहुन्छ तर उक्त डिभाइस अलि सुस्त चल्न सक्छ।\n\nसेलाइसकेपछि भने तपाईंको डिभाइस पहिले जस्तै राम्ररी चल्न थाल्ने छ।"</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"तपाईंको ट्याब्लेटले स्वतः सेलाउने प्रयास गर्ने छ। तपाईं अझै पनि आफ्नो ट्याब्लेट प्रयोग गर्न सक्नुहुन्छ तर उक्त ट्याब्लेट अलि सुस्त चल्न सक्छ।\n\nसेलाइसकेपछि भने तपाईंको ट्याब्लेट पहिले जस्तै राम्ररी चल्न थाल्ने छ।"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"फिंगरप्रिन्ट सेन्सर पावर बटनमा हुन्छ। यो ट्याब्लेटको किनारामा रहेको थोरै उचालिएको भोल्युम बटनको छेउमा रहेको चेप्टो बटन नै पावर बटन हो।"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"फिंगरप्रिन्ट सेन्सर पावर बटनमा हुन्छ। यो डिभाइसको किनारामा रहेको थोरै उचालिएको भोल्युम बटनको छेउमा रहेको चेप्टो बटन नै पावर बटन हो।"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"फिंगरप्रिन्ट सेन्सर पावर बटनमा हुन्छ। यो फोनको किनारामा रहेको थोरै उचालिएको भोल्युम बटनको छेउमा रहेको चेप्टो बटन नै पावर बटन हो।"</string>
diff --git a/packages/SystemUI/res-product/values-nl/strings.xml b/packages/SystemUI/res-product/values-nl/strings.xml
index 70cd0a4..abdc7ee 100644
--- a/packages/SystemUI/res-product/values-nl/strings.xml
+++ b/packages/SystemUI/res-product/values-nl/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> mislukte pogingen ondernomen om de telefoon te ontgrendelen. Het werkprofiel wordt verwijderd, waardoor alle profielgegevens worden verwijderd."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen wordt je gevraagd je tablet te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%3$d</xliff:g> seconden opnieuw."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen wordt je gevraagd je telefoon te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%3$d</xliff:g> seconden opnieuw."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Telefoon uitgezet wegens hitte"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Apparaat uitgezet wegens hitte"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tablet uitgezet wegens hitte"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Je telefoon functioneert nu weer zoals normaal.\nTik voor meer informatie"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Je apparaat functioneert nu weer zoals normaal.\nTik voor meer informatie"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Je tablet functioneert nu weer zoals normaal.\nTik voor meer informatie"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Je telefoon was te warm en is uitgezet om af te koelen. Je telefoon presteert nu weer zoals normaal.\n\nJe telefoon kan warm worden als je:\n	• bronintensieve apps gebruikt (zoals game-, video-, of navigatie-apps),\n	• grote bestanden up- of downloadt,\n	• je telefoon gebruikt bij hoge temperaturen."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Je apparaat was te warm en is uitgezet om af te koelen. Je apparaat presteert nu weer zoals normaal.\n\nJe apparaat kan warm worden als je:\n	• bronintensieve apps gebruikt (zoals game-, video-, of navigatie-apps),\n	• grote bestanden up- of downloadt,\n	• je apparaat gebruikt bij hoge temperaturen."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Je tablet was te warm en is uitgezet om af te koelen. Je tablet presteert nu weer zoals normaal.\n\nJe tablet kan warm worden als je:\n	• bronintensieve apps gebruikt (zoals game-, video-, of navigatie-apps),\n	• grote bestanden up- of downloadt,\n	• je tablet gebruikt bij hoge temperaturen."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"De telefoon wordt warm"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Het apparaat wordt warm"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"De tablet wordt warm"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Bepaalde functies zijn beperkt terwijl de telefoon afkoelt.\nTik voor meer informatie"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Bepaalde functies zijn beperkt terwijl het apparaat afkoelt.\nTik voor meer informatie"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Bepaalde functies zijn beperkt terwijl de tablet afkoelt.\nTik voor meer informatie"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Je telefoon probeert automatisch af te koelen. Je kunt je telefoon nog steeds gebruiken, maar deze kan langzamer werken.\n\nZodra de telefoon is afgekoeld, werkt deze weer normaal."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Je apparaat probeert automatisch af te koelen. Je kunt je apparaat nog steeds gebruiken, maar het kan langzamer werken.\n\nZodra het apparaat is afgekoeld, werkt het weer normaal."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Je tablet probeert automatisch af te koelen. Je kunt je tablet nog steeds gebruiken, maar deze kan langzamer werken.\n\nZodra de tablet is afgekoeld, werkt deze weer normaal."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Je vindt de vingerafdruksensor op de aan/uit-knop. Het is de platte knop naast de verhoogde volumeknop aan de zijkant van de tablet."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Je vindt de vingerafdruksensor op de aan/uit-knop. Het is de platte knop naast de verhoogde volumeknop aan de zijkant van het apparaat."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Je vindt de vingerafdruksensor op de aan/uit-knop. Het is de platte knop naast de verhoogde volumeknop aan de zijkant van de telefoon."</string>
diff --git a/packages/SystemUI/res-product/values-or/strings.xml b/packages/SystemUI/res-product/values-or/strings.xml
index f3e8d2f..5d9345b 100644
--- a/packages/SystemUI/res-product/values-or/strings.xml
+++ b/packages/SystemUI/res-product/values-or/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"ଆପଣ ଫୋନ୍‌କୁ ଅନ୍‌ଲକ୍ କରିବାକୁ<xliff:g id="NUMBER">%d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। କାର୍ଯ୍ୟ ପ୍ରୋଫାଇଲ୍ ବାହାର କରିଦିଆଯିବ, ଯାହା ଫଳରେ ସମସ୍ତ ପ୍ରୋଫାଇଲ୍ ଡାଟା ଡିଲିଟ୍ ହେବ।"</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"ଆପଣ ଆପଣଙ୍କ ଅନ୍‌ଲକ୍ ପାଟର୍ନକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ଭାବେ ଡ୍ର କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ ପ୍ରୟାସ ପରେ ଆପଣଙ୍କୁ ଏକ ଇମେଲ୍ ଆକାଉଣ୍ଟ ବ୍ୟବହାର କରି ଆପଣଙ୍କ ଟାବ୍‌ଲୋଟ୍‌କୁ ଅନ୍‌ଲକ୍ କରିବା ପାଇଁ କୁହାଯିବ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ସେକେଣ୍ଡ ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"ଆପଣ ଆପଣଙ୍କ ଅନ୍‌ଲକ୍ ପାଟର୍ନକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ଭାବେ ଡ୍ର କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ ପ୍ରୟାସ ପରେ ଆପଣଙ୍କୁ ଏକ ଇମେଲ୍ ଆକାଉଣ୍ଟ ବ୍ୟବହାର କରି ଆପଣଙ୍କ ଫୋନ୍‌କୁ ଅନ୍‌ଲକ୍‌ କରିବା ପାଇଁ କୁହାଯିବ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ସେକେଣ୍ଡ ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"ଗରମ ହେବା ଯୋଗୁଁ ଫୋନଟି ବନ୍ଦ ହୋଇଯାଇଛି"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"ଗରମ ହେବା ଯୋଗୁଁ ଡିଭାଇସଟି ବନ୍ଦ ହୋଇଯାଇଛି"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"ଗରମ ହେବା ଯୋଗୁଁ ଟାବଲେଟଟି ବନ୍ଦ ହୋଇଯାଇଛି"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"ଆପଣଙ୍କ ଫୋନ ବର୍ତ୍ତମାନ ସ୍ୱାଭାବିକ ଭାବେ ଚାଲୁଛି।\nଅଧିକ ସୂଚନା ପାଇଁ ଟାପ କରନ୍ତୁ"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"ଆପଣଙ୍କ ଡିଭାଇସ ବର୍ତ୍ତମାନ ସ୍ୱାଭାବିକ ଭାବେ ଚାଲୁଛି।\nଅଧିକ ସୂଚନା ପାଇଁ ଟାପ କରନ୍ତୁ"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"ଆପଣଙ୍କ ଟାବଲେଟ ବର୍ତ୍ତମାନ ସ୍ୱାଭାବିକ ଭାବେ ଚାଲୁଛି।\nଅଧିକ ସୂଚନା ପାଇଁ ଟାପ କରନ୍ତୁ"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"ଆପଣଙ୍କ ଫୋନଟି ଅତ୍ୟଧିକ ଗରମ ଥିବା ଯୋଗୁଁ ଥଣ୍ଡା କରାଯିବାକୁ ଏହାକୁ ବନ୍ଦ କରାଯାଇଛି। ଆପଣଙ୍କ ଫୋନ ବର୍ତ୍ତମାନ ସ୍ୱାଭାବିକ ଭାବେ ଚାଲୁଛି।\n\nଆପଣଙ୍କ ଫୋନ ଅତ୍ୟଧିକ ଗରମ ହୋଇଯାଇପାରେ ଯଦି ଆପଣ:\n	• ରିସୋର୍ସ-ଇଣ୍ଟେନସିଭ ଆପ୍ସ (ଯେପରି ଗେମିଂ, ଭିଡିଓ କିମ୍ବା ନେଭିଗେସନ ଆପ୍ସ) ବ୍ୟବହାର କରନ୍ତି\n	• ବଡ଼ ଫାଇଲଗୁଡ଼ିକ ଡାଉନଲୋଡ କିମ୍ବା ଅପଲୋଡ କରନ୍ତି\n	• ଅଧିକ ତାପମାତ୍ରାରେ ଆପଣଙ୍କ ଫୋନ ବ୍ୟବହାର କରନ୍ତି"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"ଆପଣଙ୍କ ଡିଭାଇସଟି ଅତ୍ୟଧିକ ଗରମ ଥିବା ଯୋଗୁଁ ଥଣ୍ଡା କରାଯିବାକୁ ଏହାକୁ ବନ୍ଦ କରାଯାଇଛି। ଆପଣଙ୍କ ଡିଭାଇସ ବର୍ତ୍ତମାନ ସ୍ୱାଭାବିକ ଭାବେ ଚାଲୁଛି।\n\nଆପଣଙ୍କ ଡିଭାଇସ ଅତ୍ୟଧିକ ଗରମ ହୋଇଯାଇପାରେ ଯଦି ଆପଣ:\n	• ରିସୋର୍ସ-ଇଣ୍ଟେନସିଭ ଆପ୍ସ (ଯେପରି ଗେମିଂ, ଭିଡିଓ କିମ୍ବା ନେଭିଗେସନ ଆପ୍ସ) ବ୍ୟବହାର କରନ୍ତି\n	• ବଡ଼ ଫାଇଲଗୁଡ଼ିକ ଡାଉନଲୋଡ କିମ୍ବା ଅପଲୋଡ କରନ୍ତି\n	• ଅଧିକ ତାପମାତ୍ରାରେ ଆପଣଙ୍କ ଡିଭାଇସ ବ୍ୟବହାର କରନ୍ତି"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"ଆପଣଙ୍କ ଟାବଲେଟଟି ଅତ୍ୟଧିକ ଗରମ ଥିବା ଯୋଗୁଁ ଥଣ୍ଡା କରାଯିବାକୁ ଏହାକୁ ବନ୍ଦ କରାଯାଇଛି। ଆପଣଙ୍କ ଟାବଲେଟ ବର୍ତ୍ତମାନ ସ୍ୱାଭାବିକ ଭାବେ ଚାଲୁଛି।\n\nଆପଣଙ୍କ ଟାବଲେଟ ଅତ୍ୟଧିକ ଗରମ ହୋଇଯାଇପାରେ ଯଦି ଆପଣ:\n	• ରିସୋର୍ସ-ଇଣ୍ଟେନସିଭ ଆପ୍ସ (ଯେପରି ଗେମିଂ, ଭିଡିଓ କିମ୍ବା ନେଭିଗେସନ ଆପ୍ସ) ବ୍ୟବହାର କରନ୍ତି\n	• ବଡ଼ ଫାଇଲଗୁଡ଼ିକ ଡାଉନଲୋଡ କିମ୍ବା ଅପଲୋଡ କରନ୍ତି\n	• ଅଧିକ ତାପମାତ୍ରାରେ ଆପଣଙ୍କ ଟାବଲେଟ ବ୍ୟବହାର କରନ୍ତି"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"ଫୋନଟି ଗରମ ହେଉଛି"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"ଡିଭାଇସଟି ଗରମ ହେଉଛି"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"ଟାବଲେଟଟି ଗରମ ହେଉଛି"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"ଫୋନ ଥଣ୍ଡା ହେବା ସମୟରେ କିଛି ଫିଚର ସୀମିତ ଅଟେ।\nଅଧିକ ସୂଚନା ପାଇଁ ଟାପ କରନ୍ତୁ"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"ଡିଭାଇସ ଥଣ୍ଡା ହେବା ସମୟରେ କିଛି ଫିଚର ସୀମିତ ଅଟେ।\nଅଧିକ ସୂଚନା ପାଇଁ ଟାପ କରନ୍ତୁ"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"ଟାବଲେଟ ଥଣ୍ଡା ହେବା ସମୟରେ କିଛି ଫିଚର ସୀମିତ ଅଟେ।\nଅଧିକ ସୂଚନା ପାଇଁ ଟାପ କରନ୍ତୁ"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"ଆପଣଙ୍କ ଫୋନ ସ୍ୱତଃ ଥଣ୍ଡା ହେବାକୁ ଚେଷ୍ଟା କରିବ। ଆପଣ ଏବେ ବି ଆପଣଙ୍କ ଫୋନ ବ୍ୟବହାର କରିପାରିବେ, କିନ୍ତୁ ଏହା ଧୀରେ ଚାଲିପାରେ।\n\nଆପଣଙ୍କ ଫୋନ ଥଣ୍ଡା ହୋଇଯିବା ପରେ ଏହା ସ୍ୱାଭାବିକ ଭାବେ ଚାଲିବ।"</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"ଆପଣଙ୍କ ଡିଭାଇସ ସ୍ୱତଃ ଥଣ୍ଡା ହେବାକୁ ଚେଷ୍ଟା କରିବ। ଆପଣ ଏବେ ବି ଆପଣଙ୍କ ଡିଭାଇସ ବ୍ୟବହାର କରିପାରିବେ, କିନ୍ତୁ ଏହା ଧୀରେ ଚାଲିପାରେ।\n\nଆପଣଙ୍କ ଡିଭାଇସ ଥଣ୍ଡା ହୋଇଯିବା ପରେ ଏହା ସ୍ୱାଭାବିକ ଭାବେ ଚାଲିବ।"</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"ଆପଣଙ୍କ ଟାବଲେଟ ସ୍ୱତଃ ଥଣ୍ଡା ହେବାକୁ ଚେଷ୍ଟା କରିବ। ଆପଣ ଏବେ ବି ଆପଣଙ୍କ ଟାବଲେଟ ବ୍ୟବହାର କରିପାରିବେ, କିନ୍ତୁ ଏହା ଧୀରେ ଚାଲିପାରେ।\n\nଆପଣଙ୍କ ଟାବଲେଟ ଥଣ୍ଡା ହୋଇଯିବା ପରେ ଏହା ସ୍ୱାଭାବିକ ଭାବେ ଚାଲିବ।"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"ଟିପଚିହ୍ନ ସେନ୍ସର ପାୱାର ବଟନରେ ଅଛି। ଏହା ଟାବଲେଟର ଧାରରେ ବଢ଼ାଯାଇଥିବା ଭଲ୍ୟୁମ ବଟନ ପାଖରେ ଥିବା ଫ୍ଲାଟ ବଟନ ଅଟେ।"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"ଟିପଚିହ୍ନ ସେନ୍ସର ପାୱାର ବଟନରେ ଅଛି। ଏହା ଡିଭାଇସର ଧାରରେ ବଢ଼ାଯାଇଥିବା ଭଲ୍ୟୁମ ବଟନ ପାଖରେ ଥିବା ଫ୍ଲାଟ ବଟନ ଅଟେ।"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"ଟିପଚିହ୍ନ ସେନ୍ସର ପାୱାର ବଟନରେ ଅଛି। ଏହା ଫୋନର ଧାରରେ ଉଠି ରହିଥିବା ଭଲ୍ୟୁମ ବଟନ ପାଖରେ ଥିବା ଫ୍ଲାଟ ବଟନ ଅଟେ।"</string>
diff --git a/packages/SystemUI/res-product/values-pa/strings.xml b/packages/SystemUI/res-product/values-pa/strings.xml
index 38fd890..81b047c 100644
--- a/packages/SystemUI/res-product/values-pa/strings.xml
+++ b/packages/SystemUI/res-product/values-pa/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਫ਼ੋਨ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਹੈ। ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਸਾਰਾ ਪ੍ਰੋਫਾਈਲ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਣਲਾਕ ਪੈਟਰਨ ਗਲਤ ਢੰਗ ਨਾਲ ਉਲੀਕਿਆ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਇੱਕ ਈਮੇਲ ਖਾਤਾ ਵਰਤਦੇ ਹੋਏ ਆਪਣੇ ਟੈਬਲੈੱਟ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਵੇਗਾ।\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਣਲਾਕ ਪੈਟਰਨ ਗਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਇੱਕ ਈਮੇਲ ਖਾਤਾ ਵਰਤਦੇ ਹੋਏ ਆਪਣਾ ਫ਼ੋਨ ਅਣਲਾਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"ਗਰਮ ਹੋਣ ਕਰਕੇ ਫ਼ੋਨ ਬੰਦ ਹੋ ਗਿਆ"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"ਗਰਮ ਹੋਣ ਕਰਕੇ ਡੀਵਾਈਸ ਬੰਦ ਹੋ ਗਿਆ"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"ਗਰਮ ਹੋਣ ਕਰਕੇ ਟੈਬਲੈੱਟ ਬੰਦ ਹੋ ਗਿਆ"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"ਤੁਹਾਡਾ ਫ਼ੋਨ ਹੁਣ ਸਹੀ ਚੱਲ ਰਿਹਾ ਹੈ।\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਹੁਣ ਸਹੀ ਚੱਲ ਰਿਹਾ ਹੈ।\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"ਤੁਹਾਡਾ ਟੈਬਲੈੱਟ ਹੁਣ ਸਹੀ ਚੱਲ ਰਿਹਾ ਹੈ।\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"ਤੁਹਾਡਾ ਫ਼ੋਨ ਬਹੁਤ ਗਰਮ ਸੀ, ਇਸ ਲਈ ਇਹ ਠੰਡਾ ਹੋਣ ਵਾਸਤੇ ਬੰਦ ਹੋ ਗਿਆ ਸੀ। ਤੁਹਾਡਾ ਫ਼ੋਨ ਹੁਣ ਸਹੀ ਚੱਲ ਰਿਹਾ ਹੈ।\n\nਤੁਹਾਡਾ ਫ਼ੋਨ ਬਹੁਤ ਗਰਮ ਹੋ ਸਕਦਾ ਹੈ ਜੇ:\n	• ਤੁਸੀਂ ਸਰੋਤਾਂ ਦੀ ਵੱਧ ਵਰਤੋਂ ਵਾਲੀਆਂ ਐਪਾਂ (ਜਿਵੇਂ ਗੇਮਿੰਗ, ਵੀਡੀਓ, ਜਾਂ ਦਿਸ਼ਾ-ਨਿਰਦੇਸ਼ ਐਪਾਂ) ਵਰਤਦੇ ਹੋ\n	• ਵੱਡੀਆਂ ਫ਼ਾਈਲਾਂ ਡਾਊਨਲੋਡ ਜਾਂ ਅੱਪਲੋਡ ਕਰਦੇ ਹੋ\n	• ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਉੱਚ ਤਾਪਮਾਨਾਂ ਵਿੱਚ ਵਰਤਦੇ ਹੋ"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਬਹੁਤ ਗਰਮ ਸੀ, ਇਸ ਲਈ ਇਹ ਠੰਡਾ ਹੋਣ ਵਾਸਤੇ ਬੰਦ ਹੋ ਗਿਆ ਸੀ। ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਹੁਣ ਸਹੀ ਚੱਲ ਰਿਹਾ ਹੈ।\n\nਤੁਹਾਡਾ ਡੀਵਾਈਸ ਬਹੁਤ ਗਰਮ ਹੋ ਸਕਦਾ ਹੈ ਜੇ:\n	• ਤੁਸੀਂ ਸਰੋਤਾਂ ਦੀ ਵੱਧ ਵਰਤੋਂ ਵਾਲੀਆਂ ਐਪਾਂ (ਜਿਵੇਂ ਗੇਮਿੰਗ, ਵੀਡੀਓ, ਜਾਂ ਦਿਸ਼ਾ-ਨਿਰਦੇਸ਼ ਐਪਾਂ) ਵਰਤਦੇ ਹੋ\n	• ਵੱਡੀਆਂ ਫ਼ਾਈਲਾਂ ਡਾਊਨਲੋਡ ਜਾਂ ਅੱਪਲੋਡ ਕਰਦੇ ਹੋ\n	• ਆਪਣੇ ਡੀਵਾਈਸ ਨੂੰ ਉੱਚ ਤਾਪਮਾਨਾਂ ਵਿੱਚ ਵਰਤਦੇ ਹੋ"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"ਤੁਹਾਡਾ ਟੈਬਲੈੱਟ ਬਹੁਤ ਗਰਮ ਸੀ, ਇਸ ਲਈ ਇਹ ਠੰਡਾ ਹੋਣ ਵਾਸਤੇ ਬੰਦ ਹੋ ਗਿਆ ਸੀ। ਤੁਹਾਡਾ ਟੈਬਲੈੱਟ ਹੁਣ ਸਹੀ ਚੱਲ ਰਿਹਾ ਹੈ।\n\nਤੁਹਾਡਾ ਟੈਬਲੈੱਟ ਬਹੁਤ ਗਰਮ ਹੋ ਸਕਦਾ ਹੈ ਜੇ:\n	• ਤੁਸੀਂ ਸਰੋਤਾਂ ਦੀ ਵੱਧ ਵਰਤੋਂ ਵਾਲੀਆਂ ਐਪਾਂ (ਜਿਵੇਂ ਗੇਮਿੰਗ, ਵੀਡੀਓ, ਜਾਂ ਦਿਸ਼ਾ-ਨਿਰਦੇਸ਼ ਐਪਾਂ) ਵਰਤਦੇ ਹੋ\n	• ਵੱਡੀਆਂ ਫ਼ਾਈਲਾਂ ਡਾਊਨਲੋਡ ਜਾਂ ਅੱਪਲੋਡ ਕਰਦੇ ਹੋ\n	• ਆਪਣੇ ਟੈਬਲੈੱਟ ਨੂੰ ਉੱਚ ਤਾਪਮਾਨਾਂ ਵਿੱਚ ਵਰਤਦੇ ਹੋ"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"ਫ਼ੋਨ ਗਰਮ ਹੋ ਰਿਹਾ ਹੈ"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"ਡੀਵਾਈਸ ਗਰਮ ਹੋ ਰਿਹਾ ਹੈ"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"ਟੈਬਲੈੱਟ ਗਰਮ ਹੋ ਰਿਹਾ ਹੈ"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"ਫ਼ੋਨ ਦੇ ਠੰਡਾ ਹੋਣ ਦੇ ਦੌਰਾਨ ਕੁਝ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਸੀਮਤ ਹੁੰਦੀਆਂ ਹਨ।\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"ਡੀਵਾਈਸ ਦੇ ਠੰਡਾ ਹੋਣ ਦੇ ਦੌਰਾਨ ਕੁਝ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਸੀਮਤ ਹੁੰਦੀਆਂ ਹਨ।\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"ਟੈਬਲੈੱਟ ਦੇ ਠੰਡਾ ਹੋਣ ਦੇ ਦੌਰਾਨ ਕੁਝ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਸੀਮਤ ਹੁੰਦੀਆਂ ਹਨ।\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"ਤੁਹਾਡਾ ਫ਼ੋਨ ਆਪਣੇ-ਆਪ ਠੰਡਾ ਹੋਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੇਗਾ। ਤੁਸੀਂ ਹਾਲੇ ਵੀ ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਵਰਤ ਸਕਦੇ ਹੋ, ਪਰ ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਇਹ ਹੌਲੀ ਚੱਲੇ।\n\nਠੰਡਾ ਹੋਣ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਡਾ ਫ਼ੋਨ ਆਮ ਵਾਂਗ ਚੱਲੇਗਾ।"</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਆਪਣੇ-ਆਪ ਠੰਡਾ ਹੋਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੇਗਾ। ਤੁਸੀਂ ਹਾਲੇ ਵੀ ਆਪਣੇ ਡੀਵਾਈਸ ਨੂੰ ਵਰਤ ਸਕਦੇ ਹੋ, ਪਰ ਹੋ ਸਕਦਾ ਹੈ ਇਹ ਹੌਲੀ ਚੱਲੇ।\n\nਠੰਡਾ ਹੋਣ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਆਮ ਵਾਂਗ ਚੱਲੇਗਾ।"</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"ਤੁਹਾਡਾ ਟੈਬਲੈੱਟ ਆਪਣੇ-ਆਪ ਠੰਡਾ ਹੋਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੇਗਾ। ਤੁਸੀਂ ਹਾਲੇ ਵੀ ਆਪਣੇ ਟੈਬਲੈੱਟ ਨੂੰ ਵਰਤ ਸਕਦੇ ਹੋ, ਪਰ ਹੋ ਸਕਦਾ ਹੈ ਇਹ ਹੌਲੀ ਚੱਲੇ।\n\nਠੰਡਾ ਹੋਣ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਡਾ ਟੈਬਲੈੱਟ ਆਮ ਵਾਂਗ ਚੱਲੇਗਾ।"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਪਾਵਰ ਬਟਨ \'ਤੇ ਹੈ। ਇਹ ਟੈਬਲੈੱਟ ਦੇ ਕਿਨਾਰੇ \'ਤੇ ਅਜਿਹਾ ਸਮਤਲ ਬਟਨ ਹੁੰਦਾ ਹੈ ਜੋ ਉੱਭਰੇ ਹੋਏ ਅਵਾਜ਼ ਬਟਨ ਦੇ ਅੱਗੇ ਹੁੰਦਾ ਹੈ।"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਪਾਵਰ ਬਟਨ \'ਤੇ ਹੈ। ਇਹ ਡੀਵਾਈਸ ਦੇ ਕਿਨਾਰੇ \'ਤੇ ਅਜਿਹਾ ਸਮਤਲ ਬਟਨ ਹੁੰਦਾ ਹੈ ਜੋ ਉੱਭਰੇ ਹੋਏ ਅਵਾਜ਼ ਬਟਨ ਦੇ ਅੱਗੇ ਹੁੰਦਾ ਹੈ।"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਪਾਵਰ ਬਟਨ \'ਤੇ ਹੈ। ਇਹ ਫ਼ੋਨ ਦੇ ਕਿਨਾਰੇ \'ਤੇ ਅਜਿਹਾ ਸਮਤਲ ਬਟਨ ਹੁੰਦਾ ਹੈ ਜੋ ਉੱਭਰੇ ਹੋਏ ਅਵਾਜ਼ ਬਟਨ ਦੇ ਅੱਗੇ ਹੁੰਦਾ ਹੈ।"</string>
diff --git a/packages/SystemUI/res-product/values-pl/strings.xml b/packages/SystemUI/res-product/values-pl/strings.xml
index 7dc2ded..286a242 100644
--- a/packages/SystemUI/res-product/values-pl/strings.xml
+++ b/packages/SystemUI/res-product/values-pl/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Po raz <xliff:g id="NUMBER">%d</xliff:g> próbowano nieprawidłowo odblokować telefon. Profil służbowy zostanie usunięty, co spowoduje skasowanie wszystkich jego danych."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> nieprawidłowo narysowano wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach konieczne będzie odblokowanie tabletu przy użyciu konta e-mail.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> nieprawidłowo narysowano wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach konieczne będzie odblokowanie telefonu przy użyciu konta e-mail.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Telefon wyłączony: przegrzanie"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Urządzenie wyłączone: przegrzanie"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tablet wyłączony: przegrzanie"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Telefon działa teraz normalnie.\nKliknij, aby dowiedzieć się więcej"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Urządzenie działa teraz normalnie.\nKliknij, aby dowiedzieć się więcej"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Tablet działa teraz normalnie.\nKliknij, aby dowiedzieć się więcej"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Telefon był zbyt gorący i wyłączył się, aby obniżyć temperaturę. Działa teraz normalnie.\n\nTelefon może się przegrzać, gdy:\n	• używasz aplikacji zużywających dużo zasobów (np. aplikacji do gier, nawigacji lub odtwarzania filmów);\n	• pobierasz lub przesyłasz duże pliki;\n	• używasz go w wysokiej temperaturze."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Urządzenie było zbyt gorące i wyłączyło się, aby obniżyć temperaturę. Działa teraz normalnie.\n\nUrządzenie może się przegrzać, gdy:\n	• używasz aplikacji zużywających dużo zasobów (np. aplikacji do gier, nawigacji lub odtwarzania filmów);\n	• pobierasz lub przesyłasz duże pliki;\n	• używasz go w wysokiej temperaturze."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Tablet był zbyt gorący i wyłączył się, aby obniżyć temperaturę. Działa teraz normalnie.\n\nTablet może się przegrzać, gdy:\n	• używasz aplikacji zużywających dużo zasobów (np. aplikacji do gier, nawigacji lub odtwarzania filmów);\n	• pobierasz lub przesyłasz duże pliki;\n	• używasz go w wysokiej temperaturze."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Telefon się nagrzewa"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Urządzenie się nagrzewa"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Tablet się nagrzewa"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Podczas obniżania temperatury telefonu niektóre funkcje są ograniczone.\nKliknij, aby dowiedzieć się więcej"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Podczas obniżania temperatury urządzenia niektóre funkcje są ograniczone.\nKliknij, aby dowiedzieć się więcej"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Podczas obniżania temperatury tabletu niektóre funkcje są ograniczone.\nKliknij, aby dowiedzieć się więcej"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Telefon automatycznie podejmie próbę obniżenia temperatury. Możesz go wciąż używać, ale może działać wolniej.\n\nGdy temperatura się obniży, telefon będzie działać normalnie."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Urządzenie automatycznie podejmie próbę obniżenia temperatury. Możesz go wciąż używać, ale może działać wolniej.\n\nGdy temperatura się obniży, urządzenie będzie działać normalnie."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Tablet automatycznie podejmie próbę obniżenia temperatury. Możesz go wciąż używać, ale może działać wolniej.\n\nGdy temperatura się obniży, tablet będzie działać normalnie."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Czytnik linii papilarnych znajduje się na przycisku zasilania. To płaski przycisk przy uniesionym przycisku głośności na krawędzi tabletu."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Czytnik linii papilarnych znajduje się na przycisku zasilania. To płaski przycisk przy uniesionym przycisku głośności na krawędzi urządzenia."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Czytnik linii papilarnych znajduje się na przycisku zasilania. To płaski przycisk przy uniesionym przycisku głośności na krawędzi telefonu."</string>
diff --git a/packages/SystemUI/res-product/values-pt-rBR/strings.xml b/packages/SystemUI/res-product/values-pt-rBR/strings.xml
index 53efe3e..3d6d890 100644
--- a/packages/SystemUI/res-product/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res-product/values-pt-rBR/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. O perfil de trabalho será removido, o que excluirá todos os dados do perfil."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use uma conta de e-mail para desbloquear o tablet.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use uma conta de e-mail para desbloquear o smartphone.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Smartphone desligado por superaquecimento"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Dispositivo desligado por superaquecimento"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tablet desligado por superaquecimento"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"O smartphone está funcionando normalmente agora.\nToque para saber mais"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"O dispositivo está funcionando normalmente agora.\nToque para saber mais"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"O tablet está funcionando normalmente agora.\nToque para saber mais"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"O smartphone estava muito quente e foi desligado para resfriar. Agora, ele está funcionando normalmente.\n\nO smartphone pode ficar quente demais se você:\n	• usar apps que consomem muitos recursos (como apps de jogos, vídeos ou navegação);\n	• fizer o download ou upload de arquivos grandes;\n	• usar o smartphone em temperaturas altas."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"O dispositivo estava muito quente e foi desligado para resfriar. Agora, ele está funcionando normalmente.\n\nO dispositivo pode ficar quente demais se você:\n	• usa apps que consomem muitos recursos (como apps de jogos, vídeos ou navegação);\n	• faz download ou upload de arquivos grandes;\n	• usa o dispositivo em temperaturas altas."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"O tablet estava muito quente e foi desligado para resfriar. Agora, ele está funcionando normalmente.\n\nO tablet pode ficar quente demais se você:\n	• usar apps que consomem muitos recursos (como apps de jogos, vídeos ou navegação);\n	• fizer download ou upload de arquivos grandes;\n	• usar o tablet em temperaturas altas."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"O smartphone está esquentando"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"O dispositivo está esquentando"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"O tablet está esquentando"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Alguns recursos ficam limitados enquanto o smartphone é resfriado.\nToque para saber mais"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Alguns recursos ficam limitados enquanto o dispositivo é resfriado.\nToque para saber mais"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Alguns recursos ficam limitados enquanto o tablet é resfriado.\nToque para saber mais"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Seu smartphone tentará se resfriar automaticamente. Você ainda poderá usá-lo, mas talvez ele fique mais lento.\n\nQuando o smartphone estiver resfriado, ele voltará ao normal."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Seu dispositivo vai tentar se resfriar automaticamente. Você ainda poderá usá-lo, mas talvez ele fique mais lento.\n\nDepois de resfriado, o dispositivo volta ao normal."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Seu tablet vai tentar se resfriar automaticamente. Você ainda poderá usá-lo, mas talvez ele fique mais lento.\n\nDepois de resfriado, o tablet volta ao normal."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"O sensor de impressão digital fica no botão liga/desliga. Ele é plano e está ao lado do botão de volume na borda do tablet."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"O sensor de impressão digital fica no botão liga/desliga. Ele é plano e está ao lado do botão de volume na borda do dispositivo."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"O sensor de impressão digital fica no botão liga/desliga. Ele é plano e está ao lado do botão de volume na borda do smartphone."</string>
diff --git a/packages/SystemUI/res-product/values-pt-rPT/strings.xml b/packages/SystemUI/res-product/values-pt-rPT/strings.xml
index 29a2001..40c7e53 100644
--- a/packages/SystemUI/res-product/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res-product/values-pt-rPT/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Tentou desbloquear incorretamente o telemóvel <xliff:g id="NUMBER">%d</xliff:g> vezes. O perfil de trabalho será removido, o que eliminará todos os dados do mesmo."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Desenhou o padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, ser-lhe-á pedido para desbloquear o tablet através de uma conta de email.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Desenhou o padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, ser-lhe-á pedido para desbloquear o telemóvel através de uma conta de email.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Telemóvel desligado devido ao calor"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Dispositivo desligado devido ao calor"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tablet desligado devido ao calor"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"O seu telemóvel já está a funcionar normalmente.\nToque para obter mais informações"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"O seu dispositivo já está a funcionar normalmente.\nToque para obter mais informações"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"O seu tablet já está a funcionar normalmente.\nToque para obter mais informações"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"O telemóvel estava muito quente, por isso desligou-se para arrefecer. Agora funciona normalmente.\n\nO telemóvel pode sobreaquecer se:\n	• Usar apps que exigem mais recursos (jogos, vídeo ou apps de navegação)\n	• Transferir ou carregar ficheiros grandes\n	• For usado em altas temperaturas"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"O dispositivo estava muito quente, por isso desligou-se para arrefecer. Agora funciona normalmente.\n\nO dispositivo pode sobreaquecer se:\n	• Usar apps que exigem mais recursos (jogos, vídeo ou apps de navegação)\n	• Transferir ou carregar ficheiros grandes\n	• For usado em altas temperaturas"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"O tablet estava muito quente, por isso desligou-se para arrefecer. Agora funciona normalmente.\n\nO tablet pode sobreaquecer se:\n	• Usar apps que exigem mais recursos (jogos, vídeo ou apps de navegação)\n	• Transferir ou carregar ficheiros grandes\n	• For usado em altas temperaturas"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"O telemóvel está a aquecer"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"O dispositivo está a aquecer"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"O tablet está a aquecer"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Algumas funcionalidades são limitadas enquanto o telemóvel arrefece.\nToque para obter mais informações"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Algumas funcionalidades são limitadas enquanto o dispositivo arrefece.\nToque para obter mais informações"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Algumas funcionalidades são limitadas enquanto o tablet arrefece.\nToque para obter mais informações"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Pode continuar a usá-lo, mas este pode funcionar mais lentamente.\n\nAssim que o telemóvel tiver arrefecido, vai funcionar normalmente."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"O dispositivo vai tentar arrefecer automaticamente. Pode continuar a usá-lo, mas este pode funcionar mais lentamente.\n\nAssim que o dispositivo tiver arrefecido, vai funcionar normalmente."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"O tablet vai tentar arrefecer automaticamente. Pode continuar a usá-lo, mas este pode funcionar mais lentamente.\n\nAssim que o tablet tiver arrefecido, vai funcionar normalmente."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"O sensor de impressões digitais encontra-se no botão ligar/desligar. É o botão sem relevo junto ao botão de volume com relevo na extremidade do tablet."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"O sensor de impressões digitais encontra-se no botão ligar/desligar. É o botão sem relevo junto ao botão de volume com relevo na extremidade do dispositivo."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"O sensor de impressões digitais encontra-se no botão ligar/desligar. É o botão sem relevo junto ao botão de volume com relevo na extremidade do telemóvel."</string>
diff --git a/packages/SystemUI/res-product/values-pt/strings.xml b/packages/SystemUI/res-product/values-pt/strings.xml
index 53efe3e..3d6d890 100644
--- a/packages/SystemUI/res-product/values-pt/strings.xml
+++ b/packages/SystemUI/res-product/values-pt/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. O perfil de trabalho será removido, o que excluirá todos os dados do perfil."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use uma conta de e-mail para desbloquear o tablet.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use uma conta de e-mail para desbloquear o smartphone.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Smartphone desligado por superaquecimento"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Dispositivo desligado por superaquecimento"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tablet desligado por superaquecimento"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"O smartphone está funcionando normalmente agora.\nToque para saber mais"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"O dispositivo está funcionando normalmente agora.\nToque para saber mais"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"O tablet está funcionando normalmente agora.\nToque para saber mais"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"O smartphone estava muito quente e foi desligado para resfriar. Agora, ele está funcionando normalmente.\n\nO smartphone pode ficar quente demais se você:\n	• usar apps que consomem muitos recursos (como apps de jogos, vídeos ou navegação);\n	• fizer o download ou upload de arquivos grandes;\n	• usar o smartphone em temperaturas altas."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"O dispositivo estava muito quente e foi desligado para resfriar. Agora, ele está funcionando normalmente.\n\nO dispositivo pode ficar quente demais se você:\n	• usa apps que consomem muitos recursos (como apps de jogos, vídeos ou navegação);\n	• faz download ou upload de arquivos grandes;\n	• usa o dispositivo em temperaturas altas."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"O tablet estava muito quente e foi desligado para resfriar. Agora, ele está funcionando normalmente.\n\nO tablet pode ficar quente demais se você:\n	• usar apps que consomem muitos recursos (como apps de jogos, vídeos ou navegação);\n	• fizer download ou upload de arquivos grandes;\n	• usar o tablet em temperaturas altas."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"O smartphone está esquentando"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"O dispositivo está esquentando"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"O tablet está esquentando"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Alguns recursos ficam limitados enquanto o smartphone é resfriado.\nToque para saber mais"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Alguns recursos ficam limitados enquanto o dispositivo é resfriado.\nToque para saber mais"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Alguns recursos ficam limitados enquanto o tablet é resfriado.\nToque para saber mais"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Seu smartphone tentará se resfriar automaticamente. Você ainda poderá usá-lo, mas talvez ele fique mais lento.\n\nQuando o smartphone estiver resfriado, ele voltará ao normal."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Seu dispositivo vai tentar se resfriar automaticamente. Você ainda poderá usá-lo, mas talvez ele fique mais lento.\n\nDepois de resfriado, o dispositivo volta ao normal."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Seu tablet vai tentar se resfriar automaticamente. Você ainda poderá usá-lo, mas talvez ele fique mais lento.\n\nDepois de resfriado, o tablet volta ao normal."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"O sensor de impressão digital fica no botão liga/desliga. Ele é plano e está ao lado do botão de volume na borda do tablet."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"O sensor de impressão digital fica no botão liga/desliga. Ele é plano e está ao lado do botão de volume na borda do dispositivo."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"O sensor de impressão digital fica no botão liga/desliga. Ele é plano e está ao lado do botão de volume na borda do smartphone."</string>
diff --git a/packages/SystemUI/res-product/values-ro/strings.xml b/packages/SystemUI/res-product/values-ro/strings.xml
index cd08dee..f10d5ca 100644
--- a/packages/SystemUI/res-product/values-ro/strings.xml
+++ b/packages/SystemUI/res-product/values-ro/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Ai făcut <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a telefonului. Profilul de serviciu va fi eliminat, iar toate datele profilului vor fi șterse."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Ai desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereușite, ți se va solicita să deblochezi tableta cu ajutorul unui cont de e-mail.\n\n Încearcă din nou peste <xliff:g id="NUMBER_2">%3$d</xliff:g> secunde."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Ai desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereușite, ți se va solicita să deblochezi telefonul cu ajutorul unui cont de e-mail.\n\n Încearcă din nou peste <xliff:g id="NUMBER_2">%3$d</xliff:g> secunde."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Telefonul s-a oprit din cauza încălzirii"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Dispozitiv oprit din cauza căldurii"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tableta s-a oprit din cauza încălzirii"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Acum telefonul funcționează normal.\nAtinge pentru mai multe informații"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Acum dispozitivul funcționează normal.\nAtinge pentru mai multe informații"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Acum tableta funcționează normal.\nAtinge pentru mai multe informații"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Telefonul se încălzise prea mult și s-a oprit pentru a se răci. Acum funcționează normal.\n\nTelefonul s-ar putea încălzi prea mult dacă:\n	• folosești aplicații care consumă multe resurse (de ex., jocuri, aplicații video sau de navigare);\n	• descarci sau încarci fișiere mari;\n	• folosești telefonul la temperaturi ridicate."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Dispozitivul se încălzise prea mult și s-a oprit pentru a se răci. Acum funcționează normal.\n\nDispozitivul s-ar putea încălzi prea mult dacă:\n	• folosești aplicații care consumă multe resurse (de ex., jocuri, aplicații video sau de navigare);\n	• descarci sau încarci fișiere mari;\n	• folosești dispozitivul la temperaturi ridicate."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Tableta se încălzise prea mult și s-a oprit pentru a se răci. Acum funcționează normal.\n\nTableta s-ar putea încălzi prea mult dacă:\n	• folosești aplicații care consumă multe resurse (de ex., jocuri, aplicații video sau de navigare);\n	• descarci sau încarci fișiere mari;\n	• folosești tableta la temperaturi ridicate."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Telefonul se încălzește"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Dispozitivul se încălzește"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Tableta se încălzește"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Anumite funcții sunt limitate în timp ce telefonul se răcește.\nAtinge pentru mai multe informații"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Anumite funcții sunt limitate în timp ce dispozitivul se răcește.\nAtinge pentru mai multe informații"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Anumite funcții sunt limitate în timp ce tableta se răcește.\nAtinge pentru mai multe informații"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Telefonul va încerca automat să se răcească. Îl poți folosi în continuare, dar e posibil să funcționeze mai lent.\n\nDupă ce se răcește, telefonul va funcționa normal."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Dispozitivul va încerca automat să se răcească. Îl poți folosi în continuare, dar e posibil să funcționeze mai lent.\n\nDupă ce se răcește, dispozitivul va funcționa normal."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Tableta va încerca automat să se răcească. O poți folosi în continuare, dar e posibil să funcționeze mai lent.\n\nDupă ce se răcește, tableta va funcționa normal."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Senzorul de amprentă se află pe butonul de pornire. Este butonul plat de lângă butonul de volum în relief de pe marginea tabletei."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Senzorul de amprentă se află pe butonul de pornire. Este butonul plat de lângă butonul de volum în relief de pe marginea dispozitivului."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Senzorul de amprentă se află pe butonul de pornire. Este butonul plat de lângă butonul de volum în relief de pe marginea telefonului."</string>
diff --git a/packages/SystemUI/res-product/values-ru/strings.xml b/packages/SystemUI/res-product/values-ru/strings.xml
index 1649c02..ed9ad1a 100644
--- a/packages/SystemUI/res-product/values-ru/strings.xml
+++ b/packages/SystemUI/res-product/values-ru/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Вы несколько раз (<xliff:g id="NUMBER">%d</xliff:g>) не смогли разблокировать телефон. Рабочий профиль и все его данные будут удалены."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Вы несколько раз (<xliff:g id="NUMBER_0">%1$d</xliff:g>) ввели неверный графический ключ. Осталось попыток: <xliff:g id="NUMBER_1">%2$d</xliff:g>. В случае неудачи вам будет предложено разблокировать планшет с помощью аккаунта электронной почты.\n\nПовторите попытку через <xliff:g id="NUMBER_2">%3$d</xliff:g> сек."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Вы несколько раз (<xliff:g id="NUMBER_0">%1$d</xliff:g>) ввели неверный графический ключ. Осталось попыток: <xliff:g id="NUMBER_1">%2$d</xliff:g>. В случае неудачи вам будет предложено разблокировать телефон с помощью аккаунта электронной почты.\n\nПовторите попытку через <xliff:g id="NUMBER_2">%3$d</xliff:g> сек."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Телефон выключился из-за перегрева"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Устройство выключилось из-за перегрева"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Планшет выключился из-за перегрева"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Сейчас телефон работает нормально.\nНажмите, чтобы получить дополнительную информацию."</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Сейчас устройство работает нормально.\nНажмите, чтобы получить дополнительную информацию."</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Сейчас планшет работает нормально.\nНажмите, чтобы получить дополнительную информацию."</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Телефон выключился из-за перегрева. Сейчас он работает нормально.\n\nВозможные причины перегрева:\n	• использование ресурсоемких игр и приложений, например связанных с видео или навигацией;\n	• скачивание или загрузка больших файлов;\n	• высокая температура окружающей среды."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Устройство выключилось из-за перегрева. Сейчас оно работает нормально.\n\nВозможные причины перегрева:\n	• использование ресурсоемких игр и приложений, например связанных с видео или навигацией;\n	• скачивание или загрузка больших файлов;\n	• высокая температура окружающей среды."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Планшет выключился из-за перегрева. Сейчас он работает нормально.\n\nВозможные причины перегрева:\n	• использование ресурсоемких игр и приложений, например связанных с видео или навигацией;\n	• скачивание или загрузка больших файлов;\n	• высокая температура окружающей среды."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Телефон нагревается"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Устройство нагревается"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Планшет нагревается"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Пока телефон не остынет, некоторые функции могут быть недоступны.\nНажмите, чтобы получить дополнительную информацию."</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Пока устройство не остынет, некоторые функции могут быть недоступны.\nНажмите, чтобы получить дополнительную информацию."</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Пока планшет не остынет, некоторые функции могут быть недоступны.\nНажмите, чтобы получить дополнительную информацию."</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Телефон автоматически попробует снизить температуру. Вы можете продолжать им пользоваться, но его производительность, возможно, уменьшится.\n\nСкорость работы телефона восстановится, когда он остынет."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Устройство автоматически попробует снизить температуру. Вы можете продолжать им пользоваться, но его производительность, возможно, уменьшится.\n\nСкорость работы устройства восстановится, когда оно остынет."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Планшет автоматически попробует снизить температуру. Вы можете продолжать им пользоваться, но его производительность, возможно, уменьшится.\n\nСкорость работы планшета восстановится, когда он остынет."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Сканер отпечатков пальцев находится на кнопке питания. Она плоская и расположена рядом с приподнятой кнопкой регулировки громкости на боковой стороне планшета."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Сканер отпечатков пальцев находится на кнопке питания. Она плоская и расположена рядом с приподнятой кнопкой регулировки громкости на боковой стороне устройства."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Сканер отпечатков пальцев находится на кнопке питания. Она плоская и расположена рядом с приподнятой кнопкой регулировки громкости на боковой стороне телефона."</string>
diff --git a/packages/SystemUI/res-product/values-si/strings.xml b/packages/SystemUI/res-product/values-si/strings.xml
index 4ab2a4b..f2c0f43 100644
--- a/packages/SystemUI/res-product/values-si/strings.xml
+++ b/packages/SystemUI/res-product/values-si/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"ඔබ දුරකථනය අගුළු හැරීමට <xliff:g id="NUMBER">%d</xliff:g> වරක් වැරදියට උත්සාහ කර ඇත. කාර්යාල පැතිකඩ ඉවත් කරනු ඇති අතර, එය සියලු පැතිකඩ දත්ත මකනු ඇත."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"ඔබ අගුළු ඇරිමේ රටාව <xliff:g id="NUMBER_0">%1$d</xliff:g> වතාවක් වැරදියට ඇඳ ඇත. තවත් අසාර්ථක උත්සාහ <xliff:g id="NUMBER_1">%2$d</xliff:g> කින් පසුව, ඊ-තැපැල් ගිණුම භාවිතා කරමින් ඔබගේ ටැබ්ලටයේ අගුළු ඇරීමට ඔබට පවසනු ඇත.\n\n නැවත තත්පර <xliff:g id="NUMBER_2">%3$d</xliff:g> කින් උත්සාහ කරන්න."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"ඔබ වැරදියට <xliff:g id="NUMBER_0">%1$d</xliff:g> වතාවක් ඔබගේ අගුළු හැරීමේ රටාව ඇඳ ඇත. අසාර්ථක උත්සහ කිරීම් <xliff:g id="NUMBER_1">%2$d</xliff:g> න් පසුව, ඔබගේ ඊ-තැපැල් ලිපිනය භාවිතයෙන් ඔබගේ දුරකථනය අගුළු හැරීමට ඔබගෙන් අසයි.\n\n තත්පර <xliff:g id="NUMBER_2">%3$d</xliff:g> න් පසුව නැවත උත්සහ කරන්න."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"දුරකථනය රත් වීම නිසා ක්‍රියාවිරහිත විය"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"උණුසුම හේතුවෙන් උපාංගය ක්‍රියාවිරහිත විය"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"ටැබ්ලටය රත් වීම නිසා ක්‍රියාවිරහිත විය"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"ඔබේ දුරකථනය දැන් සාමාන්‍ය ලෙස ධාවනය වේ.\nතව තතු සඳහා තට්ටු කරන්න"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"ඔබේ උපාංගය දැන් සාමාන්‍ය ලෙස ධාවනය වේ.\nතව තතු සඳහා තට්ටු කරන්න"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"ඔබේ ටැබ්ලටය දැන් සාමාන්‍ය ලෙස ධාවනය වේ.\nතව තතු සඳහා තට්ටු කරන්න"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"ඔබේ දුරකථනය ඉතාම උණුසුම් විය, එම නිසා එය සිසිල් වීමට ක්‍රියාවිරහිත කරන ලදි. දැන් ඔබේ දුරකථනය සාමාන්‍ය පරිදි ධාවනය වේ.\n\nඔබ පහත දේවල් සිදු කළහොත් ඔබේ දුරකථනය ඉතාම උණුසුම් විය හැක:\n	• සම්පත්-දැඩි සත්කාරක යෙදුම් භාවිතය (ක්‍රීඩා, වීඩියෝ, හෝ සංචලන යෙදුම් යනාදී)\n	• විශාල ගොනු බාගැනීම හෝ උඩුගත කිරීම\n	• ඔබේ දුරකථනය අධික උෂ්ණත්වයේදී භාවිත කිරීම"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"ඔබේ උපාංගය ඉතාම උණුසුම් විය, එම නිසා එය සිසිල් වීමට ක්‍රියාවිරහිත කරන ලදි. දැන් ඔබේ දුරකථනය සාමාන්‍ය පරිදි ධාවනය වේ.\n\nඔබ පහත දේවල් සිදු කළහොත් ඔබේ උපාංගය ඉතාම උණුසුම් විය හැක:\n	• සම්පත්-දැඩි සත්කාරක යෙදුම් භාවිතය (ක්‍රීඩා, වීඩියෝ, හෝ සංචලන යෙදුම් යනාදී)\n	• විශාල ගොනු බාගැනීම හෝ උඩුගත කිරීම\n	• ඔබේ දුරකථනය අධික උෂ්ණත්වයේ දී භාවිත කිරීම"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"ඔබේ ටැබ්ලටය ඉතාම උණුසුම් විය, එම නිසා එය සිසිල් වීමට ක්‍රියාවිරහිත කරන ලදි. දැන් ඔබේ දුරකථනය සාමාන්‍ය පරිදි ධාවනය වේ.\n\nඔබ පහත දේවල් සිදු කළහොත් ඔබේ දුරකථනය ඉතාම උණුසුම් විය හැක:\n	• සම්පත්-දැඩි සත්කාරක යෙදුම් භාවිතය (ක්‍රීඩා, වීඩියෝ, හෝ සංචලන යෙදුම් යනාදී)\n	• විශාල ගොනු බාගැනීම හෝ උඩුගත කිරීම\n	• ඔබේ දුරකථනය අධික උෂ්ණත්වයේ දී භාවිත කිරීම"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"දුරකථනය උණුසුම් වෙමින්"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"උපාංගය උණුසුම් වෙමින් පවතී"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"ටැබ්ලටය උණුසුම් වෙමින් පවතී"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"දුරකථනය සිසිල් වන අතරේ සමහර විශේෂාංග සීමිත විය හැක.\nතව තතු සඳහා තට්ටු කරන්න"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"උපාංගය සිසිල් වන අතරේ සමහර විශේෂාංග සීමිත විය හැක.\nතව තතු සඳහා තට්ටු කරන්න"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"ටැබ්ලටය සිසිල් වන අතරේ සමහර විශේෂාංග සීමිත විය හැක.\nතව තතු සඳහා තට්ටු කරන්න"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"ඔ බේ දුරකථනය ස්වයංක්‍රීයව සිසිල් වීමට උත්සාහ කරනු ඇත. ඔබට තවම ඔබේ දුරකථනය භාවිත කළ හැකි නමුත්, එය සෙමින් ධාවනය විය හැක.\n\nඔබේ දුරකථනය සිසිල් වූ පසු, එය සාමාන්‍ය ලෙස ධාවනය වනු ඇත."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"ඔබේ උපාංගය ස්වයංක්‍රීයව සිසිල් වීමට උත්සාහ දරනු ඇත. ඔබට තවමත් බබේ උපාංගය භාවිතා කළ හැකි නමුත්, එය මන්දගාමීව ධාවනය විය හැක.\n\nඔබේ උපාංගය සිසිල් වූ පසු, එය සාමාන්‍ය පරිදි ධාවනය වනු ඇත."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"ඔබේ ටැබ්ලටය ස්වයංක්‍රීයව සිසිල් වීමට උත්සාහ දරනු ඇත. ඔබට තවමත් බබේ ටැබ්ලටය භාවිතා කළ හැකි නමුත්, එය මන්දගාමීව ධාවනය විය හැක.\n\nඔබේ ටැබ්ලටය සිසිල් වූ පසු, එය සාමාන්‍ය පරිදි ධාවනය වනු ඇත."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"ඇඟිලි සලකුණු සංවේදකය බල බොත්තම මත ඇත. එය ටැබ්ලටයෙහි කෙළවර ඇති ඉහළ හඬ පරිමා බොත්තම අසල ඇති පැතලි බොත්තමයි."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"ඇඟිලි සලකුණු සංවේදකය බල බොත්තම මත ඇත. එය උපාංගයෙහි කෙළවර ඇති ඉහළ හඬ පරිමා බොත්තම අසල ඇති පැතලි බොත්තමයි."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"ඇඟිලි සලකුණු සංවේදකය බල බොත්තම මත ඇත. එය දුරකථනයෙහි කෙළවර ඇති ඉහළ හඬ පරිමා බොත්තම අසල ඇති පැතලි බොත්තමයි."</string>
diff --git a/packages/SystemUI/res-product/values-sk/strings.xml b/packages/SystemUI/res-product/values-sk/strings.xml
index 21bcc2a..8e1bb39 100644
--- a/packages/SystemUI/res-product/values-sk/strings.xml
+++ b/packages/SystemUI/res-product/values-sk/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Telefón ste sa pokúsili <xliff:g id="NUMBER">%d</xliff:g>‑krát nesprávne odomknúť. Pracovný profil bude odstránený spolu so všetkými údajmi."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"<xliff:g id="NUMBER_0">%1$d</xliff:g>‑krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> ďalších neúspešných pokusoch sa zobrazí výzva na odomknutie tabletu pomocou e‑mailového účtu.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Už ste <xliff:g id="NUMBER_0">%1$d</xliff:g>‑krát nesprávne nakreslili svoj bezpečnostný vzor. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> ďalších neúspešných pokusoch sa zobrazí výzva na odomknutie telefónu pomocou e‑mailového účtu.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Telefón sa vypol z dôvodu prehriatia"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Zariadenie sa vyplo z dôvodu prehriatia"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tablet sa vypol z dôvodu prehriatia"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Teraz telefón funguje ako obvykle.\nViac sa dozviete po klepnutí."</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Teraz zariadenie funguje ako obvykle.\nViac sa dozviete po klepnutí."</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Teraz tablet funguje ako obvykle.\nViac sa dozviete po klepnutí."</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Telefón bol príliš horúci, preto sa vypol, aby vychladol. Teraz funguje ako obvykle.\n\nTelefón sa môže prehrievať, keď:\n	• používate aplikácie náročné na zdroje (ako sú aplikácie na video alebo herné či navigačné),\n	• sťahujete alebo nahrávate veľké súbory,\n	• používate telefón pri vysokých teplotách."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Zariadenie bolo príliš horúce, preto sa vyplo, aby vychladlo. Teraz funguje ako obvykle.\n\nZariadenie sa môže prehrievať, keď:\n	• používate aplikácie náročné na zdroje (ako sú aplikácie na video alebo herné či navigačné),\n	• sťahujete alebo nahrávate veľké súbory,\n	• používate zariadenie pri vysokých teplotách."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Tablet bol príliš horúci, preto sa vypol, aby vychladol. Teraz funguje ako obvykle.\n\nTablet sa môže prehrievať, keď:\n	• používate aplikácie náročné na zdroje (ako sú aplikácie na video alebo herné či navigačné),\n	• sťahujete alebo nahrávate veľké súbory,\n	• používate tablet pri vysokých teplotách."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Telefón sa prehrieva"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Zariadenie sa prehrieva"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Tablet sa prehrieva"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Niektoré funkcie budú obmedzené, dokým neklesne teplota telefónu.\nViac sa dozviete po klepnutí."</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Niektoré funkcie budú obmedzené, dokým neklesne teplota zariadenia.\nViac sa dozviete po klepnutí."</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Niektoré funkcie budú obmedzené, dokým neklesne teplota tabletu.\nViac sa dozviete po klepnutí."</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Váš telefón sa automaticky pokúsi schladiť. Môžete ho naďalej používať, ale môže fungovať pomalšie.\n\nPo poklese teploty bude fungovať ako obvykle."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Vaše zariadenie sa automaticky pokúsi schladiť. Môžete ho naďalej používať, ale môže fungovať pomalšie.\n\nPo poklese teploty bude fungovať ako obvykle."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Váš tablet sa automaticky pokúsi schladiť. Môžete ho naďalej používať, ale môže fungovať pomalšie.\n\nPo poklese teploty bude fungovať ako obvykle."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Senzor odtlačkov prstov je na vypínači. Je to ploché tlačidlo vedľa vypuklého tlačidla hlasitosti na okraji tabletu."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Senzor odtlačkov prstov je na vypínači. Je to ploché tlačidlo vedľa vypuklého tlačidla hlasitosti na okraji zariadenia."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Senzor odtlačkov prstov je na vypínači. Je to ploché tlačidlo vedľa vypuklého tlačidla hlasitosti na okraji telefónu."</string>
diff --git a/packages/SystemUI/res-product/values-sl/strings.xml b/packages/SystemUI/res-product/values-sl/strings.xml
index 95191a4..04c7bc7 100644
--- a/packages/SystemUI/res-product/values-sl/strings.xml
+++ b/packages/SystemUI/res-product/values-sl/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Telefon ste neuspešno poskusili odkleniti <xliff:g id="NUMBER">%d</xliff:g>-krat. Delovni profil bo odstranjen in vsi podatki profila bodo izbrisani."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat napačno vnesli. Če ga neuspešno poskusite vnesti še <xliff:g id="NUMBER_1">%2$d</xliff:g>-krat, boste pozvani, da tablični računalnik odklenete z e-poštnim računom.\n\nPoskusite znova čez <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat napačno vnesli. Če ga neuspešno poskusite vnesti še <xliff:g id="NUMBER_1">%2$d</xliff:g>-krat, boste pozvani, da telefon odklenete z e-poštnim računom.\n\nPoskusite znova čez <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Telefon se je izklopil zaradi vročine"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Naprava se je izklopila zaradi vročine"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tablični računalnik se je izklopil zaradi vročine"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Telefon zdaj deluje kot običajno.\nDotaknite se za več informacij"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Naprava zdaj deluje kot običajno.\nDotaknite se za več informacij"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Tablični računalnik zdaj deluje kot običajno.\nDotaknite se za več informacij"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Telefon je bil prevroč, zato se je izklopil, da se ohladi. Zdaj deluje kot običajno.\n\nTelefon lahko postane prevroč pri:\n	• uporabi aplikacij, ki intenzivno porabljajo sredstva (npr. za igranje iger, videoposnetke ali navigacijo);\n	• prenosu ali nalaganju velikih datotek;\n	• uporabi naprave pri visokih temperaturah."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Naprava je bila prevroča, zato se je izklopila, da se ohladi. Zdaj deluje kot običajno.\n\nNaprava lahko postane prevroča pri:\n	• uporabi aplikacij, ki intenzivno porabljajo sredstva (npr. za igranje iger, videoposnetke ali navigacijo);\n	• prenosu ali nalaganju velikih datotek;\n	• uporabi naprave pri visokih temperaturah."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Tablični računalnik je bil prevroč, zato se je izklopil, da se ohladi. Zdaj deluje kot običajno.\n\nTablični računalnik lahko postane prevroč pri:\n	• uporabi aplikacij, ki intenzivno porabljajo sredstva (npr. za igranje iger, videoposnetke ali navigacijo);\n	• prenosu ali nalaganju velikih datotek;\n	• uporabi naprave pri visokih temperaturah."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Telefon se segreva"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Naprava se segreva"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Tablični računalnik se segreva"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Nekatere funkcije bodo med ohlajanjem telefona omejene.\nDotaknite se za več informacij"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Nekatere funkcije bodo med ohlajanjem naprave omejene.\nDotaknite se za več informacij"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Nekatere funkcije bodo med ohlajanjem tabličnega računalnika omejene.\nDotaknite se za več informacij"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Telefon se bo samodejno poskusil ohladiti. Še naprej ga lahko uporabljate, vendar bo morda deloval počasneje.\n\nKo se bo telefon ohladil, bo znova deloval kot običajno."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Naprava se bo samodejno poskusila ohladiti. Še naprej jo lahko uporabljate, vendar bo morda delovala počasneje.\n\nKo se bo naprava ohladila, bo znova delovala kot običajno."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Tablični računalnik se bo samodejno poskusil ohladiti. Še naprej ga lahko uporabljate, vendar bo morda deloval počasneje.\n\nKo se bo tablični računalnik ohladil, bo znova deloval kot običajno."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Tipalo prstnih odtisov je na gumbu za vklop. To je ploski gumb ob izbočenem gumbu za glasnost na robu tabličnega računalnika."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Tipalo prstnih odtisov je na gumbu za vklop. To je ploski gumb ob izbočenem gumbu za glasnost na robu naprave."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Tipalo prstnih odtisov je na gumbu za vklop. To je ploski gumb ob izbočenem gumbu za glasnost na robu telefona."</string>
diff --git a/packages/SystemUI/res-product/values-sq/strings.xml b/packages/SystemUI/res-product/values-sq/strings.xml
index 435966eb..619f22f 100644
--- a/packages/SystemUI/res-product/values-sq/strings.xml
+++ b/packages/SystemUI/res-product/values-sq/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Ke tentuar <xliff:g id="NUMBER">%d</xliff:g> herë pa sukses për ta shkyçur telefonin. Profili i punës do të hiqet, gjë që do të fshijë të gjitha të dhënat e profilit."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Ke vizatuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses motivin tënd të shkyçjes. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme, do të të duhet ta shkyçësh tabletin duke përdorur një llogari email-i.\n\n Provo sërish për <xliff:g id="NUMBER_2">%3$d</xliff:g> sekonda."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Ke vizatuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses motivin tënd. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme, do të të duhet ta shkyçësh telefonin duke përdorur një llogari email-i.\n\n Provo sërish për <xliff:g id="NUMBER_2">%3$d</xliff:g> sekonda."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Telefoni u fik për shkak të nxehtësisë"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Pajisja u fik për shkak të nxehtësisë"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tableti u fik për shkak të nxehtësisë"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Telefoni tani po funksionon normalisht.\nTrokit për më shumë informacione"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Pajisja tani po funksionon normalisht.\nTrokit për më shumë informacione"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Tableti tani po funksionon normalisht.\nTrokit për më shumë informacione"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Telefoni yt ishte shumë i nxehtë, prandaj u fik për t\'u ftohur. Telefoni tani po funksionon normalisht.\n\nTelefoni yt mund të nxehet shumë nëse ti:\n	• Përdor aplikacione intensive për burimet (si p.sh. aplikacione lojërash, videosh ose navigimi)\n	• Shkarkon ose ngarkon skedarë të mëdhenj\n	• Përdor telefonin në temperatura të larta"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Pajisja jote ishte shumë e nxehtë, prandaj u fik për t\'u ftohur. Pajisja tani po funksionon normalisht.\n\nPajisja jote mund të nxehet shumë nëse ti:\n	• Përdor aplikacione intensive për burimet (si p.sh. aplikacione lojërash, videosh ose navigimi)\n	• Shkarkon ose ngarkon skedarë të mëdhenj\n	• Përdor pajisjen në temperatura të larta"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Tableti yt ishte shumë i nxehtë, prandaj u fik për t\'u ftohur. Tableti tani po funksionon normalisht.\n\nTableti yt mund të nxehet shumë nëse ti:\n	• Përdor aplikacione intensive për burimet (si p.sh. aplikacione lojërash, videosh ose navigimi)\n	• Shkarkon ose ngarkon skedarë të mëdhenj\n	• Përdor tabletin në temperatura të larta"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Telefoni po nxehet"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Pajisja po nxehet"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Tableti po nxehet"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Disa veçori janë të kufizuara ndërkohë që telefoni ftohet.\nTrokit për më shumë informacione"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Disa veçori janë të kufizuara ndërkohë që pajisja ftohet.\nTrokit për më shumë informacione"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Disa veçori janë të kufizuara ndërkohë që telefoni ftohet.\nTrokit për më shumë informacione"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Telefoni yt do të përpiqet automatikisht të ftohet. Mund të vazhdosh ta përdorësh telefonin, por ai mund të funksionojë më ngadalë.\n\nPasi telefoni të jetë ftohur, ai do të funksionojë normalisht."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Pajisja jote do të përpiqet automatikisht të ftohet. Mund të vazhdosh ta përdorësh pajisjen, por ajo mund të funksionojë më ngadalë.\n\nPasi pajisja të jetë ftohur, ajo do të funksionojë normalisht."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Tableti yt do të përpiqet automatikisht të ftohet. Mund të vazhdosh ta përdorësh tabletin, por ai mund të funksionojë më ngadalë.\n\nPasi tableti të jetë ftohur, ai do të funksionojë normalisht."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Sensori i gjurmës së gishtit është në butonin e energjisë. Ai është butoni i rrafshët pranë butonit të ngritur të volumit në anë të tabletit."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Sensori i gjurmës së gishtit është në butonin e energjisë. Ai është butoni i rrafshët pranë butonit të ngritur të volumit në anë të pajisjes."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Sensori i gjurmës së gishtit është në butonin e energjisë. Ai është butoni i rrafshët pranë butonit të ngritur të volumit në anë të telefonit."</string>
diff --git a/packages/SystemUI/res-product/values-sr/strings.xml b/packages/SystemUI/res-product/values-sr/strings.xml
index 4c458a4..76cd9ed 100644
--- a/packages/SystemUI/res-product/values-sr/strings.xml
+++ b/packages/SystemUI/res-product/values-sr/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Погрешно сте покушали да откључате телефон <xliff:g id="NUMBER">%d</xliff:g> пута. Уклонићемо пословни профил, чиме се бришу сви подаци са профила."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Нетачно сте нацртали шаблон за откључавање <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, затражићемо да откључате таблет помоћу имејл налога.\n\n Пробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> сек."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Нетачно сте нацртали шаблон за откључавање <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, затражићемо да откључате телефон помоћу имејл налога.\n\n Пробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> сек."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Телефон се искључио због топлоте"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Уређај се искључио због топлоте"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Таблет се искључио због топлоте"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Телефон сада функционише нормално.\nДодирните за више информација"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Уређај сада функционише нормално.\nДодирните за више информација"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Таблет сада функционише нормално.\nДодирните за више информација"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Телефон је био преврућ, па се искључио да се охлади. Сада ради нормално.\n\nТелефон може превише да се угреје ако:\n	• користите апликације које захтевају пуно ресурса (нпр. видео игре, видео или апликације за навигацију)\n	• преузимате или отпремате велике фајлове\n	• користите телефон на високој температури"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Уређај је био преврућ, па се искључио да се охлади. Сада ради нормално.\n\nУређај може превише да се угреје ако:\n	• користите апликације које захтевају пуно ресурса (нпр. видео игре, видео или апликације за навигацију)\n	• преузимате или отпремате велике фајлове\n	• користите уређај на високој температури"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Таблет је био преврућ, па се искључио да се охлади. Сада ради нормално.\n\nТаблет може превише да се угреје ако:\n	• користите апликације које захтевају пуно ресурса (нпр. видео игре, видео или апликације за навигацију)\n	• преузимате или отпремате велике фајлове\n	• користите таблет на високој температури"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Телефон се загрејао"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Уређај се загрејао"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Таблет се загрејао"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Неке функције су ограничене док се телефон не охлади.\nДодирните за више информација"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Неке функције су ограничене док се уређај не охлади.\nДодирните за више информација"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Неке функције су ограничене док се таблет не охлади.\nДодирните за више информација"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Телефон ће аутоматски покушати да се охлади. И даље можете да користите телефон, али ће можда радити спорије.\n\nКад се телефон охлади, функционисаће нормално."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Уређај ће аутоматски покушати да се охлади. И даље можете да користите уређај, али ће можда радити спорије.\n\nКад се уређај охлади, функционисаће нормално."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Таблет ће аутоматски покушати да се охлади. И даље можете да користите таблет, али ће можда радити спорије.\n\nКад се таблет охлади, функционисаће нормално."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Сензор за отисак прста се налази на дугмету за укључивање. То је равно дугме поред издигнутог дугмета за јачину звука на ивици таблета."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Сензор за отисак прста се налази на дугмету за укључивање. То је равно дугме поред издигнутог дугмета за јачину звука на ивици уређаја."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Сензор за отисак прста се налази на дугмету за укључивање. То је равно дугме поред издигнутог дугмета за јачину звука на ивици телефона."</string>
diff --git a/packages/SystemUI/res-product/values-sv/strings.xml b/packages/SystemUI/res-product/values-sv/strings.xml
index e2bbfa1..bb97e5c 100644
--- a/packages/SystemUI/res-product/values-sv/strings.xml
+++ b/packages/SystemUI/res-product/values-sv/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Du har försökt låsa upp telefonen på ett felaktigt sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Jobbprofilen tas bort och all profildata raderas."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> försök måste du låsa upp surfplattan med hjälp av ett e-postkonto.\n\n Försök igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> försök måste du låsa upp telefonen med hjälp av ett e-postkonto.\n\n Försök igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Telefonen stängdes av p.g.a. värme"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Enheten stängdes av p.g.a. värme"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Surfplattan stängdes av p.g.a. värme"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Telefonen fungerar nu som vanligt.\nTryck för mer information"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Enheten fungerar nu som vanligt.\nTryck för mer information"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Surfplattan fungerar nu som vanligt.\nTryck för mer information"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Telefonen var för varm och stängdes av för att svalna. Den fungerar nu som vanligt.\n\nTelefonen kan bli för varm om du\n	• använder resurskrävande appar (till exempel spel-, video- eller navigeringsappar)\n	• laddar ned eller laddar upp stora filer\n	• använder telefonen vid höga temperaturer."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Enheten var för varm och stängdes av för att svalna. Den fungerar nu som vanligt.\n\nEnheten kan bli för varm om du\n	• använder resurskrävande appar (till exempel spel-, video- eller navigeringsappar)\n	• laddar ned eller laddar upp stora filer\n	• använder enheten vid höga temperaturer."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Surfplattan var för varm och stängdes av för att svalna. Den fungerar nu som vanligt.\n\nSurfplattan kan bli för varm om du\n	• använder resurskrävande appar (till exempel spel-, video- eller navigeringsappar)\n	• laddar ned eller laddar upp stora filer\n	• använder surfplattan vid höga temperaturer."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Telefonen börjar bli varm"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Enheten börjar bli varm"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Surfplattan börjar bli varm"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Vissa funktioner är begränsade medan telefonen svalnar.\nTryck för mer information"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Vissa funktioner är begränsade medan enheten svalnar.\nTryck för mer information"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Vissa funktioner är begränsade medan surfplattan svalnar.\nTryck för mer information"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Telefonen försöker svalna automatiskt. Du kan fortfarande använda telefonen, men den kan vara långsammare än vanligt.\n\nTelefonen fungerar som vanligt när den har svalnat."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Enheten försöker svalna automatiskt. Du kan fortfarande använda enheten, men den kan vara långsammare än vanligt.\n\nEnheten fungerar som vanligt när den har svalnat."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Surfplattan försöker svalna automatiskt. Du kan fortfarande använda surfplattan, men den kan vara långsammare än vanligt.\n\nSurfplattan fungerar som vanligt när den har svalnat."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Fingeravtryckssensorn sitter på av/på-knappen. Det är den platta knappen bredvid den upphöjda volymknappen på surfplattans kant."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Fingeravtryckssensorn sitter på av/på-knappen. Det är den platta knappen bredvid den upphöjda volymknappen på enhetens kant."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Fingeravtryckssensorn sitter på av/på-knappen. Det är den platta knappen bredvid den upphöjda volymknappen på telefonens kant."</string>
diff --git a/packages/SystemUI/res-product/values-sw/strings.xml b/packages/SystemUI/res-product/values-sw/strings.xml
index 2ebc3eb..44e95de 100644
--- a/packages/SystemUI/res-product/values-sw/strings.xml
+++ b/packages/SystemUI/res-product/values-sw/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Umejaribu kufungua simu mara <xliff:g id="NUMBER">%d</xliff:g> bila mafanikio. Wasifu wa kazini utaondolewa, hatua itakayofuta data yote ya wasifu."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Umeweka mchoro usio sahihi wa kufungua skrini mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%2$d</xliff:g> zaidi bila mafanikio, utaombwa ufungue kompyuta yako kibao kwa kutumia akaunti ya barua pepe.\n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%3$d</xliff:g>."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Umeweka mchoro usio sahihi wa kufungua skrini mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Ukikosea mara nyingine <xliff:g id="NUMBER_1">%2$d</xliff:g>, utaombwa ufungue simu yako kwa kutumia akaunti ya barua pepe.\n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%3$d</xliff:g>."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Simu imezimika kwa sababu ya joto"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Kifaa kimezimika kwa sababu ya joto"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Kishikwambi kimezimika kutokana na joto"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Simu yako sasa inafanya kazi inavyostahili.\nGusa ili upate maelezo zaidi"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Kifaa chako sasa kinafanya kazi inavyostahili.\nGusa ili upate maelezo zaidi"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Kishikwambi chako sasa kinafanya kazi inavyostahili.\nGusa ili upate maelezo zaidi"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Simu yako ilikuwa na joto jingi mno, kwa hivyo imezimika ili ipoe. Simu yako sasa inafanya kazi inavyostahili.\n\nHuenda simu yako ikawa na joto jingi mno:\n	• Ukitumia programu zinazoendesha nyenzo nyingi (kama vile michezo ya video, video au programu za uelekezaji)\n	• Ukipakua au ukipakia faili kubwa\n	• Ukitumia simu mahali palipo na joto jingi"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Kifaa chako kilikuwa na joto jingi mno, kwa hivyo kimezimika ili kipoe. Kifaa chako sasa kinafanya kazi inavyostahili.\n\nHuenda kifaa chako kikawa na joto jingi mno:\n	• Ukitumia programu zinazoendesha nyenzo nyingi (kama vile michezo ya video, video au programu za uelekezaji)\n	• Ukipakua au ukipakia faili kubwa\n	• Ukitumia kifaa mahali palipo na joto jingi"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Kishikwambi chako kilikuwa na joto jingi mno, kwa hivyo kimezimika ili kipoe. Kishikwambi chako sasa kinafanya kazi inavyostahili.\n\nHuenda kishikwambi chako kikawa na joto jingi mno:\n	• Ukitumia programu zinazoendesha nyenzo nyingi (kama vile michezo ya video, video au programu za uelekezaji)\n	• Ukipakua au ukipakia faili kubwa\n	• Ukitumia kishikwambi mahali palipo na joto jingi"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Simu inapata joto"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Kifaa kinapata joto"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Kishikwambi kinapata joto"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Huenda usiweze kutumia baadhi ya vipengele wakati simu inapoa.\nGusa ili upate maelezo zaidi"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Huenda usiweze kutumia baadhi ya vipengele wakati kifaa kinapoa.\nGusa ili upate maelezo zaidi"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Huenda usiweze kutumia baadhi ya vipengele wakati kishikwambi kinapoa.\nGusa ili upate maelezo zaidi"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Simu yako itajaribu kupoa kiotomatiki. Bado unaweza kutumia simu yako, lakini huenda ikafanya kazi polepole.\n\nSimu yako ikipoa, itaendelea kufanya kazi inavyostahili."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Kifaa chako kitajaribu kupoa kiotomatiki. Bado unaweza kutumia kifaa chako, lakini huenda kikafanya kazi polepole.\n\nKifaa chako kikipoa, kitaendelea kufanya kazi inavyostahili."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Kishikwambi chako kitajaribu kupoa kiotomatiki. Bado unaweza kutumia kishikwambi chako, lakini huenda kikafanya kazi polepole.\n\nKishikwambi chako kikipoa, kitaendelea kufanya kazi inavyostahili."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Kitambuzi cha alama ya kidole kinapatikana kwenye kitufe cha kuwasha/kuzima. Ni kitufe bapa pembeni pa kitufe cha sauti kilichoinuka kwenye ukingo wa kompyuta kibao."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Kitambuzi cha alama ya kidole kinapatikana kwenye kitufe cha kuwasha/kuzima. Ni kitufe bapa pembeni pa kitufe cha sauti kilichoinuka kwenye ukingo wa kifaa."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Kitambuzi cha alama ya kidole kinapatikana kwenye kitufe cha kuwasha/kuzima. Ni kitufe bapa pembeni pa kitufe cha sauti kilichoinuka kwenye ukingo wa simu."</string>
diff --git a/packages/SystemUI/res-product/values-ta/strings.xml b/packages/SystemUI/res-product/values-ta/strings.xml
index 967afed..774134e 100644
--- a/packages/SystemUI/res-product/values-ta/strings.xml
+++ b/packages/SystemUI/res-product/values-ta/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"மொபைலை அன்லாக் செய்ய, <xliff:g id="NUMBER">%d</xliff:g> முறை தவறாக முயன்றுவிட்டதனால் பணிக் கணக்கு அகற்றப்படும். இதனால் அதிலுள்ள அனைத்துச் சுயவிவரத் தரவும் நீக்கப்படும்."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"அன்லாக் பேட்டர்னை, <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக வரைந்துவிட்டீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறாக வரைந்தால், மின்னஞ்சல் கணக்கைப் பயன்படுத்தி டேப்லெட்டை அன்லாக் செய்யும்படி கேட்கப்படுவீர்கள்.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"அன்லாக் பேட்டர்னை, <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக வரைந்துவிட்டீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறாக வரைந்தால், மின்னஞ்சல் கணக்கைப் பயன்படுத்தி மொபைலை அன்லாக் செய்யும்படி கேட்கப்படுவீர்கள்.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"மொபைல் சூடானதால் அணைக்கப்பட்டது"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"சாதனம் சூடானதால் அணைக்கப்பட்டது"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"டேப்லெட் சூடானதால் அணைக்கப்பட்டது"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"இப்போது உங்கள் மொபைல் இயல்புநிலையில் இயங்குகிறது.\nமேலும் தகவலுக்குத் தட்டவும்."</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"இப்போது உங்கள் சாதனம் இயல்புநிலையில் இயங்குகிறது.\nமேலும் தகவலுக்குத் தட்டவும்."</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"இப்போது உங்கள் டேப்லெட் இயல்புநிலையில் இயங்குகிறது.\nமேலும் தகவலுக்குத் தட்டவும்."</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"உங்கள் மொபைல் அதிக சூடானதால் அதன் சூட்டைக் குறைக்க அணைக்கப்பட்டது. இப்போது உங்கள் மொபைல் இயல்புநிலையில் இயங்குகிறது.\n\nபின்வருபவற்றைச் செய்தால், உங்கள் மொபைல் சூடாகலாம்:\n	• அதிகளவு தரவைப் பயன்படுத்தும் ஆப்ஸை (கேமிங், வீடியோ, வழிகாட்டுதல் ஆப்ஸ் போன்றவை) பயன்படுத்துதல்\n	• பெரிய ஃபைல்களைப் பதிவிறக்குதல்/பதிவேற்றுதல்\n	• அதிக வெப்பநிலையில் மொபைலைப் பயன்படுத்துதல்"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"உங்கள் சாதனம் அதிக சூடானதால் அதன் சூட்டைக் குறைக்க அணைக்கப்பட்டது. இப்போது உங்கள் சாதனம் இயல்புநிலையில் இயங்குகிறது.\n\nபின்வருபவற்றைச் செய்தால், உங்கள் சாதனம் சூடாகலாம்:\n	• அதிகளவு தரவைப் பயன்படுத்தும் ஆப்ஸை (கேமிங், வீடியோ, வழிகாட்டுதல் ஆப்ஸ் போன்றவை) பயன்படுத்துதல்\n	• பெரிய ஃபைல்களைப் பதிவிறக்குதல்/பதிவேற்றுதல்\n	• அதிக வெப்பநிலையில் சாதனத்தைப் பயன்படுத்துதல்"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"உங்கள் டேப்லெட் அதிக சூடானதால் அதன் சூட்டைக் குறைக்க அணைக்கப்பட்டது. இப்போது உங்கள் டேப்லெட் இயல்புநிலையில் இயங்குகிறது.\n\nபின்வருபவற்றைச் செய்தால், உங்கள் டேப்லெட் சூடாகலாம்:\n	• அதிகளவு தரவைப் பயன்படுத்தும் ஆப்ஸை (கேமிங், வீடியோ, வழிகாட்டுதல் ஆப்ஸ் போன்றவை) பயன்படுத்துதல்\n	• பெரிய ஃபைல்களைப் பதிவிறக்குதல்/பதிவேற்றுதல்\n	• அதிக வெப்பநிலையில் டேப்லெட்டைப் பயன்படுத்துதல்"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"மொபைல் சூடாகிறது"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"சாதனம் சூடாகிறது"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"டேப்லெட் சூடாகிறது"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"மொபைலின் சூடு குறையும் வரை சில அம்சங்களைப் பயன்படுத்த முடியாது.\nமேலும் தகவலுக்குத் தட்டவும்."</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"சாதனத்தின் சூடு குறையும் வரை சில அம்சங்களைப் பயன்படுத்த முடியாது.\nமேலும் தகவலுக்குத் தட்டவும்."</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"டேப்லெட்டின் சூடு குறையும் வரை சில அம்சங்களைப் பயன்படுத்த முடியாது.\nமேலும் தகவலுக்குத் தட்டவும்."</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"உங்கள் மொபைல் தானாகவே அதன் சூட்டைக் குறைக்க முயலும். தொடர்ந்து மொபைலை உங்களால் பயன்படுத்த முடியும். ஆனால் அது மெதுவாக இயங்கக்கூடும்.\n\nஉங்கள் மொபைலின் சூடு குறைந்தவுடன் அது இயல்பாக இயங்கும்."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"உங்கள் சாதனம் தானாகவே அதன் சூட்டைக் குறைக்க முயலும். தொடர்ந்து சாதனத்தை உங்களால் பயன்படுத்த முடியும். ஆனால் அது மெதுவாக இயங்கக்கூடும்.\n\nஉங்கள் சாதனத்தின் சூடு குறைந்தவுடன் அது இயல்பாக இயங்கும்."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"உங்கள் டேப்லெட் தானாகவே அதன் சூட்டைக் குறைக்க முயலும். தொடர்ந்து டேப்லெட்டை உங்களால் பயன்படுத்த முடியும். ஆனால் அது மெதுவாக இயங்கக்கூடும்.\n\nஉங்கள் டேப்லெட்டின் சூடு குறைந்தவுடன் அது இயல்பாக இயங்கும்."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"\'கைரேகை சென்சார்\' பவர் பட்டனில் உள்ளது. இது டேப்லெட்டின் விளிம்பில் சற்று மேலெழும்பிய ஒலியளவு பட்டனுக்கு அடுத்துள்ள தட்டையான பட்டனாகும்."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"\'கைரேகை சென்சார்\' பவர் பட்டனில் உள்ளது. இது சாதனத்தின் விளிம்பில் சற்று மேலெழும்பிய ஒலியளவு பட்டனுக்கு அடுத்துள்ள தட்டையான பட்டனாகும்."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"\'கைரேகை சென்சார்\' பவர் பட்டனில் உள்ளது. இது மொபைலின் விளிம்பில் சற்று மேலெழும்பிய ஒலியளவு பட்டனுக்கு அடுத்துள்ள தட்டையான பட்டனாகும்."</string>
diff --git a/packages/SystemUI/res-product/values-te/strings.xml b/packages/SystemUI/res-product/values-te/strings.xml
index 80622f5..357b274 100644
--- a/packages/SystemUI/res-product/values-te/strings.xml
+++ b/packages/SystemUI/res-product/values-te/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"మీరు ఫోన్‌ను అన్‌లాక్ చేయడానికి <xliff:g id="NUMBER">%d</xliff:g> సార్లు తప్పు ప్రయత్నాలు చేశారు. కార్యాలయ ప్రొఫైల్ తీసివేయబడుతుంది, దీని వలన ప్రొఫైల్ డేటా మొత్తం తొలగించబడుతుంది."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"మీరు మీ అన్‌లాక్ నమూనాను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా గీసారు. మరో <xliff:g id="NUMBER_1">%2$d</xliff:g> ప్రయత్నాలలో విఫలమైతే, మీరు ఈమెయిల్‌ ఖాతాను ఉపయోగించి మీ టాబ్లెట్‌ను అన్‌లాక్ చేయాల్సి వస్తుంది.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> సెకన్లలో మళ్లీ ట్రై చేయండి."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"మీరు మీ అన్‌లాక్ నమూనాను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా గీసారు. మరో <xliff:g id="NUMBER_1">%2$d</xliff:g> ప్రయత్నాలలో విఫలమైతే, మీరు ఈమెయిల్‌ ఖాతాను ఉపయోగించి మీ ఫోన్‌ను అన్‌లాక్ చేయాల్సి వస్తుంది.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> సెకన్లలో మళ్లీ ట్రై చేయండి."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"వేడెక్కినందుకు ఫోన్ ఆఫ్ చేయబడింది"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"వేడెక్కినందుకు పరికరం ఆఫ్ చేయబడింది"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"వేడెక్కినందుకు టాబ్లెట్ ఆఫ్ చేయబడింది"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"మీ ఫోన్ ఇప్పుడు సాధారణంగా పని చేస్తోంది.\nమరింత సమాచారం కోసం ట్యాప్ చేయండి"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"మీ పరికరం ఇప్పుడు సాధారణంగా పని చేస్తోంది.\nమరింత సమాచారం కోసం ట్యాప్ చేయండి"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"మీ టాబ్లెట్ ఇప్పుడు సాధారణంగా పని చేస్తోంది.\nమరింత సమాచారం కోసం ట్యాప్ చేయండి"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"మీ ఫోన్ చాలా వేడిగా ఉంది, కనుక చల్లబర్చడానికి ఆఫ్ చేయబడింది. మీ ఫోన్ ఇప్పుడు సాధారణంగా పని చేస్తుంది.\n\nమీరు ఇలా చేస్తే మీ ఫోన్ చాలా వేడెక్కవచ్చు:\n	• రిసోర్స్-ఆధారిత యాప్‌లు (వీడియో గేమ్‌లు, వీడియో లేదా నావిగేషన్ వంటి యాప్‌లు) ఉపయోగించడం\n	• పెద్ద ఫైల్స్‌ను డౌన్‌లోడ్ లేదా అప్‌లోడ్ చేయడం\n	• అధిక ఉష్ణోగ్రతలలో మీ ఫోన్‌ని ఉపయోగించడం"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"మీ పరికరం చాలా వేడిగా ఉంది, కనుక చల్లబర్చడానికి ఆఫ్ చేయబడింది. మీ పరికరం ఇప్పుడు సాధారణంగా పని చేస్తుంది.\n\nమీరు ఇలా చేస్తే మీ పరికరం చాలా వేడెక్కవచ్చు:\n	• రిసోర్స్-ఆధారిత యాప్‌లు (వీడియో గేమ్‌లు, వీడియో లేదా నావిగేషన్ వంటి యాప్‌లు) ఉపయోగించడం\n	• పెద్ద ఫైల్స్‌ను డౌన్‌లోడ్ లేదా అప్‌లోడ్ చేయడం\n	• అధిక ఉష్ణోగ్రతలలో మీ పరికరాన్ని ఉపయోగించడం"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"మీ టాబ్లెట్ చాలా వేడిగా ఉంది, కనుక చల్లబర్చడానికి ఆఫ్ చేయబడింది. మీ టాబ్లెట్ ఇప్పుడు సాధారణంగా పని చేస్తుంది.\n\nమీరు ఇలా చేస్తే మీ టాబ్లెట్ చాలా వేడెక్కవచ్చు:\n	• రిసోర్స్-ఆధారిత యాప్‌లు (వీడియో గేమ్‌లు, వీడియో లేదా నావిగేషన్ వంటి యాప్‌లు) ఉపయోగించడం\n	• పెద్ద ఫైల్స్‌ను డౌన్‌లోడ్ లేదా అప్‌లోడ్ చేయడం\n	• అధిక ఉష్ణోగ్రతలలో మీ టాబ్లెట్‌ను ఉపయోగించడం"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"ఫోన్ వేడెక్కుతోంది"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"పరికరం వేడెక్కుతోంది"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"టాబ్లెట్ వేడెక్కుతోంది"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"ఫోన్‌ను చల్లబరిచే క్రమంలో కొన్ని ఫీచర్‌లు పరిమితం చేయబడ్డాయి.\nమరింత సమాచారం కోసం ట్యాప్ చేయండి"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"పరికరాన్ని చల్లబరిచే క్రమంలో కొన్ని ఫీచర్‌లు పరిమితం చేయబడ్డాయి.\nమరింత సమాచారం కోసం ట్యాప్ చేయండి"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"టాబ్లెట్‌ను చల్లబరిచే క్రమంలో కొన్ని ఫీచర్‌లు పరిమితం చేయబడ్డాయి.\nమరింత సమాచారం కోసం ట్యాప్ చేయండి"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"మీ ఫోన్ ఆటోమేటిక్‌గా చల్లబడటానికి ప్రయత్నిస్తుంది. మీరు ఇప్పటికీ మీ ఫోన్‌ను ఉపయోగించవచ్చు, కానీ దాని పనితీరు నెమ్మదిగా ఉండవచ్చు.\n\nమీ ఫోన్ చల్లబడిన తర్వాత, అది సాధారణ రీతిలో పని చేస్తుంది."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"మీ పరికరం ఆటోమేటిక్‌గా చల్లబరచడానికి ట్రై చేస్తుంది. మీరు ఇప్పటికీ మీ పరికరాన్ని ఉపయోగించవచ్చు, కానీ దాని పనితీరు నెమ్మదిగా ఉండవచ్చు.\n\nమీ పరికరం చల్లబడిన తర్వాత, అది సాధారణ రీతిలో పని చేస్తుంది."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"మీ టాబ్లెట్ ఆటోమేటిక్‌గా చల్లబరచడానికి ట్రై చేస్తుంది. మీరు ఇప్పటికీ మీ టాబ్లెట్‌ని ఉపయోగించవచ్చు, కానీ దాని పనితీరు నెమ్మదిగా ఉండవచ్చు.\n\nమీ టాబ్లెట్ చల్లబడిన తర్వాత, అది సాధారణ రీతిలో పని చేస్తుంది."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"వేలిముద్ర సెన్సార్ పవర్ బటన్‌పై ఉంది. ఇది, ఈ టాబ్లెట్ అంచున ఉబ్బెత్తుగా ఉన్న వాల్యూమ్ బటన్ పక్కన ఉన్న ఫ్లాట్ బటన్."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"వేలిముద్ర సెన్సార్ పవర్ బటన్‌పై ఉంది. ఇది, ఈ పరికరం అంచున ఉబ్బెత్తుగా ఉన్న వాల్యూమ్ బటన్ పక్కన ఉన్న ఫ్లాట్ బటన్."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"వేలిముద్ర సెన్సార్ పవర్ బటన్‌పై ఉంది. ఇది, ఈ ఫోన్ అంచున ఉబ్బెత్తుగా ఉన్న వాల్యూమ్ బటన్ పక్కన ఉన్న ఫ్లాట్ బటన్."</string>
diff --git a/packages/SystemUI/res-product/values-th/strings.xml b/packages/SystemUI/res-product/values-th/strings.xml
index e3d5640..ae1f3ed 100644
--- a/packages/SystemUI/res-product/values-th/strings.xml
+++ b/packages/SystemUI/res-product/values-th/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"คุณปลดล็อกโทรศัพท์ไม่ถูกต้อง <xliff:g id="NUMBER">%d</xliff:g> ครั้งแล้ว ระบบจะนำโปรไฟล์งานออก ซึ่งจะเป็นการลบข้อมูลทั้งหมดในโปรไฟล์"</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%1$d</xliff:g> ครั้งแล้ว หากทำไม่สำเร็จอีก <xliff:g id="NUMBER_1">%2$d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกแท็บเล็ตโดยใช้บัญชีอีเมล\n\n โปรดลองอีกครั้งใน <xliff:g id="NUMBER_2">%3$d</xliff:g> วินาที"</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%1$d</xliff:g> ครั้งแล้ว หากทำไม่สำเร็จอีก <xliff:g id="NUMBER_1">%2$d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกโทรศัพท์โดยใช้บัญชีอีเมล\n\n โปรดลองอีกครั้งในอีก <xliff:g id="NUMBER_2">%3$d</xliff:g> วินาที"</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"โทรศัพท์ปิดไปเพราะร้อนมาก"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"อุปกรณ์ปิดไปเพราะร้อนมาก"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"แท็บเล็ตปิดไปเพราะร้อนมาก"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"ขณะนี้โทรศัพท์ทำงานเป็นปกติ\nแตะเพื่อดูข้อมูลเพิ่มเติม"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"ขณะนี้อุปกรณ์ทำงานเป็นปกติ\nแตะเพื่อดูข้อมูลเพิ่มเติม"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"ขณะนี้แท็บเล็ตทำงานเป็นปกติ\nแตะเพื่อดูข้อมูลเพิ่มเติม"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"โทรศัพท์ร้อนเกินไปจึงปิดเครื่องเพื่อให้เย็นลง ขณะนี้โทรศัพท์ทำงานเป็นปกติ\n\nโทรศัพท์อาจร้อนเกินไปหากคุณ\n	• ใช้แอปที่ใช้ทรัพยากรมาก (เช่น เกม วิดีโอ หรือแอปการนำทาง)\n	• ดาวน์โหลดหรืออัปโหลดไฟล์ขนาดใหญ่\n	• ใช้โทรศัพท์ในอุณหภูมิที่สูง"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"อุปกรณ์ร้อนเกินไปจึงปิดเครื่องเพื่อให้เย็นลง ขณะนี้อุปกรณ์ทำงานเป็นปกติ\n\nอุปกรณ์อาจร้อนเกินไปหากคุณ\n	• ใช้แอปที่ใช้ทรัพยากรมาก (เช่น เกม วิดีโอ หรือแอปการนำทาง)\n	• ดาวน์โหลดหรืออัปโหลดไฟล์ขนาดใหญ่\n	• ใช้อุปกรณ์ในอุณหภูมิที่สูง"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"แท็บเล็ตร้อนเกินไปจึงปิดเครื่องเพื่อให้เย็นลง ขณะนี้แท็บเล็ตทำงานเป็นปกติ\n\nแท็บเล็ตอาจร้อนเกินไปหากคุณ\n	• ใช้แอปที่ใช้ทรัพยากรมาก (เช่น เกม วิดีโอ หรือแอปการนำทาง)\n	• ดาวน์โหลดหรืออัปโหลดไฟล์ขนาดใหญ่\n	• ใช้แท็บเล็ตในอุณหภูมิที่สูง"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"โทรศัพท์เริ่มร้อน"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"อุปกรณ์เริ่มร้อน"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"แท็บเล็ตเริ่มร้อน"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"ฟีเจอร์บางอย่างจะใช้งานได้จำกัดขณะโทรศัพท์เย็นลง\nแตะเพื่อดูข้อมูลเพิ่มเติม"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"ฟีเจอร์บางอย่างจะใช้งานได้จำกัดขณะอุปกรณ์เย็นลง\nแตะเพื่อดูข้อมูลเพิ่มเติม"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"ฟีเจอร์บางอย่างจะใช้งานได้จำกัดขณะแท็บเล็ตเย็นลง\nแตะเพื่อดูข้อมูลเพิ่มเติม"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"โทรศัพท์จะพยายามลดอุณหภูมิลงโดยอัตโนมัติ คุณยังสามารถใช้โทรศัพท์ได้ แต่อาจทำงานช้าลง\n\nโทรศัพท์จะทำงานตามปกติเมื่อเย็นลงแล้ว"</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"อุปกรณ์จะพยายามลดอุณหภูมิลงโดยอัตโนมัติ คุณยังสามารถใช้อุปกรณ์ได้ แต่อาจทำงานช้าลง\n\nอุปกรณ์จะทำงานตามปกติเมื่อเย็นลงแล้ว"</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"แท็บเล็ตจะพยายามลดอุณหภูมิลงโดยอัตโนมัติ คุณยังสามารถใช้แท็บเล็ตได้ แต่อาจทำงานช้าลง\n\nแท็บเล็ตจะทำงานตามปกติเมื่อเย็นลงแล้ว"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"เซ็นเซอร์ลายนิ้วมืออยู่ที่ปุ่มเปิด/ปิด ซึ่งเป็นปุ่มแบนข้างปุ่มนูนที่ใช้ปรับระดับเสียงตรงบริเวณขอบของแท็บเล็ต"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"เซ็นเซอร์ลายนิ้วมืออยู่ที่ปุ่มเปิด/ปิด ซึ่งเป็นปุ่มแบนข้างปุ่มนูนที่ใช้ปรับระดับเสียงตรงบริเวณขอบของอุปกรณ์"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"เซ็นเซอร์ลายนิ้วมืออยู่ที่ปุ่มเปิด/ปิด ซึ่งเป็นปุ่มแบนข้างปุ่มนูนที่ใช้ปรับระดับเสียงตรงบริเวณขอบของโทรศัพท์"</string>
diff --git a/packages/SystemUI/res-product/values-tl/strings.xml b/packages/SystemUI/res-product/values-tl/strings.xml
index 4c286eb..74f30ae 100644
--- a/packages/SystemUI/res-product/values-tl/strings.xml
+++ b/packages/SystemUI/res-product/values-tl/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"<xliff:g id="NUMBER">%d</xliff:g> (na) beses mo nang sinubukang i-unlock ang telepono gamit ang maling password. Aalisin ang profile sa trabaho, na magiging dahilan para ma-delete ang lahat ng data sa profile."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"<xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses kang nagkamali sa pagguhit ng iyong pattern sa pag-unlock. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagsubok, hihilingin sa iyong i-unlock ang tablet mo gamit ang isang email account.\n\n Subukan ulit sa loob ng <xliff:g id="NUMBER_2">%3$d</xliff:g> (na) segundo."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"<xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses kang nagkamali sa pagguhit ng iyong pattern sa pag-unlock. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagsubok, hihilingin sa iyong i-unlock ang telepono mo gamit ang isang email account.\n\n Subukan ulit sa loob ng <xliff:g id="NUMBER_2">%3$d</xliff:g> (na) segundo."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Na-off ang telepono dahil sa init"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Na-off ang device dahil sa init"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Na-off ang tablet dahil sa init"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Maayos na ngayong gumagana ang iyong telepono.\nMag-tap para sa higit pang impormasyon"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Maayos na ngayong gumagana ang iyong device.\nMag-tap para sa higit pang impormasyon"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Maayos na ngayong gumagana ang iyong tablet.\nMag-tap para sa higit pang impormasyon"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Napakainit ng telepono mo, kaya nag-off ito para magpalamig. Maayos na itong gumagana.\n\nPosibleng lubos na uminit ang iyong telepono kapag:\n	• Gumagamit ka ng mga resource-intensive na app (gaya ng app para sa gaming, video, o pag-navigate)\n	• Nagda-download o nag-a-upload ka ng malalaking file\n	• Ginagamit mo ang iyong telepono sa maiinit na lugar"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Napakainit ng device mo, kaya nag-off ito para magpalamig. Maayos na itong gumagana.\n\nPosibleng lubos na uminit ang iyong device kapag:\n	• Gumagamit ka ng mga resource-intensive na app (gaya ng app para sa gaming, video, o pag-navigate)\n	• Nagda-download o nag-a-upload ka ng malalaking file\n	• Ginagamit mo ang iyong device sa maiinit na lugar"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Napakainit ng tablet mo, kaya nag-off ito para magpalamig. Maayos na itong gumagana.\n\nPosibleng lubos na uminit ang iyong tablet kapag:\n	• Gumagamit ka ng mga resource-intensive na app (gaya ng app para sa gaming, video, o pag-navigate)\n	• Nagda-download o nag-a-upload ka ng malalaking file\n	• Ginagamit mo ang iyong tablet sa maiinit na lugar"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Umiinit ang telepono"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Umiinit ang device"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Umiinit ang tablet"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Limitado ang ilang feature habang nagpapalamig ang telepono.\nMag-tap para sa higit pang impormasyon"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Limitado ang ilang feature habang nagpapalamig ang device.\nMag-tap para sa higit pang impormasyon"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Limitado ang ilang feature habang nagpapalamig ang tablet.\nMag-tap para sa higit pang impormasyon"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Awtomatikong susubukan ng iyong telepono na magpalamig. Magagamit mo pa rin ang iyong telepono, pero posibleng mas mabagal ang paggana nito.\n\nKapag lumamig na ang telepono mo, gagana ito gaya ng karaniwan."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Awtomatikong susubukan ng iyong device na magpalamig. Magagamit mo pa rin ang iyong device, pero posibleng mas mabagal ang paggana nito.\n\nKapag lumamig na ang device mo, gagana ito gaya ng karaniwan."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Awtomatikong susubukan ng iyong tablet na magpalamig. Magagamit mo pa rin ang iyong tablet, pero posibleng mas mabagal ang paggana nito.\n\nKapag lumamig na ang tablet mo, gagana ito gaya ng karaniwan."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Nasa power button ang sensor para sa fingerprint. Ito ang flat na button sa tabi ng nakaangat na button ng volume sa gilid ng tablet."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Nasa power button ang sensor para sa fingerprint. Ito ang flat na button sa tabi ng nakaangat na button ng volume sa gilid ng device."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Nasa power button ang sensor para sa fingerprint. Ito ang flat na button sa tabi ng nakaangat na button ng volume sa gilid ng telepono."</string>
diff --git a/packages/SystemUI/res-product/values-tr/strings.xml b/packages/SystemUI/res-product/values-tr/strings.xml
index b376e98..68183e4 100644
--- a/packages/SystemUI/res-product/values-tr/strings.xml
+++ b/packages/SystemUI/res-product/values-tr/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Telefonun kilidini <xliff:g id="NUMBER">%d</xliff:g> kez hatalı bir şekilde açmayı denediniz. İş profili kaldırılacak ve tüm profil verileri silinecektir."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%1$d</xliff:g> kez hatalı çizdiniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız deneme daha yaparsanız tabletinizin kilidini bir e-posta hesabı kullanarak açmanız istenir.\n<xliff:g id="NUMBER_2">%3$d</xliff:g>\n saniye içinde tekrar deneyin."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız deneme daha yaparsanız telefonunuzu bir e-posta hesabı kullanarak açmanız istenir.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Telefon ısındığından kapatıldı"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Cihaz ısındığından kapatıldı"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Tablet ısındığından kapatıldı"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Telefonunuz şu anda normal bir şekilde çalışıyor.\nDaha fazla bilgi için dokunun"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Cihazınız şu anda normal bir şekilde çalışıyor.\nDaha fazla bilgi için dokunun"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Tabletiniz şu anda normal bir şekilde çalışıyor.\nDaha fazla bilgi için dokunun"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Telefonunuz çok ısındığından soğuması için kapatıldı ve şu anda normal bir şekilde çalışıyor.\n\nTelefonunuz şu koşullarda çok ısınabilir:\n	• Yoğun kaynak gerektiren uygulamalar (oyun, video veya gezinme uygulamaları gibi) kullanma\n	• Büyük dosyalar indirme veya yükleme\n	• Telefonunuzu sıcak yerlerde kullanma"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Cihazınız çok ısındığından soğuması için kapatıldı ve şu anda normal bir şekilde çalışıyor.\n\nAygıtınız şu koşullarda çok ısınabilir:\n	• Yoğun kaynak gerektiren uygulamalar (oyun, video veya gezinme uygulamaları gibi) kullanma\n	• Büyük dosyalar indirme veya yükleme\n	• Cihazınızı sıcak yerlerde kullanma"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Tabletiniz çok ısındığından soğuması için kapatıldı ve şu anda normal bir şekilde çalışıyor.\n\nTabletiniz şu koşullarda çok ısınabilir:\n	• Yoğun kaynak gerektiren uygulamalar (oyun, video veya gezinme uygulamaları gibi) kullanma\n	• Büyük dosyalar indirme veya yükleme\n	• Tabletinizi sıcak yerlerde kullanma"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Telefon ısınıyor"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Cihaz ısınıyor"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Tablet ısınıyor"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Telefon soğurken bazı özellikler sınırlı olarak kullanılabilir.\nDaha fazla bilgi için dokunun"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Telefon soğurken bazı özellikler sınırlı olarak kullanılabilir.\nDaha fazla bilgi için dokunun"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Tablet soğurken bazı özellikler sınırlı olarak kullanılabilir.\nDaha fazla bilgi için dokunun"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Telefonunuz otomatik olarak soğumaya çalışacak. Bu sırada telefonunuzu kullanmaya devam edebilirsiniz ancak uygulamalar daha yavaş çalışabilir.\n\nTelefonunuz soğuduktan sonra normal şekilde çalışacaktır."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Cihazınız otomatik olarak soğumaya çalışacak. Cihazınız bu sırada kullanılabilir ancak daha yavaş çalışabilir.\n\nCihazınız soğuduktan sonra normal şekilde çalışacaktır."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Tabletiniz otomatik olarak soğumaya çalışacak. Tabletiniz bu sırada kullanılabilir ancak daha yavaş çalışabilir.\n\nTabletiniz soğuduktan sonra normal şekilde çalışacaktır."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Parmak izi sensörü güç düğmesinin üzerindedir. Bu sensör, tabletin kenarındaki standart ses düğmesinin yanında bulunan düz düğmedir."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Parmak izi sensörü güç düğmesinin üzerindedir. Bu sensör, cihazın kenarındaki standart ses düğmesinin yanında bulunan düz düğmedir."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Parmak izi sensörü güç düğmesinin üzerindedir. Bu sensör, telefonun kenarındaki standart ses düğmesinin yanında bulunan düz düğmedir."</string>
diff --git a/packages/SystemUI/res-product/values-uk/strings.xml b/packages/SystemUI/res-product/values-uk/strings.xml
index ed0762b..e0aff9e8 100644
--- a/packages/SystemUI/res-product/values-uk/strings.xml
+++ b/packages/SystemUI/res-product/values-uk/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Кількість невдалих спроб розблокувати телефон: <xliff:g id="NUMBER">%d</xliff:g>. Буде видалено робочий профіль і всі його дані."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Залишилося спроб: <xliff:g id="NUMBER_1">%2$d</xliff:g>. У разі невдачі з\'явиться запит розблокувати планшет за допомогою облікового запису електронної пошти.\n\n Повторіть спробу за <xliff:g id="NUMBER_2">%3$d</xliff:g> с."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Залишилося спроб: <xliff:g id="NUMBER_1">%2$d</xliff:g>. У разі невдачі з\'явиться запит розблокувати телефон за допомогою облікового запису електронної пошти.\n\n Повторіть спробу за <xliff:g id="NUMBER_2">%3$d</xliff:g> с."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Телефон перегрівся й вимкнувся"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Пристрій перегрівся й вимкнувся"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Планшет перегрівся й вимкнувся"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Зараз телефон працює як зазвичай.\nНатисніть, щоб дізнатися більше"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Зараз пристрій працює як зазвичай.\nНатисніть, щоб дізнатися більше"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Зараз планшет працює як зазвичай.\nНатисніть, щоб дізнатися більше"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Телефон перегрівся, тому вимкнувся, щоб охолонути. Зараз він працює як зазвичай.\n\nТелефон може перегріватися, якщо ви:\n	• використовуєте ресурсомісткі додатки (наприклад, ігри, додатки з відео чи для навігації);\n	• завантажуєте великі файли на телефон або з нього;\n	• використовуєте телефон за високої температури."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Пристрій перегрівся, тому вимкнувся, щоб охолонути. Зараз він працює як зазвичай.\n\nПристрій може перегріватися, якщо ви:\n	• використовуєте ресурсомісткі додатки (наприклад, ігри, додатки з відео чи для навігації);\n	• завантажуєте великі файли на пристрій або з нього;\n	• використовуєте пристрій за високої температури."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Планшет перегрівся, тому вимкнувся, щоб охолонути. Зараз він працює як зазвичай.\n\nПланшет може перегріватися, якщо ви:\n	• використовуєте ресурсомісткі додатки (наприклад, ігри, додатки з відео чи для навігації);\n	• завантажуєте великі файли на планшет або з нього;\n	• використовуєте планшет за високої температури."</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Телефон нагрівається"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Пристрій нагрівається"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Планшет нагрівається"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Під час охолодження телефона деякі функції обмежуються.\nНатисніть, щоб дізнатися більше"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Під час охолодження пристрою деякі функції обмежуються.\nНатисніть, щоб дізнатися більше"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Під час охолодження планшета деякі функції обмежуються.\nНатисніть, щоб дізнатися більше"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Ваш телефон автоматично спробує охолодитися. Ви можете й далі користуватися ним, але він може працювати повільніше.\n\nКоли телефон охолоне, він знову працюватиме як зазвичай."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Ваш пристрій автоматично спробує охолодитися. Ви можете й далі користуватися ним, але він може працювати повільніше.\n\nКоли пристрій охолоне, він знову працюватиме як зазвичай."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Ваш планшет автоматично спробує охолодитися. Ви можете й далі користуватися ним, але він може працювати повільніше.\n\nКоли планшет охолоне, він знову працюватиме як зазвичай."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Сканер відбитків пальців розташовано на кнопці живлення. Це плоска кнопка поруч із випуклою кнопкою гучності на бічній крайці планшета."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Сканер відбитків пальців розташовано на кнопці живлення. Це плоска кнопка поруч із випуклою кнопкою гучності на бічній крайці пристрою."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Сканер відбитків пальців розташовано на кнопці живлення. Це плоска кнопка поруч із випуклою кнопкою гучності на бічній крайці телефона."</string>
diff --git a/packages/SystemUI/res-product/values-ur/strings.xml b/packages/SystemUI/res-product/values-ur/strings.xml
index c706aba..98fe163 100644
--- a/packages/SystemUI/res-product/values-ur/strings.xml
+++ b/packages/SystemUI/res-product/values-ur/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"آپ نے فون کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER">%d</xliff:g> بار غلط طریقے سے کوشش کی ہے۔ دفتری پروفائل ہٹا دی جائے گی، جس سے پروفائل کا سبھی ڈیٹا حذف ہو جائے گا۔"</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"آپ نے اپنا غیر مقفل کرنے کا پیٹرن <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے ڈرا کیا ہے۔ <xliff:g id="NUMBER_1">%2$d</xliff:g> مزید ناکام کوششوں کے بعد، آپ سے ایک ای میل اکاؤنٹ استعمال کر کے اپنا ٹیبلیٹ غیر مقفل کرنے کو کہا جائے گا۔\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"آپ نے اپنا غیر مقفل کرنے کا پیٹرن <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے ڈرا کیا ہے۔ <xliff:g id="NUMBER_1">%2$d</xliff:g> مزید ناکام کوششوں کے بعد، آپ سے ایک ای میل اکاؤنٹ استعمال کر کے اپنا فون غیر مقفل کرنے کو کہا جائے گا۔\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"گرم ہونے کی وجہ سے فون آف ہو گیا"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"گرم ہونے کی وجہ سے آلہ آف ہو گیا"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"گرم ہونے کی وجہ سے ٹیبلیٹ آف ہو گیا"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"آپ کا فون اب حسب معمول چل رہا ہے۔\nمزید معلومات کیلئے تھپتھپائیں"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"آپ کا آلہ اب حسب معمول چل رہا ہے۔\nمزید معلومات کیلئے تھپتھپائیں"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"آپ کا ٹیبلیٹ اب حسب معمول چل رہا ہے۔\nمزید معلومات کیلئے تھپتھپائیں"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"آپ کا فون کافی گرم ہو گيا تھا، اس لئے ٹھنڈا ہونے کیلئے یہ آف ہو گیا۔ اب آپ کا فون حسب معمول کام کر رہا ہے۔\n\nمندرجہ ذیل چیزیں کرنے پر آپ کا فون کافی گرم ہو سکتا ہے:\n	• ماخذ کا زیادہ استعمال کرنے والی ایپس (جیسے کہ گیمنگ، ویڈیو، یا نیویگیشن ایپس) کا استعمال کرنا\n	• بڑی فائلز ڈاؤن لوڈ یا اپ لوڈ کرنا\n	• اعلی درجہ حرارت میں فون کا استعمال کرنا"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"آپ کا آلہ کافی گرم ہو گيا تھا، اس لئے ٹھنڈا ہونے کیلئے یہ آف ہو گیا۔ اب آپ کا آلہ حسب معمول کام کر رہا ہے۔\n\nمندرجہ ذیل چیزیں کرنے پر آپ کا آلہ کافی گرم ہو سکتا ہے:\n	• ماخذ کا زیادہ استعمال کرنے والی ایپس (جیسے کہ گیمنگ، ویڈیو، یا نیویگیشن ایپس) کا استعمال کرنا\n	• بڑی فائلز ڈاؤن لوڈ یا اپ لوڈ کرنا\n	• اعلی درجہ حرارت میں آلہ کا استعمال کرنا"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"آپ کا ٹیبلیٹ کافی گرم ہو گيا تھا، اس لئے ٹھنڈا ہونے کیلئے یہ آف ہو گیا۔ اب آپ کا ٹیبلیٹ حسب معمول کام کر رہا ہے۔\n\nمندرجہ ذیل چیزیں کرنے پر آپ کا ٹیبلیٹ کافی گرم ہو سکتا ہے:\n	• ماخذ کا زیادہ استعمال کرنے والی ایپس (جیسے کہ گیمنگ، ویڈیو، یا نیویگیشن ایپس) کا استعمال کرنا\n	• بڑی فائلز ڈاؤن لوڈ یا اپ لوڈ کرنا\n	• اعلی درجہ حرارت میں اپنے ٹیبلیٹ کا استعمال کرنا"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"فون گرم ہو رہا ہے"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"آلہ گرم ہو رہا ہے"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"ٹیبلیٹ گرم ہو رہا ہے"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"فون کے ٹھنڈا ہونے تک کچھ خصوصیات محدود ہیں۔\nمزید معلومات کیلئے تھپتھپائیں"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"آلہ کے ٹھنڈا ہونے تک کچھ خصوصیات محدود ہیں۔\nمزید معلومات کیلئے تھپتھپائیں"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"ٹیبلیٹ کے ٹھنڈا ہونے تک کچھ خصوصیات محدود ہیں۔\nمزید معلومات کیلئے تھپتھپائیں"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"آپ کا فون خودکار طور پر ٹھنڈا ہونے کی کوشش کرے گا۔ آپ ابھی بھی اپنا فون استعمال کر سکتے ہیں، مگر ہو سکتا ہے یہ سست چلے۔\n\nآپ کا فون ٹھنڈا ہونے کے بعد، یہ حسب معمول چلے گا۔"</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"آپ کا آلہ خودکار طور پر ٹھنڈا ہونے کی کوشش کرے گا۔ آپ اب بھی اپنا آلہ استعمال کر سکتے ہیں، لیکن یہ آہستہ چل سکتا ہے۔\n\nآپ کا آلہ ٹھنڈا ہونے کے بعد، یہ حسب معمول چلے گا۔"</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"آپ کا ٹیبلیٹ خودکار طور پر ٹھنڈا ہونے کی کوشش کرے گا۔ آپ اب بھی اپنا ٹیبلیٹ استعمال کر سکتے ہیں، لیکن یہ آہستہ چل سکتا ہے۔\n\nآپ کا ٹیبلیٹ ٹھنڈا ہونے کے بعد، یہ حسب معمول چلے گا۔"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"فنگر پرنٹ سینسر پاور بٹن پر موجود ہے۔ یہ ٹیبلیٹ کے کنارے پر ابھرے ہوئے والیوم بٹن کے آگے والا ہموار بٹن ہے۔"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"فنگر پرنٹ سینسر پاور بٹن پر موجود ہے۔ یہ آلے کے کنارے پر ابھرے ہوئے والیوم بٹن کے آگے والا ہموار بٹن ہے۔"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"فنگر پرنٹ سینسر پاور بٹن پر موجود ہے۔ یہ فون کے کنارے پر ابھرے ہوئے والیوم بٹن کے آگے والا ہموار بٹن ہے۔"</string>
diff --git a/packages/SystemUI/res-product/values-uz/strings.xml b/packages/SystemUI/res-product/values-uz/strings.xml
index 3afa159..38f9ebb 100644
--- a/packages/SystemUI/res-product/values-uz/strings.xml
+++ b/packages/SystemUI/res-product/values-uz/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Siz telefonni qulfdan chiqarish uchun <xliff:g id="NUMBER">%d</xliff:g> marta xato urinish qildingiz. Endi ish profili oʻchirib tashlanadi va undagi barcha maʼlumotlar ham oʻchib ketadi."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Grafik kalit <xliff:g id="NUMBER_0">%1$d</xliff:g> marta xato chizildi. <xliff:g id="NUMBER_1">%2$d</xliff:g> marta muvaffaqiyatsiz urinishdan keyin sizdan emailingizdan foydalanib, planshet qulfini ochishingiz soʻraladi.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> soniyadan keyin yana urinib koʻring."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Grafik kalit <xliff:g id="NUMBER_0">%1$d</xliff:g> marta xato chizildi. <xliff:g id="NUMBER_1">%2$d</xliff:g> marta muvaffaqiyatsiz urinishdan keyin sizdan emailngizdan foydalanib, telefon qulfini ochishingiz soʻraladi.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> soniyadan keyin qayta urinib koʻring."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Telefon isib ketgani sababli oʻchirildi"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Qurilma isib ketgani sababli oʻchirildi"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Planshet isib ketgani sababli oʻchirildi"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Endi telefoningiz normal holatda ishlayapti.\nBatafsil axborot uchun bosing"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Endi qurilmangiz normal holatda ishlayapti.\nBatafsil axborot uchun bosing"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Endi planshetingiz normal holatda ishlayapti.\nBatafsil axborot uchun bosing"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Telefon qizib ketganligi sababli sovitish uchun oʻchirilgan edi. Endi telefoningiz normal holatda ishlayapti.\n\nTelefon quyidagi hollarda qizib ketishi mumkin:\n	• Resurstalab ilovalar ishlatilganda (masalan, oʻyin, video yoki navigatsiya ilovalari)\n	• Katta faylni yuklab olishda yoki yuklashda\n	• Telefondan yuqori haroratda foydalanganda"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Qurilma qizib ketganligi sababli sovitish uchun oʻchirilgan edi. Endi qurilmangiz normal holatda ishlayapti.\n\nQurilma quyidagi hollarda qizib ketishi mumkin:\n	• Resurstalab ilovalar ishlatilganda (masalan, oʻyin, video yoki navigatsiya ilovalari)\n	• Katta faylni yuklab olishda yoki yuklashda\n	• Qurilmadan yuqori haroratda foydalanganda"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Planshet qizib ketganligi sababli sovitish uchun oʻchirilgan edi. Endi planshetingiz normal holatda ishlayapti.\n\nPlanshet quyidagi hollarda qizib ketishi mumkin:\n	• Resurstalab ilovalar ishlatilganda (masalan, oʻyin, video yoki navigatsiya ilovalari)\n	• Katta faylni yuklab olishda yoki yuklashda\n	• Planshetdan yuqori haroratda foydalanganda"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Telefon qizimoqda"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Qurilma qizimoqda"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Planshet qizimoqda"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Telefon sovib olishi uchun ayrim funksiyalar cheklanadi.\nBatafsil axborot uchun bosing"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Qurilma sovib olishi uchun ayrim funksiyalar cheklanadi.\nBatafsil axborot uchun bosing"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Planshet sovib olishi uchun ayrim funksiyalar cheklanadi.\nBatafsil axborot uchun bosing"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Telefoningiz avtomatik ravishda oʻzini sovitadi. Telefondan foydalanishda davom etishingiz mumkin, lekin u sekinroq ishlashi mumkin.\n\nTelefon sovishi bilan normal holatda ishlashni boshlaydi."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Qurilmangiz avtomatik ravishda oʻzini sovitadi. Qurilmadan foydalanishda davom etishingiz mumkin, lekin u sekinroq ishlashi mumkin.\n\nQurilma sovishi bilan normal holatda ishlashni boshlaydi."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Planshetingiz avtomatik ravishda oʻzini sovitadi. Planshetdan foydalanishda davom etishingiz mumkin, lekin u sekinroq ishlashi mumkin.\n\nPlanshet sovishi bilan normal holatda ishlashni boshlaydi."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Barmoq izi sensori quvvat tugmasida joylashgan. U tekis tugma planshetning yon chekkasida tovush balandligi tugmasining yonida joylashgan."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Barmoq izi sensori quvvat tugmasida joylashgan. U tekis tugma qurilmaning yon chekkasida tovush balandligi tugmasining yonida joylashgan."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Barmoq izi sensori quvvat tugmasida joylashgan. U tekis tugma telefonning yon chekkasida tovush balandligi tugmasining yonida joylashgan."</string>
diff --git a/packages/SystemUI/res-product/values-vi/strings.xml b/packages/SystemUI/res-product/values-vi/strings.xml
index 6e121c6..fb3f862 100644
--- a/packages/SystemUI/res-product/values-vi/strings.xml
+++ b/packages/SystemUI/res-product/values-vi/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Bạn đã mở khóa điện thoại sai <xliff:g id="NUMBER">%d</xliff:g> lần. Hồ sơ công việc sẽ bị xóa, tức là tất cả dữ liệu hồ sơ sẽ bị xóa."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Bạn đã vẽ không chính xác hình mở khóa <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa máy tính bảng bằng tài khoản email.\n\n Hãy thử lại sau <xliff:g id="NUMBER_2">%3$d</xliff:g> giây."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Bạn đã vẽ không chính xác hình mở khóa <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa điện thoại bằng tài khoản email.\n\n Hãy thử lại sau <xliff:g id="NUMBER_2">%3$d</xliff:g> giây."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Điện thoại đã tắt do quá nóng"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Thiết bị đã tắt do quá nóng"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Máy tính bảng đã tắt do quá nóng"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Hiện điện thoại của bạn đang chạy bình thường.\nHãy nhấn để biết thêm thông tin"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Hiện thiết bị của bạn đang chạy bình thường.\nHãy nhấn để biết thêm thông tin"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Hiện máy tính bảng của bạn đang chạy bình thường.\nHãy nhấn để biết thêm thông tin"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Do quá nóng nên điện thoại đã tắt để hạ nhiệt. Hiện điện thoại của bạn đang chạy bình thường.\n\nĐiện thoại có thể bị quá nóng nếu bạn:\n	• Dùng các ứng dụng tốn nhiều tài nguyên (như ứng dụng trò chơi, video hoặc chỉ đường)\n	• Tải xuống hoặc tải lên tệp có dung lượng lớn\n	• Dùng điện thoại ở nhiệt độ cao"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Do quá nóng nên thiết bị đã tắt để hạ nhiệt. Hiện thiết bị của bạn đang chạy bình thường.\n\nThiết bị có thể bị quá nóng nếu bạn:\n	• Dùng các ứng dụng tốn nhiều tài nguyên (như ứng dụng trò chơi, video hoặc chỉ đường)\n	• Tải xuống hoặc tải lên tệp có dung lượng lớn\n	• Dùng thiết bị ở nhiệt độ cao"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Do quá nóng nên máy tính bảng đã tắt để hạ nhiệt. Hiện máy tính bảng của bạn đang chạy bình thường.\n\nMáy tính bảng có thể bị quá nóng nếu bạn:\n	• Dùng các ứng dụng tốn nhiều tài nguyên (như ứng dụng trò chơi, video hoặc chỉ đường)\n	• Tải xuống hoặc tải lên tệp có dung lượng lớn\n	• Dùng máy tính bảng ở nhiệt độ cao"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Điện thoại đang nóng lên"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Thiết bị đang nóng lên"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Máy tính bảng đang nóng lên"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Một số tính năng bị hạn chế trong khi điện thoại nguội dần.\nHãy nhấn để biết thêm thông tin"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Một số tính năng bị hạn chế trong khi thiết bị nguội dần.\nHãy nhấn để biết thêm thông tin"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Một số tính năng bị hạn chế trong khi máy tính bảng nguội dần.\nHãy nhấn để biết thêm thông tin"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Điện thoại của bạn sẽ tự động nguội dần. Bạn vẫn sẽ sử dụng được điện thoại, nhưng điện thoại có thể chạy chậm hơn.\n\nSau khi đã nguội, điện thoại sẽ chạy bình thường."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Thiết bị của bạn sẽ tự động nguội dần. Bạn vẫn sẽ sử dụng được thiết bị, nhưng thiết bị có thể chạy chậm hơn.\n\nSau khi đã nguội, thiết bị sẽ chạy bình thường."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Máy tính bảng của bạn sẽ tự động nguội dần. Bạn vẫn sẽ sử dụng được máy tính bảng, nhưng máy tính bảng có thể chạy chậm hơn.\n\nSau khi đã nguội, máy tính bảng sẽ chạy bình thường."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Cảm biến vân tay nằm trên nút nguồn. Đó là nút phẳng cạnh nút âm lượng nhô lên trên cạnh của máy tính bảng."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Cảm biến vân tay nằm trên nút nguồn. Đó là nút phẳng cạnh nút âm lượng nhô lên trên cạnh của thiết bị."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Cảm biến vân tay nằm trên nút nguồn. Đó là nút phẳng cạnh nút âm lượng nhô lên trên cạnh của điện thoại."</string>
diff --git a/packages/SystemUI/res-product/values-zh-rCN/strings.xml b/packages/SystemUI/res-product/values-zh-rCN/strings.xml
index a60982f..6895219 100644
--- a/packages/SystemUI/res-product/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res-product/values-zh-rCN/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"您尝试解锁手机后失败的次数已达 <xliff:g id="NUMBER">%d</xliff:g> 次。系统将移除此工作资料,而这将删除所有的工作资料数据。"</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"您已 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐号解锁平板电脑。\n\n请在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒后重试。"</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"您已 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐号解锁手机。\n\n请在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒后重试。"</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"手机先前因过热而关机"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"设备先前因过热而关机"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"平板电脑先前因过热而关机"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"现在,您的手机已恢复正常运行。\n点按即可了解详情"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"现在,您的设备已恢复正常运行。\n点按即可了解详情"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"现在,您的平板电脑已恢复正常运行。\n点按即可了解详情"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"您的手机先前因过热而关机降温。现已恢复正常运行。\n\n以下情况可能会导致您的手机过热:\n	• 使用占用大量资源的应用(例如游戏、视频或导航应用)\n	• 下载或上传大型文件\n	• 在高温环境下使用手机"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"您的设备先前因过热而关机降温。现已恢复正常运行。\n\n以下情况可能会导致您的设备过热:\n	• 使用占用大量资源的应用(例如游戏、视频或导航应用)\n	• 下载或上传大型文件\n	• 在高温环境下使用设备"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"您的平板电脑先前因过热而关机降温。现已恢复正常运行。\n\n以下情况可能会导致您的平板电脑过热:\n	• 使用占用大量资源的应用(例如游戏、视频或导航应用)\n	• 下载或上传大型文件\n	• 在高温环境下使用平板电脑"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"手机温度上升中"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"设备温度上升中"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"平板电脑温度上升中"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"手机降温期间,部分功能的使用会受限制。\n点按即可了解详情"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"设备降温期间,部分功能的使用会受限制。\n点按即可了解详情"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"平板电脑降温期间,部分功能的使用会受限制。\n点按即可了解详情"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"您的手机将自动尝试降温。您依然可以使用您的手机,但是它的运行速度可能会较慢。\n\n手机降温完毕后,就会恢复正常的运行速度。"</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"您的设备将自动尝试降温。您依然可以使用您的设备,但是它的运行速度可能会较慢。\n\n设备降温完毕后,就会恢复正常的运行速度。"</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"您的平板电脑将自动尝试降温。您依然可以使用您的平板电脑,但是它的运行速度可能会较慢。\n\n平板电脑降温完毕后,就会恢复正常的运行速度。"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"指纹传感器在电源按钮上。电源按钮是一个扁平按钮,位于平板电脑边缘凸起的音量按钮旁边。"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"指纹传感器在电源按钮上。电源按钮是一个扁平按钮,位于设备边缘凸起的音量按钮旁边。"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"指纹传感器在电源按钮上。电源按钮是一个扁平按钮,位于手机边缘凸起的音量按钮旁边。"</string>
diff --git a/packages/SystemUI/res-product/values-zh-rHK/strings.xml b/packages/SystemUI/res-product/values-zh-rHK/strings.xml
index 85f482a..6bcb048 100644
--- a/packages/SystemUI/res-product/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res-product/values-zh-rHK/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"你嘗試解鎖手機已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統將移除此工作設定檔,而所有設定檔資料亦會一併刪除。"</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"你已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求你透過電郵帳戶解鎖平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"你已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求你透過電郵帳戶解鎖手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"手機因過熱而關機"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"裝置因過熱而關機"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"平板電腦因過熱而關機"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"你的手機現已正常運作。\n輕按即可瞭解詳情"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"你的裝置現已正常運作。\n輕按即可瞭解詳情"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"你的平板電腦現已正常運作。\n輕按即可瞭解詳情"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"你的手機之前因過熱而關機降溫。手機現已正常運作。\n\n以下情況可能會導致手機過熱:\n	• 使用耗用大量資源的應用程式 (例如遊戲、影片或導航應用程式)\n	• 下載或上載大型檔案\n	• 在高溫環境下使用手機"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"你的裝置之前因過熱而關機降溫。裝置現已正常運作。\n\n以下情況可能會導致裝置過熱:\n	• 使用耗用大量資源的應用程式 (例如遊戲、影片或導航應用程式)\n	• 下載或上載大型檔案\n	• 在高溫環境下使用裝置"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"你的平板電腦之前因過熱而關機降溫。平板電腦現已正常運作。\n\n以下情況可能會導致平板電腦過熱:\n	• 使用耗用大量資源的應用程式 (例如遊戲、影片或導航應用程式)\n	• 下載或上載大型檔案\n	• 在高溫環境下使用平板電腦"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"手機溫度正在上升"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"裝置溫度正在上升"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"平板電腦溫度正在上升"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"手機降溫時,部分功能會受限制。\n輕按即可瞭解詳情"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"裝置降溫時,部分功能會受限制。\n輕按即可瞭解詳情"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"平板電腦降溫時,部分功能會受限制。\n輕按即可瞭解詳情"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"手機會自動嘗試降溫。你仍可以使用手機,但手機的運作速度可能較慢。\n\n手機降溫後便會正常運作。"</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"裝置會自動嘗試降溫。你仍可以使用裝置,但裝置的運作速度可能較慢。\n\n裝置降溫後便會正常運作。"</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"平板電腦會自動嘗試降溫。你仍可以使用平板電腦,但平板電腦的運作速度可能較慢。\n\n平板電腦降溫後便會正常運作。"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"指紋感應器位於開關按鈕上,開關按鈕形狀扁平,位於平板電腦邊緣凸起的音量按鈕旁。"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"指紋感應器位於開關按鈕上,開關按鈕形狀扁平,位於裝置邊緣凸起的音量按鈕旁。"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"指紋感應器位於開關按鈕上,開關按鈕形狀扁平,位於手機邊緣凸起的音量按鈕旁。"</string>
diff --git a/packages/SystemUI/res-product/values-zh-rTW/strings.xml b/packages/SystemUI/res-product/values-zh-rTW/strings.xml
index c0f75c7..8b79732f 100644
--- a/packages/SystemUI/res-product/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res-product/values-zh-rTW/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"你嘗試解鎖手機已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。你的工作資料夾將遭到移除,所有設定檔資料也會一併遭到刪除。"</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"你的解鎖圖案已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,系統會要求你透過電子郵件帳戶將平板電腦解鎖。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"你的解鎖圖案已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,系統會要求你透過電子郵件帳戶將手機解鎖。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"手機因過熱而關機"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"裝置因過熱而關機"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"平板電腦因過熱而關機"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"手機現在已恢復正常運作。\n輕觸即可瞭解詳情"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"裝置現在已恢復正常運作。\n輕觸即可瞭解詳情"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"平板電腦現在已恢復正常運作。\n輕觸即可瞭解詳情"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"手機先前過熱,因此關機降溫,現在已恢復正常運作。\n\n以下狀況可能會導致手機過熱:\n	• 使用的應用程式需要大量資源,例如遊戲、影片或導航應用程式\n	• 下載或上傳大型檔案\n	• 在高溫下使用手機"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"裝置先前過熱,因此關機降溫,現在已恢復正常運作。\n\n以下狀況可能會導致裝置過熱:\n	• 使用的應用程式需要大量資源,例如遊戲、影片或導航應用程式\n	• 下載或上傳大型檔案\n	• 在高溫下使用裝置"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"平板電腦先前過熱,因此關機降溫,現在已恢復正常運作。\n\n以下狀況可能會導致平板電腦過熱:\n	• 使用的應用程式需要大量資源,例如遊戲、影片或導航應用程式\n	• 下載或上傳大型檔案\n	• 在高溫下使用平板電腦"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"手機溫度上升"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"裝置溫度上升"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"平板電腦溫度上升"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"手機降溫時,某些功能會受到限制。\n輕觸即可瞭解詳情"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"裝置降溫時,某些功能會受到限制。\n輕觸即可瞭解詳情"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"平板電腦降溫時,某些功能會受到限制。\n輕觸即可瞭解詳情"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"手機會自動嘗試降溫。你仍可繼續使用手機,但運作速度可能會變慢。\n\n手機降溫後就會恢復正常運作。"</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"裝置會自動嘗試降溫。你仍可繼續使用裝置,但運作速度可能會變慢。\n\n裝置降溫後就會恢復正常運作。"</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"平板電腦會自動嘗試降溫。你仍可繼續使用平板電腦,但運作速度可能會變慢。\n\n平板電腦降溫後就會恢復正常運作。"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"指紋感應器在電源鍵上。電源鍵的形狀是扁平的,位在平板電腦側邊凸起的音量按鈕旁。"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"指紋感應器在電源鍵上。電源鍵的形狀是扁平的,位在裝置側邊凸起的音量按鈕旁。"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"指紋感應器在電源鍵上。電源鍵的形狀是扁平的,位在手機側邊凸起的音量鍵旁。"</string>
diff --git a/packages/SystemUI/res-product/values-zu/strings.xml b/packages/SystemUI/res-product/values-zu/strings.xml
index 6b20014..89d4264 100644
--- a/packages/SystemUI/res-product/values-zu/strings.xml
+++ b/packages/SystemUI/res-product/values-zu/strings.xml
@@ -40,6 +40,24 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Uzame ngokungalungile ukuvula ifoni izikhathi ezingu-<xliff:g id="NUMBER">%d</xliff:g>. Iphrofayela yomsebenzi izosuswa, okuzosusa yonke idatha yephrofayela."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Udwebe ngokungalungile iphethini yakho yokuvula ngezikhathi ezingu-<xliff:g id="NUMBER_0">%1$d</xliff:g>. Ngemuva kwemizamo engaphumelelanga kaningi engu-<xliff:g id="NUMBER_1">%2$d</xliff:g>, uzocelwa ukuthi uvule ithebulethi yakho usebenzisa i-akhawunti ye-imeyili.\n\nZama futhi kumasekhondi angu-<xliff:g id="NUMBER_2">%3$d</xliff:g>."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Ukulayisha ungenisa iphathini yakho yokuvula ngendlela engalungile izikhathi ezi-<xliff:g id="NUMBER_0">%1$d</xliff:g> Emva kweminye imizamo engu-<xliff:g id="NUMBER_1">%2$d</xliff:g>, uzocelwa ukuvula ifoni yakho usebenzisa ukungena ngemvume ku-Google\n\n Zame futhi emumva kwengu- <xliff:g id="NUMBER_2">%3$d</xliff:g> imizuzwana."</string>
+    <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"Ifoni ivaliwe ngenxa yokushisa"</string>
+    <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"Idivayisi ivaliwe ngenxa yokushisa"</string>
+    <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"Ithebulethi ivaliwe ngenxa yokushisa"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Ifoni yakho manje isebenza ngokuvamile.\nThepha ukuze uthole ulwazi olungeziwe"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Idivayisi yakho manje isebenza ngokuvamile.\nThepha ukuze uthole ulwazi olwengeziwe"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Ithebulethi yakho manje isebenza ngokuvamile.\nThepha ukuze uthole ulwazi olwengeziwe"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Ifoni yakho ibishisa kakhulu, ngakho-ke yacisha ukuze iphole. Ifoni yakho manje isebenza ngokuvamile.\n\nIfoni yakho ingashisa kakhulu uma:\n	• Usebenzisa izinhlelo zokusebenza ezinkulu (njegegeyimu, ividiyo, noma ama-app okufuna)\n	• Landa noma layisha amafayela amakhulu\n	• Sebenzisa ifoni yakho kumazinga okushisa aphezulu"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Idivayisi yakho ibishisa kakhulu, ngakho-ke yacisha ukuze iphole. Idivayisi yakho manje isebenza ngokuvamile.\n\nIdivayisi yakho ingashisa kakhulu uma:\n	• Usebenzisa ama-app wensiza enamandla (njegegeyimu, ividiyo, noma ama-app wokufuna)\n	• Dawuniloda noma layisha amafayela amakhulu\n	• Sebenzisa idivayisi yakho kumazinga wokushisa aphezulu"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Ithebulethi yakho ibishisa kakhulu, ngakho-ke yacisha ukuze iphole. Ithebulethi yakho manje isebenza ngokuvamile.\n\nIthebulethi yakho ingashisa kakhulu uma:\n	• Usebenzisa ama-app wensiza enamandla (njegegeyimu, ividiyo, noma ama-app wokufuna)\n	• Dawuniloda noma layisha amafayela amakhulu\n	• Sebenzisa ithebulethi yakho kumazinga wokushisa aphezulu kakhulu"</string>
+    <string name="high_temp_title" product="default" msgid="5365000411304924115">"Ifoni iyafudumala"</string>
+    <string name="high_temp_title" product="device" msgid="6622009907401563664">"Idivayisi iyafudumala"</string>
+    <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"Ithebulethi iyafudumala"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"Ezinye izakhi zikhawulelwe ngenkathi ifoni iphola.\nThepha mayelana nolwazi olwengeziwe"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"Ezinye izakhi zikhawulelwe ngenkathi idivayisi iphola.\nThepha mayelana nolwazi olwengeziwe"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"Ezinye izakhi zikhawulelwe ngenkathi ithebulethi iphola.\nThepha mayelana nolwazi olwengeziwe"</string>
+    <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"Ifoni yakho izozama ngokuzenzakalela ukuphola. Ungasasebenzisa ifoni yakho, kodwa ingasebenza ngokungasheshi.\n\nUma ifoni yakho isipholile, izosebenza ngokuvamile."</string>
+    <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"Idivayisi yakho izozama ukupholisa ngokuzenzekelayo. Usengasebenzisa idivayisi yakho, kodwa ingase isebenze ngokunensayo.\n\nLapho idivayisi yakho isipholile, izosebenza ngokuvamile."</string>
+    <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"Ithebulethi yakho izozama ukupholisa. Usengasebenzisa ithebulethi yakho, kodwa ingase isebenze ngokunensayo.\n\nLapho ithebulethi yakho isipholile, izosebenza ngokuvamile."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Inzwa yesigxivizo somunwe esenkinobhweni yamandla. Inkinobho eyisicaba eduze kwenkinobho yevolumu ephakanyisiwe emaphethelweni wethebulethi."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Inzwa yesigxivizo somunwe esenkinobhweni yamandla. Inkinobho eyisicaba eduze kwenkinobho yevolumu ephakanyisiwe emaphethelweni edivayisi."</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Inzwa yesigxivizo somunwe esenkinobhweni yamandla. Inkinobho eyisicaba eduze kwenkinobho yevolumu ephakanyisiwe emaphethelweni efoni."</string>
diff --git a/core/res/res/color/letterbox_background.xml b/packages/SystemUI/res/color/brightness_slider_overlay_color.xml
similarity index 69%
rename from core/res/res/color/letterbox_background.xml
rename to packages/SystemUI/res/color/brightness_slider_overlay_color.xml
index 955948a..a8abd79 100644
--- a/core/res/res/color/letterbox_background.xml
+++ b/packages/SystemUI/res/color/brightness_slider_overlay_color.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2022 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.
@@ -14,6 +14,9 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
+
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="@color/system_neutral1_500" android:lStar="5" />
-</selector>
+    <item android:state_pressed="true" android:color="?attr/onShadeActive" android:alpha="0.12" />
+    <item android:state_hovered="true" android:color="?attr/onShadeActive" android:alpha="0.09" />
+    <item android:color="@color/transparent" />
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/brightness_progress_full_drawable.xml b/packages/SystemUI/res/drawable/brightness_progress_full_drawable.xml
index 2ea90c7..a9e7adf 100644
--- a/packages/SystemUI/res/drawable/brightness_progress_full_drawable.xml
+++ b/packages/SystemUI/res/drawable/brightness_progress_full_drawable.xml
@@ -26,6 +26,13 @@
             <corners android:radius="@dimen/rounded_slider_corner_radius"/>
         </shape>
     </item>
+    <item>
+        <shape>
+            <corners android:radius="@dimen/rounded_slider_corner_radius" />
+            <size android:height="@dimen/rounded_slider_height" />
+            <solid android:color="@color/brightness_slider_overlay_color" />
+        </shape>
+    </item>
     <item
         android:id="@+id/slider_icon"
         android:gravity="center_vertical|right"
diff --git a/packages/SystemUI/res/drawable/ic_expand_more_48dp.xml b/packages/SystemUI/res/drawable/ic_expand_more_48dp.xml
new file mode 100644
index 0000000..c61a300
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_expand_more_48dp.xml
@@ -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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="48.0dp"
+        android:height="48.0dp"
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M33.17,17.17L24.0,26.34l-9.17,-9.17L12.0,20.0l12.0,12.0 12.0,-12.0z"/>
+</vector>
diff --git a/core/res/res/color/letterbox_background.xml b/packages/SystemUI/res/drawable/immersive_cling_bg_circ.xml
similarity index 64%
copy from core/res/res/color/letterbox_background.xml
copy to packages/SystemUI/res/drawable/immersive_cling_bg_circ.xml
index 955948a..4029702 100644
--- a/core/res/res/color/letterbox_background.xml
+++ b/packages/SystemUI/res/drawable/immersive_cling_bg_circ.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2022 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.
@@ -12,8 +12,15 @@
   ~ distributed under the License is distributed on an "AS IS" BASIS,
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
+  ~ limitations under the License
   -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="@color/system_neutral1_500" android:lStar="5" />
-</selector>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="oval" >
+
+    <solid android:color="@android:color/white" />
+
+    <size
+        android:height="56dp"
+        android:width="56dp" />
+
+</shape>
diff --git a/core/res/res/color/letterbox_background.xml b/packages/SystemUI/res/drawable/immersive_cling_light_bg_circ.xml
similarity index 65%
copy from core/res/res/color/letterbox_background.xml
copy to packages/SystemUI/res/drawable/immersive_cling_light_bg_circ.xml
index 955948a..e3c7d0c 100644
--- a/core/res/res/color/letterbox_background.xml
+++ b/packages/SystemUI/res/drawable/immersive_cling_light_bg_circ.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2022 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.
@@ -12,8 +12,15 @@
   ~ distributed under the License is distributed on an "AS IS" BASIS,
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
+  ~ limitations under the License
   -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="@color/system_neutral1_500" android:lStar="5" />
-</selector>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="oval" >
+
+    <solid android:color="#80ffffff" />
+
+    <size
+        android:height="76dp"
+        android:width="76dp" />
+
+</shape>
diff --git a/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml b/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml
index 87b5a4c..32dc4b3 100644
--- a/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml
+++ b/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml
@@ -20,7 +20,7 @@
     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/colorSurface"/>
+  <solid android:color="?androidprv:attr/materialColorSurfaceContainerHigh"/>
   <size
       android:width="@dimen/keyguard_affordance_fixed_width"
       android:height="@dimen/keyguard_affordance_fixed_height"/>
diff --git a/packages/SystemUI/res/layout/activity_rear_display_education.xml b/packages/SystemUI/res/layout/activity_rear_display_education.xml
index c295cfe..1b6247f 100644
--- a/packages/SystemUI/res/layout/activity_rear_display_education.xml
+++ b/packages/SystemUI/res/layout/activity_rear_display_education.xml
@@ -28,7 +28,7 @@
         app:cardCornerRadius="28dp"
         app:cardBackgroundColor="@color/rear_display_overlay_animation_background_color">
 
-            <com.airbnb.lottie.LottieAnimationView
+            <com.android.systemui.reardisplay.RearDisplayEducationLottieViewWrapper
                 android:id="@+id/rear_display_folded_animation"
                 android:importantForAccessibility="no"
                 android:layout_width="@dimen/rear_display_animation_width"
diff --git a/packages/SystemUI/res/layout/activity_rear_display_education_opened.xml b/packages/SystemUI/res/layout/activity_rear_display_education_opened.xml
index 0e6b281..bded012 100644
--- a/packages/SystemUI/res/layout/activity_rear_display_education_opened.xml
+++ b/packages/SystemUI/res/layout/activity_rear_display_education_opened.xml
@@ -29,7 +29,7 @@
         app:cardCornerRadius="28dp"
         app:cardBackgroundColor="@color/rear_display_overlay_animation_background_color">
 
-        <com.airbnb.lottie.LottieAnimationView
+        <com.android.systemui.reardisplay.RearDisplayEducationLottieViewWrapper
             android:id="@+id/rear_display_folded_animation"
             android:importantForAccessibility="no"
             android:layout_width="@dimen/rear_display_animation_width_opened"
diff --git a/packages/SystemUI/res/layout/auth_biometric_contents.xml b/packages/SystemUI/res/layout/auth_biometric_contents.xml
index efc661a..50b3bec 100644
--- a/packages/SystemUI/res/layout/auth_biometric_contents.xml
+++ b/packages/SystemUI/res/layout/auth_biometric_contents.xml
@@ -57,7 +57,7 @@
 
         <include layout="@layout/auth_biometric_icon"/>
 
-        <com.airbnb.lottie.LottieAnimationView
+        <com.android.systemui.biometrics.BiometricPromptLottieViewWrapper
             android:id="@+id/biometric_icon_overlay"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
diff --git a/packages/SystemUI/res/layout/biometric_prompt_layout.xml b/packages/SystemUI/res/layout/biometric_prompt_layout.xml
index 05ff1b1..ecb0bfa 100644
--- a/packages/SystemUI/res/layout/biometric_prompt_layout.xml
+++ b/packages/SystemUI/res/layout/biometric_prompt_layout.xml
@@ -39,6 +39,7 @@
         android:singleLine="true"
         android:marqueeRepeatLimit="1"
         android:ellipsize="marquee"
+        android:importantForAccessibility="no"
         style="@style/TextAppearance.AuthCredential.Subtitle"/>
 
     <TextView
@@ -59,7 +60,7 @@
         android:layout_height="wrap_content"
         android:layout_gravity="center">
 
-        <com.airbnb.lottie.LottieAnimationView
+        <com.android.systemui.biometrics.BiometricPromptLottieViewWrapper
             android:id="@+id/biometric_icon"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
@@ -67,7 +68,7 @@
             android:contentDescription="@null"
             android:scaleType="fitXY" />
 
-        <com.airbnb.lottie.LottieAnimationView
+        <com.android.systemui.biometrics.BiometricPromptLottieViewWrapper
             android:id="@+id/biometric_icon_overlay"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
diff --git a/packages/SystemUI/res/layout/combined_qs_header.xml b/packages/SystemUI/res/layout/combined_qs_header.xml
index 665c612..f3a6bbe 100644
--- a/packages/SystemUI/res/layout/combined_qs_header.xml
+++ b/packages/SystemUI/res/layout/combined_qs_header.xml
@@ -121,10 +121,12 @@
     <LinearLayout
         android:id="@+id/shade_header_system_icons"
         android:layout_width="wrap_content"
-        app:layout_constraintHeight_min="@dimen/large_screen_shade_header_min_height"
-        android:layout_height="@dimen/large_screen_shade_header_min_height"
+        android:layout_height="@dimen/shade_header_system_icons_height"
         android:clickable="true"
         android:orientation="horizontal"
+        android:gravity="center_vertical"
+        android:paddingStart="@dimen/shade_header_system_icons_padding_start"
+        android:paddingEnd="@dimen/shade_header_system_icons_padding_end"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="@id/privacy_container"
         app:layout_constraintTop_toTopOf="@id/clock">
@@ -132,13 +134,13 @@
         <com.android.systemui.statusbar.phone.StatusIconContainer
             android:id="@+id/statusIcons"
             android:layout_width="wrap_content"
-            android:layout_height="match_parent"
+            android:layout_height="wrap_content"
             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"
+            android:layout_height="wrap_content"
             app:textAppearance="@style/TextAppearance.QS.Status" />
     </LinearLayout>
 
diff --git a/packages/SystemUI/res/layout/connected_display_chip.xml b/packages/SystemUI/res/layout/connected_display_chip.xml
new file mode 100644
index 0000000..d9df91e
--- /dev/null
+++ b/packages/SystemUI/res/layout/connected_display_chip.xml
@@ -0,0 +1,48 @@
+<?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:id="@+id/connected_display_chip"
+    android:layout_width="wrap_content"
+    android:layout_height="match_parent"
+    android:layout_gravity="center_vertical|end"
+    tools:parentTag="com.android.systemui.statusbar.ConnectedDisplayChip">
+
+
+    <FrameLayout
+        android:id="@+id/icons_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:clipToPadding="false"
+        android:gravity="center"
+        android:maxWidth="@dimen/ongoing_appops_chip_max_width"
+        android:minWidth="@dimen/ongoing_appops_chip_min_width">
+
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:layout_marginHorizontal="10dp"
+            android:scaleType="centerInside"
+            android:src="@drawable/stat_sys_connected_display"
+            android:tint="@android:color/black" />
+    </FrameLayout>
+</merge>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml b/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
index 50dcaf3..bb32022 100644
--- a/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
@@ -57,7 +57,6 @@
             android:layout_width="@dimen/dream_overlay_status_bar_icon_size"
             android:layout_height="match_parent"
             android:layout_marginStart="@dimen/dream_overlay_status_icon_margin"
-            android:layout_marginTop="@dimen/dream_overlay_status_bar_marginTop"
             android:src="@drawable/ic_alarm"
             android:tint="@android:color/white"
             android:visibility="gone"
@@ -68,7 +67,6 @@
             android:layout_width="@dimen/dream_overlay_status_bar_icon_size"
             android:layout_height="match_parent"
             android:layout_marginStart="@dimen/dream_overlay_status_icon_margin"
-            android:layout_marginTop="@dimen/dream_overlay_status_bar_marginTop"
             android:src="@drawable/ic_qs_dnd_on"
             android:tint="@android:color/white"
             android:visibility="gone"
@@ -79,7 +77,6 @@
             android:layout_width="@dimen/dream_overlay_status_bar_icon_size"
             android:layout_height="match_parent"
             android:layout_marginStart="@dimen/dream_overlay_status_icon_margin"
-            android:layout_marginTop="@dimen/dream_overlay_status_bar_marginTop"
             android:src="@drawable/ic_signal_wifi_off"
             android:visibility="gone"
             android:contentDescription="@string/dream_overlay_status_bar_wifi_off" />
diff --git a/packages/SystemUI/res/layout/heads_up_status_bar_layout.xml b/packages/SystemUI/res/layout/heads_up_status_bar_layout.xml
index bacb5c1..49744e7 100644
--- a/packages/SystemUI/res/layout/heads_up_status_bar_layout.xml
+++ b/packages/SystemUI/res/layout/heads_up_status_bar_layout.xml
@@ -27,8 +27,8 @@
          view. -->
     <Space
         android:id="@+id/icon_placeholder"
-        android:layout_width="@dimen/status_bar_icon_drawing_size"
-        android:layout_height="@dimen/status_bar_icon_drawing_size"
+        android:layout_width="@dimen/status_bar_icon_size_sp"
+        android:layout_height="@dimen/status_bar_icon_size_sp"
         android:layout_gravity="center_vertical"
     />
     <TextView
diff --git a/packages/SystemUI/res/layout/immersive_mode_cling.xml b/packages/SystemUI/res/layout/immersive_mode_cling.xml
new file mode 100644
index 0000000..bfb8184
--- /dev/null
+++ b/packages/SystemUI/res/layout/immersive_mode_cling.xml
@@ -0,0 +1,91 @@
+<?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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center_vertical"
+        android:paddingBottom="24dp">
+
+    <FrameLayout
+            android:id="@+id/immersive_cling_chevron"
+            android:layout_width="76dp"
+            android:layout_height="76dp"
+            android:layout_marginTop="-24dp"
+            android:layout_centerHorizontal="true">
+
+        <ImageView
+                android:id="@+id/immersive_cling_back_bg_light"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:scaleType="center"
+                android:src="@drawable/immersive_cling_light_bg_circ" />
+
+        <ImageView
+                android:id="@+id/immersive_cling_back_bg"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:scaleType="center"
+                android:src="@drawable/immersive_cling_bg_circ" />
+
+        <ImageView
+                android:id="@+id/immersive_cling_ic_expand_more"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:paddingTop="8dp"
+                android:scaleType="center"
+                android:src="@drawable/ic_expand_more_48dp"/>
+    </FrameLayout>
+
+    <TextView
+            android:id="@+id/immersive_cling_title"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/immersive_cling_chevron"
+            android:paddingEnd="48dp"
+            android:paddingStart="48dp"
+            android:paddingTop="40dp"
+            android:text="@string/immersive_cling_title"
+            android:textColor="@android:color/white"
+            android:textSize="24sp" />
+
+    <TextView
+            android:id="@+id/immersive_cling_description"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/immersive_cling_title"
+            android:paddingEnd="48dp"
+            android:paddingStart="48dp"
+            android:paddingTop="12.6dp"
+            android:text="@string/immersive_cling_description"
+            android:textColor="@android:color/white"
+            android:textSize="16sp" />
+
+    <Button
+            android:id="@+id/ok"
+            style="@android:style/Widget.Material.Button.Borderless"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentEnd="true"
+            android:layout_below="@+id/immersive_cling_description"
+            android:layout_marginEnd="40dp"
+            android:layout_marginTop="18dp"
+            android:paddingEnd="8dp"
+            android:paddingStart="8dp"
+            android:text="@string/immersive_cling_positive"
+            android:textColor="@android:color/white"
+            android:textSize="14sp" />
+
+</RelativeLayout>
diff --git a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
index e95c6a7..91550b3 100644
--- a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
+++ b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
@@ -34,5 +34,6 @@
             android:paddingEnd="0dp"
             android:progressDrawable="@drawable/brightness_progress_drawable"
             android:splitTrack="false"
+            android:clickable="true"
         />
     </com.android.systemui.settings.brightness.BrightnessSliderView>
diff --git a/packages/SystemUI/res/layout/sidefps_view.xml b/packages/SystemUI/res/layout/sidefps_view.xml
index 73050c2..4d95220 100644
--- a/packages/SystemUI/res/layout/sidefps_view.xml
+++ b/packages/SystemUI/res/layout/sidefps_view.xml
@@ -14,7 +14,7 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<com.airbnb.lottie.LottieAnimationView
+<com.android.systemui.biometrics.SideFpsLottieViewWrapper
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/sidefps_animation"
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index 331307a0..0ab921f 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -32,7 +32,7 @@
 
     <ImageView
         android:id="@+id/notification_lights_out"
-        android:layout_width="@dimen/status_bar_icon_size"
+        android:layout_width="@dimen/status_bar_icon_size_sp"
         android:layout_height="match_parent"
         android:paddingStart="@dimen/status_bar_padding_start"
         android:paddingBottom="2dip"
diff --git a/packages/SystemUI/res/layout/status_bar_notification_footer.xml b/packages/SystemUI/res/layout/status_bar_notification_footer.xml
index db94c92..909048e 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_footer.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_footer.xml
@@ -17,10 +17,9 @@
 <!-- Extends Framelayout -->
 <com.android.systemui.statusbar.notification.row.FooterView
         xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:app="http://schemas.android.com/apk/res-auto"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:paddingStart="16dp"
-        android:paddingEnd="16dp"
         android:visibility="gone">
     <com.android.systemui.statusbar.AlphaOptimizedFrameLayout
         android:id="@+id/content"
@@ -37,31 +36,45 @@
             android:visibility="gone"
             android:textAppearance="?android:attr/textAppearanceButton"
             android:text="@string/unlock_to_see_notif_text"/>
-        <com.android.systemui.statusbar.notification.row.FooterViewButton
-            style="@style/TextAppearance.NotificationSectionHeaderButton"
-            android:id="@+id/manage_text"
-            android:layout_width="wrap_content"
-            android:layout_height="48dp"
-            android:layout_marginTop="12dp"
-            android:layout_gravity="start"
-            android:background="@drawable/notif_footer_btn_background"
-            android:focusable="true"
-            android:textColor="@color/notif_pill_text"
-            android:contentDescription="@string/manage_notifications_history_text"
-            android:text="@string/manage_notifications_history_text"
-        />
-        <com.android.systemui.statusbar.notification.row.FooterViewButton
-            style="@style/TextAppearance.NotificationSectionHeaderButton"
-            android:id="@+id/dismiss_text"
-            android:layout_width="wrap_content"
-            android:layout_height="48dp"
-            android:layout_marginTop="12dp"
-            android:layout_gravity="end"
-            android:background="@drawable/notif_footer_btn_background"
-            android:focusable="true"
-            android:textColor="@color/notif_pill_text"
-            android:contentDescription="@string/accessibility_clear_all"
-            android:text="@string/clear_all_notifications_text"
-        />
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            >
+            <com.android.systemui.statusbar.notification.row.FooterViewButton
+                style="@style/TextAppearance.NotificationSectionHeaderButton"
+                android:id="@+id/manage_text"
+                android:layout_width="wrap_content"
+                android:layout_height="48dp"
+                android:layout_marginTop="12dp"
+                android:layout_marginStart="16dp"
+                app:layout_constraintVertical_bias="0.0"
+                app:layout_constraintHorizontal_chainStyle="spread_inside"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintEnd_toStartOf="@id/dismiss_text"
+                android:background="@drawable/notif_footer_btn_background"
+                android:focusable="true"
+                android:textColor="@color/notif_pill_text"
+                android:contentDescription="@string/manage_notifications_history_text"
+                android:text="@string/manage_notifications_history_text"
+                />
+            <com.android.systemui.statusbar.notification.row.FooterViewButton
+                style="@style/TextAppearance.NotificationSectionHeaderButton"
+                android:id="@+id/dismiss_text"
+                android:layout_width="wrap_content"
+                android:layout_height="48dp"
+                android:layout_marginTop="12dp"
+                android:layout_marginEnd="16dp"
+                app:layout_constraintVertical_bias="1.0"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintStart_toEndOf="@id/manage_text"
+                android:background="@drawable/notif_footer_btn_background"
+                android:focusable="true"
+                android:textColor="@color/notif_pill_text"
+                android:contentDescription="@string/accessibility_clear_all"
+                android:text="@string/clear_all_notifications_text"
+                />
+        </androidx.constraintlayout.widget.ConstraintLayout>
     </com.android.systemui.statusbar.AlphaOptimizedFrameLayout>
 </com.android.systemui.statusbar.notification.row.FooterView>
diff --git a/packages/SystemUI/res/layout/status_bar_wifi_group_inner.xml b/packages/SystemUI/res/layout/status_bar_wifi_group_inner.xml
index 0ea0653..4c5cd7d 100644
--- a/packages/SystemUI/res/layout/status_bar_wifi_group_inner.xml
+++ b/packages/SystemUI/res/layout/status_bar_wifi_group_inner.xml
@@ -24,16 +24,17 @@
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
         android:gravity="center_vertical"
-        android:layout_marginStart="2.5dp"
+        android:layout_marginStart="2.5sp"
     >
         <FrameLayout
                 android:id="@+id/inout_container"
-                android:layout_height="17dp"
+                android:layout_height="@dimen/status_bar_wifi_inout_container_size"
                 android:layout_width="wrap_content"
                 android:gravity="center_vertical" >
             <ImageView
                 android:id="@+id/wifi_in"
-                android:layout_height="wrap_content"
+                android:layout_height="@dimen/status_bar_wifi_signal_size"
+                android:adjustViewBounds="true"
                 android:layout_width="wrap_content"
                 android:src="@drawable/ic_activity_down"
                 android:visibility="gone"
@@ -41,7 +42,8 @@
             />
             <ImageView
                 android:id="@+id/wifi_out"
-                android:layout_height="wrap_content"
+                android:layout_height="@dimen/status_bar_wifi_signal_size"
+                android:adjustViewBounds="true"
                 android:layout_width="wrap_content"
                 android:src="@drawable/ic_activity_up"
                 android:paddingEnd="2dp"
@@ -75,7 +77,7 @@
         <View
             android:id="@+id/wifi_airplane_spacer"
             android:layout_width="@dimen/status_bar_airplane_spacer_width"
-            android:layout_height="4dp"
+            android:layout_height="wrap_content"
             android:visibility="gone"
         />
     </com.android.keyguard.AlphaOptimizedLinearLayout>
diff --git a/packages/SystemUI/res/layout/udfps_keyguard_preview.xml b/packages/SystemUI/res/layout/udfps_keyguard_preview.xml
index c068b7b..0964a21 100644
--- a/packages/SystemUI/res/layout/udfps_keyguard_preview.xml
+++ b/packages/SystemUI/res/layout/udfps_keyguard_preview.xml
@@ -24,7 +24,7 @@
     android:background="@drawable/fingerprint_bg">
 
     <!-- LockScreen fingerprint icon from 0 stroke width to full width -->
-    <com.airbnb.lottie.LottieAnimationView
+    <com.android.systemui.keyguard.ui.view.UdfpsLottieViewWrapper
         android:layout_width="0dp"
         android:layout_height="0dp"
         android:scaleType="centerCrop"
diff --git a/packages/SystemUI/res/layout/udfps_keyguard_view_internal.xml b/packages/SystemUI/res/layout/udfps_keyguard_view_internal.xml
index 191158e..1d6147c 100644
--- a/packages/SystemUI/res/layout/udfps_keyguard_view_internal.xml
+++ b/packages/SystemUI/res/layout/udfps_keyguard_view_internal.xml
@@ -32,7 +32,7 @@
 
     <!-- Fingerprint -->
     <!-- AOD dashed fingerprint icon with moving dashes -->
-    <com.airbnb.lottie.LottieAnimationView
+    <com.android.systemui.keyguard.ui.view.UdfpsLottieViewWrapper
         android:id="@+id/udfps_aod_fp"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
@@ -43,7 +43,7 @@
         app:lottie_rawRes="@raw/udfps_aod_fp"/>
 
     <!-- LockScreen fingerprint icon from 0 stroke width to full width -->
-    <com.airbnb.lottie.LottieAnimationView
+    <com.android.systemui.keyguard.ui.view.UdfpsLottieViewWrapper
         android:id="@+id/udfps_lockscreen_fp"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 2fa9711..5bd2184 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Aktiveer USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Kom meer te wete"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Skermkiekie"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Verleng Ontsluiting is gedeaktiveer"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Hou Ontsluit is gedeaktiveer"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"het \'n prent gestuur"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Stoor tans skermkiekie..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Stoor tans skermskoot in werkprofiel …"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Aan/af-kieslys"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Bladsy <xliff:g id="ID_1">%1$d</xliff:g> van <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Sluitskerm"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Foon afgeskakel weens hitte"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Jou foon werk nou normaal.\nTik vir meer inligting"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Jou foon was te warm en dit het afgeskakel om af te koel. Jou foon werk nou normaal.\n\nJou foon kan dalk te warm word as jy:\n	• Hulpbron-intensiewe programme (soos dobbel-, video- of navigasieprogramme) gebruik\n	• Groot lêers af- of oplaai\n	• Jou foon in hoë temperature gebruik"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Sien versorgingstappe"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Foon raak warm"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Sommige kenmerke is beperk terwyl foon afkoel.\nTik vir meer inligting"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Jou foon sal outomaties probeer om af te koel. Jy kan steeds jou foon gebruik, maar dit sal dalk stadiger wees.\n\nJou foon sal normaalweg werk nadat dit afgekoel het."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Sien versorgingstappe"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Prop jou toestel uit"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Jou toestel word tans warm naby die laaipoort. Prop dit uit as dit aan ’n laaier of USB-bykomstigheid gekoppel is. Wees versigtig, aangesien die kabel dalk ook warm is."</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 6d6b435..f2eb766 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"ዩኤስቢ አንቃ"</string>
     <string name="learn_more" msgid="4690632085667273811">"የበለጠ ለመረዳት"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"ቅጽበታዊ ገፅ እይታ"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"መክፈትን አራዝም ተሰናክሏል"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock ተሰናክሏል"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ምስል ተልኳል"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"ቅጽበታዊ ገፅ እይታ በማስቀመጥ ላይ..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"ቅጽበታዊ ገፅ እይታን ወደ የስራ መገለጫ በማስቀመጥ ላይ…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"የኃይል ምናሌ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ገፅ <xliff:g id="ID_1">%1$d</xliff:g> ከ <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"ማያ ገፅ ቁልፍ"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"ስልክ በሙቀት ምክንያት ጠፍቷል"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"የእርስዎ ስልክ በመደበኛ ሁኔታ እየሠራ ነው።\nለተጨማሪ መረጃ መታ ያድርጉ"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"የእርስዎ ስልክ በጣም ግሎ ነበር፣ ስለዚህ እንዲቀዘቅዝ ጠፍቷል። የእርስዎ ስልክ አሁን በመደበኝነት እያሄደ ነው።\n\nየሚከተሉትን ካደረጉ የእርስዎ በጣም ሊግል ይችላል፦\n	• ኃይል በጣም የሚጠቀሙ መተግበሪያዎችን (እንደ ጨዋታ፣ ቪዲዮ ወይም የአሰሳ መተግበሪያዎች ያሉ) ከተጠቀሙ\n	• ትላልቅ ፋይሎችን ካወረዱ ወይም ከሰቀሉ\n	• ስልክዎን በከፍተኛ ሙቀት ውስጥ ከተጠቀሙ"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"የእንክብካቤ ደረጃዎችን ይመልከቱ"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"ስልኩ እየሞቀ ነው"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"አንዳንድ ባሕሪያት ስልኩ እየቀዘቀዘ እያለ ውስን ይሆናሉ።\nለተጨማሪ መረጃ መታ ያድርጉ"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"የእርስዎ ስልክ በራስ-ሰር ለመቀዝቀዝ ይሞክራል። አሁንም ስልክዎን መጠቀም ይችላሉ፣ ነገር ግን ሊንቀራፈፍ ይችላል።\n\nአንዴ ስልክዎ ከቀዘቀዘ በኋላ በመደበኝነት ያሄዳል።"</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"የእንክብካቤ ደረጃዎችን ይመልከቱ"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"መሣሪያዎን ይንቀሉ"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"መሣሪያዎ ከኃይል መሙያ ወደቡ አቅራቢያ እየሞቀ ነው። ከኃይል መሙያ ወይም ከዩኤስቢ ተጨማሪ መሣሪያ ጋር ከተገናኘ ይንቀሉት እና ገመዱ የሞቀ ሊሆን ስለሚችል ጥንቃቄ ያድርጉ።"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 614b968..9a74144 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"‏تفعيل USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"مزيد من المعلومات"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"لقطة شاشة"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"‏تم إيقاف ميزة Extend Unlock."</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"تم إيقاف ميزة \"إبقاء الجهاز مفتوحًا\"."</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"أرسَل صورة"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"جارٍ حفظ لقطة الشاشة..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"جارٍ حفظ لقطة الشاشة في الملف الشخصي للعمل…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"قائمة زر التشغيل"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"الصفحة <xliff:g id="ID_1">%1$d</xliff:g> من <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"شاشة القفل"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"تم إيقاف الهاتف بسبب الحرارة"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"يعمل هاتفك الآن بشكل طبيعي.\nانقر للحصول على مزيد من المعلومات."</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"ارتفعت درجة حرارة هاتفك بشدة، لذا تم إيقاف تشغيله لخفض درجة حرارته. يعمل هاتفك الآن بشكل طبيعي.\n\nقد ترتفع بشدة درجة حرارة هاتفك إذا:\n	• استخدمت تطبيقات كثيفة الاستخدام لموارد الجهاز (مثل الألعاب أو الفيديو أو تطبيقات التنقل)\n	• نزَّلت أو حمَّلت ملفات كبيرة الحجم\n	• استخدمت هاتفك وسط أجواء مرتفعة الحرارة"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"الاطّلاع على خطوات العناية"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"تزداد درجة حرارة الهاتف"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"يتم تقييد عمل بعض الميزات إلى أن تنخفض درجة حرارة الهاتف.\nانقر للحصول على مزيد من المعلومات."</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"سيحاول الهاتف تخفيض درجة حرارته تلقائيًا. سيظل بإمكانك استخدام هاتفك، ولكن قد يعمل بشكل أبطأ.\n\nبعد أن تنخفض درجة حرارة الهاتف، سيستعيد سرعته المعتادة."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"الاطّلاع على خطوات العناية"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"افصِل جهازك"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"‏تزداد حرارة الجهاز بالقرب من منفذ الشحن. إذا كان الجهاز متصلاً بشاحن أو ملحق USB، عليك فصله وتوخي الحذر لأن درجة حرارة الكابل قد تكون مرتفعة أيضًا."</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 06c9f53d..856989c 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB সক্ষম কৰক"</string>
     <string name="learn_more" msgid="4690632085667273811">"অধিক জানক"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"স্ক্ৰীনশ্বট"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock অক্ষম কৰা আছে"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"এক্সটেণ্ড আনলক অক্ষম কৰা আছে"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"এখন প্ৰতিচ্ছবি পঠিয়াইছে"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"স্ক্ৰীনশ্বট ছেভ কৰি থকা হৈছে…"</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"কৰ্মস্থানৰ প্ৰ’ফাইলত স্ক্ৰীনশ্বট ছেভ কৰি থকা হৈছে…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"পাৱাৰ মেনু"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g>ৰ পৃষ্ঠা <xliff:g id="ID_1">%1$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"লক স্ক্ৰীন"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"আপোনাৰ ফ\'নটো গৰম হোৱাৰ কাৰণে অফ কৰা হৈছিল"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"আপোনাৰ ফ’নটো এতিয়া স্বাভাৱিকভাৱে চলি আছে।\nঅধিক তথ্যৰ বাবে টিপক"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"আপোনাৰ ফ\'নটো অত্যধিক গৰম হোৱাৰ বাবে ইয়াক ঠাণ্ডা কৰিবলৈ অফ কৰা হৈছিল। আপোনাৰ ফ\'নটো এতিয়া স্বাভাৱিকভাৱে চলি আছে।\n\nআপোনাৰ ফ\'নটো গৰম হ\'ব পাৰে, যদিহে আপুনি:\n	• ফ\'নটোৰ হাৰ্ডৱেৰ অত্যধিক মাত্ৰাত ব্যৱহাৰ কৰা এপ্‌সমূহ চলালে (যেনে, ভিডিঅ\' গেইম, ভিডিঅ\', দিক্-নিৰ্দেশনা এপ্‌সমূহ)\n	• খুউব ডাঙৰ আকাৰৰ ফাইল আপল\'ড বা ডাউনল’ড কৰিলে\n	• আপোনাৰ ফ\'নটো উচ্চ তাপমাত্ৰাৰ পৰিৱেশত ব্যৱহাৰ কৰিলে"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"যত্ন লোৱাৰ পদক্ষেপসমূহ চাওক"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"ফ\'নটো গৰম হ\'বলৈ ধৰিছে"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"ফ’নটো ঠাণ্ডা হৈ থকাৰ সময়ত কিছুমান সুবিধা উপলব্ধ নহয়।\nঅধিক তথ্যৰ বাবে টিপক"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"আপোনাৰ ফ\'নটোৱে নিজে নিজে ঠাণ্ডা হ\'বলৈ স্বয়ংক্ৰিয়ভাৱে চেষ্টা কৰিব। আপুনি ফ\'নটো ব্যৱহাৰ কৰি থাকিব পাৰে কিন্তু ই লাহে লাহে চলিব পাৰে।\n\nফ\'নটো সম্পূৰ্ণভাৱে ঠাণ্ডা হোৱাৰ পাছত ই আগৰ নিচিনাকৈয়েই চলিব।"</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"যত্ন লোৱাৰ পদক্ষেপসমূহ চাওক"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"আপোনাৰ ডিভাইচটো আনপ্লাগ কৰক"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"আপোনাৰ ডিভাইচটো চাৰ্জিং প’ৰ্টৰ ওচৰত গৰম হৈছে। যদি এইটো কোনো চার্জাৰ অথবা ইউএছবিৰ সহায়ক সামগ্ৰীৰ সৈতে সংযুক্ত হৈ আছে, ইয়াক আনপ্লাগ কৰক আৰু কে’বলডালো গৰম হ\'ব পাৰে, গতিকে যত্ন লওক।"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index a413e6b..1c14b04e 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB-ni aktiv edin"</string>
     <string name="learn_more" msgid="4690632085667273811">"Ətraflı məlumat"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Skrinşot"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock deaktiv edilib"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Uzaqdan kiliddən çıxarma deaktiv edilib"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"şəkil göndərdi"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Skrinşot yadda saxlanır..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"İş profili skrinşotu saxlanılır…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Qidalanma düyməsi menyusu"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> səhifədən <xliff:g id="ID_1">%1$d</xliff:g> səhifə"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Ekran kilidi"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"İstiliyə görə telefon söndü"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Telefonunuz indi normal işləyir.\nƏtraflı məlumat üçün toxunun"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefon çox isti idi və soyumaq üçün söndü. Hazırda telefon normal işləyir.\n\n Telefon bu hallarda çox isti ola bilər:\n 	• Çox resurslu tətbiq istifadə etsəniz (oyun, video və ya naviqasiya tətbiqi kimi)\n	• Böyük həcmli fayl endirsəniz və ya yükləsəniz\n	• Telefonu yüksək temperaturda istifadə etsəniz"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Ehtiyat tədbiri mərhələlərinə baxın"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Telefon qızmağa başlayır"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Telefon soyuyana kimi bəzi funksiyalar məhdudlaşdırılır.\nƏtraflı məlumat üçün toxunun"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Telefonunuz avtomatik olaraq soyumağa başlayacaq. Telefon istifadəsinə davam edə bilərsiniz, lakin sürəti yavaşlaya bilər.\n\nTelefonunuz soyuduqdan sonra normal işləyəcək."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Ehtiyat tədbiri mərhələlərinə baxın"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Cihazınızı ayırın"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Cihazınız şarj portunun yaxınlığında qızmağa başlayır. Şarj cihazına və ya USB aksesuarına qoşulubsa, onu ayırın və diqqətli olun, çünki kabel də qıza bilər."</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 3d52d51..c00cd6a 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Meni dugmeta za uključivanje"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>. strana od <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Zaključan ekran"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon se isključio zbog toplote"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Telefon sada normalno radi.\nDodirnite za više informacija"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefon je bio prevruć, pa se isključio da se ohladi. Sada radi normalno.\n\nTelefon može previše da se ugreje ako:\n	• Koristite aplikacije koje zahtevaju puno resursa (npr. video igre, video ili aplikacije za navigaciju)\n	• Preuzimate/otpremate velike datoteke\n	• Koristite telefon na visokoj temperaturi"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Pogledajte upozorenja"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Telefon se zagrejao"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Neke funkcije su ograničene dok se telefon ne ohladi.\nDodirnite za više informacija"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Telefon će automatski pokušati da se ohladi. I dalje ćete moći da koristite telefon, ali će sporije reagovati.\n\nKada se telefon ohladi, normalno će raditi."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Pogledajte upozorenja"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Isključite uređaj"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Uređaj se zagreva u blizini porta za punjenje. Ako je povezan sa punjačem ili USB opremom, isključite je i budite pažljivi jer i kabl može da bude vruć."</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 5f2d7b5..95eebad 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Уключыць USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Даведацца больш"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Здымак экрана"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Функцыя падоўжанай разблакіроўкі адключана"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Функцыя працяглай разблакіроўкі адключана"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"адпраўлены відарыс"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Захаванне скрыншота..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Захаванне здымка экрана ў працоўны профіль…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Меню кнопкі сілкавання"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Старонка <xliff:g id="ID_1">%1$d</xliff:g> з <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Экран блакіроўкі"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"З-за перагрэву тэл. выключыўся"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Ваш тэлефон працуе нармальна.\nНацісніце, каб даведацца больш"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Ваш тэлефон пераграваўся, таму ён выключыўся, каб астыць. Зараз тэлефон працуе нармальна.\n\nТэлефон можа перагравацца пры:\n	• Выкарыстанні рэсурсаёмістых праграм (напрыклад, гульняў, відэа або праграм навігацыі)\n	• Спампоўцы або запампоўцы вялікіх файлаў\n	• Выкарыстанні тэлефона пры высокіх тэмпературах"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Глядзець паэтапную дапамогу"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Тэлефон награваецца"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Некаторыя функцыі абмежаваны, пакуль тэлефон не астыне.\nНацісніце, каб даведацца больш"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Ваш тэлефон аўтаматычна паспрабуе астыць. Вы можаце па-ранейшаму карыстацца сваім тэлефонам, але ён можа працаваць больш павольна.\n\nПасля таго як ваш тэлефон астыне, ён будзе працаваць у звычайным рэжыме."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Глядзець паэтапную дапамогу"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Адключыце прыладу"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Ваша прылада моцна награваецца ў месцы, дзе знаходзіцца зарадны порт. Калі яна падключана да зараднай прылады ці USB-прылады, адключыце яе і будзьце асцярожнымі з кабелем, які таксама можа награвацца."</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 9201f40..567a22b 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Меню за включване/изключване"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Страница <xliff:g id="ID_1">%1$d</xliff:g> от <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Заключен екран"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Тел. се изкл. поради загряване"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Телефонът ви вече работи нормално.\nДокоснете за още информация"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Телефонът ви бе твърде горещ, затова се изключи с цел охлаждане. Вече работи нормално.\n\nТелефонът ви може да стане твърде горещ, ако:\n	• използвате приложения, които ползват голям обем ресурси (като например игри, видеосъдържание или приложения за навигация);\n	• изтегляте или качвате големи файлове;\n	• използвате устройството си при високи температури."</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Вижте стъпките, които да предприемете"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Телефонът загрява"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Някои функции са ограничени, докато телефонът се охлажда.\nДокоснете за още информация"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Телефонът ви автоматично ще направи опит за охлаждане. Пак можете да го използвате, но той може да работи по-бавно.\n\nСлед като се охлади, ще работи нормално."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Вижте стъпките, които да предприемете"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Изключете устройството си"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Устройството ви се загрява до порта за зареждане. Ако е свързано със зарядно устройство или аксесоар за USB, изключете го и внимавайте, тъй като и кабелът може да е топъл."</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index d8cb70d..38308e2 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"পাওয়ার মেনু"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g>টির মধ্যে <xliff:g id="ID_1">%1$d</xliff:g> নং পৃষ্ঠা"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"লক স্ক্রিন"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"আপনার ফোন গরম হওয়ার জন্য বন্ধ হয়ে গেছে"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"আপনার ফোন এখন ভালভাবে কাজ করছে।\nআরও তথ্যের জন্য ট্যাপ করুন"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"আপনার ফোন খুব বেশি গরম হয়েছিল বলে ঠাণ্ডা হওয়ার জন্য বন্ধ হয়ে গেছে। আপনার ফোন ঠিক-ঠাক ভাবে চলছে না।\n\nআপনার ফোন খুব বেশি গরম হয়ে যাবে যদি আপনি:\n	•এমন অ্যাপ ব্যবহার করলে যেটি আপনার ডিভাইসের রিসোর্স বেশি ব্যবহার করে (যেমন গেমিং, ভিডিও বা নেভিগেশন অ্যাপ)\n	• বড় ফাইল ডাউনলোড বা আপলোড করলে\n	• বেশি তাপমাত্রায় আপনার ফোন ব্যবহার করলে"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"ডিভাইস রক্ষণাবেক্ষণের ধাপগুলি দেখুন"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"ফোনটি গরম হচ্ছে"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"ফোন ঠাণ্ডা না হওয়া পর্যন্ত কিছু ফিচার কাজ করে না।\nআরও তথ্যের জন্য ট্যাপ করুন"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"আপনার ফোনটি নিজে থেকেই ঠাণ্ডা হওয়ার চেষ্টা করবে৷ আপনি তবুও আপনার ফোন ব্যবহার করতে পারেন, কিন্তু এটি একটু ধীরে চলতে পারে৷\n\nআপনার ফোনটি পুরোপুরি ঠাণ্ডা হয়ে গেলে এটি স্বাভাবিকভাবে চলবে৷"</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"ডিভাইস রক্ষণাবেক্ষণের ধাপগুলি দেখুন"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"আপনার ডিভাইস আনপ্লাগ করা"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"চার্জিং পোর্টের কাছে আপনার ডিভাইসটি গরম হচ্ছে। এটি চার্জার বা ইউএসবি অ্যাক্সেসরির সাথে কানেক্ট করা থাকলে, আনপ্লাগ করুন এবং সতর্ক থাকুন কারণ কেবেলটিও গরম হতে পারে।"</string>
@@ -988,7 +982,7 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"অডিও আউটপুটের জন্য উপলভ্য ডিভাইস।"</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"ভলিউম"</string>
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
-    <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"স্পিকার &amp; ডিসপ্লে"</string>
+    <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"স্পিকার ও ডিসপ্লে"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"সাজেস্ট করা ডিভাইস"</string>
     <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"অন্য ডিভাইসে মিডিয়া সরাতে আপনার শেয়ার করা সেশন বন্ধ করুন"</string>
     <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"বন্ধ করুন"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 89c964d..eaa0d9d 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Meni napajanja"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Stranica <xliff:g id="ID_1">%1$d</xliff:g> od <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Zaključani ekran"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon se isključio zbog pregrijavanja"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Vaš telefon sada radi normalno.\nDodirnite za više informacija"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Vaš telefon se pregrijao, pa se isključio da se ohladi. Telefon sada radi normalno.\n\nTelefon se može pregrijati ako:\n	• Koristite aplikacije koje troše puno resursa (kao što su aplikacije za igranje, videozapise ili navigaciju)\n	• Preuzimate ili otpremate velike fajlove\n	• Koristite telefon na visokim temperaturama"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Pogledajte korake za zaštitu"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Telefon se pregrijava"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Neke funkcije su ograničene dok se telefon hladi.\nDodirnite za više informacija"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Vaš telefon će se automatski pokušati ohladiti. I dalje možete koristi telefon, ali će možda raditi sporije.\n\nNakon što se ohladi, telefon će normalno raditi."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Pogledajte korake za zaštitu"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Iskopčajte uređaj"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Uređaj se zagrijava u blizini priključka za punjenje. Ako je povezan s punjačem ili USB dodatkom, iskopčajte ga i vodite računa jer i kabl može biti topao."</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index e0e78ae..6416543 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Activa l\'USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Més informació"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Captura de pantalla"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock desactivat"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Desbloqueig ampliat desactivat"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ha enviat una imatge"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"S\'està desant la captura de pantalla..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"S\'està desant la captura al perfil de treball…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menú d\'engegada"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Pàgina <xliff:g id="ID_1">%1$d</xliff:g> (<xliff:g id="ID_2">%2$d</xliff:g> en total)"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Pantalla de bloqueig"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telèfon apagat per la calor"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Ara el telèfon funciona correctament.\nToca per obtenir més informació"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"El telèfon s\'havia sobreescalfat i s\'ha apagat per refredar-se. Ara funciona amb normalitat.\n\nEs pot sobreescalfar si:\n	• utilitzes aplicacions que consumeixen molts recursos (com ara, videojocs, vídeos o aplicacions de navegació);\n	• baixes o penges fitxers grans;\n	• l\'utilitzes amb temperatures altes."</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Mostra els passos de manteniment"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"El telèfon s\'està escalfant"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Algunes funcions estan limitades mentre el telèfon es refreda.\nToca per obtenir més informació"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"El telèfon provarà de refredar-se automàticament. Podràs continuar utilitzant-lo, però és possible que funcioni més lentament.\n\nUn cop s\'hagi refredat, funcionarà amb normalitat."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Mostra els passos de manteniment"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Desconnecta el dispositiu"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"El dispositiu s\'està escalfant a prop del port de càrrega. Si està connectat a un carregador o a un accessori USB, desconnecta\'l. Ves amb compte perquè el cable també pot haver-se escalfat."</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 522300b..56ae4b8 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Aktivovat USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Další informace"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Snímek obrazovky"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Prodloužení odemknutí deaktivováno"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Rozšíření odemknutí deaktivováno"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"odesílá obrázek"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Ukládání snímku obrazovky..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Ukládání snímku obrazovky do pracovního profilu…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Nabídka vypínače"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Stránka <xliff:g id="ID_1">%1$d</xliff:g> z <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Obrazovka uzamčení"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon se vypnul z důvodu zahřátí"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Nyní telefon funguje jako obvykle.\nKlepnutím zobrazíte další informace"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefon byl příliš zahřátý, proto se vypnul, aby vychladl. Nyní telefon funguje jako obvykle.\n\nTelefon se může příliš zahřát v těchto případech:\n	• používání náročných aplikací (např. her, videí nebo navigace),\n	• stahování nebo nahrávání velkých souborů,\n	• používání telefonu při vysokých teplotách."</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Zobrazit pokyny, co dělat"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Telefon se zahřívá"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Některé funkce jsou při chladnutí telefonu omezeny.\nKlepnutím zobrazíte další informace"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Telefon se automaticky pokusí vychladnout. Lze jej nadále používat, ale může být pomalejší.\n\nAž telefon vychladne, bude fungovat normálně."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Zobrazit pokyny, co dělat"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Odpojte zařízení"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Zařízení se zahřívá v oblasti nabíjecího portu. Pokud je připojeno k nabíječce nebo příslušenství USB, odpojte ho (dejte pozor, kabel také může být zahřátý)."</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index e9a522f..0ce9932 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Aktivér USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Få flere oplysninger"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Screenshot"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Hold oplåst er deaktiveret"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Hold ulåst er deaktiveret"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"sendte et billede"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Gemmer screenshot..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Gemmer screenshot på din arbejdsprofil…"</string>
@@ -661,12 +661,12 @@
     <string name="group_system_access_system_settings" msgid="7961639365383008053">"Åbn systemindstillinger"</string>
     <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Åbn Google Assistent"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Lås skærm"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Hent appen Notes for at skrive et hurtigt notat"</string>
+    <string name="group_system_quick_memo" msgid="2914234890158583919">"Åbn appen Notes for at skrive et hurtigt notat"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Systemmultitasking"</string>
     <string name="system_multitasking_rhs" msgid="6593269428880305699">"Start opdelt skærm med aktuel app til højre"</string>
     <string name="system_multitasking_lhs" msgid="8839380725557952846">"Start opdelt skærm med aktuel app til venstre"</string>
     <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Skift fra opdelt skærm til fuld skærm"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Ved opdelt skærm: Erstat en app med én app ad gangen"</string>
+    <string name="system_multitasking_replace" msgid="844285282472557186">"Ved opdelt skærm: Erstat en app med en anden app"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
     <string name="input_switch_input_language_next" msgid="3394291576873633793">"Skift inputsprog (næste sprog)"</string>
     <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Skift inputsprog (forrige sprog)"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu for afbryderknappen"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Side <xliff:g id="ID_1">%1$d</xliff:g> af <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Låseskærm"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefonen slukkede pga. varme"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Din telefon kører nu normalt.\nTryk for at få flere oplysninger"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Din telefon var blevet for varm, så den slukkede for at køle ned. Din telefon kører nu igen normalt. \n\nDin telefon kan blive for varm, hvis du:\n	• Bruger ressourcekrævende apps (f.eks. spil, video eller navigation)\n	• Downloader eller uploader store filer\n	• Bruger din telefon i varme omgivelser"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Se håndteringsvejledning"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Telefonen er ved at blive varm"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Nogle funktioner er begrænsede, mens telefonen køler ned.\nTryk for at få flere oplysninger"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Din telefon forsøger automatisk at køle ned. Du kan stadig bruge telefonen, men den kører muligvis langsommere.\n\nNår din telefon er kølet ned, fungerer den normalt igen."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Se håndteringsvejledning"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Træk stikket ud af din enhed"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Din enhed er ved at blive varm i nærheden af opladningsporten. Hvis enheden er tilsluttet en oplader eller USB-enhed, skal du trække stikket ud. Vær opmærksom på, at stikket også kan være varmt."</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index dc06ee1..ef76528 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Ein-/Aus-Menü"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Seite <xliff:g id="ID_1">%1$d</xliff:g> von <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Sperrbildschirm"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Ausgeschaltet, da zu heiß"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Dein Smartphone funktioniert jetzt wieder normal.\nFür mehr Informationen tippen."</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Dein Smartphone war zu heiß und wurde zum Abkühlen ausgeschaltet. Nun funktioniert es wieder normal.\n\nMögliche Ursachen:\n	• Verwendung ressourcenintensiver Apps (z. B. Spiele-, Video- oder Navigations-Apps)\n	• Download oder Upload großer Dateien \n	• Verwendung des Smartphones bei hohen Temperaturen"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Schritte zur Abkühlung des Geräts ansehen"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Smartphone wird warm"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Einige Funktionen sind während der Abkühlphase des Smartphones eingeschränkt.\nFür mehr Informationen tippen."</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Dein Smartphone kühlt sich automatisch ab. Du kannst dein Smartphone weiterhin nutzen, aber es reagiert möglicherweise langsamer.\n\nSobald dein Smartphone abgekühlt ist, funktioniert es wieder normal."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Schritte zur Abkühlung des Geräts ansehen"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Gerät vom Stromnetz trennen"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Dein Gerät erwärmt sich am Ladeanschluss. Trenne das Gerät vom Stromnetz, wenn es an ein Ladegerät oder USB-Zubehör angeschlossen ist. Sei vorsichtig, denn das Kabel könnte ebenfalls heiß sein."</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 08d5b4b..2c4b332 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Ενεργοποίηση USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Μάθετε περισσότερα"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Στιγμιότυπο οθόνης"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Το εκτεταμένο ξεκλείδωμα είναι απενεργοποιημένο"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Η Επέκταση ξεκλειδώματος είναι απενεργοποιημένη"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"έστειλε μια εικόνα"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Αποθήκευση στιγμιότυπου οθόνης..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Αποθήκευση στιγμιότ. οθόνης στο προφίλ εργασίας…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Μενού λειτουργίας"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Σελίδα <xliff:g id="ID_1">%1$d</xliff:g> από <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Οθόνη κλειδώματος"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Το τηλέφωνο απεν. λόγω ζέστης"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Το τηλέφωνο λειτουργεί πλέον κανονικά.\nΠατήστε για περισσότερες πληροφορίες."</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Η θερμοκρασία του τηλεφώνου είναι πολύ υψηλή και απενεργοποιήθηκε για να κρυώσει. Πλέον, λειτουργεί κανονικά.\n\nΗ θερμοκρασία ενδέχεται να ανέβει κατά τη:\n	• Χρήση εφαρμογών υψηλής κατανάλωσης πόρων (όπως gaming, βίντεο ή περιήγησης)\n	• Λήψη/μεταφόρτωση μεγάλων αρχείων\n	• Χρήση σε υψηλές θερμοκρασίες"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Δείτε βήματα αντιμετώπισης."</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Αύξηση θερμοκρασίας τηλεφώνου"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Ορισμένες λειτουργίες περιορίζονται κατά τη μείωση της θερμοκρασίας.\nΠατήστε για περισσότερες πληροφορίες."</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Το τηλέφωνό σας θα προσπαθήσει να μειώσει αυτόματα τη θερμοκρασία. Μπορείτε να εξακολουθήσετε να το χρησιμοποιείτε, αλλά είναι πιθανό να λειτουργεί πιο αργά.\n\nΜόλις μειωθεί η θερμοκρασία του τηλεφώνου σας, θα λειτουργεί ξανά κανονικά."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Δείτε βήματα αντιμετώπισης."</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Αποσυνδέστε τη συσκευή"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Η συσκευή έχει αρχίσει να ζεσταίνεται κοντά στη θύρα φόρτισης. Αν είναι συνδεδεμένη σε φορτιστή ή αξεσουάρ USB, αποσυνδέστε την και προσέξτε γιατί και το καλώδιο μπορεί να έχει ζεσταθεί."</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index e4719e4..03d2a51 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Phone turned off due to heat"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Your phone is now running normally.\nTap for more info"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Your phone was too hot, so it turned off to cool down. Your phone is now running normally.\n\nYour phone may get too hot if you:\n	• Use resource-intensive apps (such as gaming, video or navigation apps)\n	• Download or upload large files\n	• Use your phone in high temperatures"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"See care steps"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Phone is getting warm"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Some features are limited while phone cools down.\nTap for more info"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Your phone will automatically try to cool down. You can still use your phone, but it may run more slowly.\n\nOnce your phone has cooled down, it will run normally."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"See care steps"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Unplug your device"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Your device is getting warm near the charging port. If it’s connected to a charger or USB accessory, unplug it and take care as the cable may also be warm."</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 43d58ca..f328508 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Phone turned off due to heat"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Your phone is now running normally.\nTap for more info"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Your phone was too hot, so it turned off to cool down. Your phone is now running normally.\n\nYour phone may get too hot if you:\n	• Use resource-intensive apps (such as gaming, video, or navigation apps)\n	• Download or upload large files\n	• Use your phone in high temperatures"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"See care steps"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Phone is getting warm"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Some features limited while phone cools down.\nTap for more info"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Your phone will automatically try to cool down. You can still use your phone, but it may run slower.\n\nOnce your phone has cooled down, it will run normally."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"See care steps"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Unplug your device"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Your device is getting warm near the charging port. If it’s connected to a charger or USB accessory, unplug it, and take care as the cable may also be warm."</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index e4719e4..03d2a51 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Phone turned off due to heat"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Your phone is now running normally.\nTap for more info"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Your phone was too hot, so it turned off to cool down. Your phone is now running normally.\n\nYour phone may get too hot if you:\n	• Use resource-intensive apps (such as gaming, video or navigation apps)\n	• Download or upload large files\n	• Use your phone in high temperatures"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"See care steps"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Phone is getting warm"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Some features are limited while phone cools down.\nTap for more info"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Your phone will automatically try to cool down. You can still use your phone, but it may run more slowly.\n\nOnce your phone has cooled down, it will run normally."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"See care steps"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Unplug your device"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Your device is getting warm near the charging port. If it’s connected to a charger or USB accessory, unplug it and take care as the cable may also be warm."</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index e4719e4..03d2a51 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Phone turned off due to heat"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Your phone is now running normally.\nTap for more info"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Your phone was too hot, so it turned off to cool down. Your phone is now running normally.\n\nYour phone may get too hot if you:\n	• Use resource-intensive apps (such as gaming, video or navigation apps)\n	• Download or upload large files\n	• Use your phone in high temperatures"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"See care steps"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Phone is getting warm"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Some features are limited while phone cools down.\nTap for more info"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Your phone will automatically try to cool down. You can still use your phone, but it may run more slowly.\n\nOnce your phone has cooled down, it will run normally."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"See care steps"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Unplug your device"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Your device is getting warm near the charging port. If it’s connected to a charger or USB accessory, unplug it and take care as the cable may also be warm."</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index b4c5d10..ed958d8 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‎‎‎‏‎‏‎‏‏‎‏‎‎‎‏‏‎‎‏‎‏‎‎‎‏‎‎‎‎‎‎‏‎‎‏‏‏‏‏‏‎‎‏‏‎‎‎Power menu‎‏‎‎‏‎"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‏‎‏‏‏‏‎‏‎‎‎‎‏‎‏‎‏‎‎‏‏‏‎‎‏‏‎‎‏‎‏‏‎‏‎‏‎‏‎‏‏‎‎‏‎‏‏‏‎‎‎‏‎Page ‎‏‎‎‏‏‎<xliff:g id="ID_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ of ‎‏‎‎‏‏‎<xliff:g id="ID_2">%2$d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‎‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎‏‎‎‏‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‏‎‎‏‏‏‎‎‎‎‎‎Lock screen‎‏‎‎‏‎"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‏‏‏‏‎‎‎‎‏‎‎‎‏‎‏‏‎‎‏‏‎‎‎‎‎‎‎‎‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‎‎‎Phone turned off due to heat‎‏‎‎‏‎"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‏‏‎‎‎‎‎‎‎‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‎‎‎‏‏‏‎‎‎‏‏‏‎‎‎‎Your phone is now running normally.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Tap for more info‎‏‎‎‏‎"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‏‏‏‎‏‎‏‏‏‏‏‎‎‎‎‎‏‎‎‏‏‎‎‎‎‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‏‏‎Your phone was too hot, so it turned off to cool down. Your phone is now running normally.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Your phone may get too hot if you:‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎	• Use resource-intensive apps (such as gaming, video, or navigation apps)‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎	• Download or upload large files‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎	• Use your phone in high temperatures‎‏‎‎‏‎"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‎‎‎‎‏‎‎‏‏‏‏‎‏‎‎‏‎‏‎‎‏‏‎‏‎‎‏‏‏‎‏‎‏‏‎‎‏‎‏‏‎‎‎‎‎‎‏‏‏‎‏‎‏‎See care steps‎‏‎‎‏‎"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‎‏‏‎‏‎‏‎‏‎‎‎‏‎‏‎‎‎‏‎‎‎‏‏‎‎‎‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎Phone is getting warm‎‏‎‎‏‎"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‏‎‏‎‎‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‏‎‎‏‎‏‎‏‎‏‎‏‎‎‎‎‎‎‏‏‏‎‏‎‎‎‎‏‏‎‏‎Some features limited while phone cools down.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Tap for more info‎‏‎‎‏‎"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‏‎‎‏‎‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‏‏‏‏‎‏‎‎‎‏‏‏‏‏‎‏‎‏‎‎‎‎‎Your phone will automatically try to cool down. You can still use your phone, but it may run slower.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Once your phone has cooled down, it will run normally.‎‏‎‎‏‎"</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‏‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎‏‎‏‏‏‏‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‏‎‏‏‎‏‏‎‎‎‎‏‎‎See care steps‎‏‎‎‏‎"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‎‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‏‏‏‏‏‎‎‎‎‎‏‏‎‎‎‏‎‎‏‎Unplug your device‎‏‎‎‏‎"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‏‏‏‏‎‎‎‏‏‎‎‎‏‎‏‎‎‏‏‏‏‏‎‎‎‏‏‎‏‏‎‏‏‏‏‎‏‏‏‏‎‎‎‎‎‏‏‏‎‏‏‎‎‎Your device is getting warm near the charging port. If it’s connected to a charger or USB accessory, unplug it, and take care as the cable may also be warm.‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 0678e68..91b6be6 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -414,7 +414,7 @@
     <string name="media_projection_entry_generic_permission_dialog_continue" msgid="8640381403048097116">"Iniciar"</string>
     <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Bloqueada por tu administrador de TI"</string>
     <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"La captura de pantalla está inhabilitada debido a la política del dispositivo"</string>
-    <string name="clear_all_notifications_text" msgid="348312370303046130">"Borrar todo"</string>
+    <string name="clear_all_notifications_text" msgid="348312370303046130">"Cerrar todo"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Administrar"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Historial"</string>
     <string name="notification_section_header_incoming" msgid="850925217908095197">"Nuevo"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menú de encendido"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Pantalla de bloqueo"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"El teléfono se apagó por calor"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Tu teléfono ahora se ejecuta con normalidad.\nPresiona para obtener más información"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Tu teléfono estaba muy caliente y se apagó para enfriarse. Ya funciona correctamente.\n\nTu teléfono puede calentarse en estos casos:\n	• Usas apps que consumen muchos recursos (como juegos, videos o navegación).\n	• Subes o descargas archivos grandes.\n	• Usas el teléfono en condiciones de temperatura alta."</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Ver pasos de mantenimiento"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"El teléfono se está calentando"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Algunas funciones se limitan durante el enfriamiento del teléfono.\nPresiona para obtener más información"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Tu teléfono intentará enfriarse automáticamente. Podrás usarlo, pero es posible que funcione más lento.\n\nUna vez que se haya enfriado, volverá a funcionar correctamente."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Ver pasos de mantenimiento"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Desenchufa el dispositivo"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"El puerto de carga del dispositivo se está calentando. Si está conectado a un cargador o accesorio USB, desenchúfalo con cuidado, ya que el cable también puede estar caliente."</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 0dfd63c..178c8b1 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Habilitar USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Más información"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Captura de pantalla"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock inhabilitado"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Prolongar Desbloqueo inhabilitado"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ha enviado una imagen"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Guardando captura..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Guardando captura en el perfil de trabajo…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menú de encendido"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Pantalla de bloqueo"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Teléfono apagado por calor"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"El teléfono ya funciona con normalidad.\nToca para ver más información"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"El teléfono se había calentado demasiado y se ha apagado para enfriarse. Ahora funciona con normalidad.\n\nPuede calentarse demasiado si:\n	• Usas aplicaciones que consumen muchos recursos (p. ej., apps de juegos, vídeos o navegación)\n	• Descargas o subes archivos grandes\n	• Lo usas a altas temperaturas"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Ver pasos de mantenimiento"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"El teléfono se está calentando"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Se han limitado algunas funciones mientras el teléfono se enfría.\nToca para ver más información"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"El teléfono intentará enfriarse. Puedes seguir utilizándolo, pero es posible que funcione con mayor lentitud.\n\nUna vez que se haya enfriado, funcionará con normalidad."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Ver pasos de mantenimiento"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Desenchufa tu dispositivo"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Tu dispositivo se está calentando cerca del puerto de carga. Si está conectado a un cargador o a un accesorio USB, desenchúfalo con cuidado, ya que el cable también puede estar caliente."</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index ae75d09..b2470f7 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Luba USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Lisateave"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Ekraanipilt"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock on keelatud"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Avatuna hoidmine on keelatud"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"saatis kujutise"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Kuvatõmmise salvestamine ..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Ekraanipildi salvestamine tööprofiilile …"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Toitemenüü"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Leht <xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lukustuskuva"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Tel. lül. kuumuse tõttu välja"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Telefon töötab nüüd tavapäraselt.\nPuudutage lisateabe saamiseks."</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefon oli liiga kuum, seetõttu lülitus see jahtumiseks välja. Telefon töötab nüüd tavapäraselt.\n\nTelefon võib kuumaks minna:\n • ressursse koormavate rakenduste kasutamisel (nt mängu-, video- või navigatsioonirakendused)\n • suurte failide alla-/üleslaadimisel\n • telefoni kasutamisel kõrgel temperatuuril"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Vaadake hooldusjuhiseid"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Telefon soojeneb"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Mõned funktsioonid on piiratud, kuni telefon jahtub.\nPuudutage lisateabe saamiseks."</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Teie telefon proovib automaatselt maha jahtuda. Saate telefoni ikka kasutada, kuid see võib olla aeglasem.\n\nKui telefon on jahtunud, töötab see tavapäraselt."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Vaadake hooldusjuhiseid"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Eemaldage seade"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Teie seade läheb laadimispordi juurest soojaks. Kui see on ühendatud laadija või USB-tarvikuga, eemaldage see ja olge ettevaatlik, kuna kaabel võib samuti soe olla."</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index ff78952..33fee8d 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Gaitu USB ataka"</string>
     <string name="learn_more" msgid="4690632085667273811">"Lortu informazio gehiago"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Pantaila-argazkia"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Desgaitu da desblokeatze luzatua"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Desgaitu da desblokeatuta mantentzeko eginbidea"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"erabiltzaileak irudi bat bidali du"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Pantaila-argazkia gordetzen…"</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Pantaila-argazkia laneko profilean gordetzen…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Itzaltzeko menua"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g> orria"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Pantaila blokeatua"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Beroegi egoteagatik itzali da"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Ohi bezala ari da funtzionatzen telefonoa orain.\nInformazio gehiago lortzeko, sakatu hau."</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefonoa gehiegi berotu da, eta itzali egin da tenperatura jaisteko. Orain, ohiko moduan dabil.\n\nBerotzearen zergati posibleak:\n	• Baliabide asko behar dituzten aplikazioak erabiltzea (adib., bideojokoak, bideoak edo nabigazio-aplikazioak).\n	• Fitxategi handiak deskargatu edo kargatzea.\n	• Telefonoa giro beroetan erabiltzea."</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Ikusi zaintzeko urratsak"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Berotzen ari da telefonoa"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Eginbide batzuk ezingo dira erabili telefonoa hoztu arte.\nInformazio gehiago lortzeko, sakatu hau."</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Telefonoa automatikoki saiatuko da hozten. Hoztu bitartean, telefonoa erabiltzen jarrai dezakezu, baina mantsoago funtziona lezake.\n\nTelefonoaren tenperatura jaitsi bezain laster, ohi bezala funtzionatzen jarraituko du."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Ikusi zaintzeko urratsak"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Deskonektatu gailua"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Gailua berotzen ari da kargatzeko atakaren inguruan. Kargagailu edo USB bidezko osagarri batera konektatuta badago, deskonekta ezazu kontuz, kablea ere beroa egongo baita agian."</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index cc26355..97f6930 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"منوی روشن/خاموش"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"صفحه <xliff:g id="ID_1">%1$d</xliff:g> از <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"صفحه قفل"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"تلفن به علت گرم شدن خاموش شد"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"اکنون عملکرد تلفنتان به حالت عادی برگشته است.\nبرای اطلاعات بیشتر ضربه بزنید"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"تلفنتان خیلی گرم شده بود، بنابراین خاموش شد تا خنک شود. اکنون تلفنتان عملکرد معمولش را دارد.\n\nتلفنتان خیلی گرم می‌شود، اگر:\n	• از برنامه‌های نیازمند پردازش زیاد (مانند بازی، برنامه‌های ویدیویی یا پیمایشی) استفاده کنید\n	• فایل‌های بزرگ بارگیری یا بارگذاری کنید\n	• در دماهای بالا از تلفنتان استفاده کنید"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"دیدن اقدامات محافظتی"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"تلفن درحال گرم شدن است"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"وقتی تلفن درحال خنک شدن است، بعضی از ویژگی‌ها محدود می‌شوند.\nبرای اطلاعات بیشتر ضربه بزنید"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"تلفنتان به‌طور خودکار سعی می‌کند خنک شود. همچنان می‌توانید از تلفنتان استفاده کنید، اما ممکن است کندتر عمل کند.\n\nوقتی تلفن خنک شد، عملکرد عادی‌اش از سرگرفته می‌شود."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"دیدن اقدامات محافظتی"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"دستگاه را جدا کنید"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"‏دستگاهتان کنار درگاه شارژ گرم شده است. اگر دستگاهتان به شارژر یا لوازم جانبی USB متصل است، آن را جدا کنید و مراقب باشید چون ممکن است کابل هم گرم باشد."</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 2b93430..abf52fe 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Ota USB käyttöön"</string>
     <string name="learn_more" msgid="4690632085667273811">"Lue lisää"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Kuvakaappaus"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock poistettu käytöstä"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Lukitsematon tila poistettu käytöstä"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"lähetti kuvan"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Tallennetaan kuvakaappausta..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Kuvakaappausta tallennetaan työprofiiliin…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Virtavalikko"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Sivu <xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lukitusnäyttö"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Puhelin sammui kuumuuden takia"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Puhelimesi toimii nyt normaalisti.\nLue lisää napauttamalla"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Puhelimesi oli liian kuuma, joten se sammui. Puhelimesi toimii nyt normaalisti.\n\nPuhelimesi voi kuumentua liikaa, jos\n	• käytät paljon resursseja vaativia sovelluksia (esim. pelejä, videoita tai navigointisovelluksia)\n	• lataat tai lähetät suuria tiedostoja\n	• käytät puhelintasi korkeissa lämpötiloissa."</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Katso huoltovaiheet"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Puhelin lämpenee"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Joidenkin ominaisuuksien käyttöä on rajoitettu puhelimen jäähtymisen aikana.\nLue lisää napauttamalla"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Puhelimesi yrittää automaattisesti jäähdyttää itsensä. Voit silti käyttää puhelinta, mutta se voi toimia hitaammin.\n\nKun puhelin on jäähtynyt, se toimii normaalisti."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Katso huoltovaiheet"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Irrota laite"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Laite lämpenee latausportin lähellä. Jos laite on yhdistetty laturiin tai USB-lisälaitteeseen, irrota se varoen, sillä johtokin voi olla lämmin."</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 2ac7309..4f94d1f 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Activer l\'USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"En savoir plus"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Capture d\'écran"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock désactivée"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Déverrouillage prolongé désactivé"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"a envoyé une image"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Enregistrement capture écran…"</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Sauv. de la capture dans le profil prof. en cours…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu de l\'interrupteur"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> sur <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Écran de verrouillage"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Tél. éteint car il surchauffait"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Votre téléphone fonctionne maintenant de manière normale.\nTouchez pour en savoir plus"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Votre téléphone s\'est éteint, car il surchauffait. Il s\'est refroidi et fonctionne normalement.\n\nIl peut surchauffer si vous :\n	• Util. des applis utilisant beaucoup de ressources (jeux, vidéo, navigation, etc.)\n	• Téléchargez ou téléversez de gros fichiers\n	• Utilisez téléphone dans des températures élevées"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Afficher les étapes d\'entretien"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Le téléphone commence à chauffer"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Certaines fonctionnalités sont limitées pendant que le téléphone refroidit.\nTouchez pour en savoir plus"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Votre téléphone va essayer de se refroidir automatiquement. Vous pouvez toujours l\'utiliser, mais il risque d\'être plus lent.\n\nUne fois refroidi, il fonctionnera normalement."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Afficher les étapes d\'entretien"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Débranchez votre appareil"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Votre appareil chauffe près du port de recharge. S\'il est connecté à un chargeur ou à un accessoire USB, débranchez-le en faisant attention : le câble pourrait également être chaud."</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 7646a88..0ede09a 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Activer le port USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"En savoir plus"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Capture d\'écran"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Déverrouillage étendu désactivé"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock désactivé"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"a envoyé une image"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Enregistrement de la capture d\'écran…"</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Enregistrement de capture d\'écran dans profil pro…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu Marche/Arrêt"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> sur <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Écran de verrouillage"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Tél. éteint car il surchauffait"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"À présent, votre téléphone fonctionne normalement.\nAppuyer pour en savoir plus"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Votre téléphone s\'est éteint, car il surchauffait. Il s\'est refroidi et fonctionne normalement.\n\nIl peut surchauffer si vous :\n	• exécutez applis utilisant beaucoup de ressources (jeux, vidéo, navigation, etc.) ;\n	• téléchargez ou importez gros fichiers ;\n	• utilisez téléphone à des températures élevées."</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Afficher les étapes d\'entretien"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Le téléphone chauffe"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Fonctionnalités limitées pendant le refroidissement du téléphone.\nAppuyer pour en savoir plus"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Votre téléphone va essayer de se refroidir automatiquement. Vous pouvez toujours l\'utiliser, mais il risque d\'être plus lent.\n\nUne fois refroidi, il fonctionnera normalement."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Afficher les étapes d\'entretien"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Débrancher votre appareil"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Votre appareil se réchauffe près du port de recharge. S\'il est connecté à un chargeur ou un accessoire USB, débranchez-le en faisant attention, car le câble peut lui aussi être chaud."</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index cb2375f..1446755 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Activar USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Máis información"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Facer captura"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Desactivouse o desbloqueo ampliado"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Desactivouse Desbloqueo extra"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"enviou unha imaxe"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Gardando captura de pantalla…"</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Gardando captura de pantalla no perfil de traballo"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menú de acendido"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Páxina <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Pantalla de bloqueo"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"O teléfono apagouse pola calor"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"O teléfono funciona con normalidade.\nToca para obter máis información"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"O teléfono estaba moi quente, apagouse para que arrefríe e agora funciona con normalidade.\n\nÉ posible que estea moi quente se:\n	• Usas aplicacións que requiren moitos recursos (como aplicacións de navegación, vídeos e xogos)\n	• Descargas/cargas ficheiros grandes\n	• Usas o teléfono a alta temperatura"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Ver pasos de mantemento"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"O teléfono está quentando"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"O uso dalgunhas funcións é limitado mentres o teléfono arrefría.\nToca para obter máis información"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"O teléfono tentará arrefriar automaticamente. Podes utilizalo, pero é probable que funcione máis lento.\n\nUnha vez que arrefríe, funcionará con normalidade."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Ver pasos de mantemento"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Desconectar o dispositivo"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"O dispositivo estase quentando cerca do porto de carga. Se está conectado a un cargador ou a un accesorio USB, desconéctao con coidado, xa que o cable tamén podería estar quente."</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index c3be28c..89390b1 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB ચાલુ કરો"</string>
     <string name="learn_more" msgid="4690632085667273811">"વધુ જાણો"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"સ્ક્રીનશૉટ"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlockની સુવિધા બંધ કરવામાં આવી"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"એક્સટેન્ડ અનલૉકની સુવિધા બંધ કરવામાં આવી"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"છબી મોકલી"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"સ્ક્રીનશોટ સાચવી રહ્યું છે…"</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"ઑફિસની પ્રોફાઇલમાં સ્ક્રીનશૉટ સાચવી રહ્યાં છીએ…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"પાવર મેનૂ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> માંથી <xliff:g id="ID_1">%1$d</xliff:g> પૃષ્ઠ"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"લૉક સ્ક્રીન"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"ફોન વધુ પડતી ગરમીને લીધે બંધ થઇ ગયો છે"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"તમારો ફોન હવે સામાન્યપણે કાર્ય કરી રહ્યો છે.\nવધુ માહિતી માટે ટૅપ કરો"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"તમારો ફોન અત્યંત ગરમ હતો, તેથી તે ઠંડો થવા ઑટોમૅટિક રીતે બંધ થઈ ગયો છે. તમારો ફોન હવે સામાન્યપણે કાર્ય કરી રહ્યો છે.\n\nતમારો ફોન અત્યંત ગરમ થઈ શકે છે, જો તમે:\n • એવી ઍપ વાપરતા હો જે સંસાધન સઘન રીતે વાપરતી હોય (જેમ કે ગેમિંગ, વીડિયો, અથવા નેવિગેટ કરતી ઍપ)\n • મોટી ફાઇલો અપલોડ અથવા ડાઉનલોડ કરતા હો\n • તમારા ફોનનો ઉપયોગ ઉચ્ચ તાપમાનમાં કરતા હો"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"સારસંભાળના પગલાં જુઓ"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"ફોન ગરમ થઈ રહ્યો છે"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"ફોન ઠંડો થાય ત્યાં સુધી અમુક સુવિધાઓ મર્યાદિત હોય છે.\nવધુ માહિતી માટે ટૅપ કરો"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"તમારો ફોન ઑટોમૅટિક રીતે ઠંડો થવાનો પ્રયાસ કરશે. તમે હજી પણ તમારા ફોનનો ઉપયોગ કરી શકો છો, પરંતુ તે કદાચ થોડો ધીમો ચાલે.\n\nતમારો ફોન ઠંડો થઈ જવા પર, તે સામાન્ય રીતે ચાલશે."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"સારસંભાળના પગલાં જુઓ"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"તમારા ડિવાઇસને અનપ્લગ કરો"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"તમારું ડિવાઇસ ચાર્જિંગ પોર્ટની પાસે ગરમ થઈ રહ્યું છે. જો તે કોઈ ચાર્જર અથવા USB ઍક્સેસરી સાથે કનેક્ટેડ હોય, તો તેને અનપ્લગ કરો અને ધ્યાન રાખો, કારણ કે કેબલ ગરમ પણ હોઈ શકે છે."</string>
diff --git a/packages/SystemUI/res/values-h800dp/dimens.xml b/packages/SystemUI/res/values-h800dp/dimens.xml
index 3a71994..829ef98 100644
--- a/packages/SystemUI/res/values-h800dp/dimens.xml
+++ b/packages/SystemUI/res/values-h800dp/dimens.xml
@@ -15,9 +15,6 @@
   -->
 
 <resources>
-    <!-- With the large clock, move up slightly from the center -->
-    <dimen name="keyguard_large_clock_top_margin">-112dp</dimen>
-
     <!-- Margin above the ambient indication container -->
     <dimen name="ambient_indication_container_margin_top">20dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 60fd680..fb017da 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"पावर मेन्यू"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"पेज <xliff:g id="ID_2">%2$d</xliff:g> में से <xliff:g id="ID_1">%1$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"लॉक स्‍क्रीन"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"गर्म होने की वजह से फ़ोन बंद हुआ"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"आपका फ़ोन सामान्य रूप से काम कर रहा है.\nज़्यादा जानकारी के लिए टैप करें"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"फ़ोन बहुत गर्म हो गया था, इसलिए ठंडा होने के लिए बंद हो गया. फ़ोन अब अच्छे से चल रहा है.\n\nफ़ोन तब बहुत गर्म हो सकता है जब आप:\n	• ज़्यादा रिसॉर्स का इस्तेमाल करने वाले ऐप्लिकेशन चलाते हैं (जैसे गेमिंग, वीडियो या नेविगेशन ऐप्लिकेशन)\n	• बड़ी फ़ाइलें डाउनलोड या अपलोड करते हैं\n	• ज़्यादा तापमान में फ़ोन का इस्तेमाल करते हैं"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"डिवाइस के रखरखाव के तरीके देखें"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"फ़ोन गर्म हो रहा है"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"फ़ोन के ठंडा होने तक कुछ सुविधाएं काम नहीं करतीं.\nज़्यादा जानकारी के लिए टैप करें"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"आपका फ़ोन अपने आप ठंडा होने की कोशिश करेगा. आप अब भी अपने फ़ोन का उपयोग कर सकते हैं, लेकिन हो सकता है कि यह धीमी गति से चले.\n\nठंडा हो जाने पर आपका फ़ोन सामान्य रूप से चलेगा."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"डिवाइस के रखरखाव के तरीके देखें"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"डिवाइस को अनप्लग करें"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"आपका डिवाइस चार्जिंग पोर्ट के पास गर्म हो रहा है. अगर डिवाइस चार्जर या यूएसबी ऐक्सेसरी से कनेक्ट है, तो उसे अनप्लग करें. साथ ही, ध्यान रखें कि केबल भी गर्म हो सकती है."</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 02c1be7..b7a7cdd 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Izbornik tipke za uključivanje/isključivanje"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Stranica <xliff:g id="ID_1">%1$d</xliff:g> od <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Zaključani zaslon"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon se isključio zbog vrućine"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Telefon sad radi normalno.\nDodirnite za više informacija"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefon se pregrijao, stoga se isključio kako bi se ohladio Telefon sada radi normalno.\n\nTelefon se može pregrijati ako:\n	• upotrebljavate zahtjevne aplikacije (kao što su igre, aplikacije za videozapise ili navigaciju)\n	• preuzimate ili prenosite velike datoteke\n	• upotrebljavate telefon na visokim temperaturama."</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Pročitajte upute za održavanje"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Telefon se zagrijava"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Neke su značajke ograničene dok se telefon ne ohladi.\nDodirnite za više informacija"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Telefon će se automatski pokušati ohladiti. Možete ga nastaviti koristiti, no mogao bi raditi sporije.\n\nKad se ohladi, radit će normalno."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Pročitajte upute za održavanje"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Iskopčajte uređaj"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Vaš se uređaj zagrijava u blizini priključka za punjenje. Ako je priključen u punjač ili USB uređaj, iskopčajte ga. Pazite jer se i kabel možda zagrijao."</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index b5081d0..6a96fcc 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB engedélyezése"</string>
     <string name="learn_more" msgid="4690632085667273811">"Részletek"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Képernyőkép"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock letiltva"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Tartós feloldás letiltva"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"képet küldött"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Képernyőkép mentése..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Képernyőkép mentése a munkaprofilba…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Bekapcsológombhoz tartozó menü"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>. oldal, összesen: <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lezárási képernyő"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"A meleg miatt kikapcsolt"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Telefonja most már megfelelően működik.\nKoppintson, ha további információra van szüksége."</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefonja túlmelegedett, így kikapcsolt, hogy lehűlhessen. Most már megfelelően működik.\n\nA telefon akkor melegedhet túl, ha Ön:\n	• Energiaigényes alkalmazásokat használ (például játékokat, videókat vagy navigációs alkalmazásokat)\n	• Nagy fájlokat tölt le vagy fel\n	• Melegben használja a telefonját"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Olvassa el a kímélő használat lépéseit"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"A telefon melegszik"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Bizonyos funkciók korlátozottan működnek a telefon lehűlése közben.\nKoppintson, ha további információra van szüksége."</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"A telefon automatikusan megpróbál lehűlni. Továbbra is tudja használni a telefont, de elképzelhető, hogy működése lelassul.\n\nAmint a telefon lehűl, újra a szokásos módon működik majd."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Olvassa el a kímélő használat lépéseit"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Húzza ki az eszközt"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Eszköze kezd melegedni a töltőport közelében. Ha töltő vagy USB-s kiegészítő van csatlakoztatva hozzá, húzza ki, és legyen óvatos, mert a kábel is meleg lehet."</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index cfc92a4..d91b3dd2 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Միացնել USB-ն"</string>
     <string name="learn_more" msgid="4690632085667273811">"Իմանալ ավելին"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Սքրինշոթ"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"«Երկարացնել կողպումը» գործառույթն անջատված է"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"«Հետաձգված ապակողպում» գործառույթն անջատված է"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"պատկեր է ուղարկվել"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Սքրինշոթը պահվում է..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Սքրինշոթը պահվում է աշխատանքային պրոֆիլում…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Սնուցման կոճակի ընտրացանկ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Էջ <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Կողպէկրան"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Հեռախոսն անջատվել էր տաքանալու պատճառով"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Հեռախոսն այժմ նորմալ է աշխատում։\nՀպեք՝ ավելին իմանալու համար։"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Ձեր հեռախոսը չափազանց տաք էր, այդ պատճառով այն անջատվել է՝ հովանալու համար: Հեռախոսն այժմ նորմալ աշխատում է:\n\nՀեռախոսը կարող է տաքանալ, եթե՝\n	• Օգտագործում եք ռեսուրսատար հավելվածներ (օրինակ՝ խաղեր, տեսանյութեր կամ նավիգացիայի հավելվածներ)\n	• Ներբեռնում կամ վերբեռնում եք ծանր ֆայլեր\n	• Օգտագործում եք ձեր հեռախոսը բարձր ջերմային պայմաններում"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Քայլեր գերտաքացման ահազանգի դեպքում"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Հեռախոսը տաքանում է"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Հովանալու ընթացքում հեռախոսի որոշ գործառույթներ սահմանափակ են։\nՀպեք՝ ավելին իմանալու համար։"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Ձեր հեռախոսն ավտոմատ կերպով կփորձի hովանալ: Կարող եք շարունակել օգտագործել հեռախոսը, սակայն հնարավոր է, որ այն ավելի դանդաղ աշխատի:\n\nՀովանալուց հետո հեռախոսը կաշխատի կանոնավոր կերպով:"</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Քայլեր գերտաքացման ահազանգի դեպքում"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Անջատեք սարքը"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Լիցքավորման միացքի հատվածում սարքը տաքանում է։ Եթե լիցքավորիչի կամ USB լրասարքի է միացված սարքը, անջատեք այն և զգույշ եղեք, քանի որ մալուխը ևս կարող է տաքացած լինել։"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 515f80f..550b048 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu daya"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Halaman <xliff:g id="ID_1">%1$d</xliff:g> dari <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Layar kunci"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Ponsel dimatikan karena panas"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Ponsel kini berfungsi normal.\nKetuk untuk info selengkapnya"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Ponsel menjadi terlalu panas, jadi dimatikan untuk mendinginkan. Ponsel kini berfungsi normal.\n\nPonsel dapat menjadi terlalu panas jika Anda:\n	• Menggunakan aplikasi yang menggunakan sumber daya secara intensif (seperti aplikasi game, video, atau navigasi)\n	• Mendownload atau mengupload file besar\n	• Menggunakan ponsel dalam suhu tinggi"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Lihat langkah-langkah perawatan"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Ponsel menjadi hangat"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Beberapa fitur dibatasi saat ponsel mendingin.\nKetuk untuk info selengkapnya"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Ponsel akan otomatis mencoba mendingin. Anda tetap dapat menggunakan ponsel, tetapi mungkin berjalan lebih lambat.\n\nSetelah dingin, ponsel akan berjalan seperti biasa."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Lihat langkah-langkah perawatan"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Cabut perangkat"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Perangkat menjadi panas saat di dekat port pengisi daya. Jika perangkat terhubung ke pengisi daya atau aksesori USB, cabutlah dan berhati-hatilah karena suhu kabel mungkin juga panas."</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index fb73c0b..86455c0 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Virkja USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Frekari upplýsingar"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Skjámynd"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Slökkt á Extend Unlock"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Slökkt á Lengri opnun"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"sendi mynd"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Vistar skjámynd…"</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Vistar skjámynd á vinnusnið…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Aflrofavalmynd"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Blaðsíða <xliff:g id="ID_1">%1$d</xliff:g> af <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lásskjár"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Slökkt var á símanum vegna hita"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Síminn virkar nú eins og venjulega.\nÝttu til að fá frekari upplýsingar"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Síminn varð of heitur og því var slökkt á honum til að kæla hann. Síminn virkar núna sem skyldi.\n\nSíminn getur orðið of heitur ef þú:\n	• Notar plássfrek forrit (t.d. leikja-, myndbands- eða leiðsagnarforrit\n	• Sækir eða hleður upp stórum skrám\n	• Notar símann í miklum hita"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Sjá varúðarskref"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Síminn er að hitna"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Sumir eiginleikar eru takmarkaðir meðan síminn kælir sig.\nÝttu til að fá frekari upplýsingar"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Síminn reynir sjálfkrafa að kæla sig. Þú getur enn notað símann en hann gæti verið hægvirkari.\n\nEftir að síminn hefur kælt sig niður virkar hann eðlilega."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Sjá varúðarskref"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Taktu tækið úr sambandi"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Tækið er að hitna nálægt hleðslutenginu. Ef það er tengt við hleðslutæki eða USB-aukahlut skaltu taka það úr sambandi og hafa í huga að snúran gæti einnig verið heit."</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 62d5a46..17ec328 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Attiva USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Scopri di più"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Screenshot"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Funzionalità Extend Unlock disattivata"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Sblocco avanzato disattivato"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"è stata inviata un\'immagine"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Salvataggio screenshot…"</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Salvataggio screenshot nel profilo di lavoro…"</string>
@@ -661,7 +661,7 @@
     <string name="group_system_access_system_settings" msgid="7961639365383008053">"Accedi alle impostazioni di sistema"</string>
     <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Accedi all\'Assistente Google"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Blocca lo schermo"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Visualizza l\'app Note per rapidi appunti"</string>
+    <string name="group_system_quick_memo" msgid="2914234890158583919">"Visualizza l\'app Note per appunti rapidi"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitasking di sistema"</string>
     <string name="system_multitasking_rhs" msgid="6593269428880305699">"Attiva lo schermo diviso con l\'app corrente a destra"</string>
     <string name="system_multitasking_lhs" msgid="8839380725557952846">"Attiva lo schermo diviso con l\'app corrente a sinistra"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu del tasto di accensione"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Pagina <xliff:g id="ID_1">%1$d</xliff:g> di <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Schermata di blocco"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Il telefono si è spento perché surriscaldato"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Ora il telefono funziona normalmente.\nTocca per ulteriori informazioni"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Il telefono era surriscaldato e si è spento per raffreddarsi. Ora funziona normalmente.\n\nIl telefono può surriscaldarsi se:\n	• Utilizzi app che consumano molte risorse (ad esempio app di navigazione, giochi o video)\n	• Scarichi o carichi grandi file\n	• Lo utilizzi in presenza di alte temperature"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Leggi le misure da adottare"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Il telefono si sta scaldando"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Alcune funzionalità limitate durante il raffreddamento del telefono.\nTocca per ulteriori informazioni"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Il telefono cercherà automaticamente di raffreddarsi. Puoi comunque usarlo, ma potrebbe essere più lento.\n\nUna volta raffreddato, il telefono funzionerà normalmente."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Leggi le misure da adottare"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Scollega il dispositivo"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Il tuo dispositivo si sta scaldando vicino alla porta di ricarica. Se è collegato a un caricabatterie o a un accessorio USB, scollegalo e fai attenzione perché il cavo potrebbe essere caldo."</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 7497bd4..5b317cb 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"‏הפעלת USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"מידע נוסף"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"צילום מסך"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"התכונה \'הרחבה של ביטול הנעילה\' מושבתת"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"‏התכונה Extend Unlock מושבתת"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"נשלחה תמונה"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"המערכת שומרת את צילום המסך..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"צילום המסך נשמר בפרופיל העבודה…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"תפריט הפעלה"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"דף <xliff:g id="ID_1">%1$d</xliff:g> מתוך <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"מסך נעילה"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"הטלפון כבה עקב התחממות"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"הטלפון פועל כרגיל עכשיו.\nיש להקיש כדי להציג מידע נוסף"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"הטלפון שלך התחמם יותר מדי וכבה כדי להתקרר. הטלפון פועל כרגיל עכשיו.\n\nייתכן שהטלפון יתחמם יותר מדי אם:\n	• משתמשים באפליקציות עתירות משאבים (כגון משחקים, אפליקציות וידאו או אפליקציות ניווט)\n	• מורידים או מעלים קבצים גדולים\n	• משתמשים בטלפון בסביבה עם טמפרטורות גבוהות"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"לצפייה בשלבי הטיפול"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"הטלפון מתחמם"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"חלק מהתכונות מוגבלות כל עוד הטלפון מתקרר.\nיש להקיש כדי להציג מידע נוסף"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"קירור הטלפון ייעשה באופן אוטומטי. ניתן עדיין להשתמש בטלפון, אבל ייתכן שהוא יפעל לאט יותר.\n\nהטלפון יחזור לפעול כרגיל לאחר שיתקרר."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"לצפייה בשלבי הטיפול"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"ניתוק המכשיר"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"‏המכשיר שלך מתחמם בקרבת יציאת הטעינה. אם המכשיר מחובר למטען או לאביזר בחיבור USB, צריך לנתק אותו בזהירות כיוון שגם הכבל עלול להיות חם."</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index d74d2f1..56a78e2 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB を有効にする"</string>
     <string name="learn_more" msgid="4690632085667273811">"詳細"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"スクリーンショット"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock は無効です"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"ロック解除延長は無効です"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"画像を送信しました"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"スクリーンショットを保存しています..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"スクリーンショットを仕事用プロファイルに保存中…"</string>
@@ -654,7 +654,7 @@
     <string name="group_system_go_back" msgid="8838454003680364227">"戻る: 前の状態に戻る([戻る] ボタン)"</string>
     <string name="group_system_access_home_screen" msgid="1857344316928441909">"ホーム画面にアクセス"</string>
     <string name="group_system_overview_open_apps" msgid="6897128761003265350">"開いているアプリの概要"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"最近使ったアプリを切り替え(進)"</string>
+    <string name="group_system_cycle_forward" msgid="9202444850838205990">"最近使ったアプリを切り替え(進む)"</string>
     <string name="group_system_cycle_back" msgid="5163464503638229131">"最近使ったアプリを切り替え(戻る)"</string>
     <string name="group_system_access_all_apps_search" msgid="488070738028991753">"すべてのアプリの一覧にアクセスして検索(検索 / ランチャー)"</string>
     <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"タスクバーを非表示 /(再)表示"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"電源ボタン メニュー"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ページ <xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"ロック画面"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"高熱で電源が OFF になりました"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"お使いのスマートフォンは現在、正常に動作しています。\nタップして詳細を表示"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"スマートフォンが熱すぎたため電源が OFF になりました。現在は正常に動作しています。\n\nスマートフォンは以下の場合に熱くなる場合があります。\n	• リソースを集中的に使用する機能やアプリ(ゲームアプリ、動画アプリ、ナビアプリなど)を使用\n	• サイズの大きいファイルをダウンロードまたはアップロード\n	• 高温の場所で使用"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"取り扱いに関する手順をご覧ください"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"スマートフォンの温度が上昇中"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"スマートフォンのクールダウン中は一部の機能が制限されます。\nタップして詳細を表示"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"スマートフォンは自動的にクールダウンを行います。その間もスマートフォンを使用できますが、動作が遅くなる可能性があります。\n\nクールダウンが完了すると、通常どおり動作します。"</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"取り扱いに関する手順をご覧ください"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"デバイスを電源から外します"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"充電ポートの近くにデバイスを置くと、本体が熱くなります。デバイスが充電器や USB アクセサリに接続されている場合は外してください。ケーブルが熱くなっていることもあるので注意してください。"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 8662f98..f19b6b6 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB-ის ჩართვა"</string>
     <string name="learn_more" msgid="4690632085667273811">"შეიტყვეთ მეტი"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"ეკრანის ანაბეჭდი"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"გაფართოებული განბლოკვა გაითიშა"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"ხანგრძლივი განბლოკვა გაითიშა"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"გაიგზავნა სურათი"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"ეკრანის სურათის შენახვა…"</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"მიმდინარეობს ეკრანის ანაბეჭდის შენახვა სამუშაო პროფილში…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ჩართვის მენიუ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"გვერდი <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>-დან"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"ჩაკეტილი ეკრანი"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"ტელეფონი გამოირთო გაცხელების გამო"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"თქვენი ტელეფონი უკვე ნორმალურად მუშაობს.\nშეეხეთ დამატებითი ინფორმაციის მისაღებად"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"თქვენი ტელეფონი გამოირთო გასაგრილებლად, რადგან ის მეტისმეტად გაცხელდა. ახლა ის ჩვეულებრივად მუშაობს.\n\nტელეფონის გაცხელების მიზეზებია:\n	• რესურსტევადი აპების გამოყენება (მაგ. სათამაშო, ვიდეო ან ნავიგაციის აპების)\n	• დიდი ფაილების ჩამოტვირთვა ან ატვირთვა\n	• ტელეფონის გამოყენება მაღალი ტემპერატურისას"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"მისაღები ზომების გაცნობა"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"ტელეფონი ცხელდება"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"ზოგიერთი ფუნქცია შეზღუდული იქნება, სანამ ტელეფონი გაგრილდება.\nშეეხეთ დამატებითი ინფორმაციის მისაღებად"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"თქვენი ტელეფონი გაგრილებას ავტომატურად შეეცდება. შეგიძლიათ გააგრძელოთ მისით სარგებლობა, თუმცა ტელეფონმა შეიძლება უფრო ნელა იმუშაოს.\n\nგაგრილების შემდგომ ის ჩვეულებრივად იმუშავებს."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"მისაღები ზომების გაცნობა"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"გამოაერᲗეᲗ Თქვენი მოწყობილობა"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"თქვენი მოწყობილობა ხურდება დამტენის პორტთან ახლოს. თუ ის დაკავშირებულია დამტენთან ან USB აქსესუართან, გამორთეთ იგი და იზრუნეთ, რადგან შესაძლოა კაბელიც გახურებული იყოს."</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 4fd3242..c7d30e7 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Қуат мәзірі"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> ішінен <xliff:g id="ID_1">%1$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Құлыптаулы экран"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Телефон қызып кеткендіктен өшірілді"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Телефоныңыз қалыпты жұмыс істеп тұр.\nТолығырақ ақпарат алу үшін түртіңіз."</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Телефоныңыз қатты қызып кеткендіктен өшірілді. Телефоныңыз қазір қалыпты жұмыс істеп тұр.\n\nТелефоныңыз мына жағдайларда ыстық болуы мүмкін:\n	• Ресурстар талап ететін қолданбаларды пайдалану (ойын, бейне немесе навигация қолданбалары)\n	• Үлкен көлемді файлдарды жүктеу немесе жүктеп салу\n	• Телефонды жоғары температурада пайдалану"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Пайдалану нұсқаулығын қараңыз"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Телефон қызуда"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Телефон толық суығанға дейін, кейбір функциялардың жұмысы шектеледі.\nТолығырақ ақпарат үшін түртіңіз."</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Телефон автоматты түрде суи бастайды. Оны пайдалана бере аласыз, бірақ ол баяуырақ жұмыс істеуі мүмкін.\n\nТелефон суығаннан кейін, оның жұмысы қалпына келеді."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Пайдалану нұсқаулығын қараңыз"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Құрылғыны ажыратыңыз"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Құрылғының зарядтау ұяшығы тұрған бөлігі қызып келеді. Зарядтағышқа немесе USB құрылғысына жалғанған болса, оны ажыратыңыз. Абайлаңыз, кабель де ыстық болуы мүмкін."</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 5132ac0..375b79d 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"បើក USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"ស្វែងយល់​បន្ថែម"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"រូបថតអេក្រង់"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"បានបិទការដោះសោបន្ថែម"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"បានបិទ Extend Unlock"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"បាន​ផ្ញើរូបភាព"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"កំពុង​រក្សាទុក​រូបថត​អេក្រង់..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"កំពុងរក្សាទុករូបថតអេក្រង់ទៅកម្រងព័ត៌មានការងារ…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ម៉ឺនុយ​ថាមពល"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ទំព័រ <xliff:g id="ID_1">%1$d</xliff:g> នៃ <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"អេក្រង់​ចាក់សោ"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"ទូរសព្ទ​បាន​បិទដោយសារ​វា​ឡើងកម្តៅ"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"ឥឡូវនេះ ទូរសព្ទ​របស់អ្នក​កំពុងដំណើរការ​ជាធម្មតា។\nសូមចុច​ដើម្បីទទួលបាន​ព័ត៌មានបន្ថែម"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"ទូរសព្ទ​របស់អ្នក​ក្តៅពេក ដូច្នេះ​វាបាន​បិទ​ដើម្បី​បន្ថយ​កម្តៅ។ ឥឡូវនេះ ​ទូរសព្ទ​របស់អ្នក​កំពុង​ដំណើរការ​ធម្មតា។\n\nទូរសព្ទ​របស់អ្នក​អាចនឹង​ឡើង​កម្តៅ​ខ្លាំងជ្រុល ប្រសិន​បើអ្នក៖\n	• ប្រើប្រាស់​កម្មវិធី​ដែល​ប្រើប្រាស់ទិន្នន័យច្រើនក្នុងរយៈពេលខ្លី (ដូចជាហ្គេម វីដេអូ ឬកម្មវិធីរុករក)\n	• ទាញយក ឬ​បង្ហោះ​ឯកសារដែលមានទំហំធំ\n	• ប្រើប្រាស់​ទូរសព្ទ​របស់អ្នក​នៅកន្លែង​មានសីតុណ្ហភាព​ខ្ពស់"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"មើលជំហាន​ថែទាំ"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"ទូរសព្ទ​នេះ​កំពុង​កើន​កម្តៅ"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"មុខងារ​មួយចំនួន​នឹងមិនអាច​ប្រើបានពេញលេញ​នោះទេ ខណៈពេល​ដែលទូរសព្ទ​កំពុងបញ្ចុះកម្ដៅ។\nសូមចុច​ដើម្បីទទួលបាន​ព័ត៌មានបន្ថែម"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"ទូរសព្ទ​របស់អ្នក​នឹង​ព្យាយាម​បញ្ចុះ​កម្តៅ​ដោយ​ស្វ័យប្រវត្តិ។ អ្នក​នៅតែ​អាច​ប្រើ​ទូរសព្ទ​របស់អ្នក​បាន​ដដែល​ ប៉ុន្តែ​វា​នឹង​ដំណើរ​ការ​យឺត​ជាង​មុន។\n\nបន្ទាប់​ពី​ទូរសព្ទ​របស់អ្នក​ត្រជាក់​ជាង​មុន​ហើយ វា​នឹង​ដំណើរការ​ដូច​ធម្មតា។"</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"មើលជំហាន​ថែទាំ"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"ដកឧបករណ៍របស់អ្នក"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"ឧបករណ៍របស់អ្នកកំពុងឡើងកម្ដៅនៅជិតរន្ធសាកថ្ម។ ប្រសិនបើឧបករណ៍នេះត្រូវបានភ្ជាប់ទៅឆ្នាំង​សាក ឬគ្រឿងបរិក្ខារ USB សូមដកវា និងមានការប្រុងប្រយ័ត្ន ដោយសារខ្សែក៏អាចក្ដៅផងដែរ។"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 5fa9464..437f406 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ಪವರ್ ಮೆನು"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> ರಲ್ಲಿ <xliff:g id="ID_1">%1$d</xliff:g> ಪುಟ"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"ಲಾಕ್ ಪರದೆ"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"ಫೋನ್ ಬಿಸಿಯಾಗಿದ್ದರಿಂದ ಆಫ್ ಆಗಿದೆ"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"ನಿಮ್ಮ ಫೋನ್ ಈಗ ಎಂದಿನಂತೆ ರನ್ ಆಗುತ್ತಿದೆ.\nಇನ್ನಷ್ಟು ಮಾಹಿತಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"ನಿಮ್ಮ ಫೋನ್ ತುಂಬಾ ಬಿಸಿಯಾಗಿತ್ತು, ತಣ್ಣಗಾಗಲು ಅದು ತಾನಾಗಿ ಆಫ್ ಆಗಿದೆ. ಈಗ ನಿಮ್ಮ ಫೋನ್ ಎಂದಿನಂತೆ ಕೆಲಸ ಮಾಡುತ್ತಿದೆ.\n\nನಿಮ್ಮ ಫೋನ್ ಬಿಸಿಯಾಗಲು ಕಾರಣಗಳು:\n	• ಹೆಚ್ಚು ಸಂಪನ್ಮೂಲ ಉಪಯೋಗಿಸುವ ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ಬಳಕೆ (ಉದಾ, ಗೇಮಿಂಗ್, ವೀಡಿಯೊ/ನ್ಯಾವಿಗೇಶನ್ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು)\n	• ದೊಡ್ಡ ಫೈಲ್‌ಗಳ ಡೌನ್‌ಲೋಡ್ ಅಥವಾ ಅಪ್‌ಲೋಡ್\n	• ಅಧಿಕ ಉಷ್ಣಾಂಶದಲ್ಲಿ ಫೋನಿನ ಬಳಕೆ"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"ಕಾಳಜಿಯ ಹಂತಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"ಫೋನ್ ಬಿಸಿಯಾಗುತ್ತಿದೆ"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"ಫೋನ್ ತಣ್ಣಗಾಗುವವರೆಗೂ ಕೆಲವು ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಸೀಮಿತಗೊಳಿಸಲಾಗುತ್ತದೆ\nಇನ್ನಷ್ಟು ಮಾಹಿತಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"ನಿಮ್ಮ ಫೋನ್ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ತಣ್ಣಗಾಗಲು ಪ್ರಯತ್ನಿಸುತ್ತದೆ. ನಿಮ್ಮ ಫೋನ್ ಅನ್ನು ನೀವು ಈಗಲೂ ಬಳಸಬಹುದಾಗಿರುತ್ತದೆ, ಆದರೆ ಇದು ನಿಧಾನವಾಗಿರಬಹುದು.\n\nಒಮ್ಮೆ ನಿಮ್ಮ ಫೋನ್ ತಣ್ಣಗಾದ ನಂತರ ಇದು ಸಾಮಾನ್ಯ ರೀತಿಯಲ್ಲಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"ಕಾಳಜಿಯ ಹಂತಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"ನಿಮ್ಮ ಸಾಧನವನ್ನು ಅನ್‌ಪ್ಲಗ್ ಮಾಡಿ"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"ಚಾರ್ಜಿಂಗ್ ಪೋರ್ಟ್ ಸಮೀಪದಲ್ಲಿ ನಿಮ್ಮ ಸಾಧನವು ಬಿಸಿಯಾಗುತ್ತಿದೆ. ಅದನ್ನು ಚಾರ್ಜರ್ ಅಥವಾ USB ಪರಿಕರಕ್ಕೆ ಕನೆಕ್ಟ್ ಮಾಡಿದ್ದರೆ, ಅದನ್ನು ಅನ್‌ಪ್ಲಗ್ ಮಾಡಿ ಹಾಗೂ ಕೇಬಲ್ ಕೂಡ ಬಿಸಿಯಾಗಿರಬಹುದು ಆದ್ದರಿಂದ ಎಚ್ಚರಿಕೆ ವಹಿಸಿ."</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index eb4afbb..9916951 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB 사용"</string>
     <string name="learn_more" msgid="4690632085667273811">"자세히 알아보기"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"스크린샷"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"잠금 해제 연장 사용 중지됨"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"잠금 해제 유지 사용 중지됨"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"이미지 보냄"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"캡쳐화면 저장 중..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"직장 프로필에 스크린샷 저장 중…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"전원 메뉴"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g>페이지 중 <xliff:g id="ID_1">%1$d</xliff:g>페이지"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"잠금 화면"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"발열로 인해 휴대전화 전원이 종료됨"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"이제 휴대전화가 정상적으로 작동합니다.\n자세히 알아보려면 탭하세요."</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"휴대전화가 과열되어 온도를 낮추기 위해 전원이 종료되었습니다. 지금은 휴대전화가 정상적으로 실행 중입니다.\n\n휴대전화가 과열되는 이유는 다음과 같습니다.\n	• 리소스를 많이 사용하는 앱 사용(예: 게임, 동영상 또는 내비게이션 앱)\n	• 대용량 파일을 다운로드 또는 업로드\n	• 온도가 높은 곳에서 휴대폰 사용"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"해결 방법 확인하기"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"휴대전화 온도가 높음"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"휴대전화 온도를 낮추는 동안 일부 기능이 제한됩니다.\n자세히 알아보려면 탭하세요."</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"휴대전화 온도를 자동으로 낮추려고 시도합니다. 휴대전화를 계속 사용할 수는 있지만 작동이 느려질 수도 있습니다.\n\n휴대전화 온도가 낮아지면 정상적으로 작동됩니다."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"해결 방법 확인하기"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"기기 분리하기"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"기기의 충전 포트 주변 온도가 상승하고 있습니다. 충전기나 USB 액세서리가 연결된 상태라면 분리하세요. 이때 케이블도 뜨거울 수 있으므로 주의하시기 바랍니다."</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index c8f6c37..aaec2cd 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB’ни иштетүү"</string>
     <string name="learn_more" msgid="4690632085667273811">"Кененирээк"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Скриншот"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"\"Кулпуну ачуу\" функциясы өчүрүлдү"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Кулпуланбаган режим өчүрүлдү"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"сүрөт жөнөттү"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Скриншот сакталууда..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Скриншот жумуш профилине сакталууда…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Кубат баскычынын менюсу"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> ичинен <xliff:g id="ID_1">%1$d</xliff:g>-бет"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Кулпуланган экран"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Телефон ысыгандыктан өчүрүлдү"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Телефонуңуз кадимкидей иштеп жатат.\nКеңири маалымат алуу үчүн таптап коюңуз"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Телефонуңуз өтө ысып кеткендиктен, аны муздатуу үчүн өчүрүлдү. Эми телефонуңуз кадимкидей иштеп жатат.\n\nТелефонуңуз төмөнкү шарттарда ысып кетиши мүмкүн:\n	• Ашыкча ресурс короткон колдонмолорду (оюндар, видео же чабыттоо колдонмолору) пайдалансаңыз \n	• Ири көлөмдөгү файлдарды жүктөп алсаңыз же берсеңиз\n	• Телефонуңузду жогорку температураларда пайдалансаңыз"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Тейлөө кадамдарын көрүңүз"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Телефонуңуз ысып баратат"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Телефон сууганча айрым элементтердин иши чектелген.\nКеңири маалымат алуу үчүн таптап коюңуз"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Телефонуңуз автоматтык түрдө сууйт. Аны колдоно берсеңиз болот, бирок ал жайыраак иштеп калат.\n\nТелефонуңуз суугандан кийин адаттагыдай эле иштеп баштайт."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Тейлөө кадамдарын көрүңүз"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Түзмөктү сууруп коюңуз"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Түзмөгүңүздүн кубаттоо порту жылып баратат. Эгер түзмөгүңүз кубаттагычка же USB кабелине туташып турса, аны сууруп коюңуз. Абайлаңыз, кабель да жылуу болушу мүмкүн."</string>
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index da4547b..1681f7a 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -35,6 +35,9 @@
     <dimen name="volume_tool_tip_top_margin">12dp</dimen>
     <dimen name="volume_row_slider_height">128dp</dimen>
 
+    <!-- width of ImmersiveModeConfirmation (-1 for match_parent) -->
+    <dimen name="immersive_mode_cling_width">380dp</dimen>
+
     <dimen name="controls_activity_view_top_offset">25dp</dimen>
 
     <dimen name="biometric_dialog_button_negative_max_width">140dp</dimen>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 756444d..0306fc9 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"ເປີດໃຊ້ USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"ສຶກສາເພີ່ມເຕີມ"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"ພາບໜ້າຈໍ"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"ຂະຫຍາຍການປົດລັອກຖືກປິດການນຳໃຊ້ແລ້ວ"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"ຄຸນສົມບັດການປົດລັອກດົນຂຶ້ນຖືກປິດການນຳໃຊ້ແລ້ວ"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ສົ່ງຮູບແລ້ວ"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"ກຳລັງບັນທຶກພາບໜ້າຈໍ..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"ກຳລັງບັນທຶກຮູບໜ້າຈໍໃສ່ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ເມນູເປີດປິດ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g> ຈາກທັງໝົດ <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"ໜ້າຈໍລັອກ"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"ປິດໂທລະສັບເນື່ອງຈາກຮ້ອນເກີນໄປ"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"ໂທລະສັບຂອງທ່ານຕອນນີ້ເຮັດວຽກປົກກະຕິແລ້ວ.\nແຕະເພື່ອເບິ່ງຂໍ້ມູນເພີ່ມເຕີມ"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"ໂທລະສັບຂອງທ່ານຮ້ອນເກີນໄປ, ດັ່ງນັ້ນມັນຈຶ່ງຖືກປິດໄວ້ເພື່ອໃຫ້ເຢັນກ່ອນ. ໂທລະສັບຂອງທ່ານຕອນນີ້ເຮັດວຽກປົກກະຕິແລ້ວ.\n\nໂທລະສັບຂອງທ່ານອາດຮ້ອນຫາກວ່າທ່ານ:\n	• ໃຊ້ແອັບທີ່ກິນຊັບພະຍາກອນຫຼາຍ (ເຊັ່ນ: ເກມ, ວິດີໂອ ຫຼື ແອັບການນຳທາງ)\n	• ດາວໂຫລດ ຫຼື ອັບໂຫລດຮູບພາບຂະໜາດໃຫຍ່\n	• ໃຊ້ໂທລະສັບຂອງທ່ານໃນບ່ອນທີ່ມີອຸນຫະພູມສູງ"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"ເບິ່ງຂັ້ນຕອນການເບິ່ງແຍງ"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"ໂທລະສັບກຳລັງຮ້ອນຂຶ້ນ"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"ຄຸນສົມບັດບາງຢ່າງຖືກຈຳກັດໄວ້ໃນເວລາຫຼຸດອຸນຫະພູມຂອງໂທລະສັບ.\nແຕະເພື່ອເບິ່ງຂໍ້ມູນເພີ່ມເຕີມ"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"ໂທລະສັບຂອງທ່ານຈະພະຍາຍາມລົດອຸນຫະພູມລົງ. ທ່ານຍັງຄົງສາມາດໃຊ້ໂທລະສັບຂອງທ່ານໄດ້ຢູ່, ແຕ່ມັນຈະເຮັດວຽກຊ້າລົງ.\n\nເມື່ອໂທລະສັບຂອງທ່ານບໍ່ຮ້ອນຫຼາຍແລ້ວ, ມັນຈະກັບມາເຮັດວຽກຕາມປົກກະຕິ."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"ເບິ່ງຂັ້ນຕອນການເບິ່ງແຍງ"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"ຖອດອຸປະກອນຂອງທ່ານອອກ"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"ອຸປະກອນຂອງທ່ານຈະອຸ່ນຂຶ້ນເມື່ອຢູ່ໃກ້ຊ່ອງສາກໄຟ. ຫາກມັນເຊື່ອມຕໍ່ຫາສາຍສາກ ຫຼື ອຸປະກອນເສີມ USB ໃດໜຶ່ງຢູ່, ໃຫ້ຖອດມັນອອກ ແລະ ລະວັງເນື່ອງຈາກສາຍກໍອາດຈະອຸ່ນເຊັ່ນກັນ."</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index ff745b5..8548a24 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Įjungimo meniu"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g> psl. iš <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Užrakinimo ekranas"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefonas išjungt., nes įkaito"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Telefonas dabar veikia normaliai.\nPalietę gausite daugiau informacijos"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefonas per daug įkaito, todėl buvo išj., kad atvėstų. Dabar telefonas veikia įprastai.\n\nTelefonas gali per daug įkaisti, jei:\n	• esate įjungę daug išteklių naudoj. progr. (pvz., žaidimų, vaizdo įr. arba navig. progr.);\n	• atsis. arba įkeliate didelius failus;\n	• telefoną naudojate aukštoje temper."</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Žr. priežiūros veiksmus"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Telefonas kaista"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Kai kurios funkcijos gali neveikti, kol telefonas vėsta.\nPalietę gausite daugiau informacijos"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Telefonas automatiškai bandys atvėsti. Telefoną vis tiek galėsite naudoti, tačiau jis gali veikti lėčiau.\n\nKai telefonas atvės, jis veiks įprastai."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Žr. priežiūros veiksmus"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Atjunkite įrenginį"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Įrenginys kaista šalia įkrovimo prievado. Jei jis prijungtas prie kroviklio ar USB priedo, atjunkite jį ir patikrinkite, nes laidas taip pat gali būti įkaitęs."</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index c8c18fb..79f73b6 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Barošanas izvēlne"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>. lpp. no <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Bloķēšanas ekrāns"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Tālrunis izslēgts karstuma dēļ"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Tagad jūsu tālrunis darbojas normāli.\nPieskarieties, lai uzzinātu vairāk."</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Jūsu tālrunis bija pārkarsis un tika izslēgts. Tagad tas darbojas normāli.\n\nTālrunis var sakarst, ja:\n	• tiek izmantotas lietotnes, kas patērē daudz enerģijas (piem., spēles, video lietotnes vai navigācija);\n	• tiek lejupielādēti/augšupielādēti lieli faili;\n	• tālrunis tiek lietots augstā temperatūrā."</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Skatīt apkopes norādījumus"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Tālrunis kļūst silts"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Dažas funkcijas ir ierobežotas, kamēr notiek tālruņa atdzišana.\nPieskarieties, lai uzzinātu vairāk."</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Jūsu tālrunis automātiski mēģinās atdzist. Jūs joprojām varat izmantot tālruni, taču tas, iespējams, darbosies lēnāk.\n\nTiklīdz tālrunis būs atdzisis, tas darbosies normāli."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Skatīt apkopes norādījumus"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Atvienojiet savu ierīci"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Jūsu ierīce uzkarst, atrodoties uzlādes pieslēgvietas tuvumā. Ja ierīce ir pievienota lādētājam vai USB piederumam, uzmanīgi atvienojiet to, jo arī vads var būt uzkarsis."</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index e429979..b8829c6 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Мени на копчето за вклучување"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Страница <xliff:g id="ID_1">%1$d</xliff:g> од <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Заклучен екран"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Телефонот се исклучи поради загреаност"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Сега телефонот работи нормално.\nДопрете за повеќе информации"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Телефонот беше премногу загреан, така што се исклучи за да се олади. Сега работи нормално.\n\nТелефонот може премногу да се загрее ако:\n	• користите апликации што работат со многу ресурси (како што се, на пример, апликациите за видеа, навигација или игри)\n	• преземате или поставувате големи датотеки\n	•го користите телефонот на високи температури"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Прикажи ги чекорите за грижа за уредот"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Телефонот се загрева"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Некои функции се ограничени додека телефонот се лади.\nДопрете за повеќе информации"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Телефонот автоматски ќе се обиде да се олади. Вие сепак ќе може да го користите, но тој може да работи побавно.\n\nОткако ќе се олади, ќе работи нормално."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Прикажи ги чекорите за грижа за уредот"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Исклучете го уредот од кабел"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Вашиот уред се загрева во близина на портата за полнење. Ако е поврзан со полнач или USB-додаток, исклучете го од него и внимавајте бидејќи кабелот може да е топол."</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 83d045e..f8c14e6 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB പ്രവർത്തനക്ഷമമാക്കുക"</string>
     <string name="learn_more" msgid="4690632085667273811">"കൂടുതലറിയുക"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"സ്ക്രീൻഷോട്ട്"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock പ്രവർത്തനരഹിതമാക്കി"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"എക്സ്റ്റൻഡ് അൺലോക്ക് പ്രവർത്തനരഹിതമാക്കി"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ചിത്രം അയച്ചു"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"സ്‌ക്രീൻഷോട്ട് സംരക്ഷിക്കുന്നു..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"ഔദ്യോഗിക പ്രൊഫൈലിലേക്ക് സ്ക്രീൻഷോട്ട് സംരക്ഷിക്കുന്നു…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"പവർ മെനു"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"പേജ് <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"ലോക്ക് സ്‌ക്രീൻ"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"ചൂട് കൂടിയതിനാൽ ഫോൺ ഓഫാക്കി"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"നിങ്ങളുടെ ഫോൺ ഇപ്പോൾ സാധാരണ ഗതിയിൽ പ്രവർത്തിക്കുന്നു.\nകൂടുതൽ വിവരങ്ങൾക്ക് ടാപ്പ് ചെയ്യുക"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"ഫോൺ ചൂടായിരിക്കുന്നതിനാൽ തണുക്കാൻ ഓഫാക്കിയിരിക്കുന്നു. ഫോൺ ഇപ്പോൾ സാധാരണഗതിയിൽ പ്രവർത്തിക്കുന്നു.\n\nഫോണിന് ചൂട് കൂടാൻ കാരണം:\n	• ഗെയിമിംഗ്, വീഡിയോ അല്ലെങ്കിൽ നാവിഗേഷൻ തുടങ്ങിയ റിസോഴ്സ്-ഇന്റൻസീവായ ആപ്പുകൾ ഉപയോഗിക്കുന്നത്\n	• വലിയ ഫയലുകൾ അപ്‌ലോഡോ ഡൗൺലോഡോ ചെയ്യുന്നത്\n	• ഉയർന്ന താപനിലയിൽ ഫോൺ ഉപയോഗിക്കുന്നത്"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"പരിപാലന നിർദ്ദേശങ്ങൾ കാണുക"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"ഫോൺ ചൂടായിക്കൊണ്ടിരിക്കുന്നു"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"ഫോൺ തണുത്തുകൊണ്ടിരിക്കുമ്പോൾ ചില ഫീച്ചറുകൾ പരിമിതപ്പെടുത്തപ്പെടും.\nകൂടുതൽ വിവരങ്ങൾക്ക് ടാപ്പ് ചെയ്യുക"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"നിങ്ങളുടെ ഫോൺ സ്വയമേവ തണുക്കാൻ ശ്രമിക്കും. നിങ്ങൾക്ക് അപ്പോഴും ഫോൺ ഉപയോഗിക്കാമെങ്കിലും പ്രവർത്തനം മന്ദഗതിയിലായിരിക്കും.\n\nതണുത്തുകഴിഞ്ഞാൽ, ഫോൺ സാധാരണ ഗതിയിൽ പ്രവർത്തിക്കും."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"പരിപാലന നിർദ്ദേശങ്ങൾ കാണുക"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"ഉപകരണം അൺപ്ലഗ് ചെയ്യുക"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"ചാർജിംഗ് പോർട്ടിന് സമീപം നിങ്ങളുടെ ഉപകരണം ചൂടാകുന്നുണ്ട്. ഇത് ചാർജറിലേക്കോ USB ആക്‌സസറിയിലേക്കോ കണക്‌റ്റ് ചെയ്‌തിട്ടുണ്ടെങ്കിൽ അൺപ്ലഗ് ചെയ്യുക, കേബിളും ചൂടായിരിക്കാമെന്നതിനാൽ ശ്രദ്ധിക്കണം."</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 98d0ddd..ceb8782 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB-г идэвхжүүлэх"</string>
     <string name="learn_more" msgid="4690632085667273811">"Нэмэлт мэдээлэл авах"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Дэлгэцийн зураг дарах"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock-г идэвхгүй болгосон"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Түгжээгүй байлгахыг идэвхгүй болгосон"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"зураг илгээсэн"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Дэлгэцийн агшинг хадгалж байна…"</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Дэлгэцийн агшныг ажлын профайлд хадгалж байна…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Асаах/унтраах цэс"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g>-н <xliff:g id="ID_1">%1$d</xliff:g>-р хуудас"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Түгжээтэй дэлгэц"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Халснаас үүдэн утас унтарсан"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Таны утас одоо хэвийн ажиллаж байна.\nДэлгэрэнгүй мэдээлэл авах бол товшино уу"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Таны утас хэт халсан тул хөргөхөөр унтраасан болно. Таны утас одоо хэвийн ажиллаж байна.\n\nХэрэв та дараахыг хийвэл таны утас хэт халж болзошгүй:\n	• Их хэмжээний нөөц хэрэглээний апп (тоглоом, видео эсвэл шилжилтийн апп зэрэг)\n	• Багтаамж ихтэй файл татах, байршуулах\n	• Утсаа өндөр температурт ашиглах"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Хянамж болгоомжийн алхмыг харах"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Утас халж эхэлж байна"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Утсыг хөрөх үед зарим онцлогийг хязгаарлана.\nДэлгэрэнгүй мэдээлэл авах бол товшино уу"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Таны утас автоматаар хөрөх болно. Та утсаа ашиглаж болох хэдий ч удаан ажиллаж болзошгүй.\n\nТаны утас хөрсний дараагаар хэвийн ажиллана."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Хянамж болгоомжийн алхмыг харах"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Төхөөрөмжөө салгана уу"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Таны төхөөрөмж цэнэглэх портын ойролцоо халж байна. Хэрэв төхөөрөмжийг цэнэглэгч эсвэл USB дагалдах хэрэгсэлд холбосон бол төхөөрөмжийг салгаж, кабель нь халуун байж болзошгүй тул болгоомжтой байгаарай."</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 6547cfe..ba45d53 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"पॉवर मेनू"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> पैकी <xliff:g id="ID_1">%1$d</xliff:g> पेज"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"लॉक स्‍क्रीन"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"तापल्‍यामुळे फोन बंद झाला"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"तुमचा फोन आता नेहमीप्रमाणे काम करत आहे.\nअधिक माहितीसाठी टॅप करा"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"तुमचा फोन खूप तापलाय, म्हणून तो थंड होण्यासाठी बंद झाला आहे. तुमचा फोन आता व्‍यवस्थित सुरू आहे.\n\nतुम्ही असे केल्यास तुमचा फोन खूप तापेल:\n	•संसाधन केंद्रित अ‍ॅप वापरणे (गेमिंग, व्हिडिओ किंवा नेव्हिगेशन अ‍ॅप यासारखे)\n	•मोठ्या फाइल डाउनलोड किंवा अपलोड करणे\n	•उच्च तापमानामध्ये तुमचा फोन वापरणे"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"काय काळजी घ्यावी ते पहा"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"फोन ऊष्ण होत आहे"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"फोन थंड होईपर्यंत काही वैशिष्ट्ये मर्यादित केली.\nअधिक माहितीसाठी टॅप करा"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"तुमचा फोन स्वयंचलितपणे थंड होईल. तुम्ही अद्यापही तुमचा फोन वापरू शकता परंतु तो कदाचित धीमेपणे कार्य करेल.\n\nतुमचा फोन एकदा थंड झाला की, तो सामान्यपणे कार्य करेल."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"काय काळजी घ्यावी ते पहा"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"तुमचे डिव्हाइस अनप्लग करा"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"तुमचे डिव्हाइस हे चार्जिंग पोर्टच्या जवळ गरम होत आहे. हे चार्जर किंवा USB अ‍ॅक्सेसरी यांच्याशी कनेक्ट केलेले असल्यास, ते अनप्लग करा आणि काळजी घ्या कारण केबलदेखील गरम असू शकते."</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 3d1a222..e28ea01 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Dayakan USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Ketahui lebih lanjut"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Tangkapan skrin"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Lanjutkan Buka Kunci dilumpuhkan"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Buka Kunci Berterusan dilumpuhkan"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"menghantar imej"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Menyimpan tangkapan skrin..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Menyimpan tangkapan skrin ke profil kerja…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu kuasa"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Halaman <xliff:g id="ID_1">%1$d</xliff:g> daripada <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Kunci skrin"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon dimatikan kerana panas"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Telefon anda kini berjalan seperti biasa.\nKetik untuk mendapatkan maklumat lanjut"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefon anda terlalu panas, jadi telefon itu telah dimatikan untuk menyejuk. Sekarang, telefon anda berjalan seperti biasa.\n\nTelefon anda mungkin menjadi terlalu panas jika anda:\n	• Menggunakan apl intensif sumber (seperti permainan, video atau apl navigasi)\n	• Memuat turun atau memuat naik fail besar\n	• Menggunakan telefon anda dalam suhu tinggi"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Lihat langkah penjagaan"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Telefon semakin panas"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Sesetengah ciri adalah terhad semasa telefon menyejuk.\nKetik untuk mendapatkan maklumat lanjut"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Telefon anda akan cuba menyejuk secara automatik. Anda masih dapat menggunakan telefon itu tetapi telefon tersebut mungkin berjalan lebih perlahan.\n\nSetelah telefon anda sejuk, telefon itu akan berjalan seperti biasa."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Lihat langkah penjagaan"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Cabut palam peranti anda"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Peranti anda menjadi panas berdekatan port pengecasan. Jika peranti anda disambungkan ke pengecas atau aksesori USB, cabut palam peranti dan berhati-hati kerana kabel juga mungkin panas."</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 34f580a..5bcd5a0 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB ကို ဖွင့်ရန်"</string>
     <string name="learn_more" msgid="4690632085667273811">"ပိုမိုလေ့လာရန်"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"ဖန်သားပြင်ဓာတ်ပုံ"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"‘တိုးချဲ့ဖွင့်ခြင်း’ ပိတ်ထားသည်"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"‘လော့ခ်ဖွင့်ချိန်တိုးခြင်း’ ပိတ်ထားသည်"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ပုံပို့ထားသည်"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"ဖန်သားပြင်ဓါတ်ပုံရိုက်ခြင်းအား သိမ်းဆည်းပါမည်"</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"အလုပ်ပရိုဖိုင်တွင် ဖန်သားပြင်ဓာတ်ပုံ သိမ်းနေသည်…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ပါဝါမီနူး"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"စာမျက်နှာ <xliff:g id="ID_2">%2$d</xliff:g> အနက်မှ စာမျက်နှာ <xliff:g id="ID_1">%1$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"လော့ခ်ချထားချိန် မျက်နှာပြင်"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"အပူရှိန်ကြောင့်ဖုန်းပိတ်ထားသည်"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"သင့်ဖုန်းသည် ယခု ပုံမှန်အလုပ်လုပ်နေပါပြီ။\nနောက်ထပ်အချက်အလက်များအတွက် တို့ပါ"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"သင့်ဖုန်းအလွန်ပူနေသည့်အတွက် အေးသွားစေရန် ပိတ်ထားပါသည်။ ယခုပုံမှန် အလုပ်လုပ်ပါပြီ။\n\nအောက်ပါတို့ကိုသုံးလျှင် ပူလာပါမည်-\n	• အရင်းအမြစ်များသောအက်ပ်ကို သုံးခြင်း (ဥပမာ ဂိမ်းကစားခြင်း၊ ဗီဒီယိုကြည့်ခြင်း (သို့) လမ်းညွှန်အက်ပ်)\n	• ကြီးမားသောဖိုင်များ ဒေါင်းလုဒ် (သို့) အပ်လုဒ်လုပ်ခြင်း\n	• အပူရှိန်မြင့်သောနေရာတွင် သုံးခြင်း"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"ဂရုပြုစရာ အဆင့်များ ကြည့်ရန်"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"ဖုန်း ပူနွေးလာပါပြီ"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"ဖုန်းကို အေးအောင်ပြုလုပ်နေစဉ်တွင် အချို့ဝန်ဆောင်မှုများကို ကန့်သတ်ထားပါသည်။\nနောက်ထပ်အချက်အလက်များအတွက် တို့ပါ"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"သင့်ဖုန်းသည် အလိုအလျောက် ပြန်အေးသွားပါလိမ့်မည်။ ဖုန်းကို အသုံးပြုနိုင်ပါသေးသည် သို့သော် ပိုနှေးနိုင်ပါသည်။\n\nသင့်ဖုန်း အေးသွားသည်နှင့် ပုံမှန်အတိုင်း ပြန်အလုပ်လုပ်ပါလိမ့်မည်။"</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"ဂရုပြုစရာ အဆင့်များ ကြည့်ရန်"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"သင့်စက်ကို ပလတ်ဖြုတ်ပါ"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"သင့်စက်သည် အားသွင်းပို့တ်အနီးတွင် ပူနွေးလာသည်။ ၎င်းကို အားသွင်းကိရိယာ (သို့) USB ဆက်စပ်ပစ္စည်းနှင့် ချိတ်ဆက်ထားပါက ပလတ်ဖြုတ်ပါ။ ကြိုးကလည်း ပူနွေးနေနိုင်သဖြင့် ဂရုပြုပါ။"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index a6111d9..755ee81 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Slå på USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Finn ut mer"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Skjermdump"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock er slått av"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Hold ulåst er slått av"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"har sendt et bilde"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Lagrer skjermdumpen …"</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Lagrer skjermdumpen i jobbprofilen …"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Av/på-meny"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Side <xliff:g id="ID_1">%1$d</xliff:g> av <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Låseskjerm"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon ble slått av pga varme"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Telefonen kjører nå som normalt.\nTrykk for å se mer informasjon"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefonen din var for varm, så den ble slått av for å kjøles ned. Telefonen din kjører nå som normalt.\n\nTelefonen kan blir for varm hvis du:\n	• bruker ressurskrevende apper (for eksempel spill-, video- eller navigeringsapper)\n	• laster store filer opp eller ned\n	• bruker telefonen ved høy temperatur"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Se vedlikeholdstrinnene"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Telefonen begynner å bli varm"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Enkelte funksjoner er begrenset mens telefonen kjøles ned.\nTrykk for å se mer informasjon"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Telefonen din kommer til å prøve å kjøle seg ned automatisk. Du kan fremdeles bruke telefonen, men den kjører muligens saktere.\n\nTelefonen kommer til å kjøre som normalt, når den har kjølt seg ned."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Se vedlikeholdstrinnene"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Koble fra enheten"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Enheten begynner å bli varm nær ladeporten. Hvis den er koblet til en lader eller et USB-tilbehør, må du koble den fra. Vær forsiktig da kabelen også kan være varm."</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 610e28b..d1445e1 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB सक्षम पार्नुहोस्"</string>
     <string name="learn_more" msgid="4690632085667273811">"थप जान्नुहोस्"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"स्क्रिनसट"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock अफ गरिएको छ"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"एक्स्टेन्ड अनलक अफ गरिएको छ"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"कुनै छवि पठाइयो"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"स्क्रिनसट बचत गर्दै…"</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"कार्य प्रोफाइलमा स्क्रिनसट सेभ गरिँदै छ…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"पावर मेनु"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> मध्ये पृष्ठ <xliff:g id="ID_1">%1$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"लक स्क्रिन"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"फोन अति नै तातिएकाले चिसिन बन्द भयो"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"तपाईंको फोन अहिले सामान्य रूपमा चलिरहेको छ।\nथप जानकारीका लागि ट्याप गर्नुहोस्"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"तपाईंको फोन अति नै तातिएकाले चिसिन बन्द भयो। तपाईंको फोन अब सामान्य ढंगले चल्दै छ।\n\nतपाईंले निम्न कुराहरू गर्नुभयो भने तपाईंको फोन अत्यन्त तातो हुनसक्छ:\n	• धेरै संसाधन खपत गर्ने एपहरूको प्रयोग (जस्तै गेमिङ, भिडियो वा नेभिगेसन एपहरू)\n	• ठूला फाइलहरूको डाउनलोड वा अपलोड\n	• उच्च तापक्रममा फोनको प्रयोग"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"डिभाइसको हेरचाह गर्ने तरिका हेर्नुहोस्"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"फोन तातो भइरहेको छ"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"फोन नचिस्सिँदासम्म केही सुविधाहरू उपलब्ध हुने छैनन्।\nथप जानकारीका लागि ट्याप गर्नुहोस्"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"तपाईंको फोन स्वतः चिसो हुने प्रयास गर्ने छ। तपाईं अझै पनि आफ्नो फोनको प्रयोग गर्न सक्नुहुन्छ तर त्यो अझ ढिलो चल्न सक्छ।\n\nचिसो भएपछि तपाईंको फोन सामान्य गतिमा चल्नेछ।"</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"डिभाइसको हेरचाह गर्ने तरिका हेर्नुहोस्"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"डिभाइस बिजुलीको स्रोतबाट निकाल्नुहोस्"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"तपाईंको डिभाइसको चार्जिङ पोर्टतिरको भाग तातीरहेको छ। तपाईंको डिभाइस चार्जर वा USB एक्सेसरीमा जोडिएको गरिएको छ भने त्यसलाई निकाल्नुहोस्। यसका साथै सो केबल तातो हुन सक्ने भएकाले ख्याल गर्नुहोला।"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 3f7f829..932889b 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Aan/uit-menu"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Pagina <xliff:g id="ID_1">%1$d</xliff:g> van <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Vergrendelscherm"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefoon uitgezet wegens hitte"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Je telefoon functioneert nu weer zoals gebruikelijk.\nTik voor meer informatie"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Je telefoon was te warm en is uitgezet om af te koelen. Je telefoon presteert nu weer zoals gebruikelijk.\n\nJe telefoon kan warm worden als je:\n	• bronintensieve apps gebruikt (zoals game-, video-, of navigatie-apps),\n	• grote bestanden up- of downloadt,\n	• je telefoon gebruikt bij hoge temperaturen."</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Onderhoudsstappen bekijken"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"De telefoon wordt warm"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Bepaalde functies zijn beperkt terwijl de telefoon afkoelt.\nTik voor meer informatie"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Je telefoon probeert automatisch af te koelen. Je kunt je telefoon nog steeds gebruiken, maar deze kan langzamer werken.\n\nZodra de telefoon is afgekoeld, werkt deze weer normaal."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Onderhoudsstappen bekijken"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Je apparaat loskoppelen"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Je apparaat wordt warm in de buurt van de oplaadpoort. Als het apparaat is aangesloten op een oplader of USB-poort, koppel je het los. Wees voorzichtig: de kabel kan warm zijn."</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 3728d5a..8061fd6 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB ସକ୍ଷମ କରନ୍ତୁ"</string>
     <string name="learn_more" msgid="4690632085667273811">"ଅଧିକ ଜାଣନ୍ତୁ"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"ସ୍କ୍ରିନ୍‌ସଟ୍ ନିଅନ୍ତୁ"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlockକୁ ଅକ୍ଷମ କରାଯାଇଛି"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"ଏକ୍ସଟେଣ୍ଡ ଅନଲକକୁ ଅକ୍ଷମ କରାଯାଇଛି"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ଏକ ଛବି ପଠାଯାଇଛି"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"ସ୍କ୍ରୀନଶଟ୍‍ ସେଭ୍‍ କରାଯାଉଛି…"</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"ୱାର୍କ ପ୍ରୋଫାଇଲରେ ସ୍କ୍ରିନସଟ ସେଭ କରାଯାଉଛି…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ପାୱାର ମେନୁ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ପୃଷ୍ଠା <xliff:g id="ID_1">%1$d</xliff:g> ମୋଟ <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"ଲକ ସ୍କ୍ରିନ"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"ଗରମ ହେତୁ ଫୋନ୍‍ ଅଫ୍‍ କରିଦିଆଗଲା"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"ଆପଣଙ୍କ ଫୋନ୍ ବର୍ତ୍ତମାନ ସାମାନ୍ୟ ରୂପେ ଚାଲୁଛି।\nଅଧିକ ସୂଚନା ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"ଆପଣଙ୍କ ଫୋନ୍‍ ବହୁତ ଗରମ ଥିଲା, ତେଣୁ ଏହାକୁ ଥଣ୍ଡା କରାଯିବାକୁ ଅଫ୍‍ କରିଦିଆଗଲା। ଆପଣଙ୍କ ଫୋନ୍‍ ବର୍ତ୍ତମାନ ସାମାନ୍ୟ ଅବସ୍ଥାରେ ଚାଲୁଛି।\n\nଆପଣଙ୍କ ଫୋନ୍‍ ଅଧିକ ଗରମ ହୋଇଯାଇପାରେ ଯଦି ଆପଣ:\n	• ରିସୋର୍ସ-ଇଣ୍ଟେନସିଭ୍‍ ଆପ୍‍ (ଯେପରିକି ଗେମିଙ୍ଗ, ଭିଡିଓ, କିମ୍ବା ନେଭିଗେସନ୍‍ ଆପ୍‍) ବ୍ୟବହାର କରନ୍ତି\n	• ବଡ ଫାଇଲ୍‍ ଡାଉନଲୋଡ କିମ୍ବା ଅପଲୋଡ୍‍ କରନ୍ତି\n	• ଅଧିକ ତାପମାତ୍ରାରେ ଆପଣଙ୍କ ଫୋନ୍‍ ବ୍ୟବହାର କରନ୍ତି"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"ଯତ୍ନ ନେବା ପାଇଁ ଷ୍ଟେପଗୁଡ଼ିକ ଦେଖନ୍ତୁ"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"ଫୋନ୍‍ ଗରମ ହୋଇଯାଉଛି"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"ଫୋନ୍ ଥଣ୍ଡା ହେବା ସମୟରେ କିଛି ଫିଚର୍ ଠିକ ଭାବେ କାମ କରିନଥାଏ।\nଅଧିକ ସୂଚନା ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"ଆପଣଙ୍କ ଫୋନ୍‍ ସ୍ୱଚାଳିତ ଭାବେ ଥଣ୍ଡା ହେବାକୁ ଚେଷ୍ଟା କରିବ। ଆପଣ ତଥାପି ନିଜ ଫୋନ୍‍ ବ୍ୟବହାର କରିପାରିବେ, କିନ୍ତୁ ଏହା ଧୀରେ ଚାଲିପାରେ।\n\nଆପଣଙ୍କ ଫୋନ୍‍ ଥଣ୍ଡା ହୋଇଯିବାପରେ, ଏହା ସାମାନ୍ୟ ଭାବେ ଚାଲିବ।"</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"ଯତ୍ନ ନେବା ପାଇଁ ଷ୍ଟେପଗୁଡ଼ିକ ଦେଖନ୍ତୁ"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"ଆପଣଙ୍କ ଡିଭାଇସକୁ ଅନପ୍ଲଗ କରନ୍ତୁ"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"ଚାର୍ଜିଂ ପୋର୍ଟ ନିକଟରେ ଆପଣଙ୍କ ଡିଭାଇସ ଗରମ ହୋଇଯାଉଛି। ଯଦି ଏହା ଏକ ଚାର୍ଜର କିମ୍ବା USB ଆକସେସୋରୀ ସହ କନେକ୍ଟ କରାଯାଇଥାଏ ତେବେ ଏହାକୁ ଅନପ୍ଲଗ କରନ୍ତୁ ଏବଂ ଧ୍ୟାନ ରଖନ୍ତୁ କାରଣ କେବୁଲ ମଧ୍ୟ ଗରମ ହୋଇପାରେ।"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index bb511e3..0f3ef6a 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB ਚਾਲੂ ਕਰੋ"</string>
     <string name="learn_more" msgid="4690632085667273811">"ਹੋਰ ਜਾਣੋ"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"ਸਕ੍ਰੀਨਸ਼ਾਟ"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"ਐਕਸਟੈਂਡ ਅਣਲਾਕ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ਚਿੱਤਰ ਭੇਜਿਆ ਗਿਆ"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਸੁਰੱਖਿਅਤ ਕਰ ਰਿਹਾ ਹੈ…"</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ \'ਤੇ ਰੱਖਿਅਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ਪਾਵਰ ਮੀਨੂ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> ਦਾ <xliff:g id="ID_1">%1$d</xliff:g> ਪੰਨਾ"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">" ਲਾਕ  ਸਕ੍ਰੀਨ"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"ਗਰਮ ਹੋਣ ਕਾਰਨ ਫ਼ੋਨ ਬੰਦ ਹੋ ਗਿਆ"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"ਤੁਹਾਡਾ ਫ਼ੋਨ ਹੁਣ ਸਹੀ ਚੱਲ ਰਿਹਾ ਹੈ।\nਵਧੇਰੇ ਜਾਣਕਾਰੀ ਲਈ ਟੈਪ ਕਰੋ"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">\n"ਤੁਹਾਡਾ ਫ਼ੋਨ ਬਹੁਤ ਗਰਮ ਸੀ, ਇਸ ਲਈ ਇਹ ਠੰਡਾ ਹੋਣ ਵਾਸਤੇ ਬੰਦ ਹੋ ਗਿਆ ਸੀ। ਤੁਹਾਡਾ ਫ਼ੋਨ ਹੁਣ ਸਹੀ ਚੱਲ ਰਿਹਾ ਹੈ।\n\nਤੁਹਾਡਾ ਫ਼ੋਨ ਬਹੁਤ ਗਰਮ ਹੋ ਸਕਦਾ ਹੈ ਜੇ:\n	• ਤੁਸੀਂ ਸਰੋਤਾਂ ਦੀ ਵੱਧ ਵਰਤੋਂ ਵਾਲੀਆਂ ਐਪਾਂ (ਜਿਵੇਂ ਗੇਮਿੰਗ, ਵੀਡੀਓ, ਜਾਂ ਦਿਸ਼ਾ-ਨਿਰਦੇਸ਼ ਐਪਾਂ) ਵਰਤਦੇ ਹੋ 	• ਵੱਡੀਆਂ ਫ਼ਾਈਲਾਂ ਡਾਊਨਲੋਡ ਜਾਂ ਅੱਪਲੋਡ ਕਰਦੇ ਹੋ\n	• ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਉੱਚ ਤਾਪਮਾਨਾਂ ਵਿੱਚ ਵਰਤਦੇ ਹੋ"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"ਦੇਖਭਾਲ ਦੇ ਪੜਾਅ ਦੇਖੋ"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"ਫ਼ੋਨ ਗਰਮ ਹੋ ਰਿਹਾ ਹੈ"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"ਫ਼ੋਨ ਦੇ ਠੰਡਾ ਹੋਣ ਦੇ ਦੌਰਾਨ ਕੁਝ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਸੀਮਤ ਹੁੰਦੀਆਂ ਹਨ।\nਵਧੇਰੇ ਜਾਣਕਾਰੀ ਲਈ ਟੈਪ ਕਰੋ"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"ਤੁਹਾਡਾ ਫ਼ੋਨ ਸਵੈਚਲਿਤ ਰੂਪ ਵਿੱਚ ਠੰਡਾ ਹੋਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੇਗਾ। ਤੁਸੀਂ ਹਾਲੇ ਵੀ ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਵਰਤ ਸਕਦੇ ਹੋ, ਪਰੰਤੂ ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਇਹ ਵਧੇਰੇ ਹੌਲੀ ਚੱਲੇ।\n\nਇੱਕ ਵਾਰ ਠੰਡਾ ਹੋਣ ਤੋਂ ਬਾਅਦ ਤੁਹਾਡਾ ਫ਼ੋਨ ਸਧਾਰਨ ਤੌਰ \'ਤੇ ਚੱਲੇਗਾ।"</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"ਦੇਖਭਾਲ ਦੇ ਪੜਾਅ ਦੇਖੋ"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"ਆਪਣਾ ਡੀਵਾਈਸ ਅਣਪਲੱਗ ਕਰੋ"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਚਾਰਜਿੰਗ ਪੋਰਟ ਦੇ ਨੇੜੇ ਗਰਮ ਹੋ ਰਿਹਾ ਹੈ। ਜੇ ਇਹ ਕਿਸੇ ਚਾਰਜਰ ਜਾਂ USB ਐਕਸੈਸਰੀ ਨਾਲ ਕਨੈਕਟ ਹੈ, ਤਾਂ ਇਸਨੂੰ ਅਣਪਲੱਗ ਕਰੋ ਅਤੇ ਸਾਵਧਾਨ ਰਹੋ, ਕਿਉਂਕਿ ਕੇਬਲ ਵੀ ਗਰਮ ਹੋ ਸਕਦੀ ਹੈ।"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 5dcdd7e..757ffcd 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Włącz USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Więcej informacji"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Zrzut ekranu"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Wyłączono Extend Unlock"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Wyłączono rozszerzone odblokowanie"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"wysłano obraz"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Zapisywanie zrzutu ekranu..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Zapisuję zrzut ekranu w profilu służbowym…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu zasilania"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Strona <xliff:g id="ID_1">%1$d</xliff:g> z <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Ekran blokady"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon wyłączony: przegrzanie"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Telefon działa teraz normalnie\nKliknij, by dowiedzieć się więcej"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefon był zbyt gorący i wyłączył się, by obniżyć temperaturę. Urządzenie działa teraz normalnie.\n\nTelefon może się przegrzać, gdy:\n	• Używasz aplikacji zużywających dużo zasobów (np. gier, nawigacji czy odtwarzaczy filmów)\n	• Pobierasz lub przesyłasz duże pliki\n	• Używasz telefonu w wysokiej temperaturze"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Zobacz instrukcję postępowania"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Telefon się nagrzewa"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Podczas obniżania temperatury telefonu niektóre funkcje są ograniczone\nKliknij, by dowiedzieć się więcej"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Telefon automatycznie podejmie próbę obniżenia temperatury. Możesz go wciąż używać, ale telefon może działać wolniej.\n\nGdy temperatura się obniży, telefon będzie działał normalnie."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Zobacz instrukcję postępowania"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Odłącz urządzenie"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Urządzenie za bardzo się nagrzewa w okolicy gniazda ładowania. Jeśli jest podłączone do ładowarki albo akcesorium USB, odłącz je. Uważaj, bo kabel również może być nagrzany."</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 3ac3692..4ee6bd2 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Ativar USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Saiba mais"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Capturar tela"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock desativado"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Desbloqueio extra desativado"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"enviou uma imagem"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Salvando captura de tela..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Salvando captura de tela no perfil de trabalho…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu liga/desliga"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Tela de bloqueio"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"O smartphone foi desligado devido ao aquecimento"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"O smartphone está funcionando normalmente agora.\nToque para saber mais"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"O smartphone estava muito quente e foi desligado para resfriar. Agora, ele está sendo executado normalmente.\n\nO smartphone pode ficar quente demais se você:\n	• usar apps que consomem muitos recursos (como apps de jogos, vídeos ou navegação);\n	• fizer o download ou upload de arquivos grandes;\n	• usar o smartphone em temperaturas altas."</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Ver etapas de cuidado"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"O smartphone está esquentando"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Alguns recursos ficam limitados enquanto o smartphone é resfriado.\nToque para saber mais"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Seu smartphone tentará se resfriar automaticamente. Você ainda poderá usá-lo, mas talvez ele fique mais lento.\n\nQuando o smartphone estiver resfriado, ele voltará ao normal."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Ver etapas de cuidado"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Desconecte seu dispositivo"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Seu dispositivo está ficando quente perto da porta de carregamento. Desconecte qualquer carregador ou acessório USB que esteja conectado, mas tome cuidado, porque o cabo também pode estar quente."</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 6d54a64..f16b027 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Ativar USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Saiba mais"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Captura de ecrã"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Desbloqueio prolongado desativado"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Desbloqueio extra desativado"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"enviou uma imagem"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"A guardar captura de ecrã..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"A guardar captura de ecrã no perfil de trabalho…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu ligar/desligar"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Ecrã de bloqueio"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telem. deslig. devido ao calor"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"O seu telemóvel já está a funcionar normalmente.\nToque para obter mais informações."</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"O telemóvel estava muito quente, por isso desligou-se para arrefecer. Agora funciona normalmente.\n\nO telemóvel pode sobreaquecer se:\n	• Usar aplicações que utilizam mais recursos (jogos, vídeo ou aplicações de navegação)\n	• Transferir ou carregar ficheiros grandes\n	• Usar em altas temperaturas"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Veja os passos de manutenção"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"O telemóvel está a aquecer"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Algumas funcionalidades são limitadas enquanto o telemóvel arrefece.\nToque para obter mais informações."</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"O telemóvel tenta arrefecer automaticamente. Pode continuar a utilizá-lo, mas este poderá funcionar mais lentamente.\n\nAssim que o telemóvel tiver arrefecido, funcionará normalmente."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Veja os passos de manutenção"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Desligue o dispositivo"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"O dispositivo está a ficar quente perto da porta de carregamento. Se estiver ligado a um carregador ou um acessório USB, desligue-o e tenha cuidado, uma vez que o cabo também pode estar quente."</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 3ac3692..4ee6bd2 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Ativar USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Saiba mais"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Capturar tela"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock desativado"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Desbloqueio extra desativado"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"enviou uma imagem"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Salvando captura de tela..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Salvando captura de tela no perfil de trabalho…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu liga/desliga"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Tela de bloqueio"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"O smartphone foi desligado devido ao aquecimento"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"O smartphone está funcionando normalmente agora.\nToque para saber mais"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"O smartphone estava muito quente e foi desligado para resfriar. Agora, ele está sendo executado normalmente.\n\nO smartphone pode ficar quente demais se você:\n	• usar apps que consomem muitos recursos (como apps de jogos, vídeos ou navegação);\n	• fizer o download ou upload de arquivos grandes;\n	• usar o smartphone em temperaturas altas."</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Ver etapas de cuidado"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"O smartphone está esquentando"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Alguns recursos ficam limitados enquanto o smartphone é resfriado.\nToque para saber mais"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Seu smartphone tentará se resfriar automaticamente. Você ainda poderá usá-lo, mas talvez ele fique mais lento.\n\nQuando o smartphone estiver resfriado, ele voltará ao normal."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Ver etapas de cuidado"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Desconecte seu dispositivo"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Seu dispositivo está ficando quente perto da porta de carregamento. Desconecte qualquer carregador ou acessório USB que esteja conectado, mas tome cuidado, porque o cabo também pode estar quente."</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index d0764dd..e57eb5d 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Activează USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Mai multe"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Captură de ecran"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Funcția Extend Unlock este dezactivată"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Funcția Prelungirea deblocării este dezactivată"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"a trimis o imagine"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Se salvează captura de ecran..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Se salvează captura în profilul de serviciu…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Meniul de pornire"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Pagina <xliff:g id="ID_1">%1$d</xliff:g> din <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Ecran de blocare"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefonul s-a oprit din cauza încălzirii"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Acum telefonul funcționează normal.\nAtinge pentru mai multe informații"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefonul se încălzise prea mult și s-a oprit pentru a se răci. Acum telefonul funcționează normal.\n\nTelefonul s-ar putea încălzi prea mult dacă:\n	• folosești aplicații care consumă multe resurse (de ex., jocuri, aplicații video/de navigare);\n	• descarci/încarci fișiere mari;\n	• folosești telefonul la temperaturi ridicate."</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Vezi pașii pentru îngrijire"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Telefonul se încălzește"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Anumite funcții sunt limitate în timp ce telefonul se răcește.\nAtinge pentru mai multe informații."</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Telefonul va încerca automat să se răcească. Îl poți folosi în continuare, dar e posibil să funcționeze mai lent.\n\nDupă ce se răcește, telefonul va funcționa normal."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Vezi pașii pentru îngrijire"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Deconectează dispozitivul"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Dispozitivul se încălzește lângă portul de încărcare. Dacă este conectat la un încărcător sau accesoriu USB, deconectează-l și ai grijă, deoarece și cablul poate fi cald."</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 91a8534..70f6e15 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Включить USB-порт"</string>
     <string name="learn_more" msgid="4690632085667273811">"Подробнее"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Скриншот"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Функция \"Отложить блокировку\" отключена"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Отложенная блокировка отключена"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"отправлено изображение"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Сохранение..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Сохранение скриншота в рабочем профиле…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Меню кнопки питания"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Страница <xliff:g id="ID_1">%1$d</xliff:g> из <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Заблокированный экран"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Телефон выключился из-за перегрева"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Сейчас телефон работает нормально.\nНажмите, чтобы получить дополнительную информацию"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Ваш телефон выключился из-за перегрева. Сейчас он работает нормально.\n\nВозможные причины перегрева телефона:\n	• использование ресурсоемких игр и приложений, связанных с видео или навигацией);\n	• скачивание или загрузка больших файлов;\n	• высокая температура окружающей среды."</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Подробнее о действиях при перегреве…"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Телефон нагревается"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Пока телефон не остынет, некоторые функции могут быть недоступны.\nНажмите, чтобы получить дополнительную информацию"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Ваш телефон остынет автоматически.\n\nОбратите внимание, что до тех пор он может работать медленнее, чем обычно."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Подробнее о действиях при перегреве…"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Отключите устройство"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Устройство нагревается в районе зарядного порта. Если оно подключено к зарядному или USB-устройству, отключите его. Будьте осторожны: кабель тоже мог нагреться."</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 1efb408..b4dc0f2 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"බල මෙනුව"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> න් <xliff:g id="ID_1">%1$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"අගුලු තිරය"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"දුරකථනය රත් වීම නිසා ක්‍රියාවිරහිත කරන ලදී"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"ඔබගේ දුරකථනය දැන් සාමාන්‍ය ලෙස ධාවනය වේ.\nතව තතු සඳහා තට්ටු කරන්න"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"ඔබේ දුරකථනය ඉතාම උණුසුම්ය, එම නිසා එය සිසිල් වීමට ක්‍රියාවිරහිත කරන ලදී. ධැන් ඔබේ දුරකථනය සාමාන්‍ය පරිදි ධාවනය වේ.\n\nඔබ පහත දේවල් සිදු කළහොත් ඔබේ දුරකථනය ඉතාම උණුසුම් විය හැකිය:\n	• සම්පත්-දැඩි සත්කාරක යෙදුම් භාවිතය (ක්‍රීඩා, වීඩියෝ, හෝ සංචලන යෙදුම් යනාදී)\n	• විශාල ගොනු බාගැනීම හෝ උඩුගත කිරීම\n	• ඔබේ දුරකථනය අධික උෂ්ණත්වයේදී භාවිත කිරීම"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"රැකවරණ පියවර බලන්න"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"දුරකථනය උණුසුම් වෙමින්"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"දුරකථනය සිසිල් වන අතරතුර සමහර විශේෂාංග සීමිත විය හැකිය.\nතව තතු සඳහා තට්ටු කරන්න"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"ඔබගේ දුරකථනය ස්වයංක්‍රියව සිසිල් වීමට උත්සාහ කරනු ඇත. ඔබට තවම ඔබේ දුරකථනය භාවිත කළ හැකිය, නමුත් එය සෙමින් ධාවනය විය හැකිය.\n\nඔබේ දුරකථනය සිසිල් වූ පසු, එය සාමාන්‍ය ලෙස ධාවනය වනු ඇත."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"රැකවරණ පියවර බලන්න"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"ඔබේ උපාංගය ගලවන්න"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"ඔබේ උපාංගය ආරෝපණ කවුළුව අවට උණුසුම් වෙමින් පවතී. එය චාජරයකට හෝ USB උපාංගයකට සම්බන්ධ කර ඇත්නම්, එය ගලවා, කේබලය උණුසුම් විය හැකි බැවින් ප්‍රවේශම් වන්න."</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index b353293..802bd7a 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Povoliť USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Ďalšie informácie"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Snímka obrazovky"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Predĺžené odomknutie je vypnuté"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Rozšírené odomknutie je vypnuté"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"odoslal(a) obrázok"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Prebieha ukladanie snímky obrazovky..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Ukladá sa snímka obrazovky do pracovného profilu…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Ponuka vypínača"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Strana <xliff:g id="ID_1">%1$d</xliff:g> z <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Uzamknutá obrazovka"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefón sa vypol z dôvodu prehriatia"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Teraz telefón funguje ako obvykle.\nViac sa dozviete po klepnutí."</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefón bol príliš horúci, preto sa vypol, aby vychladol. Teraz funguje ako obvykle.\n\nTelefón sa môže príliš zahriať v týchto prípadoch:\n	• používanie náročných aplikácií (napr. hier, videí alebo navigácie);\n	• sťahovanie alebo nahrávanie veľkých súborov;\n	• používanie telefónu pri vysokých teplotách."</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Zobraziť opatrenia"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Teplota telefónu stúpa"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Niektoré funkcie budú obmedzené, dokým neklesne teplota telefónu.\nViac sa dozviete po klepnutí."</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Váš telefón sa automaticky pokúsi schladiť. Môžete ho naďalej používať, ale môže fungovať pomalšie.\n\nPo poklese teploty bude telefón fungovať ako normálne."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Zobraziť opatrenia"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Odpojte zariadenie"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Zariadenie sa zahrieva pri nabíjacom porte. Ak je pripojené k nabíjačke alebo príslušenstvu USB, odpojte ho a dajte pozor, lebo môže byť horúci aj kábel."</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 4dd753b..a303e20 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Omogoči USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Več o tem"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Posnetek zaslona"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Podaljšanje časa odklenjenosti je onemogočeno"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Razširjeno odklepanje je onemogočeno"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"je poslal(-a) sliko"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Shranjevanje posnetka zaslona ..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Shranjevanje posnetka zaslona v delovni profil …"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Meni za vklop/izklop"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>. stran od <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Zaklenjen zaslon"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Tel. izklopljen zaradi vročine"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Telefon zdaj deluje normalno.\nDotaknite se za več informacij"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefon je bil prevroč, zato se je izklopil, da se ohladi. Zdaj normalno deluje.\n\nTelefon lahko postane prevroč ob:\n	• uporabi aplikacij, ki intenzivno porabljajo sredstva (npr. za igranje iger, videoposnetke ali navigacijo)\n	• prenosu ali nalaganju velikih datotek\n	• uporabi telefona pri visokih temp."</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Oglejte si navodila za ukrepanje"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Telefon se segreva"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Nekatere funkcije bodo med ohlajanjem telefona omejene.\nDotaknite se za več informacij"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Telefon se bo samodejno poskusil ohladiti. Še naprej ga lahko uporabljate, vendar bo morda deloval počasneje.\n\nKo se telefon ohladi, bo zopet deloval kot običajno."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Oglejte si navodila za ukrepanje"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Odklopite napravo"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Naprava se segreva pri vratih za polnjenje. Če je priključena na polnilnik ali dodatek USB, ga odklopite in bodite tem previdni, saj je tudi kabel lahko topel."</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 475e799..4d0dcef 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Aktivizo USB-në"</string>
     <string name="learn_more" msgid="4690632085667273811">"Mëso më shumë"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Pamja e ekranit"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"\"Shkyçja e zgjeruar\" u çaktivizua"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"\"Shkyçja e zgjatur\" u çaktivizua"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"dërgoi një imazh"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Po ruan pamjen e ekranit…"</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Pamja e ekranit po ruhet te profili i punës…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menyja e energjisë"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Faqja <xliff:g id="ID_1">%1$d</xliff:g> nga <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Ekrani i kyçjes"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefoni u fik për shkak të nxehtësisë"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Telefoni tani punon normalisht.\nTrokit për më shumë informacione"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefoni yt ishte tepër i nxehtë, prandaj u fik për t\'u ftohur. Telefoni tani punon normalisht.\n\nTelefoni mund të nxehet së tepërmi nëse ti:\n	• Përdor aplikacione intensive për burimet (siç janë aplikacionet e lojërave, videove apo aplikacionet e navigimit)\n	• Shkarkon ose ngarkon skedarë të mëdhenj\n	• E përdor telefonin në temperatura të larta"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Shiko hapat për kujdesin"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Telefoni po bëhet i ngrohtë"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Disa veçori janë të kufizuara kur telefoni është duke u ftohur.\nTrokit për më shumë informacione"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Telefoni yt do të përpiqet automatikisht që të ftohet. Mund ta përdorësh përsëri telefonin, por ai mund të punojë më ngadalë.\n\nPasi telefoni të jetë ftohur, ai do të punojë si normalisht."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Shiko hapat për kujdesin"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Shkëpute pajisjen"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Pajisja jote po nxehet pranë portës së karikimit. Nëse është lidhur me një karikues ose një aksesor USB, shkëpute dhe trego kujdes pasi kablloja mund të jetë e nxehtë po ashtu."</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index eb69224..6227d5d 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Мени дугмета за укључивање"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>. страна од <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Закључан екран"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Телефон се искључио због топлоте"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Телефон сада нормално ради.\nДодирните за више информација"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Телефон је био преврућ, па се искључио да се охлади. Сада ради нормално.\n\nТелефон може превише да се угреје ако:\n	• Користите апликације које захтевају пуно ресурса (нпр. видео игре, видео или апликације за навигацију)\n	• Преузимате/отпремате велике датотеке\n	• Користите телефон на високој температури"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Погледајте упозорења"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Телефон се загрејао"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Неке функције су ограничене док се телефон не охлади.\nДодирните за више информација"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Телефон ће аутоматски покушати да се охлади. И даље ћете моћи да користите телефон, али ће спорије реаговати.\n\nКада се телефон охлади, нормално ће радити."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Погледајте упозорења"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Искључите уређај"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Уређај се загрева у близини порта за пуњење. Ако је повезан са пуњачем или USB опремом, искључите је и будите пажљиви јер и кабл може да буде врућ."</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 7e2e006..7cf096f4 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Aktivera USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Läs mer"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Skärmbild"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock har inaktiverats"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Håll olåst har inaktiverats"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"har skickat en bild"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Skärmbilden sparas ..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Sparar skärmbild i jobbprofilen …"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Startmeny"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Sida <xliff:g id="ID_1">%1$d</xliff:g> av <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Låsskärm"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Mobilen stängdes av pga. värme"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Telefonen fungerar nu som vanligt.\nTryck för mer information"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Mobilen var för varm och stängdes av för att kylas ned. Den fungerar nu som vanligt.\n\nMobilen kan bli för varm om du\n	• använder resurskrävande appar (till exempel spel-, video- eller navigeringsappar)\n	• laddar ned eller laddar upp stora filer\n	• använder mobilen vid höga temperaturer."</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Visa alla skötselråd"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Mobilen börjar bli varm"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Vissa funktioner är begränsade medan telefonen svalnar.\nTryck för mer information"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Mobilen försöker svalna automatiskt. Du kan fortfarande använda mobilen, men den kan vara långsammare än vanligt.\n\nMobilen fungerar som vanligt när den har svalnat."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Visa alla skötselråd"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Koppla ur enheten"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Enheten börjar bli varm vid laddningsporten. Om den är ansluten till en laddare eller ett USB-tillbehör kopplar du ur den. Var försiktigt eftersom kabeln också kan vara varm."</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 676edb7..892d369 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Washa kipengele cha USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Pata maelezo zaidi"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Picha ya skrini"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Kipengele cha Kuongeza muda wa Kutofunga Skrini kimezimwa"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Kiongeza Muda wa Kutofunga Skrini kimezimwa"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"imetuma picha"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Inahifadhi picha ya skrini..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Inahifadhi picha ya skrini kwenye wasifu wa kazini…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menyu ya kuzima/kuwasha"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Ukurasa wa <xliff:g id="ID_1">%1$d</xliff:g> kati ya <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Skrini iliyofungwa"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Simu ilizima kutokana na joto"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Simu yako sasa inafanya kazi ipasavyo.\nGusa ili upate maelezo zaidi"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Simu yako ilikuwa moto sana, kwa hivyo ilijizima ili ipoe. Simu yako sasa inafanya kazi ipasavyo.\n\nSimu yako inaweza kuwa moto sana ikiwa:\n	• Unatumia programu zinazotumia vipengee vingi (kama vile michezo ya video, video au programu za uelekezaji)\n	• Unapakua au upakie faili kubwa\n	• Unatumia simu yako katika maeneo yenye halijoto ya juu"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Angalia hatua za utunzaji"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Joto la simu linaongezeka"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Baadhi ya vipengele havitatumika kwenye simu wakati inapoa.\nGusa ili upate maelezo zaidi"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Simu yako itajaribu kupoa kiotomatiki. Bado unaweza kutumia simu yako, lakini huenda ikafanya kazi polepole. \n\nPindi simu yako itakapopoa, itaendelea kufanya kazi kama kawaida."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Angalia hatua za utunzaji"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Chomoa kifaa chako"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Kifaa chako kinapata joto karibu na mlango wa kuchaji. Ikiwa kimeunganishwa kwenye chaja au kifuasi cha USB, kichomoe na uwe makini kwani kebo inaweza kuwa imepata joto."</string>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index 9a2db6bfd..2b1d9d6 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -53,6 +53,9 @@
 
     <dimen name="navigation_key_padding">25dp</dimen>
 
+    <!-- width of ImmersiveModeConfirmation (-1 for match_parent) -->
+    <dimen name="immersive_mode_cling_width">380dp</dimen>
+
     <!-- Keyboard shortcuts helper -->
     <dimen name="ksh_layout_width">488dp</dimen>
 
@@ -74,6 +77,9 @@
     <dimen name="large_dialog_width">472dp</dimen>
 
     <dimen name="large_screen_shade_header_height">42dp</dimen>
+    <!-- start padding is smaller to account for status icon margins coming from drawable itself -->
+    <dimen name="shade_header_system_icons_padding_start">11dp</dimen>
+    <dimen name="shade_header_system_icons_padding_end">12dp</dimen>
 
     <!-- Lockscreen shade transition values -->
     <dimen name="lockscreen_shade_transition_by_tap_distance">200dp</dimen>
diff --git a/packages/SystemUI/res/values-sw720dp/dimens.xml b/packages/SystemUI/res/values-sw720dp/dimens.xml
index d053a7a..de913ac 100644
--- a/packages/SystemUI/res/values-sw720dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp/dimens.xml
@@ -20,13 +20,16 @@
     <dimen name="status_bar_icons_padding_start">10dp</dimen>
 
     <!-- gap on either side of status bar notification icons -->
-    <dimen name="status_bar_icon_horizontal_margin">1dp</dimen>
+    <dimen name="status_bar_icon_horizontal_margin">1sp</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>
 
+    <!-- it's a bit smaller on 720dp to account for status_bar_icon_horizontal_margin -->
+    <dimen name="shade_header_system_icons_padding_start">10dp</dimen>
+
     <!-- Biometric Auth pattern view size, better to align keyguard_security_width -->
     <dimen name="biometric_auth_pattern_view_size">348dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 390bd47..3378e13 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USBயை இயக்கு"</string>
     <string name="learn_more" msgid="4690632085667273811">"மேலும் அறிக"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"ஸ்கிரீன்ஷாட்"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"நீண்டநேர அன்லாக் அம்சம் முடக்கப்பட்டது"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"அன்லாக் நீட்டிப்பு அம்சம் முடக்கப்பட்டது"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"படம் அனுப்பப்பட்டது"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"ஸ்க்ரீன் ஷாட்டைச் சேமிக்கிறது…"</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"பணிக் கணக்கில் ஸ்கிரீன்ஷாட் சேமிக்கப்படுகிறது…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"பவர் மெனு"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"பக்கம் <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"லாக் ஸ்கிரீன்"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"வெப்பத்தினால் ஃபோன் ஆஃப் செய்யப்பட்டது"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"இப்போது உங்கள் மொபைல் இயல்புநிலையில் இயங்குகிறது.\nமேலும் தகவலுக்கு தட்டவும்"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"உங்கள் ஃபோன் அதிகமாகச் சூடானதால், அதன் சூட்டைக் குறைக்க, ஆஃப் செய்யப்பட்டது. இப்போது உங்கள் ஃபோன் இயல்புநிலையில் இயங்குகிறது.\n\nபின்வருவனவற்றைச் செய்தால், ஃபோன் சூடாகலாம்:\n	• அதிகளவு தரவைப் பயன்படுத்தும் ஆப்ஸை (எ.கா: கேமிங், வீடியோ (அ) வழிகாட்டுதல் ஆப்ஸ்) பயன்படுத்துவது\n	• பெரிய ஃபைல்களைப் பதிவிறக்குவது/பதிவேற்றுவது\n	• அதிக வெப்பநிலையில் ஃபோனைப் பயன்படுத்துவது"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"மேலும் விவரங்களுக்கு இதைப் பார்க்கவும்"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"மொபைல் சூடாகிறது"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"மொபைலின் வெப்ப அளவு குறையும் வரை சில அம்சங்களைப் பயன்படுத்த முடியாது.\nமேலும் தகவலுக்கு தட்டவும்"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"உங்கள் மொபைலின் வெப்ப அளவு தானாகவே குறையும். தொடர்ந்து நீங்கள் மொபைலைப் பயன்படுத்தலாம், ஆனால் அதன் வேகம் குறைவாக இருக்கக்கூடும்.\n\nமொபைலின் வெப்ப அளவு குறைந்தவுடன், அது இயல்பு நிலையில் இயங்கும்."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"மேலும் விவரங்களுக்கு இதைப் பார்க்கவும்"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"சாதன இணைப்பைத் துண்டித்தல்"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"சார்ஜிங் போர்ட்டிற்கு அருகே உங்கள் சாதனம் சூடாகிறது. சார்ஜருடனோ USB உபகரணத்துடனோ சாதனம் இணைக்கப்பட்டிருந்தால் அதன் இணைப்பைத் துண்டிக்கவும். கேபிளும் சூடாக இருக்கக்கூடும் என்பதால் கவனத்துடன் கையாளவும்."</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index a6cbf3d..9e50548 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USBని ప్రారంభించండి"</string>
     <string name="learn_more" msgid="4690632085667273811">"మరింత తెలుసుకోండి"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"స్క్రీన్‌షాట్"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"అన్‌లాక్‌ను పొడిగించడం డిజేబుల్ చేయబడింది"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"ఎక్స్‌టెండ్ అన్‌లాక్ డిజేబుల్ చేయబడింది"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ఇమేజ్‌ను పంపారు"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"స్క్రీన్‌షాట్‌ను సేవ్ చేస్తోంది…"</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"స్క్రీన్‌షాట్‌ను వర్క్ ప్రొఫైల్‌కు సేవ్ చేస్తోంది…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"పవర్ మెనూ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g>లో <xliff:g id="ID_1">%1$d</xliff:g>వ పేజీ"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"లాక్ స్క్రీన్"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"వేడెక్కినందుకు ఫోన్ ఆఫ్ చేయబడింది"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"మీ ఫోన్ ఇప్పుడు సాధారణంగా పని చేస్తోంది.\nమరింత సమాచారం కోసం ట్యాప్ చేయండి"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"మీ ఫోన్ చాలా వేడిగా ఉంది, కనుక చల్లబర్చడానికి ఆఫ్ చేయబడింది. మీ ఫోన్ ఇప్పుడు సాధారణంగా పని చేస్తుంది.\n\nమీరు ఇలా చేస్తే మీ ఫోన్ చాలా వేడెక్కవచ్చు:\n	• వనరు-ఆధారిత యాప్‌లు (గేమింగ్, వీడియో లేదా నావిగేషన్ వంటి యాప్‌లు) ఉపయోగించడం\n	• పెద్ద ఫైళ్లను డౌన్‌లోడ్ లేదా అప్‌లోడ్ చేయడం\n	• అధిక ఉష్ణోగ్రతలలో మీ ఫోన్‌ని ఉపయోగించడం"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"తీసుకోవాల్సిన జాగ్రత్తలు ఏమిటో చూడండి"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"ఫోన్ వేడెక్కుతోంది"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"ఫోన్‌ను చల్లబరిచే క్రమంలో కొన్ని ఫీచర్లు పరిమితం చేయబడ్డాయి.\nమరింత సమాచారం కోసం ట్యాప్ చేయండి"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"మీ ఫోన్ ఆటోమేటిక్‌గా చల్లబడటానికి ప్రయత్నిస్తుంది. మీరు ఇప్పటికీ మీ ఫోన్‌ను ఉపయోగించవచ్చు, కానీ దాని పనితీరు నెమ్మదిగా ఉండవచ్చు.\n\nమీ ఫోన్ చల్లబడిన తర్వాత, అది సాధారణ రీతిలో పని చేస్తుంది."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"తీసుకోవాల్సిన జాగ్రత్తలు ఏమిటో చూడండి"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"మీ పరికరాన్ని అన్‌ప్లగ్ చేయండి"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"ఛార్జింగ్ పోర్ట్ దగ్గర ఉంచినప్పుడు మీ పరికరం వేడెక్కుతోంది. ఇది ఛార్జర్ లేదా USB యాక్సెసరీకి కనెక్ట్ చేసి ఉంటే, దాన్ని అన్‌ప్లగ్ చేసి, కేబుల్ వేడెక్కే అవకాశం కూడా ఉన్నందున జాగ్రత్త వహించండి."</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 307d113..554324a 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"เปิดใช้ USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"ดูข้อมูลเพิ่มเติม"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"ภาพหน้าจอ"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"ปิดใช้ฟีเจอร์ขยายเวลาปลดล็อกอยู่"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"ปิดใช้ฟีเจอร์ปลดล็อกต่อเนื่องอยู่"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ส่งรูปภาพ"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"กำลังบันทึกภาพหน้าจอ..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"กำลังบันทึกภาพหน้าจอไปยังโปรไฟล์งาน…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"เมนูเปิด/ปิด"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"หน้า <xliff:g id="ID_1">%1$d</xliff:g> จาก <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"หน้าจอล็อก"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"โทรศัพท์ปิดไปเพราะร้อนมาก"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"ขณะนี้โทรศัพท์ทำงานเป็นปกติ\nแตะเพื่อดูข้อมูลเพิ่มเติม"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"โทรศัพท์ร้อนเกินไปจึงปิดเครื่องเพื่อให้เย็นลง ขณะนี้โทรศัพท์ทำงานเป็นปกติ\n\nโทรศัพท์อาจร้อนเกินไปหากคุณ\n	• ใช้แอปที่ใช้ทรัพยากรมาก (เช่น เกม วิดีโอ หรือแอปการนำทาง)\n	• ดาวน์โหลดหรืออัปโหลดไฟล์ขนาดใหญ่\n	• ใช้โทรศัพท์ในอุณหภูมิที่สูง"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"ดูขั้นตอนในการดูแลรักษา"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"โทรศัพท์เริ่มเครื่องร้อน"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"ฟีเจอร์บางอย่างจะใช้งานได้จำกัดขณะโทรศัพท์เย็นลง\nแตะเพื่อดูข้อมูลเพิ่มเติม"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"โทรศัพท์จะพยายามลดอุณหภูมิลงโดยอัตโนมัติ คุณยังสามารถใช้โทรศัพท์ได้ แต่โทรศัพท์อาจทำงานช้าลง\n\nโทรศัพท์จะทำงานตามปกติเมื่อเย็นลงแล้ว"</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"ดูขั้นตอนในการดูแลรักษา"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"ถอดปลั๊กอุปกรณ์"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"บริเวณพอร์ตชาร์จของอุปกรณ์เริ่มจะร้อนแล้ว หากมีที่ชาร์จหรืออุปกรณ์เสริม USB เสียบอยู่ ให้ถอดออกอย่างระมัดระวังเพราะสายเส้นนั้นก็อาจจะร้อนด้วยเช่นกัน"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 3997539..2c632ec 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> ng <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Na-off ang telepono dahil sa init"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Maayos na ngayong gumagana ang iyong telepono.\nMag-tap para sa higit pang impormasyon"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Napakainit ng telepono, kaya nag-off ito para lumamig. Maayos na itong gumagana.\n\nMaaaring lubos na uminit ang telepono kapag:\n	• Gumamit ka ng resource-intensive na app (gaya ng app para sa gaming, video, o navigation)\n	• Nag-download o nag-upload ka ng malaking file\n • Ginamit mo ito sa mainit na lugar"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Tingnan ang mga hakbang sa pangangalaga"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Umiinit ang telepono"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Limitado ang ilang feature habang nagku-cool down ang telepono.\nMag-tap para sa higit pang impormasyon"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Awtomatikong susubukan ng iyong telepono na mag-cool down. Magagamit mo pa rin ang iyong telepono, ngunit maaaring mas mabagal ang paggana nito.\n\nKapag nakapag-cool down na ang iyong telepono, gagana na ito nang normal."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Tingnan ang mga hakbang sa pangangalaga"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Bunutin sa saksakan ang device"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Umiinit ang iyong device malapit sa charging port. Kung nakakonekta ito sa charger o USB accessory, bunutin ito sa saksakan, at mag-ingat dahil posibleng mainit din ang cable."</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 6962aa4..8430771 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB\'yi etkinleştir"</string>
     <string name="learn_more" msgid="4690632085667273811">"Daha fazla bilgi"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Ekran görüntüsü"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock devre dışı"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Artırılmış Kilit Açma devre dışı"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"bir resim gönderildi"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Ekran görüntüsü kaydediliyor..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Ekran görüntüsü iş profiline kaydediliyor…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Güç menüsü"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Sayfa <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Kilit ekranı"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon ısındığından kapatıldı"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Telefonunuz şu anda normal bir şekilde çalışıyor.\nDaha fazla bilgi için dokunun"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefonunuz çok ısındığından soğuması için kapatıldı ve şu anda normal bir şekilde çalışıyor.\n\nTelefon şu koşullarda çok ısınabilir:\n	• Yoğun kaynak gerektiren uygulamalar (oyun, video veya gezinme uygulamaları gibi) kullanma\n	• Büyük dosyalar indirme veya yükleme\n	• Telefonu sıcak yerlerde kullanma"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Bakımla ilgili adımlara bakın"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Telefon ısınıyor"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Telefon soğurken bazı özellikler sınırlı olarak kullanılabilir.\nDaha fazla bilgi için dokunun"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Telefonunuz otomatik olarak soğumaya çalışacak. Bu sırada telefonunuzu kullanmaya devam edebilirsiniz ancak uygulamalar daha yavaş çalışabilir.\n\nTelefonunuz soğuduktan sonra normal şekilde çalışacaktır."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Bakımla ilgili adımlara bakın"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Cihazınızın fişini çekin"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Cihazınız, şarj yuvasının yakınındayken ısınıyor. Şarj cihazına veya USB aksesuarına bağlıysa cihazı çıkarın. Ayrıca, kablo sıcak olabileceği için dikkatli olun."</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 93807d0..b3ee948 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Увімкнути USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Докладніше"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Знімок екрана"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock вимкнено"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Відкладене блокування вимкнено"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"надіслане зображення"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Збереження знімка екрана..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Зберігання знімка екрана в робочому профілі…"</string>
@@ -143,7 +143,7 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Підтверджено"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Щоб завершити, натисніть \"Підтвердити\""</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="2378151312221818694">"Розблоковано (фейс-контроль)"</string>
-    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Розблоковано (фейсконтроль). Натисніть, щоб продовжити."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Розблоковано (фейс-контроль). Натисніть, щоб продовжити."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Обличчя розпізнано. Натисніть, щоб продовжити."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Обличчя розпізнано. Натисніть значок розблокування."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Автентифіковано"</string>
@@ -185,7 +185,7 @@
     <skip />
     <string name="keyguard_face_failed" msgid="9044619102286917151">"Обличчя не розпізнано"</string>
     <string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Скористайтеся відбитком"</string>
-    <string name="keyguard_face_unlock_unavailable" msgid="1581949044193418736">"Фейсконтроль недоступний"</string>
+    <string name="keyguard_face_unlock_unavailable" msgid="1581949044193418736">"Фейс-контроль недоступний"</string>
     <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth під’єднано."</string>
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Відсоток заряду акумулятора невідомий."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Підключено до <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
@@ -351,12 +351,12 @@
     <string name="tap_again" msgid="1315420114387908655">"Натисніть знову"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Проведіть пальцем угору, щоб відкрити"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Щоб відкрити, натисніть значок розблокування."</string>
-    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Розблоковано (фейсконтроль). Відкрити: проведіть угору."</string>
-    <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Розблоковано (фейсконтроль). Натисніть значок розблокування."</string>
-    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Розблоковано (фейсконтроль). Натисніть, щоб відкрити."</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Розблоковано (фейс-контроль). Відкрити: проведіть угору."</string>
+    <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Розблоковано (фейс-контроль). Натисніть значок розблокування."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Розблоковано (фейс-контроль). Натисніть, щоб відкрити."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Обличчя розпізнано. Натисніть, щоб відкрити."</string>
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Обличчя розпізнано. Натисніть значок розблокування."</string>
-    <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Розблоковано (фейсконтроль)"</string>
+    <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Розблоковано (фейс-контроль)"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Обличчя розпізнано"</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Проведіть пальцем угору, щоб повторити спробу"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Розблокуйте екран, щоб скористатись NFC"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Меню кнопки живлення"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Сторінка <xliff:g id="ID_1">%1$d</xliff:g> з <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Заблокований екран"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Телефон перегрівся й вимкнувся"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Зараз телефон працює як зазвичай.\nНатисніть, щоб дізнатися більше"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Телефон перегрівся, тому вимкнувся, щоб охолонути. Зараз він працює, як зазвичай.\n\nТелефон перегрівається, якщо ви:\n	• використовуєте ресурсомісткі додатки (ігри, відео, навігація)\n	• завантажуєте великі файли на телефон або з нього\n	• використовуєте телефон за високої температури"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Переглянути запобіжні заходи"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Телефон нагрівається"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Під час охолодження деякі функції обмежуються.\nНатисніть, щоб дізнатися більше"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Ваш телефон охолоджуватиметься автоматично. Ви можете далі користуватися телефоном, але він може працювати повільніше.\n\nКоли телефон охолоне, він працюватиме належним чином."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Переглянути запобіжні заходи"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Від’єднайте пристрій"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Пристрій нагрівається біля зарядного порту. Якщо він під’єднаний до зарядного пристрою або USB-аксесуара, від’єднайте його, однак будьте обережні, оскільки кабель також може бути гарячий."</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index ff4965f..3f47187 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"‏USB پورٹ فعال کریں"</string>
     <string name="learn_more" msgid="4690632085667273811">"مزید جانیں"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"اسکرین شاٹ"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"اَن لاک کی توسیع کو غیر فعال کیا گیا"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"اَن لاک کا دورانیہ بڑھائیں کو غیر فعال کیا گیا"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ایک تصویر بھیجی"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"اسکرین شاٹ محفوظ ہو رہا ہے…"</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"اسکرین شاٹ دفتری پروفائل میں محفوظ کیا جا رہا ہے…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"پاور مینیو"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"صفحہ <xliff:g id="ID_1">%1$d</xliff:g> از <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"مقفل اسکرین"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"حرارت کی وجہ سے فون آف ہو گیا"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"آپ کا فون اب حسب معمول چل رہا ہے۔\nمزید معلومات کیلئے تھپتھپائیں"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"آپ کا فون کافی گرم ہو گيا تھا، اس لئے سرد ہونے کیلئے یہ آف ہو گیا۔ اب آپ کا فون حسب معمول کام کر رہا ہے۔\n\nمندرجہ ذیل چیزیں کرنے پر آپ کا فون کافی گرم ہو سکتا ہے:\n	• ماخذ کا زیادہ استعمال کرنے والی ایپس (جیسے کہ گیمنگ، ویڈیو، یا نیویگیشن ایپس) کا استعمال کرنا\n	• بڑی فائلز ڈاؤن لوڈ یا اپ لوڈ کرنا\n	• اعلی درجہ حرارت میں فون کا استعمال کرنا"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"نگہداشت کے اقدامات ملاحظہ کریں"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"فون گرم ہو رہا ہے"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"فون کے ٹھنڈے ہو جانے تک کچھ خصوصیات محدود ہیں۔\nمزید معلومات کیلئے تھپتھپائیں"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"آپ کا فون خودکار طور پر ٹھنڈا ہونے کی کوشش کرے گا۔ آپ ابھی بھی اپنا فون استعمال کر سکتے ہیں، مگر ہو سکتا ہے یہ سست چلے۔\n\nایک بار آپ کا فون ٹھنڈا ہوجائے تو یہ معمول کے مطابق چلے گا۔"</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"نگہداشت کے اقدامات ملاحظہ کریں"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"اپنے آلہ کو ان پلگ کریں"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"‏آپ کا آلہ چارجنگ پورٹ کے قریب گرم ہو رہا ہے۔ اگر یہ چارجر یا USB لوازمات سے منسلک ہے تو اسے ان پلگ کریں اور خیال رکھیں کہ کیبل بھی گرم ہو سکتی ہے۔"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 538fe16d..499eb1b 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB xususiyatini yoqish"</string>
     <string name="learn_more" msgid="4690632085667273811">"Batafsil"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Skrinshot"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Kengaytirilgan ochish yoniq emas"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock yoniq emas"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"rasm yuborildi"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Skrinshot saqlanmoqda…"</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Skrinshot ish profiliga saqlanmoqda…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Quvvat menyusi"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>-sahifa, jami: <xliff:g id="ID_2">%2$d</xliff:g> ta sahifa"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Ekran qulfi"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Qizigani uchun o‘chirildi"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Endi telefoningiz normal holatda ishlayapti.\nBatafsil axborot uchun bosing"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefon qizib ketganligi sababli sovitish uchun o‘chirib qo‘yilgan. Endi telefoningiz normal holatda ishlayapti.\n\nTelefon bu hollarda qizib ketishi mumkin:\n	• Resurstalab ilovalar ishlatilganda (masalan, o‘yin, video yoki navigatsiya ilovalari)\n	• Katta faylni yuklab olishda yoki yuklashda\n	• Telefondan yuqori haroratda foydalanganda"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Batafsil axborot"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Telefon qizib ketdi"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Telefon sovib qolganda ayrim funksiyalari ishlamasligi mumkin.\nBatafsil axborot uchun bosing"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Telefon avtomatik ravishda o‘zini sovitadi. Telefoningizdan foydalanishda davom etishingiz mumkin, lekin u sekinroq ishlashi mumkin.\n\nTelefon sovishi bilan normal holatda ishlashni boshlaydi."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Batafsil axborot"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Qurilmani uzing"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Qurilmangiz quvvatlash porti yaqinida qizib ketmoqda. Agar quvvatlagich yoki USB aksessuarga ulangan boʻlsa, kabel qizib ketmasidan uni darhol uzing."</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 4120e57e..1d96b1e 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -69,7 +69,7 @@
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Bật USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Tìm hiểu thêm"</string>
     <string name="global_action_screenshot" msgid="2760267567509131654">"Chụp ảnh màn hình"</string>
-    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Đã tắt tính năng Luôn mở khoá"</string>
+    <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Đã tắt tính năng Kéo dài trạng thái mở khoá"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"đã gửi hình ảnh"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Đang lưu ảnh chụp màn hình..."</string>
     <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Đang lưu ảnh chụp màn hình vào hồ sơ công việc…"</string>
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Trình đơn nguồn"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Trang <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Màn hình khóa"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Điện thoại đã tắt do nhiệt"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Điện thoại của bạn đang chạy bình thường.\nHãy nhấn để biết thêm thông tin"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Do quá nóng nên điện thoại đã tắt để hạ nhiệt. Hiện điện thoại của bạn đang chạy bình thường.\n\nĐiện thoại có thể bị quá nóng nếu bạn:\n	• Dùng các ứng dụng tốn nhiều tài nguyên (như ứng dụng trò chơi, video hoặc điều hướng)\n	• Tải xuống hoặc tải lên tệp có dung lượng lớn\n	• Dùng điện thoại ở nhiệt độ cao"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Xem các bước chăm sóc"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Điện thoại đang nóng lên"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Một số tính năng bị hạn chế trong khi điện thoại nguội dần.\nHãy nhấn để biết thêm thông tin"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Điện thoại của bạn sẽ tự động nguội dần. Bạn vẫn có thể sử dụng điện thoại, nhưng điện thoại có thể chạy chậm hơn. \n\nSau khi đã nguội, điện thoại sẽ chạy bình thường."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Xem các bước chăm sóc"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Rút thiết bị ra"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Phần gần cổng sạc của thiết bị đang nóng lên. Nếu thiết bị kết nối với bộ sạc hoặc phụ kiện USB, hãy rút ra một cách thận trọng vì cáp có thể cũng đang nóng."</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index e167c61..0699551 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"电源菜单"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"第 <xliff:g id="ID_1">%1$d</xliff:g> 页,共 <xliff:g id="ID_2">%2$d</xliff:g> 页"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"锁定屏幕"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"手机因严重发热而自动关机"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"现在,您的手机已恢复正常运行。\n点按即可了解详情"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"由于发热严重,因此您的手机执行了自动关机以降温。现在,您的手机已恢复正常运行。\n\n以下情况可能会导致您的手机严重发热:\n • 使用占用大量资源的应用(例如游戏、视频或导航应用)\n • 下载或上传大型文件\n • 在高温环境下使用手机"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"查看处理步骤"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"手机温度上升中"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"手机降温时,部分功能的使用会受限制。\n点按即可了解详情"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"您的手机将自动尝试降温。您依然可以使用您的手机,但是手机运行速度可能会更慢。\n\n手机降温后,就会恢复正常的运行速度。"</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"查看处理步骤"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"拔出设备"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"设备的充电接口附近在发热。如果该设备已连接到充电器或 USB 配件,请立即拔掉,并注意充电线也可能会发热。"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 4066a89..7160b56 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"電源選單"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"第 <xliff:g id="ID_1">%1$d</xliff:g> 頁 (共 <xliff:g id="ID_2">%2$d</xliff:g> 頁)"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"螢幕鎖定"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"手機因過熱而關上"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"你的手機現已正常運作。\n輕按即可瞭解詳情"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"你的手機之前因過熱而關上降溫。手機現已正常運作。\n\n以下情況可能會導致手機過熱:\n	• 使用耗用大量資源的應用程式 (例如遊戲、影片或導航應用程式)\n	• 下載或上載大型檔案\n	• 在高溫環境下使用手機"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"查看保養步驟"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"手機溫度正在上升"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"手機降溫時,部分功能會受限制。\n輕按即可瞭解詳情"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"手機會自動嘗試降溫。你仍可以使用手機,但手機的運作速度可能較慢。\n\n手機降溫後便會恢復正常。"</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"查看保養步驟"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"拔除裝置"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"充電埠附近的裝置溫度正在上升。如裝置正連接充電器或 USB 配件,請拔除裝置並小心安全,因為電線的溫度可能也偏高。"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 7abe1de..0deba33 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"電源鍵選單"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"第 <xliff:g id="ID_1">%1$d</xliff:g> 頁,共 <xliff:g id="ID_2">%2$d</xliff:g> 頁"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"鎖定畫面"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"手機先前過熱,因此關閉電源"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"手機現在已恢復正常運作。\n輕觸即可瞭解詳情"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"手機先前的溫度過高,因此關閉了電源以進行降溫。手機現在已恢復正常運作。\n\n以下情況可能會導致你的手機溫度過高:\n	• 使用需要密集處理資料的應用程式 (例如遊戲、影片或導航應用程式)\n	• 下載或上傳大型檔案\n	• 在高溫環境下使用手機"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"查看處理步驟"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"手機變熱"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"手機降溫時,某些功能會受限。\n輕觸即可瞭解詳情"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"手機會自動嘗試降溫。你仍可繼續使用手機,但是手機的運作速度可能會較慢。\n\n手機降溫完畢後,就會恢復正常的運作速度。"</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"查看處理步驟"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"拔除裝置"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"裝置的充電埠附近越來越熱。如果裝置已連接充電器或 USB 配件,請立即拔除。此外,電線也可能會變熱,請特別留意。"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index e5b4c14..eb8ee45 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -759,13 +759,7 @@
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Imenyu yamandla"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Ikhasi <xliff:g id="ID_1">%1$d</xliff:g> kwangu-<xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Khiya isikrini"</string>
-    <string name="thermal_shutdown_title" msgid="2702966892682930264">"Ifoni ivaliwe ngenxa yokushisa"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"Ifoni yakho manje isebenza ngokuvamile.\nThepha ukuze uthole ulwazi olungeziwe"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Ifoni yakho ibishisa kakhulu, ngakho-ke yacisha ukuze iphole. Ifoni yakho manje isebenza ngokuvamile.\n\nIfoni yakho ingashisa kakhulu uma:\n	• Usebenzisa izinhlelo zokusebenza ezinkulu (njegegeyimu, ividiyo, noma izinhlelo zokusebenza zokuzula)\n	• Landa noma layisha amafayela amakhulu\n	• Sebenzisa ifoni yakho kumathempelesha aphezulu"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Bona izinyathelo zokunakekelwa"</string>
-    <string name="high_temp_title" msgid="2218333576838496100">"Ifoni iyafudumala"</string>
-    <string name="high_temp_notif_message" msgid="1277346543068257549">"Ezinye izici zikhawulelwe ngenkathi ifoni iphola.\nThepha mayelana nolwazi olwengeziwe"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"Ifoni yakho izozama ngokuzenzakalela ukuphola. Ungasasebenzisa ifoni yakho, kodwa ingasebenza ngokungasheshi.\n\nUma ifoni yakho isipholile, izosebenza ngokuvamile."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Bona izinyathelo zokunakekelwa"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"Khipha idivayisi yakho"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Idivayisi yakho iqala ukufudumala eduze kwembobo yokushaja. Uma ixhunywe kushaja noma insiza ye-USB, yikhiphe, futhi uqaphele njengoba ikhebuli ingase ifudumale."</string>
diff --git a/packages/SystemUI/res/values/bools.xml b/packages/SystemUI/res/values/bools.xml
index 04fc4b8..405a59f 100644
--- a/packages/SystemUI/res/values/bools.xml
+++ b/packages/SystemUI/res/values/bools.xml
@@ -30,4 +30,25 @@
 
     <!-- Whether to enable transparent background for notification scrims -->
     <bool name="notification_scrim_transparent">false</bool>
+
+    <!-- Control whether to force apps to give up control over the display of system bars at all
+     times regardless of System Ui Flags.
+     In the Automotive case, this is helpful if there's a requirement for an UI element to be on
+     screen at all times. Setting this to true also gives System UI the ability to override the
+     visibility controls for the system through the usage of the
+     "SYSTEM_BAR_VISIBILITY_OVERRIDE" setting.
+     Ex: Only setting the config to true will force show system bars for the entire system.
+     Ex: Setting the config to true and the "SYSTEM_BAR_VISIBILITY_OVERRIDE" setting to
+     "immersive.status=apps" will force show navigation bar for all apps and force hide status
+     bar for all apps. -->
+    <bool name="config_remoteInsetsControllerControlsSystemBars">false</bool>
+
+    <!-- Control whether the system bars can be requested when using a remote insets control target.
+         This allows for specifying whether or not system bars can be shown by the user (via swipe
+         or other means) when they are hidden by the logic defined by the remote insets controller.
+         This is useful for cases where the system provides alternative affordances for showing and
+         hiding the bars or for cases in which it's desired the bars not be shown for any reason.
+         This configuration will only apply when config_remoteInsetsControllerControlsSystemBars.
+         is set to true. -->
+    <bool name="config_remoteInsetsControllerSystemBarsCanBeShownByUserAction">false</bool>
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 3bd7a06..47cd1e7 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -121,24 +121,26 @@
     <dimen name="navigation_edge_cancelled_arrow_height">0dp</dimen>
     <dimen name="navigation_edge_cancelled_edge_corners">6dp</dimen>
 
-    <!-- Height of notification icons in the status bar -->
+    <!-- New sp height of notification icons in the status bar -->
+    <dimen name="status_bar_icon_size_sp">@*android:dimen/status_bar_icon_size_sp</dimen>
+    <!-- Original dp height of notification icons in the status bar -->
     <dimen name="status_bar_icon_size">@*android:dimen/status_bar_icon_size</dimen>
 
     <!-- Default horizontal drawable padding for status bar icons. -->
-    <dimen name="status_bar_horizontal_padding">2.5dp</dimen>
+    <dimen name="status_bar_horizontal_padding">2.5sp</dimen>
 
     <!-- Height of the battery icon in the status bar. -->
-    <dimen name="status_bar_battery_icon_height">13.0dp</dimen>
+    <dimen name="status_bar_battery_icon_height">13.0sp</dimen>
 
     <!-- Width of the battery icon in the status bar. The battery drawable assumes a 12x20 canvas,
-    so the width of the icon should be 13.0dp * (12.0 / 20.0) -->
-    <dimen name="status_bar_battery_icon_width">7.8dp</dimen>
+    so the width of the icon should be 13.0sp * (12.0 / 20.0) -->
+    <dimen name="status_bar_battery_icon_width">7.8sp</dimen>
 
-    <!-- The battery icon is 13dp tall, but the other system icons are 15dp tall (see
+    <!-- The battery icon is 13sp tall, but the other system icons are 15sp tall (see
          @*android:dimen/status_bar_system_icon_size) with some top and bottom padding embedded in
          the drawables themselves. So, the battery icon may need an extra 1dp of spacing so that its
          bottom still aligns with the bottom of all the other system icons. See b/258672854. -->
-    <dimen name="status_bar_battery_extra_vertical_spacing">1dp</dimen>
+    <dimen name="status_bar_battery_extra_vertical_spacing">1sp</dimen>
 
     <!-- The font size for the clock in the status bar. -->
     <dimen name="status_bar_clock_size">14sp</dimen>
@@ -153,19 +155,26 @@
     <dimen name="status_bar_left_clock_starting_padding">0dp</dimen>
 
     <!-- End padding for left-aligned status bar clock -->
-    <dimen name="status_bar_left_clock_end_padding">2dp</dimen>
+    <dimen name="status_bar_left_clock_end_padding">2sp</dimen>
 
     <!-- Spacing after the wifi signals that is present if there are any icons following it. -->
-    <dimen name="status_bar_wifi_signal_spacer_width">2.5dp</dimen>
+    <dimen name="status_bar_wifi_signal_spacer_width">2.5sp</dimen>
 
+    <!-- Size of the view displaying the wifi inout icon in the status bar. -->
+    <dimen name="status_bar_wifi_inout_container_size">17sp</dimen>
     <!-- Size of the view displaying the wifi signal icon in the status bar. -->
-    <dimen name="status_bar_wifi_signal_size">@*android:dimen/status_bar_system_icon_size</dimen>
+    <dimen name="status_bar_wifi_signal_size">13sp</dimen>
+
+    <!-- Size of the view displaying the mobile inout icon in the status bar. -->
+    <dimen name="status_bar_mobile_inout_container_size">17sp</dimen>
+    <!-- Size of the view displaying the mobile signal icon in the status bar. -->
+    <dimen name="status_bar_mobile_signal_size">13sp</dimen>
 
     <!-- Spacing before the airplane mode icon if there are any icons preceding it. -->
-    <dimen name="status_bar_airplane_spacer_width">4dp</dimen>
+    <dimen name="status_bar_airplane_spacer_width">4sp</dimen>
 
     <!-- Spacing between system icons. -->
-    <dimen name="status_bar_system_icon_spacing">0dp</dimen>
+    <dimen name="status_bar_system_icon_spacing">0sp</dimen>
 
     <!-- The amount to scale each of the status bar icons by. A value of 1 means no scaling. -->
     <item name="status_bar_icon_scale_factor" format="float" type="dimen">1.0</item>
@@ -235,6 +244,9 @@
          and the notification won't use this much, but is measured with wrap_content -->
     <dimen name="notification_messaging_actions_min_height">196dp</dimen>
 
+    <!-- width of ImmersiveModeConfirmation (-1 for match_parent) -->
+    <dimen name="immersive_mode_cling_width">-1px</dimen>
+
     <!-- a threshold in dp per second that is considered fast scrolling -->
     <dimen name="scroll_fast_threshold">1500dp</dimen>
 
@@ -335,7 +347,7 @@
     <dimen name="status_bar_icons_padding_top">8dp</dimen>
 
     <!-- gap on either side of status bar notification icons -->
-    <dimen name="status_bar_icon_horizontal_margin">0dp</dimen>
+    <dimen name="status_bar_icon_horizontal_margin">0sp</dimen>
 
     <!-- the padding on the start of the statusbar -->
     <dimen name="status_bar_padding_start">8dp</dimen>
@@ -347,10 +359,10 @@
     <dimen name="status_bar_padding_top">0dp</dimen>
 
     <!-- the radius of the overflow dot in the status bar -->
-    <dimen name="overflow_dot_radius">2dp</dimen>
+    <dimen name="overflow_dot_radius">2sp</dimen>
 
     <!-- the padding between dots in the icon overflow -->
-    <dimen name="overflow_icon_dot_padding">3dp</dimen>
+    <dimen name="overflow_icon_dot_padding">3sp</dimen>
 
     <!-- Dimensions related to screenshots -->
 
@@ -470,6 +482,10 @@
     <dimen name="large_screen_shade_header_height">48dp</dimen>
     <dimen name="large_screen_shade_header_min_height">@dimen/qs_header_row_min_height</dimen>
     <dimen name="large_screen_shade_header_left_padding">@dimen/qs_horizontal_margin</dimen>
+    <dimen name="shade_header_system_icons_height">@dimen/large_screen_shade_header_min_height</dimen>
+    <dimen name="shade_header_system_icons_height_large_screen">32dp</dimen>
+    <dimen name="shade_header_system_icons_padding_start">0dp</dimen>
+    <dimen name="shade_header_system_icons_padding_end">0dp</dimen>
 
     <!-- The top margin of the panel that holds the list of notifications.
          On phones it's always 0dp but it's overridden in Car UI
@@ -731,8 +747,6 @@
     <dimen name="keyguard_clock_switch_y_shift">14dp</dimen>
     <!-- When large clock is showing, offset the smartspace by this amount -->
     <dimen name="keyguard_smartspace_top_offset">12dp</dimen>
-    <!-- With the large clock, move up slightly from the center -->
-    <dimen name="keyguard_large_clock_top_margin">-60dp</dimen>
 
     <dimen name="notification_scrim_corner_radius">32dp</dimen>
 
@@ -838,7 +852,7 @@
 
     <!-- Padding between the mobile signal indicator and the start icon when the roaming icon
          is displayed in the upper left corner. -->
-    <dimen name="roaming_icon_start_padding">2dp</dimen>
+    <dimen name="roaming_icon_start_padding">2sp</dimen>
 
     <!-- Extra padding between the mobile data type icon and the strength indicator when the data
          type icon is wide for the tile in quick settings. -->
@@ -1064,7 +1078,7 @@
     <!-- Margin between icons of Ongoing App Ops chip -->
     <dimen name="ongoing_appops_chip_icon_margin">4dp</dimen>
     <!-- Icon size of Ongoing App Ops chip -->
-    <dimen name="ongoing_appops_chip_icon_size">16dp</dimen>
+    <dimen name="ongoing_appops_chip_icon_size">16sp</dimen>
     <!-- Radius of Ongoing App Ops chip corners -->
     <dimen name="ongoing_appops_chip_bg_corner_radius">28dp</dimen>
     <!--  One or two privacy items  -->
@@ -1793,7 +1807,6 @@
     <dimen name="dream_overlay_status_bar_ambient_text_shadow_dy">0.5dp</dimen>
     <dimen name="dream_overlay_status_bar_ambient_text_shadow_radius">2dp</dimen>
     <dimen name="dream_overlay_icon_inset_dimen">0dp</dimen>
-    <dimen name="dream_overlay_status_bar_marginTop">22dp</dimen>
 
     <!-- Default device corner radius, used for assist UI -->
     <dimen name="config_rounded_mask_size">0px</dimen>
diff --git a/packages/SystemUI/res/values/integers.xml b/packages/SystemUI/res/values/integers.xml
index 675ae32..c925b26 100644
--- a/packages/SystemUI/res/values/integers.xml
+++ b/packages/SystemUI/res/values/integers.xml
@@ -21,6 +21,8 @@
 
     <integer name="magnification_default_scale">2</integer>
 
+    <integer name="dock_enter_exit_duration">250</integer>
+
     <!-- The position of the volume dialog on the screen.
          See com.android.systemui.volume.VolumeDialogImpl.
          Value 21 corresponds to RIGHT|CENTER_VERTICAL. -->
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index a36f318..f8c13b0 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -300,6 +300,13 @@
     <!-- A toast message shown when the screen recording cannot be started due to a generic error [CHAR LIMIT=NONE] -->
     <string name="screenrecord_start_error">Error starting screen recording</string>
 
+    <!-- Cling help message title when hiding the navigation bar entering immersive mode [CHAR LIMIT=none] -->
+    <string name="immersive_cling_title">Viewing full screen</string>
+    <!-- Cling help message description when hiding the navigation bar entering immersive mode [CHAR LIMIT=none] -->
+    <string name="immersive_cling_description">To exit, swipe down from the top.</string>
+    <!-- Cling help message confirmation button when hiding the navigation bar entering immersive mode [CHAR LIMIT=30] -->
+    <string name="immersive_cling_positive">Got it</string>
+
     <!-- Content description of the back button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_back">Back</string>
     <!-- Content description of the home button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
@@ -1107,6 +1114,16 @@
     <!-- System sharing media projection permission button to continue. [CHAR LIMIT=60] -->
     <string name="media_projection_entry_generic_permission_dialog_continue">Start</string>
 
+    <!-- Task switcher notification -->
+    <!-- Task switcher notification text. [CHAR LIMIT=100] -->
+    <string name="media_projection_task_switcher_text">Sharing pauses when you switch apps</string>
+    <!-- The action for switching to the foreground task. [CHAR LIMIT=40] -->
+    <string name="media_projection_task_switcher_action_switch">Share this app instead</string>
+    <!-- The action for switching back to the projected task. [CHAR LIMIT=40] -->
+    <string name="media_projection_task_switcher_action_back">Switch back</string>
+    <!-- Task switcher notification channel name. [CHAR LIMIT=40] -->
+    <string name="media_projection_task_switcher_notification_channel">App switch</string>
+
     <!-- Title for the dialog that is shown when screen capturing is disabled by enterprise policy. [CHAR LIMIT=100] -->
     <string name="screen_capturing_disabled_by_policy_dialog_title">Blocked by your IT admin</string>
 
diff --git a/packages/SystemUI/res/xml/large_screen_shade_header.xml b/packages/SystemUI/res/xml/large_screen_shade_header.xml
index 39f4c81..cb2c3a1 100644
--- a/packages/SystemUI/res/xml/large_screen_shade_header.xml
+++ b/packages/SystemUI/res/xml/large_screen_shade_header.xml
@@ -56,7 +56,7 @@
     <Constraint android:id="@+id/shade_header_system_icons">
         <Layout
             android:layout_width="wrap_content"
-            android:layout_height="@dimen/large_screen_shade_header_min_height"
+            android:layout_height="@dimen/shade_header_system_icons_height_large_screen"
             app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintEnd_toStartOf="@id/privacy_container"
             app:layout_constraintTop_toTopOf="parent"
diff --git a/packages/SystemUI/screenshot/Android.bp b/packages/SystemUI/screenshot/Android.bp
deleted file mode 100644
index f449398..0000000
--- a/packages/SystemUI/screenshot/Android.bp
+++ /dev/null
@@ -1,45 +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 {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_packages_SystemUI_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_packages_SystemUI_license"],
-}
-
-android_library {
-    name: "SystemUIScreenshotLib",
-    manifest: "AndroidManifest.xml",
-
-    srcs: [
-        "src/**/*.kt",
-    ],
-
-    resource_dirs: [
-        "res",
-    ],
-
-    static_libs: [
-        "SystemUI-core",
-        "androidx.test.espresso.core",
-        "androidx.appcompat_appcompat",
-        "platform-screenshot-diff-core",
-        "guava",
-    ],
-
-    kotlincflags: ["-Xjvm-default=all"],
-}
diff --git a/packages/SystemUI/screenshot/AndroidManifest.xml b/packages/SystemUI/screenshot/AndroidManifest.xml
deleted file mode 100644
index ba3dc8c..0000000
--- a/packages/SystemUI/screenshot/AndroidManifest.xml
+++ /dev/null
@@ -1,27 +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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.systemui.testing.screenshot">
-    <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>
-</manifest>
diff --git a/packages/SystemUI/screenshot/res/values/themes.xml b/packages/SystemUI/screenshot/res/values/themes.xml
deleted file mode 100644
index a7f8a26..0000000
--- a/packages/SystemUI/screenshot/res/values/themes.xml
+++ /dev/null
@@ -1,31 +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.
--->
-<resources>
-    <style name="Theme.SystemUI.Screenshot" parent="Theme.SystemUI">
-        <item name="android:windowActionBar">false</item>
-        <item name="android:windowNoTitle">true</item>
-
-        <!-- We make the status and navigation bars transparent so that the screenshotted content is
-             not clipped by the status bar height when drawn into the Bitmap (which is what happens
-             given that we draw the view into the Bitmap using hardware acceleration). -->
-        <item name="android:statusBarColor">@android:color/transparent</item>
-        <item name="android:navigationBarColor">@android:color/transparent</item>
-
-        <!-- Make sure that device specific cutouts don't impact the outcome of screenshot tests -->
-        <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
-    </style>
-</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/Bitmap.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/Bitmap.kt
deleted file mode 100644
index a4a70a4..0000000
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/Bitmap.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.testing.screenshot
-
-import android.graphics.Bitmap
-import android.graphics.Canvas
-import android.os.Build
-import android.view.View
-import platform.test.screenshot.matchers.MSSIMMatcher
-import platform.test.screenshot.matchers.PixelPerfectMatcher
-
-/** Draw this [View] into a [Bitmap]. */
-// TODO(b/195673633): Remove this once Compose screenshot tests use hardware rendering for their
-// tests.
-fun View.drawIntoBitmap(): Bitmap {
-    val bitmap =
-        Bitmap.createBitmap(
-            measuredWidth,
-            measuredHeight,
-            Bitmap.Config.ARGB_8888,
-        )
-    val canvas = Canvas(bitmap)
-    draw(canvas)
-    return bitmap
-}
-
-/**
- * The [BitmapMatcher][platform.test.screenshot.matchers.BitmapMatcher] that should be used for
- * screenshot *unit* tests.
- */
-val UnitTestBitmapMatcher =
-    if (Build.CPU_ABI == "x86_64") {
-        // Different CPU architectures can sometimes end up rendering differently, so we can't do
-        // pixel-perfect matching on different architectures using the same golden. Given that our
-        // presubmits are run on cf_x86_64_phone, our goldens should be perfectly matched on the
-        // x86_64 architecture and use the Structural Similarity Index on others.
-        // TODO(b/237511747): Run our screenshot presubmit tests on arm64 instead so that we can
-        // do pixel perfect matching both at presubmit time and at development time with actual
-        // devices.
-        PixelPerfectMatcher()
-    } else {
-        MSSIMMatcher()
-    }
-
-/**
- * The [BitmapMatcher][platform.test.screenshot.matchers.BitmapMatcher] that should be used for
- * screenshot *unit* tests.
- *
- * We use the Structural Similarity Index for integration tests because they usually contain
- * additional information and noise that shouldn't break the test.
- */
-val IntegrationTestBitmapMatcher = MSSIMMatcher()
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ExternalViewScreenshotTestRule.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ExternalViewScreenshotTestRule.kt
deleted file mode 100644
index e032bb9..0000000
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ExternalViewScreenshotTestRule.kt
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.testing.screenshot
-
-import android.app.Activity
-import android.graphics.Color
-import android.view.View
-import android.view.Window
-import android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
-import androidx.core.view.WindowInsetsCompat
-import androidx.core.view.WindowInsetsControllerCompat
-import androidx.core.view.WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
-import androidx.test.platform.app.InstrumentationRegistry
-import org.junit.rules.RuleChain
-import org.junit.rules.TestRule
-import org.junit.runner.Description
-import org.junit.runners.model.Statement
-import platform.test.screenshot.*
-
-/**
- * A rule that allows to run a screenshot diff test on a view that is hosted in another activity.
- */
-class ExternalViewScreenshotTestRule(
-    emulationSpec: DeviceEmulationSpec,
-    assetPathRelativeToBuildRoot: String
-) : TestRule {
-
-    private val colorsRule = MaterialYouColorsRule()
-    private val deviceEmulationRule = DeviceEmulationRule(emulationSpec)
-    private val screenshotRule =
-        ScreenshotTestRule(
-            SystemUIGoldenImagePathManager(
-                getEmulatedDevicePathConfig(emulationSpec),
-                assetPathRelativeToBuildRoot
-            )
-        )
-    private val delegateRule =
-        RuleChain.outerRule(colorsRule).around(deviceEmulationRule).around(screenshotRule)
-    private val matcher = UnitTestBitmapMatcher
-
-    override fun apply(base: Statement, description: Description): Statement {
-        return delegateRule.apply(base, description)
-    }
-
-    /**
-     * Compare the content of the [view] with the golden image identified by [goldenIdentifier] in
-     * the context of [emulationSpec]. Window must be specified to capture views that render
-     * hardware buffers.
-     */
-    fun screenshotTest(goldenIdentifier: String, view: View, window: Window? = null) {
-        view.removeElevationRecursively()
-
-        ScreenshotRuleAsserter.Builder(screenshotRule)
-            .setScreenshotProvider { view.toBitmap(window) }
-            .withMatcher(matcher)
-            .build()
-            .assertGoldenImage(goldenIdentifier)
-    }
-
-    /**
-     * Compare the content of the [activity] with the golden image identified by [goldenIdentifier]
-     * in the context of [emulationSpec].
-     */
-    fun activityScreenshotTest(
-        goldenIdentifier: String,
-        activity: Activity,
-    ) {
-        val rootView = activity.window.decorView
-
-        // Hide system bars, remove insets, focus and make sure device-specific cutouts
-        // don't affect screenshots
-        InstrumentationRegistry.getInstrumentation().runOnMainSync {
-            val window = activity.window
-            window.setDecorFitsSystemWindows(false)
-            WindowInsetsControllerCompat(window, rootView).apply {
-                hide(WindowInsetsCompat.Type.systemBars())
-                systemBarsBehavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
-            }
-
-            window.statusBarColor = Color.TRANSPARENT
-            window.navigationBarColor = Color.TRANSPARENT
-            window.attributes =
-                window.attributes.apply {
-                    layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
-                }
-
-            rootView.removeInsetsRecursively()
-            activity.currentFocus?.clearFocus()
-        }
-
-        screenshotTest(goldenIdentifier, rootView, activity.window)
-    }
-}
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotActivity.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotActivity.kt
deleted file mode 100644
index 2a55a80..0000000
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotActivity.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.testing.screenshot
-
-import androidx.activity.ComponentActivity
-
-/** The Activity that is launched and whose content is set for screenshot tests. */
-class ScreenshotActivity : ComponentActivity()
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/SystemUIGoldenImagePathManager.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/SystemUIGoldenImagePathManager.kt
deleted file mode 100644
index 72d8c5a..0000000
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/SystemUIGoldenImagePathManager.kt
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.testing.screenshot
-
-import androidx.test.platform.app.InstrumentationRegistry
-import platform.test.screenshot.GoldenImagePathManager
-import platform.test.screenshot.PathConfig
-
-/** A [GoldenImagePathManager] that should be used for all SystemUI screenshot tests. */
-class SystemUIGoldenImagePathManager(
-    pathConfig: PathConfig,
-    assetsPathRelativeToBuildRoot: String
-) :
-    GoldenImagePathManager(
-        appContext = InstrumentationRegistry.getInstrumentation().context,
-        assetsPathRelativeToBuildRoot = assetsPathRelativeToBuildRoot,
-        deviceLocalPath =
-            InstrumentationRegistry.getInstrumentation()
-                .targetContext
-                .filesDir
-                .absolutePath
-                .toString() + "/sysui_screenshots",
-        pathConfig = pathConfig,
-    ) {
-    override fun toString(): String {
-        // This string is appended to all actual/expected screenshots on the device, so make sure
-        // it is a static value.
-        return "SystemUIGoldenImagePathManager"
-    }
-}
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/TestAppComponentFactory.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/TestAppComponentFactory.kt
deleted file mode 100644
index 98e9aaf..0000000
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/TestAppComponentFactory.kt
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.testing.screenshot
-
-import android.app.Activity
-import android.content.Intent
-import androidx.core.app.AppComponentFactory
-
-class TestAppComponentFactory : AppComponentFactory() {
-
-    init {
-        instance = this
-    }
-
-    private val overrides: MutableMap<String, () -> Activity> = hashMapOf()
-
-    fun clearOverrides() {
-        overrides.clear()
-    }
-
-    fun <T : Activity> registerActivityOverride(activity: Class<T>, provider: () -> T) {
-        overrides[activity.name] = provider
-    }
-
-    override fun instantiateActivityCompat(
-        cl: ClassLoader,
-        className: String,
-        intent: Intent?
-    ): Activity {
-        return overrides
-            .getOrDefault(className) { super.instantiateActivityCompat(cl, className, intent) }
-            .invoke()
-    }
-
-    companion object {
-
-        private var instance: TestAppComponentFactory? = null
-
-        fun getInstance(): TestAppComponentFactory =
-            instance
-                ?: error(
-                    "TestAppComponentFactory is not initialized, " +
-                        "did you specify it in the manifest?"
-                )
-    }
-}
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/View.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/View.kt
deleted file mode 100644
index b84d26a..0000000
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/View.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.testing.screenshot
-
-import android.view.View
-import android.view.ViewGroup
-import com.android.systemui.util.children
-import android.view.WindowInsets
-
-/**
- * Elevation/shadows is not deterministic when doing hardware rendering, this exentsion allows to
- * disable it for any view in the hierarchy.
- */
-fun View.removeElevationRecursively() {
-    this.elevation = 0f
-    (this as? ViewGroup)?.children?.forEach(View::removeElevationRecursively)
-}
-
-/**
- * Different devices could have different insets (e.g. different height of the navigation bar or
- * taskbar). This method dispatches empty insets to the whole view hierarchy and removes
- * the original listener, so the views won't receive real insets.
- */
-fun View.removeInsetsRecursively() {
-    this.dispatchApplyWindowInsets(WindowInsets.CONSUMED)
-    this.setOnApplyWindowInsetsListener(null)
-    (this as? ViewGroup)?.children?.forEach(View::removeInsetsRecursively)
-}
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewCapture.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewCapture.kt
deleted file mode 100644
index dedf0a7..0000000
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewCapture.kt
+++ /dev/null
@@ -1,233 +0,0 @@
-package com.android.systemui.testing.screenshot
-
-import android.annotation.WorkerThread
-import android.app.Activity
-import android.content.Context
-import android.content.ContextWrapper
-import android.graphics.Bitmap
-import android.graphics.Canvas
-import android.graphics.HardwareRenderer
-import android.graphics.Rect
-import android.os.Build
-import android.os.Handler
-import android.os.Looper
-import android.util.Log
-import android.view.PixelCopy
-import android.view.SurfaceView
-import android.view.View
-import android.view.ViewTreeObserver
-import android.view.Window
-import androidx.annotation.RequiresApi
-import androidx.concurrent.futures.ResolvableFuture
-import androidx.test.annotation.ExperimentalTestApi
-import androidx.test.core.internal.os.HandlerExecutor
-import androidx.test.espresso.Espresso
-import androidx.test.platform.graphics.HardwareRendererCompat
-import com.google.common.util.concurrent.FutureCallback
-import com.google.common.util.concurrent.Futures
-import com.google.common.util.concurrent.ListenableFuture
-import kotlin.coroutines.suspendCoroutine
-import kotlinx.coroutines.runBlocking
-
-/*
- * This file was forked from androidx/test/core/view/ViewCapture.kt to add [Window] parameter to
- * [View.captureToBitmap].
- * TODO(b/195673633): Remove this fork and use the AndroidX version instead.
- */
-
-/**
- * Asynchronously captures an image of the underlying view into a [Bitmap].
- *
- * For devices below [Build.VERSION_CODES#O] (or if the view's window cannot be determined), the
- * image is obtained using [View#draw]. Otherwise, [PixelCopy] is used.
- *
- * This method will also enable [HardwareRendererCompat#setDrawingEnabled(boolean)] if required.
- *
- * This API is primarily intended for use in lower layer libraries or frameworks. For test authors,
- * its recommended to use espresso or compose's captureToImage.
- *
- * This API is currently experimental and subject to change or removal.
- */
-@ExperimentalTestApi
-@RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
-fun View.captureToBitmap(window: Window? = null): ListenableFuture<Bitmap> {
-    val bitmapFuture: ResolvableFuture<Bitmap> = ResolvableFuture.create()
-    val mainExecutor = HandlerExecutor(Handler(Looper.getMainLooper()))
-    val isRobolectric = if (Build.FINGERPRINT.contains("robolectric")) true else false
-
-    // disable drawing again if necessary once work is complete
-    if (!HardwareRendererCompat.isDrawingEnabled()) {
-        HardwareRendererCompat.setDrawingEnabled(true)
-        bitmapFuture.addListener({ HardwareRendererCompat.setDrawingEnabled(false) }, mainExecutor)
-    }
-
-    mainExecutor.execute {
-        if (isRobolectric) {
-            generateBitmap(bitmapFuture)
-        } else {
-            val forceRedrawFuture = forceRedraw()
-            forceRedrawFuture.addListener({ generateBitmap(bitmapFuture, window) }, mainExecutor)
-        }
-    }
-
-    return bitmapFuture
-}
-
-/**
- * Synchronously captures an image of the view into a [Bitmap]. Synchronous equivalent of
- * [captureToBitmap].
- */
-@WorkerThread
-@ExperimentalTestApi
-@RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
-fun View.toBitmap(window: Window? = null): Bitmap {
-    if (Looper.getMainLooper() == Looper.myLooper()) {
-        error("toBitmap() can't be called from the main thread")
-    }
-
-    if (!HardwareRenderer.isDrawingEnabled()) {
-        error("Hardware rendering is not enabled")
-    }
-
-    // Make sure we are idle.
-    Espresso.onIdle()
-
-    val mainExecutor = context.mainExecutor
-    return runBlocking {
-        suspendCoroutine { continuation ->
-            Futures.addCallback(
-                captureToBitmap(window),
-                object : FutureCallback<Bitmap> {
-                    override fun onSuccess(result: Bitmap?) {
-                        continuation.resumeWith(Result.success(result!!))
-                    }
-
-                    override fun onFailure(t: Throwable) {
-                        continuation.resumeWith(Result.failure(t))
-                    }
-                },
-                // We know that we are not on the main thread, so we can block the current
-                // thread and wait for the result in the main thread.
-                mainExecutor,
-            )
-        }
-    }
-}
-
-/**
- * Trigger a redraw of the given view.
- *
- * Should only be called on UI thread.
- *
- * @return a [ListenableFuture] that will be complete once ui drawing is complete
- */
-// NoClassDefFoundError occurs on API 15
-@RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
-// @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-@ExperimentalTestApi
-fun View.forceRedraw(): ListenableFuture<Void> {
-    val future: ResolvableFuture<Void> = ResolvableFuture.create()
-
-    if (Build.VERSION.SDK_INT >= 29 && isHardwareAccelerated) {
-        viewTreeObserver.registerFrameCommitCallback() { future.set(null) }
-    } else {
-        viewTreeObserver.addOnDrawListener(
-            object : ViewTreeObserver.OnDrawListener {
-                var handled = false
-                override fun onDraw() {
-                    if (!handled) {
-                        handled = true
-                        future.set(null)
-                        // cannot remove on draw listener inside of onDraw
-                        Handler(Looper.getMainLooper()).post {
-                            viewTreeObserver.removeOnDrawListener(this)
-                        }
-                    }
-                }
-            }
-        )
-    }
-    invalidate()
-    return future
-}
-
-private fun View.generateBitmap(
-    bitmapFuture: ResolvableFuture<Bitmap>,
-    window: Window? = null,
-) {
-    if (bitmapFuture.isCancelled) {
-        return
-    }
-    val destBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
-    when {
-        Build.VERSION.SDK_INT < 26 -> generateBitmapFromDraw(destBitmap, bitmapFuture)
-        this is SurfaceView -> generateBitmapFromSurfaceViewPixelCopy(destBitmap, bitmapFuture)
-        else -> {
-            val window = window ?: getActivity()?.window
-            if (window != null) {
-                generateBitmapFromPixelCopy(window, destBitmap, bitmapFuture)
-            } else {
-                Log.i(
-                    "View.captureToImage",
-                    "Could not find window for view. Falling back to View#draw instead of PixelCopy"
-                )
-                generateBitmapFromDraw(destBitmap, bitmapFuture)
-            }
-        }
-    }
-}
-
-@SuppressWarnings("NewApi")
-private fun SurfaceView.generateBitmapFromSurfaceViewPixelCopy(
-    destBitmap: Bitmap,
-    bitmapFuture: ResolvableFuture<Bitmap>
-) {
-    val onCopyFinished =
-        PixelCopy.OnPixelCopyFinishedListener { result ->
-            if (result == PixelCopy.SUCCESS) {
-                bitmapFuture.set(destBitmap)
-            } else {
-                bitmapFuture.setException(
-                    RuntimeException(String.format("PixelCopy failed: %d", result))
-                )
-            }
-        }
-    PixelCopy.request(this, null, destBitmap, onCopyFinished, handler)
-}
-
-internal fun View.generateBitmapFromDraw(
-    destBitmap: Bitmap,
-    bitmapFuture: ResolvableFuture<Bitmap>
-) {
-    destBitmap.density = resources.displayMetrics.densityDpi
-    computeScroll()
-    val canvas = Canvas(destBitmap)
-    canvas.translate((-scrollX).toFloat(), (-scrollY).toFloat())
-    draw(canvas)
-    bitmapFuture.set(destBitmap)
-}
-
-private fun View.getActivity(): Activity? {
-    fun Context.getActivity(): Activity? {
-        return when (this) {
-            is Activity -> this
-            is ContextWrapper -> this.baseContext.getActivity()
-            else -> null
-        }
-    }
-    return context.getActivity()
-}
-
-private fun View.generateBitmapFromPixelCopy(
-    window: Window,
-    destBitmap: Bitmap,
-    bitmapFuture: ResolvableFuture<Bitmap>
-) {
-    val locationInWindow = intArrayOf(0, 0)
-    getLocationInWindow(locationInWindow)
-    val x = locationInWindow[0]
-    val y = locationInWindow[1]
-    val boundsInWindow = Rect(x, y, x + width, y + height)
-
-    return window.generateBitmapFromPixelCopy(boundsInWindow, destBitmap, bitmapFuture)
-}
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt
deleted file mode 100644
index 070a451..0000000
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.testing.screenshot
-
-import android.app.Activity
-import android.app.Dialog
-import android.graphics.Bitmap
-import android.os.Build
-import android.view.View
-import android.view.ViewGroup
-import android.view.ViewGroup.LayoutParams
-import android.view.ViewGroup.LayoutParams.MATCH_PARENT
-import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
-import androidx.activity.ComponentActivity
-import androidx.test.ext.junit.rules.ActivityScenarioRule
-import java.util.concurrent.TimeUnit
-import org.junit.Assert.assertEquals
-import org.junit.rules.RuleChain
-import org.junit.rules.TestRule
-import org.junit.runner.Description
-import org.junit.runners.model.Statement
-import platform.test.screenshot.DeviceEmulationRule
-import platform.test.screenshot.DeviceEmulationSpec
-import platform.test.screenshot.MaterialYouColorsRule
-import platform.test.screenshot.ScreenshotTestRule
-import platform.test.screenshot.getEmulatedDevicePathConfig
-import platform.test.screenshot.matchers.BitmapMatcher
-
-/** A rule for View screenshot diff unit tests. */
-open class ViewScreenshotTestRule(
-    emulationSpec: DeviceEmulationSpec,
-    private val matcher: BitmapMatcher = UnitTestBitmapMatcher,
-    assetsPathRelativeToBuildRoot: String
-) : TestRule {
-    private val colorsRule = MaterialYouColorsRule()
-    private val deviceEmulationRule = DeviceEmulationRule(emulationSpec)
-    protected val screenshotRule =
-        ScreenshotTestRule(
-            SystemUIGoldenImagePathManager(
-                getEmulatedDevicePathConfig(emulationSpec),
-                assetsPathRelativeToBuildRoot
-            )
-        )
-    private val activityRule = ActivityScenarioRule(ScreenshotActivity::class.java)
-    private val roboRule =
-        RuleChain.outerRule(deviceEmulationRule).around(screenshotRule).around(activityRule)
-    private val delegateRule = RuleChain.outerRule(colorsRule).around(roboRule)
-    private val isRobolectric = if (Build.FINGERPRINT.contains("robolectric")) true else false
-
-    override fun apply(base: Statement, description: Description): Statement {
-        if (isRobolectric) {
-            // In robolectric mode, we enable NATIVE graphics and unpack font and icu files.
-            // We need to use reflection, as this library is only needed and therefore
-            //  only available in deviceless mode.
-            val nativeLoaderClassName = "org.robolectric.nativeruntime.DefaultNativeRuntimeLoader"
-            val defaultNativeRuntimeLoader = Class.forName(nativeLoaderClassName)
-            System.setProperty("robolectric.graphicsMode", "NATIVE")
-            defaultNativeRuntimeLoader.getMethod("injectAndLoad").invoke(null)
-        }
-        val ruleToApply = if (isRobolectric) roboRule else delegateRule
-        return ruleToApply.apply(base, description)
-    }
-
-    protected fun takeScreenshot(
-        mode: Mode = Mode.WrapContent,
-        viewProvider: (ComponentActivity) -> View,
-        beforeScreenshot: (ComponentActivity) -> Unit = {}
-    ): Bitmap {
-        activityRule.scenario.onActivity { activity ->
-            // Make sure that the activity draws full screen and fits the whole display instead of
-            // the system bars.
-            val window = activity.window
-            window.setDecorFitsSystemWindows(false)
-
-            // Set the content.
-            activity.setContentView(viewProvider(activity), mode.layoutParams)
-
-            // Elevation/shadows is not deterministic when doing hardware rendering, so we disable
-            // it for any view in the hierarchy.
-            window.decorView.removeElevationRecursively()
-
-            activity.currentFocus?.clearFocus()
-        }
-
-        // We call onActivity again because it will make sure that our Activity is done measuring,
-        // laying out and drawing its content (that we set in the previous onActivity lambda).
-        var contentView: View? = null
-        activityRule.scenario.onActivity { activity ->
-            // Check that the content is what we expected.
-            val content = activity.requireViewById<ViewGroup>(android.R.id.content)
-            assertEquals(1, content.childCount)
-            contentView = content.getChildAt(0)
-            beforeScreenshot(activity)
-        }
-
-        return if (isRobolectric) {
-            contentView?.captureToBitmap()?.get(10, TimeUnit.SECONDS)
-                ?: error("timeout while trying to capture view to bitmap")
-        } else {
-            contentView?.toBitmap() ?: error("contentView is null")
-        }
-    }
-
-    /**
-     * Compare the content of the view provided by [viewProvider] with the golden image identified
-     * by [goldenIdentifier] in the context of [emulationSpec].
-     */
-    fun screenshotTest(
-        goldenIdentifier: String,
-        mode: Mode = Mode.WrapContent,
-        beforeScreenshot: (ComponentActivity) -> Unit = {},
-        viewProvider: (ComponentActivity) -> View
-    ) {
-        val bitmap = takeScreenshot(mode, viewProvider, beforeScreenshot)
-        screenshotRule.assertBitmapAgainstGolden(
-            bitmap,
-            goldenIdentifier,
-            matcher,
-        )
-    }
-
-    /**
-     * Compare the content of the dialog provided by [dialogProvider] with the golden image
-     * identified by [goldenIdentifier] in the context of [emulationSpec].
-     */
-    fun dialogScreenshotTest(
-        goldenIdentifier: String,
-        dialogProvider: (Activity) -> Dialog,
-    ) {
-        var dialog: Dialog? = null
-        activityRule.scenario.onActivity { activity ->
-            dialog =
-                dialogProvider(activity).apply {
-                    // Make sure that the dialog draws full screen and fits the whole display
-                    // instead of the system bars.
-                    window.setDecorFitsSystemWindows(false)
-
-                    // Disable enter/exit animations.
-                    create()
-                    window.setWindowAnimations(0)
-
-                    // Elevation/shadows is not deterministic when doing hardware rendering, so we
-                    // disable it for any view in the hierarchy.
-                    window.decorView.removeElevationRecursively()
-
-                    // Show the dialog.
-                    show()
-                }
-        }
-
-        try {
-            val bitmap = dialog?.toBitmap() ?: error("dialog is null")
-            screenshotRule.assertBitmapAgainstGolden(
-                bitmap,
-                goldenIdentifier,
-                matcher,
-            )
-        } finally {
-            dialog?.dismiss()
-        }
-    }
-
-    private fun Dialog.toBitmap(): Bitmap {
-        val window = window
-        return window.decorView.toBitmap(window)
-    }
-
-    enum class Mode(val layoutParams: LayoutParams) {
-        WrapContent(LayoutParams(WRAP_CONTENT, WRAP_CONTENT)),
-        MatchSize(LayoutParams(MATCH_PARENT, MATCH_PARENT)),
-        MatchWidth(LayoutParams(MATCH_PARENT, WRAP_CONTENT)),
-        MatchHeight(LayoutParams(WRAP_CONTENT, MATCH_PARENT)),
-    }
-}
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/WindowCapture.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/WindowCapture.kt
deleted file mode 100644
index d34f46b..0000000
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/WindowCapture.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.android.systemui.testing.screenshot
-
-import android.graphics.Bitmap
-import android.graphics.Rect
-import android.os.Handler
-import android.os.Looper
-import android.view.PixelCopy
-import android.view.Window
-import androidx.concurrent.futures.ResolvableFuture
-
-/*
- * This file was forked from androidx/test/core/view/WindowCapture.kt.
- * TODO(b/195673633): Remove this fork and use the AndroidX version instead.
- */
-fun Window.generateBitmapFromPixelCopy(
-    boundsInWindow: Rect? = null,
-    destBitmap: Bitmap,
-    bitmapFuture: ResolvableFuture<Bitmap>
-) {
-    val onCopyFinished =
-        PixelCopy.OnPixelCopyFinishedListener { result ->
-            if (result == PixelCopy.SUCCESS) {
-                bitmapFuture.set(destBitmap)
-            } else {
-                bitmapFuture.setException(
-                    RuntimeException(String.format("PixelCopy failed: %d", result))
-                )
-            }
-        }
-    PixelCopy.request(
-        this,
-        boundsInWindow,
-        destBitmap,
-        onCopyFinished,
-        Handler(Looper.getMainLooper())
-    )
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/util/TraceUtils.kt b/packages/SystemUI/shared/src/com/android/systemui/util/TraceUtils.kt
index e02e592..96a974d 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/util/TraceUtils.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/util/TraceUtils.kt
@@ -67,7 +67,7 @@
          * under a single track.
          */
         inline fun <T> traceAsync(method: String, block: () -> T): T =
-            traceAsync(method, "AsyncTraces", block)
+            traceAsync("AsyncTraces", method, block)
 
         /**
          * Creates an async slice in a track with [trackName] while [block] runs.
@@ -76,7 +76,7 @@
          * [trackName] of the track. The track is one of the rows visible in a perfetto trace inside
          * SystemUI process.
          */
-        inline fun <T> traceAsync(method: String, trackName: String, block: () -> T): T {
+        inline fun <T> traceAsync(trackName: String, method: String, block: () -> T): T {
             val cookie = lastCookie.incrementAndGet()
             Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_APP, trackName, method, cookie)
             try {
diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
index 91937af..4a6e53d 100644
--- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
@@ -26,6 +26,7 @@
 import android.view.View
 import android.view.View.OnAttachStateChangeListener
 import android.view.ViewTreeObserver
+import android.view.ViewTreeObserver.OnGlobalLayoutListener
 import android.widget.FrameLayout
 import androidx.annotation.VisibleForTesting
 import androidx.lifecycle.Lifecycle
@@ -88,12 +89,21 @@
 ) {
     var clock: ClockController? = null
         set(value) {
+            smallClockOnAttachStateChangeListener?.let {
+                field?.smallClock?.view?.removeOnAttachStateChangeListener(it)
+                smallClockFrame?.viewTreeObserver
+                        ?.removeOnGlobalLayoutListener(onGlobalLayoutListener)
+            }
+            largeClockOnAttachStateChangeListener?.let {
+                field?.largeClock?.view?.removeOnAttachStateChangeListener(it)
+            }
+
             field = value
             if (value != null) {
                 smallLogBuffer?.log(TAG, DEBUG, {}, { "New Clock" })
-                value.smallClock.logBuffer = smallLogBuffer
+                value.smallClock.messageBuffer = smallLogBuffer
                 largeLogBuffer?.log(TAG, DEBUG, {}, { "New Clock" })
-                value.largeClock.logBuffer = largeLogBuffer
+                value.largeClock.messageBuffer = largeLogBuffer
 
                 value.initialize(resources, dozeAmount, 0f)
 
@@ -130,44 +140,62 @@
                     }
                     value.events.onWeatherDataChanged(it)
                 }
-                value.smallClock.view.addOnAttachStateChangeListener(
+
+                smallClockOnAttachStateChangeListener =
                     object : OnAttachStateChangeListener {
                         var pastVisibility: Int? = null
                         override fun onViewAttachedToWindow(view: View?) {
                             value.events.onTimeFormatChanged(DateFormat.is24HourFormat(context))
                             if (view != null) {
-                                val smallClockFrame = view.parent as FrameLayout
-                                pastVisibility = smallClockFrame.visibility
-                                smallClockFrame.viewTreeObserver.addOnGlobalLayoutListener(
-                                        ViewTreeObserver.OnGlobalLayoutListener {
-                                    val currentVisibility = smallClockFrame.visibility
-                                    if (pastVisibility != currentVisibility) {
-                                        pastVisibility = currentVisibility
-                                        // when small clock  visible, recalculate bounds and sample
-                                        if (currentVisibility == View.VISIBLE) {
-                                            smallRegionSampler?.stopRegionSampler()
-                                            smallRegionSampler?.startRegionSampler()
+                                smallClockFrame = view.parent as FrameLayout
+                                smallClockFrame?.let {frame ->
+                                    pastVisibility = frame.visibility
+                                    onGlobalLayoutListener = OnGlobalLayoutListener {
+                                        val currentVisibility = frame.visibility
+                                        if (pastVisibility != currentVisibility) {
+                                            pastVisibility = currentVisibility
+                                            // when small clock  visible,
+                                            // recalculate bounds and sample
+                                            if (currentVisibility == View.VISIBLE) {
+                                                smallRegionSampler?.stopRegionSampler()
+                                                smallRegionSampler?.startRegionSampler()
+                                            }
                                         }
                                     }
-                                })
+                                    frame.viewTreeObserver
+                                            .addOnGlobalLayoutListener(onGlobalLayoutListener)
+                                }
                             }
                         }
 
                         override fun onViewDetachedFromWindow(p0: View?) {
+                            smallClockFrame?.viewTreeObserver
+                                    ?.removeOnGlobalLayoutListener(onGlobalLayoutListener)
                         }
-                })
-                value.largeClock.view.addOnAttachStateChangeListener(
+                }
+                value.smallClock.view
+                        .addOnAttachStateChangeListener(smallClockOnAttachStateChangeListener)
+
+                largeClockOnAttachStateChangeListener =
                     object : OnAttachStateChangeListener {
                         override fun onViewAttachedToWindow(p0: View?) {
                             value.events.onTimeFormatChanged(DateFormat.is24HourFormat(context))
                         }
-
                         override fun onViewDetachedFromWindow(p0: View?) {
                         }
-                })
+                }
+                value.largeClock.view
+                        .addOnAttachStateChangeListener(largeClockOnAttachStateChangeListener)
             }
         }
 
+    @VisibleForTesting
+    var smallClockOnAttachStateChangeListener: OnAttachStateChangeListener? = null
+    @VisibleForTesting
+    var largeClockOnAttachStateChangeListener: OnAttachStateChangeListener? = null
+    private var smallClockFrame: FrameLayout? = null
+    private var onGlobalLayoutListener: OnGlobalLayoutListener? = null
+
     private var isDozing = false
         private set
 
@@ -307,7 +335,6 @@
             return
         }
         isRegistered = true
-
         broadcastDispatcher.registerReceiver(
             localeBroadcastReceiver,
             IntentFilter(Intent.ACTION_LOCALE_CHANGED)
@@ -346,6 +373,12 @@
         largeRegionSampler?.stopRegionSampler()
         smallTimeListener?.stop()
         largeTimeListener?.stop()
+        clock?.smallClock?.view
+                ?.removeOnAttachStateChangeListener(smallClockOnAttachStateChangeListener)
+        smallClockFrame?.viewTreeObserver
+                ?.removeOnGlobalLayoutListener(onGlobalLayoutListener)
+        clock?.largeClock?.view
+                ?.removeOnAttachStateChangeListener(largeClockOnAttachStateChangeListener)
     }
 
     private fun updateTimeListeners() {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index 6c98376..16eb21d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -21,6 +21,8 @@
 
 import static com.android.keyguard.KeyguardClockSwitch.LARGE;
 import static com.android.keyguard.KeyguardClockSwitch.SMALL;
+import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED;
+import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
 
 import android.annotation.Nullable;
 import android.database.ContentObserver;
@@ -33,12 +35,15 @@
 import android.widget.LinearLayout;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
 
 import com.android.systemui.Dumpable;
 import com.android.systemui.R;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
 import com.android.systemui.log.LogBuffer;
 import com.android.systemui.log.core.LogLevel;
 import com.android.systemui.log.dagger.KeyguardClockLog;
@@ -58,6 +63,7 @@
 
 import java.io.PrintWriter;
 import java.util.Locale;
+import java.util.function.Consumer;
 
 import javax.inject.Inject;
 
@@ -99,8 +105,20 @@
     private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
 
     private boolean mOnlyClock = false;
+    private boolean mIsActiveDreamLockscreenHosted = false;
+    private FeatureFlags mFeatureFlags;
+    private KeyguardInteractor mKeyguardInteractor;
     private final DelayableExecutor mUiExecutor;
     private boolean mCanShowDoubleLineClock = true;
+    @VisibleForTesting
+    final Consumer<Boolean> mIsActiveDreamLockscreenHostedCallback =
+            (Boolean isLockscreenHosted) -> {
+                if (mIsActiveDreamLockscreenHosted == isLockscreenHosted) {
+                    return;
+                }
+                mIsActiveDreamLockscreenHosted = isLockscreenHosted;
+                updateKeyguardStatusAreaVisibility();
+            };
     private final ContentObserver mDoubleLineClockObserver = new ContentObserver(null) {
         @Override
         public void onChange(boolean change) {
@@ -137,7 +155,9 @@
             @Main DelayableExecutor uiExecutor,
             DumpManager dumpManager,
             ClockEventController clockEventController,
-            @KeyguardClockLog LogBuffer logBuffer) {
+            @KeyguardClockLog LogBuffer logBuffer,
+            KeyguardInteractor keyguardInteractor,
+            FeatureFlags featureFlags) {
         super(keyguardClockSwitch);
         mStatusBarStateController = statusBarStateController;
         mClockRegistry = clockRegistry;
@@ -151,6 +171,8 @@
         mClockEventController = clockEventController;
         mLogBuffer = logBuffer;
         mView.setLogBuffer(mLogBuffer);
+        mFeatureFlags = featureFlags;
+        mKeyguardInteractor = keyguardInteractor;
 
         mClockChangedListener = new ClockRegistry.ClockChangeListener() {
             @Override
@@ -191,6 +213,12 @@
 
         mDumpManager.unregisterDumpable(getClass().toString()); // unregister previous clocks
         mDumpManager.registerDumpable(getClass().toString(), this);
+
+        if (mFeatureFlags.isEnabled(LOCKSCREEN_WALLPAPER_DREAM_ENABLED)) {
+            mStatusArea = mView.findViewById(R.id.keyguard_status_area);
+            collectFlow(mStatusArea, mKeyguardInteractor.isActiveDreamLockscreenHosted(),
+                    mIsActiveDreamLockscreenHostedCallback);
+        }
     }
 
     @Override
@@ -524,6 +552,15 @@
         }
     }
 
+    private void updateKeyguardStatusAreaVisibility() {
+        if (mStatusArea != null) {
+            mUiExecutor.execute(() -> {
+                mStatusArea.setVisibility(
+                        mIsActiveDreamLockscreenHosted ? View.INVISIBLE : View.VISIBLE);
+            });
+        }
+    }
+
     /**
      * Sets the clipChildren property on relevant views, to allow the smartspace to draw out of
      * bounds during the unlock transition.
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
index 99b5d52..38c07dc 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
@@ -16,8 +16,10 @@
 package com.android.keyguard;
 
 import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_HALF_OPENED;
+import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_UNKNOWN;
 
 import android.content.Context;
+import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.SystemClock;
 import android.text.TextUtils;
@@ -74,6 +76,7 @@
     BouncerKeyguardMessageArea mSecurityMessageDisplay;
     private View mEcaView;
     private ConstraintLayout mContainer;
+    @DevicePostureInt private int mLastDevicePosture = DEVICE_POSTURE_UNKNOWN;
 
     public KeyguardPatternView(Context context) {
         this(context, null);
@@ -95,14 +98,25 @@
                 mContext, android.R.interpolator.fast_out_linear_in));
     }
 
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        updateMargins();
+    }
+
     void onDevicePostureChanged(@DevicePostureInt int posture) {
+        mLastDevicePosture = posture;
+        updateMargins();
+    }
+
+    private void updateMargins() {
         // Update the guideline based on the device posture...
         float halfOpenPercentage =
                 mContext.getResources().getFloat(R.dimen.half_opened_bouncer_height_ratio);
 
         ConstraintSet cs = new ConstraintSet();
         cs.clone(mContainer);
-        cs.setGuidelinePercent(R.id.pattern_top_guideline, posture == DEVICE_POSTURE_HALF_OPENED
+        cs.setGuidelinePercent(R.id.pattern_top_guideline,
+                mLastDevicePosture == DEVICE_POSTURE_HALF_OPENED
                 ? halfOpenPercentage : 0.0f);
         cs.applyTo(mContainer);
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
index 3e16d55..794e694 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
@@ -77,6 +77,7 @@
             });
         }
         mPasswordEntry.setUserActivityListener(this::onUserInput);
+        mView.onDevicePostureChanged(mPostureController.getDevicePosture());
         mPostureController.addCallback(mPostureCallback);
     }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 6853f81..42a4e72 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -793,8 +793,6 @@
 
     void reloadColors() {
         mViewMode.reloadColors();
-        setBackgroundColor(Utils.getColorAttrDefaultColor(getContext(),
-                com.android.internal.R.attr.materialColorSurface));
     }
 
     /** Handles density or font scale changes. */
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index 458ca2b..f952337 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -79,17 +79,25 @@
 import com.android.systemui.log.SessionTracker;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.scene.domain.interactor.SceneInteractor;
+import com.android.systemui.scene.shared.model.SceneContainerNames;
+import com.android.systemui.scene.shared.model.SceneKey;
 import com.android.systemui.shared.system.SysUiStatsLog;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
+import com.android.systemui.user.domain.interactor.UserInteractor;
 import com.android.systemui.util.ViewController;
+import com.android.systemui.util.kotlin.JavaAdapter;
 import com.android.systemui.util.settings.GlobalSettings;
 
 import java.io.File;
 import java.util.Optional;
 
 import javax.inject.Inject;
+import javax.inject.Provider;
+
+import kotlinx.coroutines.Job;
 
 /** Controller for {@link KeyguardSecurityContainer} */
 @KeyguardBouncerScope
@@ -378,6 +386,10 @@
                     showPrimarySecurityScreen(false);
                 }
             };
+    private final UserInteractor mUserInteractor;
+    private final Provider<SceneInteractor> mSceneInteractor;
+    private final Provider<JavaAdapter> mJavaAdapter;
+    @Nullable private Job mSceneTransitionCollectionJob;
 
     @Inject
     public KeyguardSecurityContainerController(KeyguardSecurityContainer view,
@@ -402,7 +414,10 @@
             ViewMediatorCallback viewMediatorCallback,
             AudioManager audioManager,
             KeyguardFaceAuthInteractor keyguardFaceAuthInteractor,
-            BouncerMessageInteractor bouncerMessageInteractor
+            BouncerMessageInteractor bouncerMessageInteractor,
+            Provider<JavaAdapter> javaAdapter,
+            UserInteractor userInteractor,
+            Provider<SceneInteractor> sceneInteractor
     ) {
         super(view);
         mLockPatternUtils = lockPatternUtils;
@@ -429,6 +444,9 @@
         mAudioManager = audioManager;
         mKeyguardFaceAuthInteractor = keyguardFaceAuthInteractor;
         mBouncerMessageInteractor = bouncerMessageInteractor;
+        mUserInteractor = userInteractor;
+        mSceneInteractor = sceneInteractor;
+        mJavaAdapter = javaAdapter;
     }
 
     @Override
@@ -451,6 +469,24 @@
         mView.setOnKeyListener(mOnKeyListener);
 
         showPrimarySecurityScreen(false);
+
+        if (mFeatureFlags.isEnabled(Flags.SCENE_CONTAINER)) {
+            // When the scene framework transitions from bouncer to gone, we dismiss the keyguard.
+            mSceneTransitionCollectionJob = mJavaAdapter.get().alwaysCollectFlow(
+                mSceneInteractor.get().sceneTransitions(SceneContainerNames.SYSTEM_UI_DEFAULT),
+                sceneTransitionModel -> {
+                    if (sceneTransitionModel != null
+                            && sceneTransitionModel.getFrom() == SceneKey.Bouncer.INSTANCE
+                            && sceneTransitionModel.getTo() == SceneKey.Gone.INSTANCE) {
+                        final int selectedUserId = mUserInteractor.getSelectedUserId();
+                        showNextSecurityScreenOrFinish(
+                                /* authenticated= */ true,
+                                selectedUserId,
+                                /* bypassSecondaryLockScreen= */ true,
+                                mSecurityModel.getSecurityMode(selectedUserId));
+                    }
+                });
+        }
     }
 
     @Override
@@ -459,6 +495,11 @@
         mConfigurationController.removeCallback(mConfigurationListener);
         mView.removeMotionEventListener(mGlobalTouchListener);
         mUserSwitcherController.removeUserSwitchCallback(mUserSwitchCallback);
+
+        if (mSceneTransitionCollectionJob != null) {
+            mSceneTransitionCollectionJob.cancel(null);
+            mSceneTransitionCollectionJob = null;
+        }
     }
 
     /** */
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 518baec..8f03eed 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -4543,13 +4543,18 @@
      * Cancels all operations in the scheduler if it is hung for 10 seconds.
      */
     public void startBiometricWatchdog() {
-        if (mFaceManager != null && !isFaceAuthInteractorEnabled()) {
-            mLogger.scheduleWatchdog("face");
-            mFaceManager.scheduleWatchdog();
-        }
-        if (mFpm != null) {
-            mLogger.scheduleWatchdog("fingerprint");
-            mFpm.scheduleWatchdog();
-        }
+        final boolean isFaceAuthInteractorEnabled = isFaceAuthInteractorEnabled();
+        mBackgroundExecutor.execute(() -> {
+            Trace.beginSection("#startBiometricWatchdog");
+            if (mFaceManager != null && !isFaceAuthInteractorEnabled) {
+                mLogger.scheduleWatchdog("face");
+                mFaceManager.scheduleWatchdog();
+            }
+            if (mFpm != null) {
+                mLogger.scheduleWatchdog("fingerprint");
+                mFpm.scheduleWatchdog();
+            }
+            Trace.endSection();
+        });
     }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index 8ef6c2e..5459718 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -24,6 +24,7 @@
 import static com.android.keyguard.LockIconView.ICON_UNLOCK;
 import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
 import static com.android.systemui.flags.Flags.DOZING_MIGRATION_1;
+import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED;
 import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
 
 import android.content.res.Configuration;
@@ -124,6 +125,7 @@
     private int mActivePointerId = -1;
 
     private boolean mIsDozing;
+    private boolean mIsActiveDreamLockscreenHosted;
     private boolean mIsBouncerShowing;
     private boolean mRunningFPS;
     private boolean mCanDismissLockScreen;
@@ -165,6 +167,13 @@
         updateVisibility();
     };
 
+    @VisibleForTesting
+    final Consumer<Boolean> mIsActiveDreamLockscreenHostedCallback =
+            (Boolean isLockscreenHosted) -> {
+                mIsActiveDreamLockscreenHosted = isLockscreenHosted;
+                updateVisibility();
+            };
+
     @Inject
     public LockIconViewController(
             @Nullable LockIconView view,
@@ -224,6 +233,11 @@
                     mDozeTransitionCallback);
             collectFlow(mView, mKeyguardInteractor.isDozing(), mIsDozingCallback);
         }
+
+        if (mFeatureFlags.isEnabled(LOCKSCREEN_WALLPAPER_DREAM_ENABLED)) {
+            collectFlow(mView, mKeyguardInteractor.isActiveDreamLockscreenHosted(),
+                    mIsActiveDreamLockscreenHostedCallback);
+        }
     }
 
     @Override
@@ -289,6 +303,11 @@
             return;
         }
 
+        if (mIsKeyguardShowing && mIsActiveDreamLockscreenHosted) {
+            mView.setVisibility(View.INVISIBLE);
+            return;
+        }
+
         boolean wasShowingFpIcon = mUdfpsEnrolled && !mShowUnlockIcon && !mShowLockIcon
                 && !mShowAodUnlockedIcon && !mShowAodLockIcon;
         mShowLockIcon = !mCanDismissLockScreen && isLockScreen()
@@ -436,6 +455,7 @@
         pw.println(" mInterpolatedDarkAmount: " + mInterpolatedDarkAmount);
         pw.println(" mSensorTouchLocation: " + mSensorTouchLocation);
         pw.println(" mDefaultPaddingPx: " + mDefaultPaddingPx);
+        pw.println(" mIsActiveDreamLockscreenHosted: " + mIsActiveDreamLockscreenHosted);
 
         if (mView != null) {
             mView.dump(pw, args);
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java
index fd3c158..859e183 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java
@@ -107,6 +107,10 @@
         return mWindowMagnificationSettings.isSettingPanelShowing();
     }
 
+    void setMagnificationScale(float scale) {
+        mWindowMagnificationSettings.setMagnificationScale(scale);
+    }
+
     @Override
     public void onConfigurationChanged(@NonNull Configuration newConfig) {
         final int configDiff = newConfig.diff(mConfiguration);
@@ -160,8 +164,9 @@
          *
          * @param displayId The logical display id.
          * @param scale Magnification scale value.
+         * @param updatePersistence whether the new scale should be persisted.
          */
-        void onMagnifierScale(int displayId, float scale);
+        void onMagnifierScale(int displayId, float scale, boolean updatePersistence);
 
         /**
          * Called when magnification mode changed.
@@ -211,9 +216,9 @@
         }
 
         @Override
-        public void onMagnifierScale(float scale) {
+        public void onMagnifierScale(float scale, boolean updatePersistence) {
             mSettingsControllerCallback.onMagnifierScale(mDisplayId,
-                    A11Y_ACTION_SCALE_RANGE.clamp(scale));
+                    A11Y_ACTION_SCALE_RANGE.clamp(scale), updatePersistence);
         }
     };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
index 1739ba4..baabd95 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
@@ -310,6 +310,10 @@
             return;
         }
         scales.put(displayId, scale);
+
+        final MagnificationSettingsController magnificationSettingsController =
+                mMagnificationSettingsSupplier.get(displayId);
+        magnificationSettingsController.setMagnificationScale(scale);
     }
 
     @VisibleForTesting
@@ -329,9 +333,10 @@
         }
 
         @Override
-        public void onPerformScaleAction(int displayId, float scale) {
+        public void onPerformScaleAction(int displayId, float scale, boolean updatePersistence) {
             if (mWindowMagnificationConnectionImpl != null) {
-                mWindowMagnificationConnectionImpl.onPerformScaleAction(displayId, scale);
+                mWindowMagnificationConnectionImpl.onPerformScaleAction(
+                        displayId, scale, updatePersistence);
             }
         }
 
@@ -380,9 +385,10 @@
         }
 
         @Override
-        public void onMagnifierScale(int displayId, float scale) {
+        public void onMagnifierScale(int displayId, float scale, boolean updatePersistence) {
             if (mWindowMagnificationConnectionImpl != null) {
-                mWindowMagnificationConnectionImpl.onPerformScaleAction(displayId, scale);
+                mWindowMagnificationConnectionImpl.onPerformScaleAction(
+                        displayId, scale, updatePersistence);
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationConnectionImpl.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationConnectionImpl.java
index f1d00ce2..928445b 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationConnectionImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationConnectionImpl.java
@@ -129,10 +129,10 @@
         }
     }
 
-    void onPerformScaleAction(int displayId, float scale) {
+    void onPerformScaleAction(int displayId, float scale, boolean updatePersistence) {
         if (mConnectionCallback != null) {
             try {
-                mConnectionCallback.onPerformScaleAction(displayId, scale);
+                mConnectionCallback.onPerformScaleAction(displayId, scale, updatePersistence);
             } catch (RemoteException e) {
                 Log.e(TAG, "Failed to inform performing scale action", e);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index e7eab7e..602f817 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -1491,13 +1491,9 @@
                 // Simulate tapping the drag view so it opens the Settings.
                 handleSingleTap(mDragView);
             } else if (action == R.id.accessibility_action_zoom_in) {
-                final float scale = mScale + A11Y_CHANGE_SCALE_DIFFERENCE;
-                mWindowMagnifierCallback.onPerformScaleAction(mDisplayId,
-                        A11Y_ACTION_SCALE_RANGE.clamp(scale));
+                performScale(mScale + A11Y_CHANGE_SCALE_DIFFERENCE);
             } else if (action == R.id.accessibility_action_zoom_out) {
-                final float scale = mScale - A11Y_CHANGE_SCALE_DIFFERENCE;
-                mWindowMagnifierCallback.onPerformScaleAction(mDisplayId,
-                        A11Y_ACTION_SCALE_RANGE.clamp(scale));
+                performScale(mScale - A11Y_CHANGE_SCALE_DIFFERENCE);
             } else if (action == R.id.accessibility_action_move_up) {
                 move(0, -mSourceBounds.height());
             } else if (action == R.id.accessibility_action_move_down) {
@@ -1512,5 +1508,11 @@
             mWindowMagnifierCallback.onAccessibilityActionPerformed(mDisplayId);
             return true;
         }
+
+        private void performScale(float scale) {
+            scale = A11Y_ACTION_SCALE_RANGE.clamp(scale);
+            mWindowMagnifierCallback.onPerformScaleAction(
+                    mDisplayId, scale, /* updatePersistence= */ true);
+        }
     }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
index 1e1d4b7..6ec5320 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
@@ -57,7 +57,6 @@
 import android.widget.Switch;
 import android.widget.TextView;
 
-import com.android.internal.accessibility.common.MagnificationConstants;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
 import com.android.systemui.R;
@@ -89,14 +88,12 @@
     private final MagnificationGestureDetector mGestureDetector;
     private boolean mSingleTapDetected = false;
 
-    @VisibleForTesting
-    SeekBarWithIconButtonsView mZoomSeekbar;
+    private SeekBarWithIconButtonsView mZoomSeekbar;
     private LinearLayout mAllowDiagonalScrollingView;
     private TextView mAllowDiagonalScrollingTitle;
     private Switch mAllowDiagonalScrollingSwitch;
     private LinearLayout mPanelView;
     private LinearLayout mSettingView;
-    private LinearLayout mButtonView;
     private ImageButton mSmallButton;
     private ImageButton mMediumButton;
     private ImageButton mLargeButton;
@@ -110,10 +107,11 @@
      * magnitude = 10 means, for every 1 scale increase, 10 progress increase in seekbar.
      */
     private int mSeekBarMagnitude;
+    private float mScale = SCALE_MIN_VALUE;
+
     private WindowMagnificationSettingsCallback mCallback;
 
     private ContentObserver mMagnificationCapabilityObserver;
-    private ContentObserver mMagnificationScaleObserver;
 
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({
@@ -163,30 +161,20 @@
                 });
             }
         };
-        mMagnificationScaleObserver = new ContentObserver(
-                mContext.getMainThreadHandler()) {
-            @Override
-            public void onChange(boolean selfChange) {
-                setScaleSeekbar(getMagnificationScale());
-            }
-        };
     }
 
     private class ZoomSeekbarChangeListener implements
             SeekBarWithIconButtonsView.OnSeekBarWithIconButtonsChangeListener {
         @Override
         public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
-            float scale = (progress / (float) mSeekBarMagnitude) + SCALE_MIN_VALUE;
-            // Update persisted scale only when scale >= PERSISTED_SCALE_MIN_VALUE const.
-            // We assume if the scale is lower than the PERSISTED_SCALE_MIN_VALUE, there will be
-            // no obvious magnification effect.
-            if (scale >= MagnificationConstants.PERSISTED_SCALE_MIN_VALUE) {
-                mSecureSettings.putFloatForUser(
-                        Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
-                        scale,
-                        UserHandle.USER_CURRENT);
+            // Notify the service to update the magnifier scale only when the progress changed is
+            // triggered by user interaction on seekbar
+            if (fromUser) {
+                final float scale = transformProgressToScale(progress);
+                // We don't need to update the persisted scale when the seekbar progress is
+                // changing. The update should be triggered when the changing is ended.
+                mCallback.onMagnifierScale(scale, /* updatePersistence= */ false);
             }
-            mCallback.onMagnifierScale(scale);
         }
 
         @Override
@@ -201,7 +189,14 @@
 
         @Override
         public void onUserInteractionFinalized(SeekBar seekBar, @ControlUnitType int control) {
-            // Do nothing
+            // Update the Settings persisted scale only when user interaction with seekbar ends
+            final int progress = seekBar.getProgress();
+            final float scale = transformProgressToScale(progress);
+            mCallback.onMagnifierScale(scale, /* updatePersistence= */ true);
+        }
+
+        private float transformProgressToScale(float progress) {
+            return (progress / (float) mSeekBarMagnitude) + SCALE_MIN_VALUE;
         }
     }
 
@@ -322,7 +317,6 @@
 
         // Unregister observer before removing view
         mSecureSettings.unregisterContentObserver(mMagnificationCapabilityObserver);
-        mSecureSettings.unregisterContentObserver(mMagnificationScaleObserver);
         mWindowManager.removeView(mSettingView);
         mIsVisible = false;
         if (resetPosition) {
@@ -374,7 +368,7 @@
     private void showSettingPanel(boolean resetPosition) {
         if (!mIsVisible) {
             updateUIControlsIfNeeded();
-            setScaleSeekbar(getMagnificationScale());
+            setScaleSeekbar(mScale);
             if (resetPosition) {
                 mDraggableWindowBounds.set(getDraggableWindowBounds());
                 mParams.x = mDraggableWindowBounds.right;
@@ -387,10 +381,6 @@
                     Settings.Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY,
                     mMagnificationCapabilityObserver,
                     UserHandle.USER_CURRENT);
-            mSecureSettings.registerContentObserverForUser(
-                    Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
-                    mMagnificationScaleObserver,
-                    UserHandle.USER_CURRENT);
 
             // Exclude magnification switch button from system gesture area.
             setSystemGestureExclusion();
@@ -430,11 +420,17 @@
                 UserHandle.USER_CURRENT);
     }
 
-    private float getMagnificationScale() {
-        return mSecureSettings.getFloatForUser(
-                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
-                SCALE_MIN_VALUE,
-                UserHandle.USER_CURRENT);
+    /**
+     * Only called from outside to notify the controlling magnifier scale changed
+     *
+     * @param scale The new controlling magnifier scale
+     */
+    public void setMagnificationScale(float scale) {
+        mScale = scale;
+
+        if (isSettingPanelShowing()) {
+            setScaleSeekbar(scale);
+        }
     }
 
     private void updateUIControlsIfNeeded() {
@@ -523,10 +519,7 @@
         mZoomSeekbar.setMax((int) (mZoomSeekbar.getChangeMagnitude()
                 * (SCALE_MAX_VALUE - SCALE_MIN_VALUE)));
         mSeekBarMagnitude = mZoomSeekbar.getChangeMagnitude();
-        float scale = mSecureSettings.getFloatForUser(
-                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 0,
-                UserHandle.USER_CURRENT);
-        setScaleSeekbar(scale);
+        setScaleSeekbar(mScale);
         mZoomSeekbar.setOnSeekBarWithIconButtonsChangeListener(new ZoomSeekbarChangeListener());
 
         mAllowDiagonalScrollingView =
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettingsCallback.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettingsCallback.java
index 3dbff5d..2eee7a6 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettingsCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettingsCallback.java
@@ -52,8 +52,9 @@
      * Called when set magnification scale.
      *
      * @param scale Magnification scale value.
+     * @param updatePersistence whether the scale should be persisted
      */
-    void onMagnifierScale(float scale);
+    void onMagnifierScale(float scale, boolean updatePersistence);
 
     /**
      * Called when magnification mode changed.
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnifierCallback.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnifierCallback.java
index e18161d..a25e9a2 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnifierCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnifierCallback.java
@@ -44,8 +44,9 @@
      *
      * @param displayId The logical display id.
      * @param scale the target scale, or {@link Float#NaN} to leave unchanged
+     * @param updatePersistence whether the scale should be persisted
      */
-    void onPerformScaleAction(int displayId, float scale);
+    void onPerformScaleAction(int displayId, float scale, boolean updatePersistence);
 
     /**
      * Called when the accessibility action is performed.
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt b/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
index 0b25184..444491f 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
@@ -14,25 +14,39 @@
  * limitations under the License.
  */
 
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
 package com.android.systemui.authentication.data.repository
 
+import com.android.internal.widget.LockPatternChecker
 import com.android.internal.widget.LockPatternUtils
+import com.android.internal.widget.LockscreenCredential
 import com.android.keyguard.KeyguardSecurityModel
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.authentication.shared.model.AuthenticationResultModel
+import com.android.systemui.authentication.shared.model.AuthenticationThrottlingModel
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.keyguard.data.repository.KeyguardRepository
 import com.android.systemui.user.data.repository.UserRepository
+import com.android.systemui.util.time.SystemClock
 import dagger.Binds
 import dagger.Module
 import java.util.function.Function
 import javax.inject.Inject
+import kotlin.coroutines.resume
+import kotlin.coroutines.suspendCoroutine
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.withContext
 
@@ -57,11 +71,17 @@
      */
     val isBypassEnabled: StateFlow<Boolean>
 
-    /**
-     * Number of consecutively failed authentication attempts. This resets to `0` when
-     * authentication succeeds.
-     */
-    val failedAuthenticationAttempts: StateFlow<Int>
+    /** Whether the auto confirm feature is enabled for the currently-selected user. */
+    val isAutoConfirmEnabled: StateFlow<Boolean>
+
+    /** The length of the PIN for which we should show a hint. */
+    val hintedPinLength: Int
+
+    /** Whether the pattern should be visible for the currently-selected user. */
+    val isPatternVisible: StateFlow<Boolean>
+
+    /** The current throttling state, as cached via [setThrottling]. */
+    val throttling: StateFlow<AuthenticationThrottlingModel>
 
     /**
      * Returns the currently-configured authentication method. This determines how the
@@ -69,11 +89,48 @@
      */
     suspend fun getAuthenticationMethod(): AuthenticationMethodModel
 
+    /** Returns the length of the PIN or `0` if the current auth method is not PIN. */
+    suspend fun getPinLength(): Int
+
+    /**
+     * Returns whether the lockscreen is enabled.
+     *
+     * When the lockscreen is not enabled, it shouldn't show in cases when the authentication method
+     * is considered not secure (for example, "swipe" is considered to be "none").
+     */
+    suspend fun isLockscreenEnabled(): Boolean
+
     /** See [isBypassEnabled]. */
     fun setBypassEnabled(isBypassEnabled: Boolean)
 
-    /** See [failedAuthenticationAttempts]. */
-    fun setFailedAuthenticationAttempts(failedAuthenticationAttempts: Int)
+    /** Reports an authentication attempt. */
+    suspend fun reportAuthenticationAttempt(isSuccessful: Boolean)
+
+    /** Returns the current number of failed authentication attempts. */
+    suspend fun getFailedAuthenticationAttemptCount(): Int
+
+    /**
+     * Returns the timestamp for when the current throttling will end, allowing the user to attempt
+     * authentication again.
+     *
+     * Note that this is in milliseconds and it matches [SystemClock.elapsedRealtime].
+     */
+    suspend fun getThrottlingEndTimestamp(): Long
+
+    /** Sets the cached throttling state, updating the [throttling] flow. */
+    fun setThrottling(throttlingModel: AuthenticationThrottlingModel)
+
+    /**
+     * Sets the throttling timeout duration (time during which the user should not be allowed to
+     * attempt authentication).
+     */
+    suspend fun setThrottleDuration(durationMs: Int)
+
+    /**
+     * Checks the given [LockscreenCredential] to see if it's correct, returning an
+     * [AuthenticationResultModel] representing what happened.
+     */
+    suspend fun checkCredential(credential: LockscreenCredential): AuthenticationResultModel
 }
 
 class AuthenticationRepositoryImpl
@@ -83,65 +140,146 @@
     private val getSecurityMode: Function<Int, KeyguardSecurityModel.SecurityMode>,
     @Background private val backgroundDispatcher: CoroutineDispatcher,
     private val userRepository: UserRepository,
-    private val lockPatternUtils: LockPatternUtils,
     keyguardRepository: KeyguardRepository,
+    private val lockPatternUtils: LockPatternUtils,
 ) : AuthenticationRepository {
 
-    override val isUnlocked: StateFlow<Boolean> =
-        keyguardRepository.isKeyguardUnlocked.stateIn(
-            scope = applicationScope,
-            started = SharingStarted.WhileSubscribed(),
-            initialValue = false,
-        )
+    override val isUnlocked: StateFlow<Boolean> = keyguardRepository.isKeyguardUnlocked
+
+    override suspend fun isLockscreenEnabled(): Boolean {
+        return withContext(backgroundDispatcher) {
+            val selectedUserId = userRepository.selectedUserId
+            !lockPatternUtils.isLockPatternEnabled(selectedUserId)
+        }
+    }
 
     private val _isBypassEnabled = MutableStateFlow(false)
     override val isBypassEnabled: StateFlow<Boolean> = _isBypassEnabled.asStateFlow()
 
-    private val _failedAuthenticationAttempts = MutableStateFlow(0)
-    override val failedAuthenticationAttempts: StateFlow<Int> =
-        _failedAuthenticationAttempts.asStateFlow()
+    override val isAutoConfirmEnabled: StateFlow<Boolean> =
+        userRepository.selectedUserInfo
+            .map { it.id }
+            .flatMapLatest { userId ->
+                flow { emit(lockPatternUtils.isAutoPinConfirmEnabled(userId)) }
+                    .flowOn(backgroundDispatcher)
+            }
+            .stateIn(
+                scope = applicationScope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue = true,
+            )
+
+    override val hintedPinLength: Int = LockPatternUtils.MIN_AUTO_PIN_REQUIREMENT_LENGTH
+
+    override val isPatternVisible: StateFlow<Boolean> =
+        userRepository.selectedUserInfo
+            .map { it.id }
+            .flatMapLatest { userId ->
+                flow { emit(lockPatternUtils.isVisiblePatternEnabled(userId)) }
+                    .flowOn(backgroundDispatcher)
+            }
+            .stateIn(
+                scope = applicationScope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue = true,
+            )
+
+    private val _throttling = MutableStateFlow(AuthenticationThrottlingModel())
+    override val throttling: StateFlow<AuthenticationThrottlingModel> = _throttling.asStateFlow()
+
+    private val UserRepository.selectedUserId: Int
+        get() = getSelectedUserInfo().id
 
     override suspend fun getAuthenticationMethod(): AuthenticationMethodModel {
         return withContext(backgroundDispatcher) {
-            val selectedUserId = userRepository.getSelectedUserInfo().id
+            val selectedUserId = userRepository.selectedUserId
             when (getSecurityMode.apply(selectedUserId)) {
                 KeyguardSecurityModel.SecurityMode.PIN,
-                KeyguardSecurityModel.SecurityMode.SimPin ->
-                    AuthenticationMethodModel.Pin(
-                        code = listOf(1, 2, 3, 4), // TODO(b/280883900): remove this
-                        autoConfirm = lockPatternUtils.isAutoPinConfirmEnabled(selectedUserId),
-                    )
-                KeyguardSecurityModel.SecurityMode.Password,
-                KeyguardSecurityModel.SecurityMode.SimPuk ->
-                    AuthenticationMethodModel.Password(
-                        password = "password", // TODO(b/280883900): remove this
-                    )
-                KeyguardSecurityModel.SecurityMode.Pattern ->
-                    AuthenticationMethodModel.Pattern(
-                        coordinates =
-                            listOf(
-                                AuthenticationMethodModel.Pattern.PatternCoordinate(2, 0),
-                                AuthenticationMethodModel.Pattern.PatternCoordinate(2, 1),
-                                AuthenticationMethodModel.Pattern.PatternCoordinate(2, 2),
-                                AuthenticationMethodModel.Pattern.PatternCoordinate(1, 1),
-                                AuthenticationMethodModel.Pattern.PatternCoordinate(0, 0),
-                                AuthenticationMethodModel.Pattern.PatternCoordinate(0, 1),
-                                AuthenticationMethodModel.Pattern.PatternCoordinate(0, 2),
-                            ), // TODO(b/280883900): remove this
-                    )
+                KeyguardSecurityModel.SecurityMode.SimPin,
+                KeyguardSecurityModel.SecurityMode.SimPuk -> AuthenticationMethodModel.Pin
+                KeyguardSecurityModel.SecurityMode.Password -> AuthenticationMethodModel.Password
+                KeyguardSecurityModel.SecurityMode.Pattern -> AuthenticationMethodModel.Pattern
                 KeyguardSecurityModel.SecurityMode.None -> AuthenticationMethodModel.None
                 KeyguardSecurityModel.SecurityMode.Invalid -> error("Invalid security mode!")
-                null -> error("Invalid security is null!")
             }
         }
     }
 
+    override suspend fun getPinLength(): Int {
+        return withContext(backgroundDispatcher) {
+            val selectedUserId = userRepository.selectedUserId
+            lockPatternUtils.getPinLength(selectedUserId)
+        }
+    }
+
     override fun setBypassEnabled(isBypassEnabled: Boolean) {
         _isBypassEnabled.value = isBypassEnabled
     }
 
-    override fun setFailedAuthenticationAttempts(failedAuthenticationAttempts: Int) {
-        _failedAuthenticationAttempts.value = failedAuthenticationAttempts
+    override suspend fun reportAuthenticationAttempt(isSuccessful: Boolean) {
+        val selectedUserId = userRepository.selectedUserId
+        withContext(backgroundDispatcher) {
+            if (isSuccessful) {
+                lockPatternUtils.reportSuccessfulPasswordAttempt(selectedUserId)
+            } else {
+                lockPatternUtils.reportFailedPasswordAttempt(selectedUserId)
+            }
+        }
+    }
+
+    override suspend fun getFailedAuthenticationAttemptCount(): Int {
+        return withContext(backgroundDispatcher) {
+            val selectedUserId = userRepository.selectedUserId
+            lockPatternUtils.getCurrentFailedPasswordAttempts(selectedUserId)
+        }
+    }
+
+    override suspend fun getThrottlingEndTimestamp(): Long {
+        return withContext(backgroundDispatcher) {
+            val selectedUserId = userRepository.selectedUserId
+            lockPatternUtils.getLockoutAttemptDeadline(selectedUserId)
+        }
+    }
+
+    override fun setThrottling(throttlingModel: AuthenticationThrottlingModel) {
+        _throttling.value = throttlingModel
+    }
+
+    override suspend fun setThrottleDuration(durationMs: Int) {
+        withContext(backgroundDispatcher) {
+            lockPatternUtils.setLockoutAttemptDeadline(
+                userRepository.selectedUserId,
+                durationMs,
+            )
+        }
+    }
+
+    override suspend fun checkCredential(
+        credential: LockscreenCredential
+    ): AuthenticationResultModel {
+        return suspendCoroutine { continuation ->
+            LockPatternChecker.checkCredential(
+                lockPatternUtils,
+                credential,
+                userRepository.selectedUserId,
+                object : LockPatternChecker.OnCheckCallback {
+                    override fun onChecked(matched: Boolean, throttleTimeoutMs: Int) {
+                        continuation.resume(
+                            AuthenticationResultModel(
+                                isSuccessful = matched,
+                                throttleDurationMs = throttleTimeoutMs,
+                            )
+                        )
+                    }
+
+                    override fun onCancelled() {
+                        continuation.resume(AuthenticationResultModel(isSuccessful = false))
+                    }
+
+                    override fun onEarlyMatched() = Unit
+                }
+            )
+        }
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt b/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
index 15e579d..82674bf 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
@@ -16,25 +16,43 @@
 
 package com.android.systemui.authentication.domain.interactor
 
-import android.app.admin.DevicePolicyManager
+import com.android.internal.widget.LockPatternView
+import com.android.internal.widget.LockscreenCredential
 import com.android.systemui.authentication.data.repository.AuthenticationRepository
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.authentication.shared.model.AuthenticationThrottlingModel
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.user.data.repository.UserRepository
+import com.android.systemui.util.time.SystemClock
 import javax.inject.Inject
+import kotlin.math.max
+import kotlin.time.Duration.Companion.seconds
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.async
+import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flow
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
 
 /** Hosts application business logic related to authentication. */
 @SysUISingleton
 class AuthenticationInteractor
 @Inject
 constructor(
-    @Application applicationScope: CoroutineScope,
+    @Application private val applicationScope: CoroutineScope,
     private val repository: AuthenticationRepository,
+    @Background private val backgroundDispatcher: CoroutineDispatcher,
+    private val userRepository: UserRepository,
+    private val clock: SystemClock,
 ) {
     /**
      * Whether the device is unlocked.
@@ -67,18 +85,66 @@
      */
     val isBypassEnabled: StateFlow<Boolean> = repository.isBypassEnabled
 
+    /** The current authentication throttling state, only meaningful if [isThrottled] is `true`. */
+    val throttling: StateFlow<AuthenticationThrottlingModel> = repository.throttling
+
     /**
-     * Number of consecutively failed authentication attempts. This resets to `0` when
-     * authentication succeeds.
+     * Whether currently throttled and the user has to wait before being able to try another
+     * authentication attempt.
      */
-    val failedAuthenticationAttempts: StateFlow<Int> = repository.failedAuthenticationAttempts
+    val isThrottled: StateFlow<Boolean> =
+        throttling
+            .map { it.remainingMs > 0 }
+            .stateIn(
+                scope = applicationScope,
+                started = SharingStarted.Eagerly,
+                initialValue = throttling.value.remainingMs > 0,
+            )
+
+    /** The length of the hinted PIN, or `null` if pin length hint should not be shown. */
+    val hintedPinLength: StateFlow<Int?> =
+        flow { emit(repository.getPinLength()) }
+            .map { currentPinLength ->
+                // Hinting is enabled for 6-digit codes only
+                currentPinLength.takeIf { repository.hintedPinLength == it }
+            }
+            .stateIn(
+                scope = applicationScope,
+                started = SharingStarted.Eagerly,
+                initialValue = null,
+            )
+
+    /** Whether the auto confirm feature is enabled for the currently-selected user. */
+    val isAutoConfirmEnabled: StateFlow<Boolean> = repository.isAutoConfirmEnabled
+
+    /** Whether the pattern should be visible for the currently-selected user. */
+    val isPatternVisible: StateFlow<Boolean> = repository.isPatternVisible
+
+    private var throttlingCountdownJob: Job? = null
+
+    init {
+        applicationScope.launch {
+            userRepository.selectedUserInfo
+                .map { it.id }
+                .distinctUntilChanged()
+                .collect { onSelectedUserChanged() }
+        }
+    }
 
     /**
      * Returns the currently-configured authentication method. This determines how the
      * authentication challenge is completed in order to unlock an otherwise locked device.
      */
     suspend fun getAuthenticationMethod(): AuthenticationMethodModel {
-        return repository.getAuthenticationMethod()
+        val authMethod = repository.getAuthenticationMethod()
+        return if (
+            authMethod is AuthenticationMethodModel.None && repository.isLockscreenEnabled()
+        ) {
+            // We treat "None" as "Swipe" when the lockscreen is enabled.
+            AuthenticationMethodModel.Swipe
+        } else {
+            authMethod
+        }
     }
 
     /**
@@ -104,39 +170,52 @@
      *   authentication failed, `null` if the check was not performed.
      */
     suspend fun authenticate(input: List<Any>, tryAutoConfirm: Boolean = false): Boolean? {
-        val authMethod = getAuthenticationMethod()
-        if (tryAutoConfirm) {
-            if ((authMethod as? AuthenticationMethodModel.Pin)?.autoConfirm != true) {
-                // Do not attempt to authenticate unless the PIN lock is set to auto-confirm.
-                return null
-            }
-
-            if (input.size < authMethod.code.size) {
-                // Do not attempt to authenticate if the PIN has not yet the required amount of
-                // digits. This intentionally only skip for shorter PINs; if the PIN is longer, the
-                // layer above might have throttled this check, and the PIN should be rejected via
-                // the auth code below.
-                return null
-            }
+        if (input.isEmpty()) {
+            throw IllegalArgumentException("Input was empty!")
         }
 
-        val isSuccessful =
-            when (authMethod) {
-                is AuthenticationMethodModel.Pin -> input.asCode() == authMethod.code
-                is AuthenticationMethodModel.Password -> input.asPassword() == authMethod.password
-                is AuthenticationMethodModel.Pattern -> input.asPattern() == authMethod.coordinates
-                else -> true
+        val skipCheck =
+            when {
+                // We're being throttled, the UI layer should not have called this; skip the
+                // attempt.
+                isThrottled.value -> true
+                // Auto-confirm attempt when the feature is not enabled; skip the attempt.
+                tryAutoConfirm && !isAutoConfirmEnabled.value -> true
+                // Auto-confirm should skip the attempt if the pin entered is too short.
+                tryAutoConfirm && input.size < repository.getPinLength() -> true
+                else -> false
             }
+        if (skipCheck) {
+            return null
+        }
 
-        if (isSuccessful) {
-            repository.setFailedAuthenticationAttempts(0)
-        } else {
-            repository.setFailedAuthenticationAttempts(
-                repository.failedAuthenticationAttempts.value + 1
+        // Attempt to authenticate:
+        val authMethod = getAuthenticationMethod()
+        val credential = authMethod.createCredential(input) ?: return null
+        val authenticationResult = repository.checkCredential(credential)
+        credential.zeroize()
+
+        if (authenticationResult.isSuccessful || !tryAutoConfirm) {
+            repository.reportAuthenticationAttempt(
+                isSuccessful = authenticationResult.isSuccessful,
             )
         }
 
-        return isSuccessful
+        // Check if we need to throttle and, if so, kick off the throttle countdown:
+        if (!authenticationResult.isSuccessful && authenticationResult.throttleDurationMs > 0) {
+            repository.setThrottleDuration(
+                durationMs = authenticationResult.throttleDurationMs,
+            )
+            startThrottlingCountdown()
+        }
+
+        if (authenticationResult.isSuccessful) {
+            // Since authentication succeeded, we should refresh throttling to make sure that our
+            // state is completely reflecting the upstream source of truth.
+            refreshThrottling()
+        }
+
+        return authenticationResult.isSuccessful
     }
 
     /** See [isBypassEnabled]. */
@@ -144,44 +223,67 @@
         repository.setBypassEnabled(!repository.isBypassEnabled.value)
     }
 
-    companion object {
-        /**
-         * Returns a PIN code from the given list. It's assumed the given list elements are all
-         * [Int] in the range [0-9].
-         */
-        private fun List<Any>.asCode(): List<Int>? {
-            if (isEmpty() || size > DevicePolicyManager.MAX_PASSWORD_LENGTH) {
-                return null
-            }
-
-            return map {
-                require(it is Int && it in 0..9) {
-                    "Pin is required to be Int in range [0..9], but got $it"
+    /** Starts refreshing the throttling state every second. */
+    private suspend fun startThrottlingCountdown() {
+        cancelCountdown()
+        throttlingCountdownJob =
+            applicationScope.launch {
+                while (refreshThrottling() > 0) {
+                    delay(1.seconds.inWholeMilliseconds)
                 }
-                it
             }
-        }
+    }
 
-        /**
-         * Returns a password from the given list. It's assumed the given list elements are all
-         * [Char].
-         */
-        private fun List<Any>.asPassword(): String {
-            val anyList = this
-            return buildString { anyList.forEach { append(it as Char) } }
-        }
+    /** Cancels any throttling state countdown started in [startThrottlingCountdown]. */
+    private fun cancelCountdown() {
+        throttlingCountdownJob?.cancel()
+        throttlingCountdownJob = null
+    }
 
-        /**
-         * Returns a list of [AuthenticationMethodModel.Pattern.PatternCoordinate] from the given
-         * list. It's assumed the given list elements are all
-         * [AuthenticationMethodModel.Pattern.PatternCoordinate].
-         */
-        private fun List<Any>.asPattern():
-            List<AuthenticationMethodModel.Pattern.PatternCoordinate> {
-            val anyList = this
-            return buildList {
-                anyList.forEach { add(it as AuthenticationMethodModel.Pattern.PatternCoordinate) }
-            }
+    /** Notifies that the currently-selected user has changed. */
+    private suspend fun onSelectedUserChanged() {
+        cancelCountdown()
+        if (refreshThrottling() > 0) {
+            startThrottlingCountdown()
+        }
+    }
+
+    /**
+     * Refreshes the throttling state, hydrating the repository with the latest state.
+     *
+     * @return The remaining time for the current throttling countdown, in milliseconds or `0` if
+     *   not being throttled.
+     */
+    private suspend fun refreshThrottling(): Long {
+        return withContext(backgroundDispatcher) {
+            val failedAttemptCount = async { repository.getFailedAuthenticationAttemptCount() }
+            val deadline = async { repository.getThrottlingEndTimestamp() }
+            val remainingMs = max(0, deadline.await() - clock.elapsedRealtime())
+            repository.setThrottling(
+                AuthenticationThrottlingModel(
+                    failedAttemptCount = failedAttemptCount.await(),
+                    remainingMs = remainingMs.toInt(),
+                ),
+            )
+            remainingMs
+        }
+    }
+
+    private fun AuthenticationMethodModel.createCredential(
+        input: List<Any>
+    ): LockscreenCredential? {
+        return when (this) {
+            is AuthenticationMethodModel.Pin ->
+                LockscreenCredential.createPin(input.joinToString(""))
+            is AuthenticationMethodModel.Password ->
+                LockscreenCredential.createPassword(input.joinToString(""))
+            is AuthenticationMethodModel.Pattern ->
+                LockscreenCredential.createPattern(
+                    input
+                        .map { it as AuthenticationMethodModel.Pattern.PatternCoordinate }
+                        .map { LockPatternView.Cell.of(it.y, it.x) }
+                )
+            else -> null
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationMethodModel.kt b/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationMethodModel.kt
index 1016b6b..97c6697 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationMethodModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationMethodModel.kt
@@ -16,8 +16,6 @@
 
 package com.android.systemui.authentication.shared.model
 
-import androidx.annotation.VisibleForTesting
-
 /** Enumerates all known authentication methods. */
 sealed class AuthenticationMethodModel(
     /**
@@ -34,30 +32,11 @@
     /** The most basic authentication method. The lock screen can be swiped away when displayed. */
     object Swipe : AuthenticationMethodModel(isSecure = false)
 
-    /**
-     * Authentication method using a PIN.
-     *
-     * In practice, a pin is restricted to 16 decimal digits , see
-     * [android.app.admin.DevicePolicyManager.MAX_PASSWORD_LENGTH]
-     */
-    data class Pin(val code: List<Int>, val autoConfirm: Boolean) :
-        AuthenticationMethodModel(isSecure = true) {
+    object Pin : AuthenticationMethodModel(isSecure = true)
 
-        /** Convenience constructor for tests only. */
-        @VisibleForTesting
-        constructor(
-            code: Long,
-            autoConfirm: Boolean = false
-        ) : this(code.toString(10).map { it - '0' }, autoConfirm) {}
-    }
+    object Password : AuthenticationMethodModel(isSecure = true)
 
-    data class Password(val password: String) : AuthenticationMethodModel(isSecure = true)
-
-    data class Pattern(
-        val coordinates: List<PatternCoordinate>,
-        val isPatternVisible: Boolean = true,
-    ) : AuthenticationMethodModel(isSecure = true) {
-
+    object Pattern : AuthenticationMethodModel(isSecure = true) {
         data class PatternCoordinate(
             val x: Int,
             val y: Int,
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationResultModel.kt b/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationResultModel.kt
new file mode 100644
index 0000000..f2a3e74
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationResultModel.kt
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+package com.android.systemui.authentication.shared.model
+
+/** Models the result of an authentication attempt. */
+data class AuthenticationResultModel(
+    /** Whether authentication was successful. */
+    val isSuccessful: Boolean = false,
+    /** If [isSuccessful] is `false`, how long the user must wait before trying again. */
+    val throttleDurationMs: Int = 0,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationThrottlingModel.kt b/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationThrottlingModel.kt
new file mode 100644
index 0000000..d0d398e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationThrottlingModel.kt
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+package com.android.systemui.authentication.shared.model
+
+/** Models a state for throttling the next authentication attempt. */
+data class AuthenticationThrottlingModel(
+
+    /** Number of failed authentication attempts so far. If not throttling this will be `0`. */
+    val failedAttemptCount: Int = 0,
+
+    /**
+     * Remaining amount of time, in milliseconds, before another authentication attempt can be done.
+     * If not throttling this will be `0`.
+     *
+     * This number is changed throughout the timeout.
+     */
+    val remainingMs: Int = 0,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
index cd8f04d..ed4b91c 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
@@ -737,7 +737,7 @@
         });
 
         mUseCredentialButton.setOnClickListener((view) -> {
-            startTransitionToCredentialUI();
+            startTransitionToCredentialUI(false /* isError */);
         });
 
         mConfirmButton.setOnClickListener((view) -> {
@@ -768,9 +768,12 @@
 
     /**
      * Kicks off the animation process and invokes the callback.
+     *
+     * @param isError if this was triggered due to an error and not a user action (unused,
+     *                previously for haptics).
      */
     @Override
-    public void startTransitionToCredentialUI() {
+    public void startTransitionToCredentialUI(boolean isError) {
         updateSize(AuthDialog.SIZE_LARGE);
         mCallback.onAction(Callback.ACTION_USE_DEVICE_CREDENTIAL);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricViewAdapter.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricViewAdapter.kt
index 631511c..68db564 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricViewAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricViewAdapter.kt
@@ -38,7 +38,7 @@
 
     fun onHelp(@BiometricAuthenticator.Modality modality: Int, help: String)
 
-    fun startTransitionToCredentialUI()
+    fun startTransitionToCredentialUI(isError: Boolean)
 
     fun requestLayout()
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index d8348ed..7a2f244 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -801,9 +801,9 @@
     }
 
     @Override
-    public void animateToCredentialUI() {
+    public void animateToCredentialUI(boolean isError) {
         if (mBiometricView != null) {
-            mBiometricView.startTransitionToCredentialUI();
+            mBiometricView.startTransitionToCredentialUI(isError);
         } else {
             Log.e(TAG, "animateToCredentialUI(): mBiometricView is null");
         }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 76e48e9..3df7ca5 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -85,7 +85,6 @@
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.keyguard.data.repository.BiometricType;
 import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.VibratorHelper;
 import com.android.systemui.util.concurrency.DelayableExecutor;
 import com.android.systemui.util.concurrency.Execution;
 
@@ -185,18 +184,6 @@
     private final @Background DelayableExecutor mBackgroundExecutor;
     private final DisplayInfo mCachedDisplayInfo = new DisplayInfo();
 
-    private final VibratorHelper mVibratorHelper;
-
-    private void vibrateSuccess(int modality) {
-        mVibratorHelper.vibrateAuthSuccess(
-                getClass().getSimpleName() + ", modality = " + modality + "BP::success");
-    }
-
-    private void vibrateError(int modality) {
-        mVibratorHelper.vibrateAuthError(
-                getClass().getSimpleName() + ", modality = " + modality + "BP::error");
-    }
-
     @VisibleForTesting
     final TaskStackListener mTaskStackListener = new TaskStackListener() {
         @Override
@@ -784,7 +771,6 @@
             @NonNull InteractionJankMonitor jankMonitor,
             @Main Handler handler,
             @Background DelayableExecutor bgExecutor,
-            @NonNull VibratorHelper vibrator,
             @NonNull UdfpsUtils udfpsUtils) {
         mContext = context;
         mFeatureFlags = featureFlags;
@@ -806,7 +792,6 @@
         mUdfpsEnrolledForUser = new SparseBooleanArray();
         mSfpsEnrolledForUser = new SparseBooleanArray();
         mFaceEnrolledForUser = new SparseBooleanArray();
-        mVibratorHelper = vibrator;
         mUdfpsUtils = udfpsUtils;
         mApplicationCoroutineScope = applicationCoroutineScope;
 
@@ -995,8 +980,6 @@
     public void onBiometricAuthenticated(@Modality int modality) {
         if (DEBUG) Log.d(TAG, "onBiometricAuthenticated: ");
 
-        vibrateSuccess(modality);
-
         if (mCurrentDialog != null) {
             mCurrentDialog.onAuthenticationSucceeded(modality);
         } else {
@@ -1093,8 +1076,6 @@
             Log.d(TAG, String.format("onBiometricError(%d, %d, %d)", modality, error, vendorCode));
         }
 
-        vibrateError(modality);
-
         final boolean isLockout = (error == BiometricConstants.BIOMETRIC_ERROR_LOCKOUT)
                 || (error == BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT);
 
@@ -1111,9 +1092,10 @@
         if (mCurrentDialog != null) {
             if (mCurrentDialog.isAllowDeviceCredentials() && isLockout) {
                 if (DEBUG) Log.d(TAG, "onBiometricError, lockout");
-                mCurrentDialog.animateToCredentialUI();
+                mCurrentDialog.animateToCredentialUI(true /* isError */);
             } else if (isSoftError) {
-                final String errorMessage = (error == BiometricConstants.BIOMETRIC_PAUSED_REJECTED)
+                final String errorMessage = (error == BiometricConstants.BIOMETRIC_PAUSED_REJECTED
+                        || error == BiometricConstants.BIOMETRIC_ERROR_TIMEOUT)
                         ? getNotRecognizedString(modality)
                         : getErrorString(modality, error, vendorCode);
                 if (DEBUG) Log.d(TAG, "onBiometricError, soft error: " + errorMessage);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
index b6eabfa..3cfc6f2 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
@@ -162,7 +162,7 @@
     /**
      * Animate to credential UI. Typically called after biometric is locked out.
      */
-    void animateToCredentialUI();
+    void animateToCredentialUI(boolean isError);
 
     /**
      * @return true if device credential is allowed.
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/package-info.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricPromptLottieViewWrapper.kt
similarity index 66%
copy from packages/SettingsLib/tests/robotests/src/com/android/settingslib/package-info.java
copy to packages/SystemUI/src/com/android/systemui/biometrics/BiometricPromptLottieViewWrapper.kt
index 9e9725f..e48e6e2 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/package-info.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricPromptLottieViewWrapper.kt
@@ -13,8 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package com.android.systemui.biometrics
 
-@LooperMode(LooperMode.Mode.LEGACY)
-package com.android.settingslib;
+import android.content.Context
+import android.util.AttributeSet
+import com.android.systemui.util.wrapper.LottieViewWrapper
 
-import org.robolectric.annotation.LooperMode;
+class BiometricPromptLottieViewWrapper
+@JvmOverloads
+constructor(context: Context, attrs: AttributeSet? = null) : LottieViewWrapper(context, attrs)
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
index 9d0cde1..37ce444 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
@@ -117,6 +117,8 @@
     private var overlayView: View? = null
         set(value) {
             field?.let { oldView ->
+                val lottie = oldView.findViewById(R.id.sidefps_animation) as LottieAnimationView
+                lottie.pauseAnimation()
                 windowManager.removeView(oldView)
                 orientationListener.disable()
             }
@@ -193,7 +195,9 @@
             requests.add(request)
             mainExecutor.execute {
                 if (overlayView == null) {
-                    traceSection("SideFpsController#show(request=${request.name}, reason=$reason") {
+                    traceSection(
+                        "SideFpsController#show(request=${request.name}, reason=$reason)"
+                    ) {
                         createOverlayForDisplay(reason)
                     }
                 } else {
@@ -208,7 +212,7 @@
         requests.remove(request)
         mainExecutor.execute {
             if (requests.isEmpty()) {
-                traceSection("SideFpsController#hide(${request.name}") { overlayView = null }
+                traceSection("SideFpsController#hide(${request.name})") { overlayView = null }
             }
         }
     }
diff --git a/packages/SettingsLib/tests/robotests/fragment/src/main/java/org/robolectric/shadows/androidx/fragment/package-info.java b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsLottieViewWrapper.kt
similarity index 66%
rename from packages/SettingsLib/tests/robotests/fragment/src/main/java/org/robolectric/shadows/androidx/fragment/package-info.java
rename to packages/SystemUI/src/com/android/systemui/biometrics/SideFpsLottieViewWrapper.kt
index dd89441..e98f6db 100644
--- a/packages/SettingsLib/tests/robotests/fragment/src/main/java/org/robolectric/shadows/androidx/fragment/package-info.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsLottieViewWrapper.kt
@@ -13,11 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package com.android.systemui.biometrics
 
-/**
- * Testing infrastructure for androidx.fragment library.
- *
- * <p>To use this in your project, add the artifact {@code
- * org.robolectric:shadows-androidx-fragment} to your project.
- */
-package org.robolectric.shadows.androidx.fragment;
+import android.content.Context
+import android.util.AttributeSet
+import com.android.systemui.util.wrapper.LottieViewWrapper
+
+class SideFpsLottieViewWrapper
+@JvmOverloads
+constructor(context: Context, attrs: AttributeSet? = null) : LottieViewWrapper(context, attrs)
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractor.kt
index d92c217..ac4b717 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractor.kt
@@ -23,7 +23,7 @@
 import com.android.systemui.biometrics.data.repository.PromptRepository
 import com.android.systemui.biometrics.domain.model.BiometricOperationInfo
 import com.android.systemui.biometrics.domain.model.BiometricPromptRequest
-import com.android.systemui.biometrics.domain.model.BiometricUserInfo
+import com.android.systemui.biometrics.shared.model.BiometricUserInfo
 import com.android.systemui.biometrics.shared.model.PromptKind
 import com.android.systemui.dagger.qualifiers.Background
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt
index be99dd9..bb87dca 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt
@@ -25,7 +25,7 @@
 import com.android.systemui.biometrics.domain.model.BiometricModalities
 import com.android.systemui.biometrics.domain.model.BiometricOperationInfo
 import com.android.systemui.biometrics.domain.model.BiometricPromptRequest
-import com.android.systemui.biometrics.domain.model.BiometricUserInfo
+import com.android.systemui.biometrics.shared.model.BiometricUserInfo
 import com.android.systemui.biometrics.shared.model.PromptKind
 import com.android.systemui.dagger.SysUISingleton
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequest.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequest.kt
index 75de47d..caebc30 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequest.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequest.kt
@@ -1,6 +1,7 @@
 package com.android.systemui.biometrics.domain.model
 
 import android.hardware.biometrics.PromptInfo
+import com.android.systemui.biometrics.shared.model.BiometricUserInfo
 
 /**
  * Preferences for BiometricPrompt, such as title & description, that are immutable while the prompt
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricUserInfo.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricUserInfo.kt
deleted file mode 100644
index 08da04d..0000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricUserInfo.kt
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.android.systemui.biometrics.domain.model
-
-/** Metadata about the current user BiometricPrompt is being shown to. */
-data class BiometricUserInfo(
-    val userId: Int,
-    val deviceCredentialOwnerId: Int = userId,
-)
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricModality.kt b/packages/SystemUI/src/com/android/systemui/biometrics/shared/model/BiometricModality.kt
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricModality.kt
rename to packages/SystemUI/src/com/android/systemui/biometrics/shared/model/BiometricModality.kt
index 3197c09..fb580ca 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricModality.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/shared/model/BiometricModality.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.biometrics.domain.model
+package com.android.systemui.biometrics.shared.model
 
 import android.hardware.biometrics.BiometricAuthenticator
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/shared/model/BiometricUserInfo.kt b/packages/SystemUI/src/com/android/systemui/biometrics/shared/model/BiometricUserInfo.kt
new file mode 100644
index 0000000..39689ec
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/shared/model/BiometricUserInfo.kt
@@ -0,0 +1,12 @@
+package com.android.systemui.biometrics.shared.model
+
+/**
+ * Metadata about the current user BiometricPrompt is being shown to.
+ *
+ * If the user's fallback credential is owned by another profile user the [deviceCredentialOwnerId]
+ * will differ from the user's [userId].
+ */
+data class BiometricUserInfo(
+    val userId: Int,
+    val deviceCredentialOwnerId: Int = userId,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
index 6a7431e..e5a4d1a 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
@@ -46,9 +46,9 @@
 import com.android.systemui.biometrics.AuthPanelController
 import com.android.systemui.biometrics.Utils
 import com.android.systemui.biometrics.domain.model.BiometricModalities
-import com.android.systemui.biometrics.domain.model.BiometricModality
-import com.android.systemui.biometrics.domain.model.asBiometricModality
+import com.android.systemui.biometrics.shared.model.BiometricModality
 import com.android.systemui.biometrics.shared.model.PromptKind
+import com.android.systemui.biometrics.shared.model.asBiometricModality
 import com.android.systemui.biometrics.ui.BiometricPromptLayout
 import com.android.systemui.biometrics.ui.viewmodel.FingerprintStartMode
 import com.android.systemui.biometrics.ui.viewmodel.PromptMessage
@@ -396,7 +396,6 @@
 
     private var lifecycleScope: CoroutineScope? = null
     private var modalities: BiometricModalities = BiometricModalities()
-    private var faceFailedAtLeastOnce = false
     private var legacyCallback: Callback? = null
 
     override var legacyIconController: AuthIconController? = null
@@ -476,19 +475,15 @@
         viewModel.ensureFingerprintHasStarted(isDelayed = true)
 
         applicationScope.launch {
-            val suppress =
-                modalities.hasFaceAndFingerprint &&
-                    (failedModality == BiometricModality.Face) &&
-                    faceFailedAtLeastOnce
-            if (failedModality == BiometricModality.Face) {
-                faceFailedAtLeastOnce = true
-            }
-
             viewModel.showTemporaryError(
                 failureReason,
                 messageAfterError = modalities.asDefaultHelpMessage(applicationContext),
                 authenticateAfterError = modalities.hasFingerprint,
-                suppressIfErrorShowing = suppress,
+                suppressIf = { currentMessage ->
+                    modalities.hasFaceAndFingerprint &&
+                        failedModality == BiometricModality.Face &&
+                        currentMessage.isError
+                },
                 failedModality = failedModality,
             )
         }
@@ -501,11 +496,10 @@
         }
 
         applicationScope.launch {
-            val suppress =
-                modalities.hasFaceAndFingerprint && (errorModality == BiometricModality.Face)
             viewModel.showTemporaryError(
                 error,
-                suppressIfErrorShowing = suppress,
+                messageAfterError = modalities.asDefaultHelpMessage(applicationContext),
+                authenticateAfterError = modalities.hasFingerprint,
             )
             delay(BiometricPrompt.HIDE_DIALOG_DELAY.toLong())
             legacyCallback?.onAction(Callback.ACTION_ERROR)
@@ -522,6 +516,8 @@
             viewModel.showTemporaryError(
                 help,
                 messageAfterError = modalities.asDefaultHelpMessage(applicationContext),
+                authenticateAfterError = modalities.hasFingerprint,
+                hapticFeedback = false,
             )
         }
     }
@@ -534,7 +530,7 @@
             else -> false
         }
 
-    override fun startTransitionToCredentialUI() {
+    override fun startTransitionToCredentialUI(isError: Boolean) {
         applicationScope.launch {
             viewModel.onSwitchToCredential()
             legacyCallback?.onAction(Callback.ACTION_USE_DEVICE_CREDENTIAL)
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPasswordViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPasswordViewBinder.kt
index 6fb8e34..c27d7152 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPasswordViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPasswordViewBinder.kt
@@ -1,5 +1,6 @@
 package com.android.systemui.biometrics.ui.binder
 
+import android.os.UserHandle
 import android.view.KeyEvent
 import android.view.View
 import android.view.inputmethod.EditorInfo
@@ -9,6 +10,7 @@
 import android.window.OnBackInvokedCallback
 import android.window.OnBackInvokedDispatcher
 import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.lifecycleScope
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.systemui.R
 import com.android.systemui.biometrics.ui.CredentialPasswordView
@@ -16,6 +18,8 @@
 import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel
 import com.android.systemui.lifecycle.repeatWhenAttached
 import kotlinx.coroutines.awaitCancellation
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.firstOrNull
 import kotlinx.coroutines.launch
 
 /** Sub-binder for the [CredentialPasswordView]. */
@@ -35,31 +39,22 @@
         val onBackInvokedCallback = OnBackInvokedCallback { host.onCredentialAborted() }
 
         view.repeatWhenAttached {
+            // the header info never changes - do it early
+            val header = viewModel.header.first()
+            passwordField.setTextOperationUser(UserHandle.of(header.user.deviceCredentialOwnerId))
+            viewModel.inputFlags.firstOrNull()?.let { flags -> passwordField.inputType = flags }
             if (requestFocusForInput) {
                 passwordField.requestFocus()
                 passwordField.scheduleShowSoftInput()
             }
+            passwordField.setOnEditorActionListener(
+                OnImeSubmitListener { text ->
+                    lifecycleScope.launch { viewModel.checkCredential(text, header) }
+                }
+            )
+            passwordField.setOnKeyListener(OnBackButtonListener(onBackInvokedCallback))
 
             repeatOnLifecycle(Lifecycle.State.STARTED) {
-                // observe credential validation attempts and submit/cancel buttons
-                launch {
-                    viewModel.header.collect { header ->
-                        passwordField.setTextOperationUser(header.user)
-                        passwordField.setOnEditorActionListener(
-                            OnImeSubmitListener { text ->
-                                launch { viewModel.checkCredential(text, header) }
-                            }
-                        )
-                        passwordField.setOnKeyListener(OnBackButtonListener(onBackInvokedCallback))
-                    }
-                }
-
-                launch {
-                    viewModel.inputFlags.collect { flags ->
-                        flags?.let { passwordField.inputType = it }
-                    }
-                }
-
                 // dismiss on a valid credential check
                 launch {
                     viewModel.validatedAttestation.collect { attestation ->
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialHeaderViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialHeaderViewModel.kt
index a64798c..3257f20 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialHeaderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialHeaderViewModel.kt
@@ -1,11 +1,11 @@
 package com.android.systemui.biometrics.ui.viewmodel
 
 import android.graphics.drawable.Drawable
-import android.os.UserHandle
+import com.android.systemui.biometrics.shared.model.BiometricUserInfo
 
 /** View model for the top-level header / info area of BiometricPrompt. */
 interface CredentialHeaderViewModel {
-    val user: UserHandle
+    val user: BiometricUserInfo
     val title: String
     val subtitle: String
     val description: String
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt
index 9d7b940..a3b23ca 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt
@@ -2,7 +2,6 @@
 
 import android.content.Context
 import android.graphics.drawable.Drawable
-import android.os.UserHandle
 import android.text.InputType
 import com.android.internal.widget.LockPatternView
 import com.android.systemui.R
@@ -10,6 +9,7 @@
 import com.android.systemui.biometrics.domain.interactor.CredentialStatus
 import com.android.systemui.biometrics.domain.interactor.PromptCredentialInteractor
 import com.android.systemui.biometrics.domain.model.BiometricPromptRequest
+import com.android.systemui.biometrics.shared.model.BiometricUserInfo
 import com.android.systemui.dagger.qualifiers.Application
 import javax.inject.Inject
 import kotlin.reflect.KClass
@@ -36,7 +36,7 @@
             request ->
             BiometricPromptHeaderViewModelImpl(
                 request,
-                user = UserHandle.of(request.userInfo.userId),
+                user = request.userInfo,
                 title = request.title,
                 subtitle = request.subtitle,
                 description = request.description,
@@ -169,7 +169,7 @@
 
 private class BiometricPromptHeaderViewModelImpl(
     val request: BiometricPromptRequest.Credential,
-    override val user: UserHandle,
+    override val user: BiometricUserInfo,
     override val title: String,
     override val subtitle: String,
     override val description: String,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptAuthState.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptAuthState.kt
index 444082c..2f9557f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptAuthState.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptAuthState.kt
@@ -16,7 +16,7 @@
 
 package com.android.systemui.biometrics.ui.viewmodel
 
-import com.android.systemui.biometrics.domain.model.BiometricModality
+import com.android.systemui.biometrics.shared.model.BiometricModality
 
 /**
  * The authenticated state with the [authenticatedModality] (when [isAuthenticated]) with an
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptMessage.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptMessage.kt
index 219da71..50f4911 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptMessage.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptMessage.kt
@@ -33,9 +33,9 @@
                 else -> ""
             }
 
-    /** If this is an [Error] or [Help] message. */
-    val isErrorOrHelp: Boolean
-        get() = this is Error || this is Help
+    /** If this is an [Error]. */
+    val isError: Boolean
+        get() = this is Error
 
     /** An error message. */
     data class Error(val errorMessage: String) : PromptMessage
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
index 05a5362..8a2e405 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
@@ -20,8 +20,9 @@
 import com.android.systemui.biometrics.AuthBiometricView
 import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor
 import com.android.systemui.biometrics.domain.model.BiometricModalities
-import com.android.systemui.biometrics.domain.model.BiometricModality
+import com.android.systemui.biometrics.shared.model.BiometricModality
 import com.android.systemui.biometrics.shared.model.PromptKind
+import com.android.systemui.statusbar.VibratorHelper
 import javax.inject.Inject
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.coroutineScope
@@ -41,6 +42,7 @@
 @Inject
 constructor(
     private val interactor: PromptSelectorInteractor,
+    private val vibrator: VibratorHelper,
 ) {
     /** The set of modalities available for this prompt */
     val modalities: Flow<BiometricModalities> =
@@ -205,37 +207,43 @@
     private var messageJob: Job? = null
 
     /**
-     * Show a temporary error [message] associated with an optional [failedModality].
+     * Show a temporary error [message] associated with an optional [failedModality] and play
+     * [hapticFeedback].
      *
-     * An optional [messageAfterError] will be shown via [showAuthenticating] when
-     * [authenticateAfterError] is set (or via [showHelp] when not set) after the error is
-     * dismissed.
+     * The [messageAfterError] will be shown via [showAuthenticating] when [authenticateAfterError]
+     * is set (or via [showHelp] when not set) after the error is dismissed.
      *
-     * The error is ignored if the user has already authenticated and it is treated as
-     * [onSilentError] if [suppressIfErrorShowing] is set and an error message is already showing.
+     * The error is ignored if the user has already authenticated or if [suppressIf] is true given
+     * the currently showing [PromptMessage].
      */
     suspend fun showTemporaryError(
         message: String,
-        messageAfterError: String = "",
-        authenticateAfterError: Boolean = false,
-        suppressIfErrorShowing: Boolean = false,
+        messageAfterError: String,
+        authenticateAfterError: Boolean,
+        suppressIf: (PromptMessage) -> Boolean = { false },
+        hapticFeedback: Boolean = true,
         failedModality: BiometricModality = BiometricModality.None,
     ) = coroutineScope {
         if (_isAuthenticated.value.isAuthenticated) {
             return@coroutineScope
         }
-        if (_message.value.isErrorOrHelp && suppressIfErrorShowing) {
-            onSilentError(failedModality)
+
+        _canTryAgainNow.value = supportsRetry(failedModality)
+
+        if (suppressIf(_message.value)) {
             return@coroutineScope
         }
 
         _isAuthenticating.value = false
         _isAuthenticated.value = PromptAuthState(false)
         _forceMediumSize.value = true
-        _canTryAgainNow.value = supportsRetry(failedModality)
         _message.value = PromptMessage.Error(message)
         _legacyState.value = AuthBiometricView.STATE_ERROR
 
+        if (hapticFeedback) {
+            vibrator.error(failedModality)
+        }
+
         messageJob?.cancel()
         messageJob = launch {
             delay(BiometricPrompt.HIDE_DIALOG_DELAY.toLong())
@@ -248,18 +256,6 @@
     }
 
     /**
-     * Call instead of [showTemporaryError] if an error from the HAL should be silently ignored to
-     * enable retry (if the [failedModality] supports retrying).
-     *
-     * Ignored if the user has already authenticated.
-     */
-    private fun onSilentError(failedModality: BiometricModality = BiometricModality.None) {
-        if (_isAuthenticated.value.isNotAuthenticated) {
-            _canTryAgainNow.value = supportsRetry(failedModality)
-        }
-    }
-
-    /**
      * Call to ensure the fingerprint sensor has started. Either when the dialog is first shown
      * (most cases) or when it should be enabled after a first error (coex implicit flow).
      */
@@ -376,6 +372,10 @@
                 AuthBiometricView.STATE_AUTHENTICATED
             }
 
+        if (!needsUserConfirmation) {
+            vibrator.success(modality)
+        }
+
         messageJob?.cancel()
         messageJob = null
 
@@ -386,18 +386,18 @@
 
     private suspend fun needsExplicitConfirmation(modality: BiometricModality): Boolean {
         val availableModalities = modalities.first()
-        val confirmationRequested = interactor.isConfirmationRequired.first()
+        val confirmationRequired = isConfirmationRequired.first()
 
         if (availableModalities.hasFaceAndFingerprint) {
             // coex only needs confirmation when face is successful, unless it happens on the
             // first attempt (i.e. without failure) before fingerprint scanning starts
+            val fingerprintStarted = fingerprintStartMode.first() != FingerprintStartMode.Pending
             if (modality == BiometricModality.Face) {
-                return (fingerprintStartMode.first() != FingerprintStartMode.Pending) ||
-                    confirmationRequested
+                return fingerprintStarted || confirmationRequired
             }
         }
         if (availableModalities.hasFaceOnly) {
-            return confirmationRequested
+            return confirmationRequired
         }
         // fingerprint only never requires confirmation
         return false
@@ -412,7 +412,6 @@
     fun confirmAuthenticated() {
         val authState = _isAuthenticated.value
         if (authState.isNotAuthenticated) {
-            "Cannot show authenticated after authenticated"
             Log.w(TAG, "Cannot confirm authenticated when not authenticated")
             return
         }
@@ -421,6 +420,8 @@
         _message.value = PromptMessage.Empty
         _legacyState.value = AuthBiometricView.STATE_AUTHENTICATED
 
+        vibrator.success(authState.authenticatedModality)
+
         messageJob?.cancel()
         messageJob = null
     }
@@ -434,6 +435,12 @@
         _forceLargeSize.value = true
     }
 
+    private fun VibratorHelper.success(modality: BiometricModality) =
+        vibrateAuthSuccess("$TAG, modality = $modality BP::success")
+
+    private fun VibratorHelper.error(modality: BiometricModality = BiometricModality.None) =
+        vibrateAuthError("$TAG, modality = $modality BP::error")
+
     companion object {
         private const val TAG = "PromptViewModel"
     }
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/BouncerRepository.kt b/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/BouncerRepository.kt
index ff896fa..943216e 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/BouncerRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/BouncerRepository.kt
@@ -16,7 +16,6 @@
 
 package com.android.systemui.bouncer.data.repository
 
-import com.android.systemui.bouncer.shared.model.AuthenticationThrottledModel
 import com.android.systemui.dagger.SysUISingleton
 import javax.inject.Inject
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -30,15 +29,7 @@
     /** The user-facing message to show in the bouncer. */
     val message: StateFlow<String?> = _message.asStateFlow()
 
-    private val _throttling = MutableStateFlow<AuthenticationThrottledModel?>(null)
-    /** The current authentication throttling state. If `null`, there's no throttling. */
-    val throttling: StateFlow<AuthenticationThrottledModel?> = _throttling.asStateFlow()
-
     fun setMessage(message: String?) {
         _message.value = message
     }
-
-    fun setThrottling(throttling: AuthenticationThrottledModel?) {
-        _throttling.value = throttling
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
index 5dd24b2..62a484d 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
@@ -14,30 +14,32 @@
  * limitations under the License.
  */
 
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
 package com.android.systemui.bouncer.domain.interactor
 
 import android.content.Context
-import androidx.annotation.VisibleForTesting
 import com.android.systemui.R
 import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.authentication.shared.model.AuthenticationThrottlingModel
 import com.android.systemui.bouncer.data.repository.BouncerRepository
-import com.android.systemui.bouncer.shared.model.AuthenticationThrottledModel
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
 import com.android.systemui.scene.domain.interactor.SceneInteractor
 import com.android.systemui.scene.shared.model.SceneKey
 import com.android.systemui.scene.shared.model.SceneModel
+import com.android.systemui.util.kotlin.pairwise
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
+import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.delay
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.launch
 
@@ -50,6 +52,7 @@
     private val repository: BouncerRepository,
     private val authenticationInteractor: AuthenticationInteractor,
     private val sceneInteractor: SceneInteractor,
+    featureFlags: FeatureFlags,
     @Assisted private val containerName: String,
 ) {
 
@@ -57,9 +60,10 @@
     val message: StateFlow<String?> =
         combine(
                 repository.message,
-                repository.throttling,
-            ) { message, throttling ->
-                messageOrThrottlingMessage(message, throttling)
+                authenticationInteractor.isThrottled,
+                authenticationInteractor.throttling,
+            ) { message, isThrottled, throttling ->
+                messageOrThrottlingMessage(message, isThrottled, throttling)
             }
             .stateIn(
                 scope = applicationScope,
@@ -67,36 +71,39 @@
                 initialValue =
                     messageOrThrottlingMessage(
                         repository.message.value,
-                        repository.throttling.value,
+                        authenticationInteractor.isThrottled.value,
+                        authenticationInteractor.throttling.value,
                     )
             )
 
-    /** The current authentication throttling state. If `null`, there's no throttling. */
-    val throttling: StateFlow<AuthenticationThrottledModel?> = repository.throttling
+    /** The current authentication throttling state, only meaningful if [isThrottled] is `true`. */
+    val throttling: StateFlow<AuthenticationThrottlingModel> = authenticationInteractor.throttling
+
+    /**
+     * Whether currently throttled and the user has to wait before being able to try another
+     * authentication attempt.
+     */
+    val isThrottled: StateFlow<Boolean> = authenticationInteractor.isThrottled
+
+    /** Whether the auto confirm feature is enabled for the currently-selected user. */
+    val isAutoConfirmEnabled: StateFlow<Boolean> = authenticationInteractor.isAutoConfirmEnabled
+
+    /** The length of the PIN for which we should show a hint. */
+    val hintedPinLength: StateFlow<Int?> = authenticationInteractor.hintedPinLength
+
+    /** Whether the pattern should be visible for the currently-selected user. */
+    val isPatternVisible: StateFlow<Boolean> = authenticationInteractor.isPatternVisible
 
     init {
-        // UNLOCKING SHOWS Gone.
-        //
-        // Move to the gone scene if the device becomes unlocked while on the bouncer scene.
-        applicationScope.launch {
-            sceneInteractor
-                .currentScene(containerName)
-                .flatMapLatest { currentScene ->
-                    if (currentScene.key == SceneKey.Bouncer) {
-                        authenticationInteractor.isUnlocked
-                    } else {
-                        flowOf(false)
+        if (featureFlags.isEnabled(Flags.SCENE_CONTAINER)) {
+            // Clear the message if moved from throttling to no-longer throttling.
+            applicationScope.launch {
+                isThrottled.pairwise().collect { (wasThrottled, currentlyThrottled) ->
+                    if (wasThrottled && !currentlyThrottled) {
+                        clearMessage()
                     }
                 }
-                .distinctUntilChanged()
-                .collect { isUnlocked ->
-                    if (isUnlocked) {
-                        sceneInteractor.setCurrentScene(
-                            containerName = containerName,
-                            scene = SceneModel(SceneKey.Gone),
-                        )
-                    }
-                }
+            }
         }
     }
 
@@ -168,41 +175,16 @@
         input: List<Any>,
         tryAutoConfirm: Boolean = false,
     ): Boolean? {
-        if (repository.throttling.value != null) {
-            return false
-        }
-
         val isAuthenticated =
             authenticationInteractor.authenticate(input, tryAutoConfirm) ?: return null
 
-        val failedAttempts = authenticationInteractor.failedAuthenticationAttempts.value
-        when {
-            isAuthenticated -> {
-                repository.setThrottling(null)
-                sceneInteractor.setCurrentScene(
-                    containerName = containerName,
-                    scene = SceneModel(SceneKey.Gone),
-                )
-            }
-            failedAttempts >= THROTTLE_AGGRESSIVELY_AFTER || failedAttempts % THROTTLE_EVERY == 0 ->
-                applicationScope.launch {
-                    var remainingDurationSec = THROTTLE_DURATION_SEC
-                    while (remainingDurationSec > 0) {
-                        repository.setThrottling(
-                            AuthenticationThrottledModel(
-                                failedAttemptCount = failedAttempts,
-                                totalDurationSec = THROTTLE_DURATION_SEC,
-                                remainingDurationSec = remainingDurationSec,
-                            )
-                        )
-                        remainingDurationSec--
-                        delay(1000)
-                    }
-
-                    repository.setThrottling(null)
-                    clearMessage()
-                }
-            else -> repository.setMessage(errorMessage(getAuthenticationMethod()))
+        if (isAuthenticated) {
+            sceneInteractor.setCurrentScene(
+                containerName = containerName,
+                scene = SceneModel(SceneKey.Gone),
+            )
+        } else {
+            repository.setMessage(errorMessage(getAuthenticationMethod()))
         }
 
         return isAuthenticated
@@ -233,13 +215,14 @@
 
     private fun messageOrThrottlingMessage(
         message: String?,
-        throttling: AuthenticationThrottledModel?,
+        isThrottled: Boolean,
+        throttlingModel: AuthenticationThrottlingModel,
     ): String {
         return when {
-            throttling != null ->
+            isThrottled ->
                 applicationContext.getString(
                     com.android.internal.R.string.lockscreen_too_many_failed_attempts_countdown,
-                    throttling.remainingDurationSec,
+                    throttlingModel.remainingMs.milliseconds.inWholeSeconds,
                 )
             message != null -> message
             else -> ""
@@ -252,10 +235,4 @@
             containerName: String,
         ): BouncerInteractor
     }
-
-    companion object {
-        @VisibleForTesting const val THROTTLE_DURATION_SEC = 30
-        @VisibleForTesting const val THROTTLE_AGGRESSIVELY_AFTER = 15
-        @VisibleForTesting const val THROTTLE_EVERY = 5
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/shared/model/AuthenticationThrottledModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/shared/model/AuthenticationThrottledModel.kt
deleted file mode 100644
index cbea635..0000000
--- a/packages/SystemUI/src/com/android/systemui/bouncer/shared/model/AuthenticationThrottledModel.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.bouncer.shared.model
-
-/**
- * Models application state for when further authentication attempts are being throttled due to too
- * many consecutive failed authentication attempts.
- */
-data class AuthenticationThrottledModel(
-    /** Total number of failed attempts so far. */
-    val failedAttemptCount: Int,
-    /** Total amount of time the user has to wait before attempting again. */
-    val totalDurationSec: Int,
-    /** Remaining amount of time the user has to wait before attempting again. */
-    val remainingDurationSec: Int,
-)
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt
index db6ca0b..a4ef5ce 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt
@@ -14,19 +14,24 @@
  * limitations under the License.
  */
 
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
 package com.android.systemui.bouncer.ui.viewmodel
 
 import android.content.Context
 import com.android.systemui.R
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
 import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
-import com.android.systemui.bouncer.shared.model.AuthenticationThrottledModel
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
 import com.android.systemui.util.kotlin.pairwise
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
+import kotlin.math.ceil
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.channels.BufferOverflow
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -46,17 +51,18 @@
     @Application private val applicationContext: Context,
     @Application private val applicationScope: CoroutineScope,
     interactorFactory: BouncerInteractor.Factory,
+    featureFlags: FeatureFlags,
     @Assisted containerName: String,
 ) {
     private val interactor: BouncerInteractor = interactorFactory.create(containerName)
 
     private val isInputEnabled: StateFlow<Boolean> =
-        interactor.throttling
-            .map { it == null }
+        interactor.isThrottled
+            .map { !it }
             .stateIn(
                 scope = applicationScope,
                 started = SharingStarted.WhileSubscribed(),
-                initialValue = interactor.throttling.value == null,
+                initialValue = !interactor.isThrottled.value,
             )
 
     private val pin: PinBouncerViewModel by lazy {
@@ -99,15 +105,48 @@
         )
 
     init {
-        applicationScope.launch {
-            _authMethod.subscriptionCount
-                .pairwise()
-                .map { (previousCount, currentCount) -> currentCount > previousCount }
-                .collect { subscriberAdded ->
-                    if (subscriberAdded) {
-                        reloadAuthMethod()
+        if (featureFlags.isEnabled(Flags.SCENE_CONTAINER)) {
+            applicationScope.launch {
+                interactor.isThrottled
+                    .map { isThrottled ->
+                        if (isThrottled) {
+                            when (interactor.getAuthenticationMethod()) {
+                                is AuthenticationMethodModel.Pin ->
+                                    R.string.kg_too_many_failed_pin_attempts_dialog_message
+                                is AuthenticationMethodModel.Password ->
+                                    R.string.kg_too_many_failed_password_attempts_dialog_message
+                                is AuthenticationMethodModel.Pattern ->
+                                    R.string.kg_too_many_failed_pattern_attempts_dialog_message
+                                else -> null
+                            }?.let { stringResourceId ->
+                                applicationContext.getString(
+                                    stringResourceId,
+                                    interactor.throttling.value.failedAttemptCount,
+                                    ceil(interactor.throttling.value.remainingMs / 1000f).toInt(),
+                                )
+                            }
+                        } else {
+                            null
+                        }
                     }
-                }
+                    .distinctUntilChanged()
+                    .collect { dialogMessageOrNull ->
+                        if (dialogMessageOrNull != null) {
+                            _throttlingDialogMessage.value = dialogMessageOrNull
+                        }
+                    }
+            }
+
+            applicationScope.launch {
+                _authMethod.subscriptionCount
+                    .pairwise()
+                    .map { (previousCount, currentCount) -> currentCount > previousCount }
+                    .collect { subscriberAdded ->
+                        if (subscriberAdded) {
+                            reloadAuthMethod()
+                        }
+                    }
+            }
         }
     }
 
@@ -115,9 +154,9 @@
     val message: StateFlow<MessageViewModel> =
         combine(
                 interactor.message,
-                interactor.throttling,
-            ) { message, throttling ->
-                toMessageViewModel(message, throttling)
+                interactor.isThrottled,
+            ) { message, isThrottled ->
+                toMessageViewModel(message, isThrottled)
             }
             .stateIn(
                 scope = applicationScope,
@@ -125,7 +164,7 @@
                 initialValue =
                     toMessageViewModel(
                         message = interactor.message.value,
-                        throttling = interactor.throttling.value,
+                        isThrottled = interactor.isThrottled.value,
                     ),
             )
 
@@ -141,37 +180,6 @@
      */
     val throttlingDialogMessage: StateFlow<String?> = _throttlingDialogMessage.asStateFlow()
 
-    init {
-        applicationScope.launch {
-            interactor.throttling
-                .map { model ->
-                    model?.let {
-                        when (interactor.getAuthenticationMethod()) {
-                            is AuthenticationMethodModel.Pin ->
-                                R.string.kg_too_many_failed_pin_attempts_dialog_message
-                            is AuthenticationMethodModel.Password ->
-                                R.string.kg_too_many_failed_password_attempts_dialog_message
-                            is AuthenticationMethodModel.Pattern ->
-                                R.string.kg_too_many_failed_pattern_attempts_dialog_message
-                            else -> null
-                        }?.let { stringResourceId ->
-                            applicationContext.getString(
-                                stringResourceId,
-                                model.failedAttemptCount,
-                                model.totalDurationSec,
-                            )
-                        }
-                    }
-                }
-                .distinctUntilChanged()
-                .collect { dialogMessageOrNull ->
-                    if (dialogMessageOrNull != null) {
-                        _throttlingDialogMessage.value = dialogMessageOrNull
-                    }
-                }
-        }
-    }
-
     /** Notifies that the emergency services button was clicked. */
     fun onEmergencyServicesButtonClicked() {
         // TODO(b/280877228): implement this
@@ -184,11 +192,11 @@
 
     private fun toMessageViewModel(
         message: String?,
-        throttling: AuthenticationThrottledModel?,
+        isThrottled: Boolean,
     ): MessageViewModel {
         return MessageViewModel(
             text = message ?: "",
-            isUpdateAnimated = throttling == null,
+            isUpdateAnimated = !isThrottled,
         )
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt
index 5efa6f0..4be539d 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt
@@ -29,7 +29,6 @@
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.asStateFlow
-import kotlinx.coroutines.flow.flow
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.launch
@@ -70,19 +69,7 @@
     val dots: StateFlow<List<PatternDotViewModel>> = _dots.asStateFlow()
 
     /** Whether the pattern itself should be rendered visibly. */
-    val isPatternVisible: StateFlow<Boolean> =
-        flow {
-                emit(null)
-                emit(interactor.getAuthenticationMethod())
-            }
-            .map { authMethod ->
-                (authMethod as? AuthenticationMethodModel.Pattern)?.isPatternVisible ?: false
-            }
-            .stateIn(
-                scope = applicationScope,
-                started = SharingStarted.Eagerly,
-                initialValue = false,
-            )
+    val isPatternVisible: StateFlow<Boolean> = interactor.isPatternVisible
 
     /** Notifies that the UI has been shown to the user. */
     fun onShown() {
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt
index 641e863..1b14acc 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt
@@ -18,13 +18,12 @@
 
 import android.content.Context
 import com.android.keyguard.PinShapeAdapter
-import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
 import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.launch
@@ -45,26 +44,18 @@
     private val mutablePinEntries = MutableStateFlow<List<EnteredKey>>(emptyList())
     val pinEntries: StateFlow<List<EnteredKey>> = mutablePinEntries
 
-    /** The length of the hinted PIN, or `null` if pin length hint should not be shown. */
-    val hintedPinLength: StateFlow<Int?> =
-        flow { emit(interactor.getAuthenticationMethod()) }
-            .map { authMethod ->
-                // Hinting is enabled for 6-digit codes only
-                autoConfirmPinLength(authMethod).takeIf { it == HINTING_PASSCODE_LENGTH }
-            }
-            .stateIn(
-                scope = applicationScope,
-                started = SharingStarted.Eagerly,
-                initialValue = null,
-            )
+    /** The length of the PIN for which we should show a hint. */
+    val hintedPinLength: StateFlow<Int?> = interactor.hintedPinLength
 
     /** Appearance of the backspace button. */
     val backspaceButtonAppearance: StateFlow<ActionButtonAppearance> =
-        mutablePinEntries
-            .map { mutablePinEntries ->
+        combine(
+                mutablePinEntries,
+                interactor.isAutoConfirmEnabled,
+            ) { mutablePinEntries, isAutoConfirmEnabled ->
                 computeBackspaceButtonAppearance(
-                    interactor.getAuthenticationMethod(),
-                    mutablePinEntries
+                    enteredPin = mutablePinEntries,
+                    isAutoConfirmEnabled = isAutoConfirmEnabled,
                 )
             }
             .stateIn(
@@ -75,11 +66,14 @@
 
     /** Appearance of the confirm button. */
     val confirmButtonAppearance: StateFlow<ActionButtonAppearance> =
-        flow {
-                emit(null)
-                emit(interactor.getAuthenticationMethod())
+        interactor.isAutoConfirmEnabled
+            .map {
+                if (it) {
+                    ActionButtonAppearance.Hidden
+                } else {
+                    ActionButtonAppearance.Shown
+                }
             }
-            .map { authMethod -> computeConfirmButtonAppearance(authMethod) }
             .stateIn(
                 scope = applicationScope,
                 started = SharingStarted.Eagerly,
@@ -134,21 +128,10 @@
         }
     }
 
-    private fun isAutoConfirmEnabled(authMethodModel: AuthenticationMethodModel?): Boolean {
-        return (authMethodModel as? AuthenticationMethodModel.Pin)?.autoConfirm == true
-    }
-
-    private fun autoConfirmPinLength(authMethodModel: AuthenticationMethodModel?): Int? {
-        if (!isAutoConfirmEnabled(authMethodModel)) return null
-
-        return (authMethodModel as? AuthenticationMethodModel.Pin)?.code?.size
-    }
-
     private fun computeBackspaceButtonAppearance(
-        authMethodModel: AuthenticationMethodModel,
-        enteredPin: List<EnteredKey>
+        enteredPin: List<EnteredKey>,
+        isAutoConfirmEnabled: Boolean,
     ): ActionButtonAppearance {
-        val isAutoConfirmEnabled = isAutoConfirmEnabled(authMethodModel)
         val isEmpty = enteredPin.isEmpty()
 
         return when {
@@ -157,15 +140,6 @@
             else -> ActionButtonAppearance.Shown
         }
     }
-    private fun computeConfirmButtonAppearance(
-        authMethodModel: AuthenticationMethodModel?
-    ): ActionButtonAppearance {
-        return if (isAutoConfirmEnabled(authMethodModel)) {
-            ActionButtonAppearance.Hidden
-        } else {
-            ActionButtonAppearance.Shown
-        }
-    }
 }
 
 /** Appearance of pin-pad action buttons. */
@@ -178,9 +152,6 @@
     Shown,
 }
 
-/** Auto-confirm passcodes of exactly 6 digits show a length hint, see http://shortn/_IXlmSNbDh6 */
-private const val HINTING_PASSCODE_LENGTH = 6
-
 private var nextSequenceNumber = 1
 
 /**
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 277b427..f362831 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
@@ -171,6 +171,22 @@
     }
 
     /**
+     * Only for testing. Get previous set mOnSeekBarChangeListener to the seekbar.
+     */
+    @VisibleForTesting
+    public OnSeekBarWithIconButtonsChangeListener getOnSeekBarWithIconButtonsChangeListener() {
+        return mSeekBarListener.mOnSeekBarChangeListener;
+    }
+
+    /**
+     * Only for testing. Get {@link #mSeekbar} in the layout.
+     */
+    @VisibleForTesting
+    public SeekBar getSeekbar() {
+        return mSeekbar;
+    }
+
+    /**
      * Start and End icons might need to be updated when there is a change in seekbar progress.
      * Icon Start will need to be enabled when the seekbar progress is larger than 0.
      * Icon End will need to be enabled when the seekbar progress is less than Max.
diff --git a/packages/SystemUI/src/com/android/systemui/controls/settings/ControlsSettingsDialogManager.kt b/packages/SystemUI/src/com/android/systemui/controls/settings/ControlsSettingsDialogManager.kt
index ce0f2e9..501bcf0 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/settings/ControlsSettingsDialogManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/settings/ControlsSettingsDialogManager.kt
@@ -135,7 +135,7 @@
         val listener = DialogListener(prefs, attempts, onAttemptCompleted)
         val d =
             dialogProvider(activityContext, R.style.Theme_SystemUI_Dialog).apply {
-                setIcon(R.drawable.ic_warning)
+                setIcon(R.drawable.ic_lock_locked)
                 setOnCancelListener(listener)
                 setNeutralButton(R.string.controls_settings_dialog_neutral_button, listener)
                 setPositiveButton(R.string.controls_settings_dialog_positive_button, listener)
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 d73c85b..776b336e 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
@@ -279,7 +279,7 @@
 
         controlsListingController.get().removeCallback(listingCallback)
         controlsController.get().unsubscribe()
-        taskViewController?.dismiss()
+        taskViewController?.removeTask()
         taskViewController = null
 
         val fadeAnim = ObjectAnimator.ofFloat(parent, "alpha", 1.0f, 0.0f)
@@ -777,7 +777,7 @@
 
             closeDialogs(true)
             controlsController.get().unsubscribe()
-            taskViewController?.dismiss()
+            taskViewController?.removeTask()
             taskViewController = null
 
             controlsById.clear()
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 025d7e4..db009dc 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt
@@ -18,7 +18,6 @@
 package com.android.systemui.controls.ui
 
 import android.app.ActivityOptions
-import android.app.ActivityTaskManager
 import android.app.ActivityTaskManager.INVALID_TASK_ID
 import android.app.PendingIntent
 import android.content.ComponentName
@@ -28,6 +27,7 @@
 import android.graphics.drawable.ShapeDrawable
 import android.graphics.drawable.shapes.RoundRectShape
 import android.os.Trace
+import com.android.internal.annotations.VisibleForTesting
 import com.android.systemui.R
 import com.android.systemui.util.boundsOnScreen
 import com.android.wm.shell.taskview.TaskView
@@ -54,12 +54,6 @@
             addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
         }
 
-    private fun removeDetailTask() {
-        if (detailTaskId == INVALID_TASK_ID) return
-        ActivityTaskManager.getInstance().removeTask(detailTaskId)
-        detailTaskId = INVALID_TASK_ID
-    }
-
     private val stateCallback =
         object : TaskView.Listener {
             override fun onInitialized() {
@@ -95,7 +89,7 @@
 
             override fun onTaskRemovalStarted(taskId: Int) {
                 detailTaskId = INVALID_TASK_ID
-                dismiss()
+                release()
             }
 
             override fun onTaskCreated(taskId: Int, name: ComponentName?) {
@@ -103,12 +97,7 @@
                 taskView.alpha = 1f
             }
 
-            override fun onReleased() {
-                removeDetailTask()
-            }
-
             override fun onBackPressedOnTaskRoot(taskId: Int) {
-                dismiss()
                 hide()
             }
         }
@@ -117,10 +106,17 @@
         taskView.onLocationChanged()
     }
 
-    fun dismiss() {
+    /** Call when the taskView is no longer being used, shouldn't be called before removeTask. */
+    @VisibleForTesting
+    fun release() {
         taskView.release()
     }
 
+    /** Call to explicitly remove the task from window manager. */
+    fun removeTask() {
+        taskView.removeTask()
+    }
+
     fun launchTaskView() {
         taskView.setListener(uiExecutor, stateCallback)
     }
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 6abe951..a5a7995 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -89,7 +89,12 @@
     // TODO(b/277338665): Tracking Bug
     @JvmField
     val NOTIFICATION_SHELF_REFACTOR =
-        unreleasedFlag(271161129, "notification_shelf_refactor")
+        unreleasedFlag(271161129, "notification_shelf_refactor", teamfood = true)
+
+    // TODO(b/290787599): Tracking Bug
+    @JvmField
+    val NOTIFICATION_ICON_CONTAINER_REFACTOR =
+        unreleasedFlag(278765923, "notification_icon_container_refactor")
 
     // TODO(b/288326013): Tracking Bug
     @JvmField
@@ -146,6 +151,14 @@
     val LOCKSCREEN_WITHOUT_SECURE_LOCK_WHEN_DREAMING = releasedFlag(208,
         "lockscreen_without_secure_lock_when_dreaming")
 
+    // TODO(b/286092087): Tracking Bug
+    @JvmField
+    val ENABLE_SYSTEM_UI_DREAM_CONTROLLER = unreleasedFlag(301, "enable_system_ui_dream_controller")
+
+    // TODO(b/288287730): Tracking Bug
+    @JvmField
+    val ENABLE_SYSTEM_UI_DREAM_HOSTING = unreleasedFlag(302, "enable_system_ui_dream_hosting")
+
     /**
      * Whether the clock on a wide lock screen should use the new "stepping" animation for moving
      * the digits when the clock moves.
@@ -161,16 +174,6 @@
     @JvmField val DOZING_MIGRATION_1 = unreleasedFlag(213, "dozing_migration_1")
 
     /**
-     * Whether to enable the code powering customizable lock screen quick affordances.
-     *
-     * This flag enables any new prebuilt quick affordances as well.
-     */
-    // TODO(b/255618149): Tracking Bug
-    @JvmField
-    val CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES =
-        releasedFlag(216, "customizable_lock_screen_quick_affordances")
-
-    /**
      * Migrates control of the LightRevealScrim's reveal effect and amount from legacy code to the
      * new KeyguardTransitionRepository.
      */
@@ -260,6 +263,16 @@
     @JvmField
     val MIGRATE_INDICATION_AREA = unreleasedFlag(236, "migrate_indication_area", teamfood = true)
 
+    /**
+     * Migrate the bottom area to the new keyguard root view.
+     * Because there is no such thing as a "bottom area" after this, this also breaks it up into
+     * many smaller, modular pieces.
+     */
+    // TODO(b/290652751): Tracking bug.
+    @JvmField
+    val MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA =
+        unreleasedFlag(290652751, "migrate_split_keyguard_bottom_area")
+
     /** Whether to listen for fingerprint authentication over keyguard occluding activities. */
     // TODO(b/283260512): Tracking bug.
     @JvmField
@@ -279,6 +292,10 @@
     @JvmField
     val MIGRATE_LOCK_ICON = unreleasedFlag(240, "migrate_lock_icon")
 
+    // TODO(b/288276738): Tracking bug.
+    @JvmField
+    val WIDGET_ON_KEYGUARD = unreleasedFlag(241, "widget_on_keyguard")
+
     // 300 - power menu
     // TODO(b/254512600): Tracking Bug
     @JvmField val POWER_MENU_LITE = releasedFlag(300, "power_menu_lite")
@@ -429,9 +446,6 @@
     // TODO(b/263272731): Tracking Bug
     val MEDIA_TTT_RECEIVER_SUCCESS_RIPPLE = releasedFlag(910, "media_ttt_receiver_success_ripple")
 
-    // TODO(b/263512203): Tracking Bug
-    val MEDIA_EXPLICIT_INDICATOR = releasedFlag(911, "media_explicit_indicator")
-
     // TODO(b/265813373): Tracking Bug
     val MEDIA_TAP_TO_TRANSFER_DISMISS_GESTURE = releasedFlag(912, "media_ttt_dismiss_gesture")
 
@@ -559,6 +573,12 @@
     val WALLPAPER_MULTI_CROP =
         sysPropBooleanFlag(1118, "persist.wm.debug.wallpaper_multi_crop", default = false)
 
+    // TODO(b/290220798): Tracking Bug
+    @Keep
+    @JvmField
+    val ENABLE_PIP2_IMPLEMENTATION =
+        sysPropBooleanFlag(1119, "persist.wm.debug.enable_pip2_implementation", default = false)
+
 
     // 1200 - predictive back
     @Keep
@@ -693,11 +713,11 @@
     // TODO(b/283071711): Tracking bug
     @JvmField
     val TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK =
-            releasedFlag(2401, "trim_resources_with_background_trim_on_lock")
+            unreleasedFlag(2401, "trim_resources_with_background_trim_on_lock")
 
     // TODO:(b/283203305): Tracking bug
     @JvmField
-    val TRIM_FONT_CACHES_AT_UNLOCK = releasedFlag(2402, "trim_font_caches_on_unlock")
+    val TRIM_FONT_CACHES_AT_UNLOCK = unreleasedFlag(2402, "trim_font_caches_on_unlock")
 
     // 2700 - unfold transitions
     // TODO(b/265764985): Tracking Bug
@@ -769,6 +789,11 @@
     val ENABLE_NEW_PRIVACY_DIALOG =
             unreleasedFlag(283740863, "enable_new_privacy_dialog", teamfood = false)
 
+    // TODO(b/289573946): Tracking Bug
+    @JvmField
+    val PRECOMPUTED_TEXT =
+        unreleasedFlag(289573946, "precomputed_text")
+
     // 2900 - CentralSurfaces-related flags
 
     // TODO(b/285174336): Tracking Bug
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
index 0511314..732102e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
@@ -50,6 +50,7 @@
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.systemui.R;
 import com.android.systemui.SystemUIAppComponentFactoryBase;
+import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.NotificationMediaManager;
@@ -151,6 +152,9 @@
     private SystemUIAppComponentFactoryBase.ContextAvailableCallback mContextAvailableCallback;
     @Inject
     WakeLockLogger mWakeLockLogger;
+    @Inject
+    @Background
+    Handler mBgHandler;
 
     /**
      * Receiver responsible for time ticking and updating the date format.
@@ -502,7 +506,7 @@
     }
 
     protected void notifyChange() {
-        mContentResolver.notifyChange(mSliceUri, null /* observer */);
+        mBgHandler.post(() -> mContentResolver.notifyChange(mSliceUri, null /* observer */));
     }
 
     @Override
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 61bacbda..29a2d12 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
@@ -50,7 +50,6 @@
 import com.android.systemui.keyguard.data.repository.KeyguardFaceAuthModule;
 import com.android.systemui.keyguard.data.repository.KeyguardRepositoryModule;
 import com.android.systemui.keyguard.domain.interactor.StartKeyguardTransitionModule;
-import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceModule;
 import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancesMetricsLogger;
 import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancesMetricsLoggerImpl;
 import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel;
@@ -91,7 +90,6 @@
         includes = {
             FalsingModule.class,
             KeyguardDataQuickAffordanceModule.class,
-            KeyguardQuickAffordanceModule.class,
             KeyguardRepositoryModule.class,
             KeyguardFaceAuthModule.class,
             StartKeyguardTransitionModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartable.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartable.kt
index cd0805e..7dbe945 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartable.kt
@@ -24,8 +24,6 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 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.repository.KeyguardQuickAffordanceRepository
 import com.android.systemui.settings.UserFileManager
 import com.android.systemui.settings.UserTracker
@@ -42,7 +40,6 @@
  */
 @SysUISingleton
 class MuteQuickAffordanceCoreStartable @Inject constructor(
-    private val featureFlags: FeatureFlags,
     private val userTracker: UserTracker,
     private val ringerModeTracker: RingerModeTracker,
     private val userFileManager: UserFileManager,
@@ -54,8 +51,6 @@
     private val observer = Observer(this::updateLastNonSilentRingerMode)
 
     override fun start() {
-        if (!featureFlags.isEnabled(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES)) return
-
         // only listen to ringerModeInternal changes when Mute is one of the selected affordances
         keyguardQuickAffordanceRepository
             .selections
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt
index 3d8f6fd..a3d1abe 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt
@@ -31,6 +31,7 @@
 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.dagger.qualifiers.Main
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.flags.FeatureFlags
@@ -126,6 +127,7 @@
     private val keyguardBypassController: KeyguardBypassController? = null,
     @Application private val applicationScope: CoroutineScope,
     @Main private val mainDispatcher: CoroutineDispatcher,
+    @Background private val backgroundDispatcher: CoroutineDispatcher,
     private val sessionTracker: SessionTracker,
     private val uiEventsLogger: UiEventLogger,
     private val faceAuthLogger: FaceAuthenticationLogger,
@@ -228,8 +230,12 @@
         keyguardTransitionInteractor.anyStateToGoneTransition
             .filter { it.transitionState == TransitionState.FINISHED }
             .onEach {
-                faceAuthLogger.watchdogScheduled()
-                faceManager?.scheduleWatchdog()
+                // We deliberately want to run this in background because scheduleWatchdog does
+                // a Binder IPC.
+                withContext(backgroundDispatcher) {
+                    faceAuthLogger.watchdogScheduled()
+                    faceManager?.scheduleWatchdog()
+                }
             }
             .launchIn(applicationScope)
     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
index edc0b45..d119920 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
@@ -87,7 +87,7 @@
     val isKeyguardShowing: Flow<Boolean>
 
     /** Is the keyguard in a unlocked state? */
-    val isKeyguardUnlocked: Flow<Boolean>
+    val isKeyguardUnlocked: StateFlow<Boolean>
 
     /** Is an activity showing over the keyguard? */
     val isKeyguardOccluded: Flow<Boolean>
@@ -121,6 +121,9 @@
     /** Observable for whether the device is dreaming with an overlay, see [DreamOverlayService] */
     val isDreamingWithOverlay: Flow<Boolean>
 
+    /** Observable for device dreaming state and the active dream is hosted in lockscreen */
+    val isActiveDreamLockscreenHosted: StateFlow<Boolean>
+
     /**
      * Observable for the amount of doze we are currently in.
      *
@@ -190,6 +193,8 @@
     fun setLastDozeTapToWakePosition(position: Point)
 
     fun setIsDozing(isDozing: Boolean)
+
+    fun setIsActiveDreamLockscreenHosted(isLockscreenHosted: Boolean)
 }
 
 /** Encapsulates application state for the keyguard. */
@@ -294,7 +299,7 @@
             }
             .distinctUntilChanged()
 
-    override val isKeyguardUnlocked: Flow<Boolean> =
+    override val isKeyguardUnlocked: StateFlow<Boolean> =
         conflatedCallbackFlow {
                 val callback =
                     object : KeyguardStateController.Callback {
@@ -325,7 +330,11 @@
 
                 awaitClose { keyguardStateController.removeCallback(callback) }
             }
-            .distinctUntilChanged()
+            .stateIn(
+                scope = scope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue = keyguardStateController.isUnlocked,
+            )
 
     override val isKeyguardGoingAway: Flow<Boolean> = conflatedCallbackFlow {
         val callback =
@@ -610,6 +619,9 @@
     private val _isQuickSettingsVisible = MutableStateFlow(false)
     override val isQuickSettingsVisible: Flow<Boolean> = _isQuickSettingsVisible.asStateFlow()
 
+    private val _isActiveDreamLockscreenHosted = MutableStateFlow(false)
+    override val isActiveDreamLockscreenHosted = _isActiveDreamLockscreenHosted.asStateFlow()
+
     override fun setAnimateDozingTransitions(animate: Boolean) {
         _animateBottomAreaDozingTransitions.value = animate
     }
@@ -628,6 +640,10 @@
         _isQuickSettingsVisible.value = isVisible
     }
 
+    override fun setIsActiveDreamLockscreenHosted(isLockscreenHosted: Boolean) {
+        _isActiveDreamLockscreenHosted.value = isLockscreenHosted
+    }
+
     private fun statusBarStateIntToObject(value: Int): StatusBarState {
         return when (value) {
             0 -> StatusBarState.SHADE
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
index 228290a..7fae752 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
@@ -81,6 +81,8 @@
     val isDreaming: Flow<Boolean> = repository.isDreaming
     /** Whether the system is dreaming with an overlay active */
     val isDreamingWithOverlay: Flow<Boolean> = repository.isDreamingWithOverlay
+    /** Whether the system is dreaming and the active dream is hosted in lockscreen */
+    val isActiveDreamLockscreenHosted: Flow<Boolean> = repository.isActiveDreamLockscreenHosted
     /** Event for when the camera gesture is detected */
     val onCameraLaunchDetected: Flow<CameraLaunchSourceModel> = conflatedCallbackFlow {
         val callback =
@@ -198,6 +200,10 @@
         }
     }
 
+    fun setIsActiveDreamLockscreenHosted(isLockscreenHosted: Boolean) {
+        repository.setIsActiveDreamLockscreenHosted(isLockscreenHosted)
+    }
+
     /** Sets whether quick settings or quick-quick settings is visible. */
     fun setQuickSettingsVisible(isVisible: Boolean) {
         repository.setQuickSettingsVisible(isVisible)
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 f692a39..324d443 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
@@ -38,7 +38,6 @@
 import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
 import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
 import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel
-import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceRegistry
 import com.android.systemui.keyguard.shared.model.KeyguardPickerFlag
 import com.android.systemui.keyguard.shared.model.KeyguardQuickAffordancePickerRepresentation
 import com.android.systemui.keyguard.shared.model.KeyguardSlotPickerRepresentation
@@ -68,7 +67,6 @@
 @Inject
 constructor(
     private val keyguardInteractor: KeyguardInteractor,
-    private val registry: KeyguardQuickAffordanceRegistry<out KeyguardQuickAffordanceConfig>,
     private val lockPatternUtils: LockPatternUtils,
     private val keyguardStateController: KeyguardStateController,
     private val userTracker: UserTracker,
@@ -83,20 +81,13 @@
     @Background private val backgroundDispatcher: CoroutineDispatcher,
     @Application private val appContext: Context,
 ) {
-    private val isUsingRepository: Boolean
-        get() = featureFlags.isEnabled(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES)
 
     /**
      * Whether the UI should use the long press gesture to activate quick affordances.
      *
      * If `false`, the UI goes back to using single taps.
      */
-    fun useLongPress(): Flow<Boolean> =
-        if (featureFlags.isEnabled(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES)) {
-            dockManager.retrieveIsDocked().map { !it }
-        } else {
-            flowOf(false)
-        }
+    fun useLongPress(): Flow<Boolean> = dockManager.retrieveIsDocked().map { !it }
 
     /** Returns an observable for the quick affordance at the given position. */
     suspend fun quickAffordance(
@@ -147,14 +138,9 @@
         expandable: Expandable?,
         slotId: String,
     ) {
-        @Suppress("UNCHECKED_CAST")
+        val (decodedSlotId, decodedConfigKey) = configKey.decode()
         val config =
-            if (isUsingRepository) {
-                val (slotId, decodedConfigKey) = configKey.decode()
-                repository.get().selections.value[slotId]?.find { it.key == decodedConfigKey }
-            } else {
-                registry.get(configKey)
-            }
+            repository.get().selections.value[decodedSlotId]?.find { it.key == decodedConfigKey }
         if (config == null) {
             Log.e(TAG, "Affordance config with key of \"$configKey\" not found!")
             return
@@ -183,7 +169,6 @@
      * @return `true` if the affordance was selected successfully; `false` otherwise.
      */
     suspend fun select(slotId: String, affordanceId: String): Boolean {
-        check(isUsingRepository)
         if (isFeatureDisabledByDevicePolicy()) {
             return false
         }
@@ -226,7 +211,6 @@
      *   the affordance was not on the slot to begin with).
      */
     suspend fun unselect(slotId: String, affordanceId: String?): Boolean {
-        check(isUsingRepository)
         if (isFeatureDisabledByDevicePolicy()) {
             return false
         }
@@ -286,17 +270,12 @@
 
     private fun quickAffordanceInternal(
         position: KeyguardQuickAffordancePosition
-    ): Flow<KeyguardQuickAffordanceModel> {
-        return if (isUsingRepository) {
-            repository
-                .get()
-                .selections
-                .map { it[position.toSlotId()] ?: emptyList() }
-                .flatMapLatest { configs -> combinedConfigs(position, configs) }
-        } else {
-            combinedConfigs(position, registry.getAll(position))
-        }
-    }
+    ): Flow<KeyguardQuickAffordanceModel> =
+        repository
+            .get()
+            .selections
+            .map { it[position.toSlotId()] ?: emptyList() }
+            .flatMapLatest { configs -> combinedConfigs(position, configs) }
 
     private fun combinedConfigs(
         position: KeyguardQuickAffordancePosition,
@@ -326,12 +305,7 @@
                     states[index] as KeyguardQuickAffordanceConfig.LockScreenState.Visible
                 val configKey = configs[index].key
                 KeyguardQuickAffordanceModel.Visible(
-                    configKey =
-                        if (isUsingRepository) {
-                            configKey.encode(position.toSlotId())
-                        } else {
-                            configKey
-                        },
+                    configKey = configKey.encode(position.toSlotId()),
                     icon = visibleState.icon,
                     activationState = visibleState.activationState,
                 )
@@ -397,8 +371,6 @@
     }
 
     suspend fun getSlotPickerRepresentations(): List<KeyguardSlotPickerRepresentation> {
-        check(isUsingRepository)
-
         if (isFeatureDisabledByDevicePolicy()) {
             return emptyList()
         }
@@ -416,7 +388,6 @@
                 name = Contract.FlagsTable.FLAG_NAME_CUSTOM_LOCK_SCREEN_QUICK_AFFORDANCES_ENABLED,
                 value =
                     !isFeatureDisabledByDevicePolicy() &&
-                        featureFlags.isEnabled(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES) &&
                         appContext.resources.getBoolean(R.bool.custom_lockscreen_shortcuts_enabled),
             ),
             KeyguardPickerFlag(
@@ -443,7 +414,7 @@
     }
 
     private suspend fun isFeatureDisabledByDevicePolicy(): Boolean =
-        traceAsync("isFeatureDisabledByDevicePolicy", TAG) {
+        traceAsync(TAG, "isFeatureDisabledByDevicePolicy") {
             withContext(backgroundDispatcher) {
                 devicePolicyManager.areKeyguardShortcutsDisabled(userId = userTracker.userId)
             }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractor.kt
index c8f7efb..1c200b0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractor.kt
@@ -20,20 +20,14 @@
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
 import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
 import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.scene.shared.model.SceneKey
-import com.android.systemui.scene.shared.model.SceneModel
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.stateIn
-import kotlinx.coroutines.launch
 
 /** Hosts business and application state accessing logic for the lockscreen scene. */
 class LockscreenSceneInteractor
@@ -42,7 +36,6 @@
     @Application applicationScope: CoroutineScope,
     private val authenticationInteractor: AuthenticationInteractor,
     bouncerInteractorFactory: BouncerInteractor.Factory,
-    private val sceneInteractor: SceneInteractor,
     @Assisted private val containerName: String,
 ) {
     private val bouncerInteractor: BouncerInteractor =
@@ -72,46 +65,6 @@
                 initialValue = false,
             )
 
-    init {
-        // LOCKING SHOWS Lockscreen.
-        //
-        // Move to the lockscreen scene if the device becomes locked while in any scene.
-        applicationScope.launch {
-            authenticationInteractor.isUnlocked
-                .map { !it }
-                .distinctUntilChanged()
-                .collect { isLocked ->
-                    if (isLocked) {
-                        sceneInteractor.setCurrentScene(
-                            containerName = containerName,
-                            scene = SceneModel(SceneKey.Lockscreen),
-                        )
-                    }
-                }
-        }
-
-        // BYPASS UNLOCK.
-        //
-        // Moves to the gone scene if bypass is enabled and the device becomes unlocked while in the
-        // lockscreen scene.
-        applicationScope.launch {
-            combine(
-                    authenticationInteractor.isBypassEnabled,
-                    authenticationInteractor.isUnlocked,
-                    sceneInteractor.currentScene(containerName),
-                    ::Triple,
-                )
-                .collect { (isBypassEnabled, isUnlocked, currentScene) ->
-                    if (isBypassEnabled && isUnlocked && currentScene.key == SceneKey.Lockscreen) {
-                        sceneInteractor.setCurrentScene(
-                            containerName = containerName,
-                            scene = SceneModel(SceneKey.Gone),
-                        )
-                    }
-                }
-        }
-    }
-
     /** Attempts to dismiss the lockscreen. This will cause the bouncer to show, if needed. */
     fun dismissLockscreen() {
         bouncerInteractor.showOrUnlockDevice(containerName = containerName)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/quickaffordance/KeyguardQuickAffordanceModule.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/quickaffordance/KeyguardQuickAffordanceModule.kt
deleted file mode 100644
index b48acb6..0000000
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/quickaffordance/KeyguardQuickAffordanceModule.kt
+++ /dev/null
@@ -1,30 +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.keyguard.domain.quickaffordance
-
-import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
-import dagger.Binds
-import dagger.Module
-
-@Module
-interface KeyguardQuickAffordanceModule {
-    @Binds
-    fun keyguardQuickAffordanceRegistry(
-        impl: KeyguardQuickAffordanceRegistryImpl
-    ): KeyguardQuickAffordanceRegistry<out KeyguardQuickAffordanceConfig>
-}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/quickaffordance/KeyguardQuickAffordanceRegistry.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/quickaffordance/KeyguardQuickAffordanceRegistry.kt
deleted file mode 100644
index 8526ada..0000000
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/quickaffordance/KeyguardQuickAffordanceRegistry.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- *  Copyright (C) 2022 The Android Open Source Project
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-
-package com.android.systemui.keyguard.domain.quickaffordance
-
-import com.android.systemui.keyguard.data.quickaffordance.HomeControlsKeyguardQuickAffordanceConfig
-import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
-import com.android.systemui.keyguard.data.quickaffordance.QrCodeScannerKeyguardQuickAffordanceConfig
-import com.android.systemui.keyguard.data.quickaffordance.QuickAccessWalletKeyguardQuickAffordanceConfig
-import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
-import javax.inject.Inject
-
-/** Central registry of all known quick affordance configs. */
-interface KeyguardQuickAffordanceRegistry<T : KeyguardQuickAffordanceConfig> {
-    fun getAll(position: KeyguardQuickAffordancePosition): List<T>
-    fun get(key: String): T
-}
-
-class KeyguardQuickAffordanceRegistryImpl
-@Inject
-constructor(
-    homeControls: HomeControlsKeyguardQuickAffordanceConfig,
-    quickAccessWallet: QuickAccessWalletKeyguardQuickAffordanceConfig,
-    qrCodeScanner: QrCodeScannerKeyguardQuickAffordanceConfig,
-) : KeyguardQuickAffordanceRegistry<KeyguardQuickAffordanceConfig> {
-    private val configsByPosition =
-        mapOf(
-            KeyguardQuickAffordancePosition.BOTTOM_START to
-                listOf(
-                    homeControls,
-                ),
-            KeyguardQuickAffordancePosition.BOTTOM_END to
-                listOf(
-                    quickAccessWallet,
-                    qrCodeScanner,
-                ),
-        )
-    private val configByKey =
-        configsByPosition.values.flatten().associateBy { config -> config.key }
-
-    override fun getAll(
-        position: KeyguardQuickAffordancePosition,
-    ): List<KeyguardQuickAffordanceConfig> {
-        return configsByPosition.getValue(position)
-    }
-
-    override fun get(
-        key: String,
-    ): KeyguardQuickAffordanceConfig {
-        return configByKey.getValue(key)
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
index 7d14198..db84268 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
@@ -343,9 +343,9 @@
             Utils.getColorAttrDefaultColor(
                 view.context,
                 if (viewModel.isActivated) {
-                    com.android.internal.R.attr.textColorPrimaryInverse
+                    com.android.internal.R.attr.materialColorOnPrimaryFixed
                 } else {
-                    com.android.internal.R.attr.textColorPrimary
+                    com.android.internal.R.attr.materialColorOnSurface
                 },
             )
         )
@@ -355,9 +355,9 @@
                 Utils.getColorAttr(
                     view.context,
                     if (viewModel.isActivated) {
-                        com.android.internal.R.attr.colorAccentPrimary
+                        com.android.internal.R.attr.materialColorPrimaryFixed
                     } else {
-                        com.android.internal.R.attr.colorSurface
+                        com.android.internal.R.attr.materialColorSurfaceContainerHigh
                     }
                 )
             } else {
diff --git a/packages/SettingsLib/tests/robotests/fragment/src/main/java/org/robolectric/shadows/androidx/fragment/package-info.java b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/UdfpsLottieViewWrapper.kt
similarity index 66%
copy from packages/SettingsLib/tests/robotests/fragment/src/main/java/org/robolectric/shadows/androidx/fragment/package-info.java
copy to packages/SystemUI/src/com/android/systemui/keyguard/ui/view/UdfpsLottieViewWrapper.kt
index dd89441..3a2c3c7 100644
--- a/packages/SettingsLib/tests/robotests/fragment/src/main/java/org/robolectric/shadows/androidx/fragment/package-info.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/UdfpsLottieViewWrapper.kt
@@ -13,11 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package com.android.systemui.keyguard.ui.view
 
-/**
- * Testing infrastructure for androidx.fragment library.
- *
- * <p>To use this in your project, add the artifact {@code
- * org.robolectric:shadows-androidx-fragment} to your project.
- */
-package org.robolectric.shadows.androidx.fragment;
+import android.content.Context
+import android.util.AttributeSet
+import com.android.systemui.util.wrapper.LottieViewWrapper
+
+class UdfpsLottieViewWrapper
+@JvmOverloads
+constructor(context: Context, attrs: AttributeSet? = null) : LottieViewWrapper(context, attrs)
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 6b993ce..576eb9e 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
@@ -716,8 +716,7 @@
         val appUid = currentEntry?.appUid ?: Process.INVALID_UID
         val isExplicit =
             desc.extras?.getLong(MediaConstants.METADATA_KEY_IS_EXPLICIT) ==
-                MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT &&
-                mediaFlags.isExplicitIndicatorEnabled()
+                MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT
 
         val progress =
             if (mediaFlags.isResumeProgressEnabled()) {
@@ -826,12 +825,10 @@
 
         // Explicit Indicator
         var isExplicit = false
-        if (mediaFlags.isExplicitIndicatorEnabled()) {
-            val mediaMetadataCompat = MediaMetadataCompat.fromMediaMetadata(metadata)
-            isExplicit =
-                mediaMetadataCompat?.getLong(MediaConstants.METADATA_KEY_IS_EXPLICIT) ==
-                    MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT
-        }
+        val mediaMetadataCompat = MediaMetadataCompat.fromMediaMetadata(metadata)
+        isExplicit =
+            mediaMetadataCompat?.getLong(MediaConstants.METADATA_KEY_IS_EXPLICIT) ==
+                MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT
 
         // Artist name
         var artist: CharSequence? = metadata?.getString(MediaMetadata.METADATA_KEY_ARTIST)
@@ -1253,6 +1250,9 @@
         return try {
             val options = BroadcastOptions.makeBasic()
             options.setInteractive(true)
+            options.setPendingIntentBackgroundActivityStartMode(
+                BroadcastOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
+            )
             intent.send(options.toBundle())
             true
         } catch (e: PendingIntent.CanceledException) {
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 35082fd..a978b92 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
@@ -23,6 +23,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorInflater;
 import android.animation.AnimatorSet;
+import android.app.ActivityOptions;
 import android.app.BroadcastOptions;
 import android.app.PendingIntent;
 import android.app.WallpaperColors;
@@ -535,7 +536,10 @@
                         mLockscreenUserManager.getCurrentUserId());
                 if (showOverLockscreen) {
                     try {
-                        clickIntent.send();
+                        ActivityOptions opts = ActivityOptions.makeBasic();
+                        opts.setPendingIntentBackgroundActivityStartMode(
+                                ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
+                        clickIntent.send(opts.toBundle());
                     } catch (PendingIntent.CanceledException e) {
                         Log.e(TAG, "Pending intent for " + key + " was cancelled");
                     }
@@ -684,6 +688,8 @@
                                 try {
                                     BroadcastOptions options = BroadcastOptions.makeBasic();
                                     options.setInteractive(true);
+                                    options.setPendingIntentBackgroundActivityStartMode(
+                                            ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
                                     deviceIntent.send(options.toBundle());
                                 } catch (PendingIntent.CanceledException e) {
                                     Log.e(TAG, "Device pending intent was canceled");
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 9bc66f6..01f047c 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
@@ -43,9 +43,6 @@
      */
     fun areNearbyMediaDevicesEnabled() = featureFlags.isEnabled(Flags.MEDIA_NEARBY_DEVICES)
 
-    /** Check whether we show explicit indicator on UMO */
-    fun isExplicitIndicatorEnabled() = featureFlags.isEnabled(Flags.MEDIA_EXPLICIT_INDICATOR)
-
     /**
      * If true, keep active media controls for the lifetime of the MediaSession, regardless of
      * whether the underlying notification was dismissed
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinator.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinator.kt
index a4f4076..a437139 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinator.kt
@@ -16,15 +16,19 @@
 
 package com.android.systemui.mediaprojection.taskswitcher.ui
 
+import android.app.Notification
+import android.app.NotificationChannel
+import android.app.NotificationManager
 import android.content.Context
 import android.util.Log
-import android.widget.Toast
+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.mediaprojection.taskswitcher.ui.model.TaskSwitcherNotificationUiState.NotShowing
 import com.android.systemui.mediaprojection.taskswitcher.ui.model.TaskSwitcherNotificationUiState.Showing
 import com.android.systemui.mediaprojection.taskswitcher.ui.viewmodel.TaskSwitcherNotificationViewModel
+import com.android.systemui.util.NotificationChannels
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
@@ -37,38 +41,69 @@
 @Inject
 constructor(
     private val context: Context,
+    private val notificationManager: NotificationManager,
     @Application private val applicationScope: CoroutineScope,
     @Main private val mainDispatcher: CoroutineDispatcher,
     private val viewModel: TaskSwitcherNotificationViewModel,
 ) {
-
     fun start() {
         applicationScope.launch {
             viewModel.uiState.flowOn(mainDispatcher).collect { uiState ->
                 Log.d(TAG, "uiState -> $uiState")
                 when (uiState) {
-                    is Showing -> showNotification(uiState)
+                    is Showing -> showNotification()
                     is NotShowing -> hideNotification()
                 }
             }
         }
     }
 
-    private fun showNotification(uiState: Showing) {
-        val text =
-            """
-            Sharing pauses when you switch apps.
-            Share this app instead.
-            Switch back.
-            """
-                .trimIndent()
-        // TODO(b/286201515): Create actual notification.
-        Toast.makeText(context, text, Toast.LENGTH_SHORT).show()
+    private fun showNotification() {
+        notificationManager.notify(TAG, NOTIFICATION_ID, createNotification())
     }
 
-    private fun hideNotification() {}
+    private fun createNotification(): Notification {
+        // TODO(b/286201261): implement actions
+        val actionSwitch =
+            Notification.Action.Builder(
+                    /* icon = */ null,
+                    context.getString(R.string.media_projection_task_switcher_action_switch),
+                    /* intent = */ null
+                )
+                .build()
+
+        val actionBack =
+            Notification.Action.Builder(
+                    /* icon = */ null,
+                    context.getString(R.string.media_projection_task_switcher_action_back),
+                    /* intent = */ null
+                )
+                .build()
+
+        val channel =
+            NotificationChannel(
+                NotificationChannels.HINTS,
+                context.getString(R.string.media_projection_task_switcher_notification_channel),
+                NotificationManager.IMPORTANCE_HIGH
+            )
+        notificationManager.createNotificationChannel(channel)
+        return Notification.Builder(context, channel.id)
+            .setSmallIcon(R.drawable.qs_screen_record_icon_on)
+            .setAutoCancel(true)
+            .setContentText(context.getString(R.string.media_projection_task_switcher_text))
+            .addAction(actionSwitch)
+            .addAction(actionBack)
+            .setPriority(Notification.PRIORITY_HIGH)
+            .setDefaults(Notification.DEFAULT_VIBRATE)
+            .build()
+    }
+
+    private fun hideNotification() {
+        notificationManager.cancel(NOTIFICATION_ID)
+    }
 
     companion object {
         private const val TAG = "TaskSwitchNotifCoord"
+        private const val NOTIFICATION_ID = 5566
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
index c3b5db4..310d234 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
@@ -15,6 +15,8 @@
 package com.android.systemui.privacy
 
 import android.content.Context
+import android.content.pm.ActivityInfo
+import android.content.res.Configuration
 import android.util.AttributeSet
 import android.view.Gravity.CENTER_VERTICAL
 import android.view.Gravity.END
@@ -35,6 +37,7 @@
     defStyleRes: Int = 0
 ) : LaunchableFrameLayout(context, attrs, defStyleAttrs, defStyleRes), BackgroundAnimatableView {
 
+    private var configuration: Configuration
     private var iconMargin = 0
     private var iconSize = 0
     private var iconColor = 0
@@ -54,6 +57,7 @@
         clipChildren = true
         clipToPadding = true
         iconsContainer = requireViewById(R.id.icons_container)
+        configuration = Configuration(context.resources.configuration)
         updateResources()
     }
 
@@ -102,6 +106,17 @@
                 R.string.ongoing_privacy_chip_content_multiple_apps, typesText)
     }
 
+    override fun onConfigurationChanged(newConfig: Configuration?) {
+        super.onConfigurationChanged(newConfig)
+        if (newConfig != null) {
+            val diff = newConfig.diff(configuration)
+            configuration.setTo(newConfig)
+            if (diff.and(ActivityInfo.CONFIG_DENSITY.or(ActivityInfo.CONFIG_FONT_SCALE)) != 0) {
+                updateResources()
+            }
+        }
+    }
+
     private fun updateResources() {
         iconMargin = context.resources
                 .getDimensionPixelSize(R.dimen.ongoing_appops_chip_icon_margin)
@@ -110,8 +125,11 @@
         iconColor =
                 Utils.getColorAttrDefaultColor(context, com.android.internal.R.attr.colorPrimary)
 
+        val height = context.resources
+                .getDimensionPixelSize(R.dimen.ongoing_appops_chip_height)
         val padding = context.resources
                 .getDimensionPixelSize(R.dimen.ongoing_appops_chip_side_padding)
+        iconsContainer.layoutParams.height = height
         iconsContainer.setPaddingRelative(padding, 0, padding, 0)
         iconsContainer.background = context.getDrawable(R.drawable.statusbar_privacy_chip_bg)
     }
diff --git a/packages/SettingsLib/tests/robotests/fragment/src/main/java/org/robolectric/shadows/androidx/fragment/package-info.java b/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayEducationLottieViewWrapper.kt
similarity index 65%
copy from packages/SettingsLib/tests/robotests/fragment/src/main/java/org/robolectric/shadows/androidx/fragment/package-info.java
copy to packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayEducationLottieViewWrapper.kt
index dd89441..716a4d6 100644
--- a/packages/SettingsLib/tests/robotests/fragment/src/main/java/org/robolectric/shadows/androidx/fragment/package-info.java
+++ b/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayEducationLottieViewWrapper.kt
@@ -13,11 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package com.android.systemui.reardisplay
 
-/**
- * Testing infrastructure for androidx.fragment library.
- *
- * <p>To use this in your project, add the artifact {@code
- * org.robolectric:shadows-androidx-fragment} to your project.
- */
-package org.robolectric.shadows.androidx.fragment;
+import android.content.Context
+import android.util.AttributeSet
+import com.android.systemui.util.wrapper.LottieViewWrapper
+
+class RearDisplayEducationLottieViewWrapper
+@JvmOverloads
+constructor(context: Context, attrs: AttributeSet? = null) : LottieViewWrapper(context, attrs)
diff --git a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
index 0a9839e..26c5219 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.scene
 
+import com.android.systemui.scene.domain.startable.SceneContainerStartableModule
 import com.android.systemui.scene.shared.model.SceneContainerConfigModule
 import com.android.systemui.scene.ui.composable.SceneModule
 import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModelModule
@@ -25,6 +26,7 @@
     includes =
         [
             SceneContainerConfigModule::class,
+            SceneContainerStartableModule::class,
             SceneContainerViewModelModule::class,
             SceneModule::class,
         ],
diff --git a/packages/SystemUI/src/com/android/systemui/scene/data/repository/SceneContainerRepository.kt b/packages/SystemUI/src/com/android/systemui/scene/data/repository/SceneContainerRepository.kt
index 1ebeced..0a86d35 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/data/repository/SceneContainerRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/data/repository/SceneContainerRepository.kt
@@ -19,6 +19,7 @@
 import com.android.systemui.scene.shared.model.SceneContainerConfig
 import com.android.systemui.scene.shared.model.SceneKey
 import com.android.systemui.scene.shared.model.SceneModel
+import com.android.systemui.scene.shared.model.SceneTransitionModel
 import javax.inject.Inject
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
@@ -45,6 +46,9 @@
         containerConfigByName
             .map { (containerName, _) -> containerName to MutableStateFlow(1f) }
             .toMap()
+    private val sceneTransitionByContainerName:
+        Map<String, MutableStateFlow<SceneTransitionModel?>> =
+        containerConfigByName.keys.associateWith { MutableStateFlow(null) }
 
     /**
      * Returns the keys to all scenes in the container with the given name.
@@ -70,11 +74,43 @@
         currentSceneByContainerName.setValue(containerName, scene)
     }
 
+    /** Sets the scene transition in the container with the given name. */
+    fun setSceneTransition(containerName: String, from: SceneKey, to: SceneKey) {
+        check(allSceneKeys(containerName).contains(from)) {
+            """
+                Cannot set current scene key to "$from". The container "$containerName" does
+                not contain a scene with that key.
+            """
+                .trimIndent()
+        }
+        check(allSceneKeys(containerName).contains(to)) {
+            """
+                Cannot set current scene key to "$to". The container "$containerName" does
+                not contain a scene with that key.
+            """
+                .trimIndent()
+        }
+
+        sceneTransitionByContainerName.setValue(
+            containerName,
+            SceneTransitionModel(from = from, to = to)
+        )
+    }
+
     /** The current scene in the container with the given name. */
     fun currentScene(containerName: String): StateFlow<SceneModel> {
         return currentSceneByContainerName.mutableOrError(containerName).asStateFlow()
     }
 
+    /**
+     * Scene transitions as pairs of keys. A new value is emitted exactly once, each time a scene
+     * transition occurs. The flow begins with a `null` value at first, because the initial scene is
+     * not something that we transition to from another scene.
+     */
+    fun sceneTransitions(containerName: String): StateFlow<SceneTransitionModel?> {
+        return sceneTransitionByContainerName.mutableOrError(containerName).asStateFlow()
+    }
+
     /** Sets whether the container with the given name is visible. */
     fun setVisible(containerName: String, isVisible: Boolean) {
         containerVisibilityByName.setValue(containerName, isVisible)
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
index 1e55975..4582370 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
@@ -20,10 +20,21 @@
 import com.android.systemui.scene.data.repository.SceneContainerRepository
 import com.android.systemui.scene.shared.model.SceneKey
 import com.android.systemui.scene.shared.model.SceneModel
+import com.android.systemui.scene.shared.model.SceneTransitionModel
 import javax.inject.Inject
 import kotlinx.coroutines.flow.StateFlow
 
-/** Business logic and app state accessors for the scene framework. */
+/**
+ * Generic business logic and app state accessors for the scene framework.
+ *
+ * Note that scene container specific business logic does not belong in this class. Instead, it
+ * should be hoisted to a class that is specific to that scene container, for an example, please see
+ * [SystemUiDefaultSceneContainerStartable].
+ *
+ * Also note that this class should not depend on state or logic of other modules or features.
+ * Instead, other feature modules should depend on and call into this class when their parts of the
+ * application state change.
+ */
 @SysUISingleton
 class SceneInteractor
 @Inject
@@ -43,7 +54,9 @@
 
     /** Sets the scene in the container with the given name. */
     fun setCurrentScene(containerName: String, scene: SceneModel) {
+        val currentSceneKey = repository.currentScene(containerName).value.key
         repository.setCurrentScene(containerName, scene)
+        repository.setSceneTransition(containerName, from = currentSceneKey, to = scene.key)
     }
 
     /** The current scene in the container with the given name. */
@@ -70,4 +83,13 @@
     fun sceneTransitionProgress(containerName: String): StateFlow<Float> {
         return repository.sceneTransitionProgress(containerName)
     }
+
+    /**
+     * Scene transitions as pairs of keys. A new value is emitted exactly once, each time a scene
+     * transition occurs. The flow begins with a `null` value at first, because the initial scene is
+     * not something that we transition to from another scene.
+     */
+    fun sceneTransitions(containerName: String): StateFlow<SceneTransitionModel?> {
+        return repository.sceneTransitions(containerName)
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartableModule.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartableModule.kt
new file mode 100644
index 0000000..b3de2d1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartableModule.kt
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+package com.android.systemui.scene.domain.startable
+
+import com.android.systemui.CoreStartable
+import dagger.Binds
+import dagger.Module
+import dagger.multibindings.ClassKey
+import dagger.multibindings.IntoMap
+
+@Module
+interface SceneContainerStartableModule {
+
+    @Binds
+    @IntoMap
+    @ClassKey(SystemUiDefaultSceneContainerStartable::class)
+    fun bind(impl: SystemUiDefaultSceneContainerStartable): CoreStartable
+}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SystemUiDefaultSceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SystemUiDefaultSceneContainerStartable.kt
new file mode 100644
index 0000000..285ff74
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SystemUiDefaultSceneContainerStartable.kt
@@ -0,0 +1,134 @@
+/*
+ * 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.
+ */
+
+package com.android.systemui.scene.domain.startable
+
+import com.android.systemui.CoreStartable
+import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import com.android.systemui.keyguard.shared.model.WakefulnessState
+import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.model.SceneContainerNames
+import com.android.systemui.scene.shared.model.SceneKey
+import com.android.systemui.scene.shared.model.SceneModel
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.filterNotNull
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
+
+/**
+ * Hooks up business logic that manipulates the state of the [SceneInteractor] for the default
+ * system UI scene container (the one named [SceneContainerNames.SYSTEM_UI_DEFAULT]) based on state
+ * from other systems.
+ */
+@SysUISingleton
+class SystemUiDefaultSceneContainerStartable
+@Inject
+constructor(
+    @Application private val applicationScope: CoroutineScope,
+    private val sceneInteractor: SceneInteractor,
+    private val authenticationInteractor: AuthenticationInteractor,
+    private val keyguardInteractor: KeyguardInteractor,
+    private val featureFlags: FeatureFlags,
+) : CoreStartable {
+
+    override fun start() {
+        if (featureFlags.isEnabled(Flags.SCENE_CONTAINER)) {
+            hydrateVisibility()
+            automaticallySwitchScenes()
+        }
+    }
+
+    /** Updates the visibility of the scene container based on the current scene. */
+    private fun hydrateVisibility() {
+        applicationScope.launch {
+            sceneInteractor
+                .currentScene(CONTAINER_NAME)
+                .map { it.key }
+                .distinctUntilChanged()
+                .collect { sceneKey ->
+                    sceneInteractor.setVisible(CONTAINER_NAME, sceneKey != SceneKey.Gone)
+                }
+        }
+    }
+
+    /** Switches between scenes based on ever-changing application state. */
+    private fun automaticallySwitchScenes() {
+        applicationScope.launch {
+            authenticationInteractor.isUnlocked
+                .map { isUnlocked ->
+                    val currentSceneKey = sceneInteractor.currentScene(CONTAINER_NAME).value.key
+                    val isBypassEnabled = authenticationInteractor.isBypassEnabled.value
+                    when {
+                        isUnlocked ->
+                            when (currentSceneKey) {
+                                // When the device becomes unlocked in Bouncer, go to Gone.
+                                is SceneKey.Bouncer -> SceneKey.Gone
+                                // When the device becomes unlocked in Lockscreen, go to Gone if
+                                // bypass is enabled.
+                                is SceneKey.Lockscreen -> SceneKey.Gone.takeIf { isBypassEnabled }
+                                // We got unlocked while on a scene that's not Lockscreen or
+                                // Bouncer, no need to change scenes.
+                                else -> null
+                            }
+                        // When the device becomes locked, to Lockscreen.
+                        !isUnlocked ->
+                            when (currentSceneKey) {
+                                // Already on lockscreen or bouncer, no need to change scenes.
+                                is SceneKey.Lockscreen,
+                                is SceneKey.Bouncer -> null
+                                // We got locked while on a scene that's not Lockscreen or Bouncer,
+                                // go to Lockscreen.
+                                else -> SceneKey.Lockscreen
+                            }
+                        else -> null
+                    }
+                }
+                .filterNotNull()
+                .collect { targetSceneKey -> switchToScene(targetSceneKey) }
+        }
+
+        applicationScope.launch {
+            keyguardInteractor.wakefulnessModel
+                .map { it.state == WakefulnessState.ASLEEP }
+                .distinctUntilChanged()
+                .collect { isAsleep ->
+                    if (isAsleep) {
+                        // When the device goes to sleep, reset the current scene.
+                        val isUnlocked = authenticationInteractor.isUnlocked.value
+                        switchToScene(if (isUnlocked) SceneKey.Gone else SceneKey.Lockscreen)
+                    }
+                }
+        }
+    }
+
+    private fun switchToScene(targetSceneKey: SceneKey) {
+        sceneInteractor.setCurrentScene(
+            containerName = CONTAINER_NAME,
+            scene = SceneModel(targetSceneKey),
+        )
+    }
+
+    companion object {
+        private const val CONTAINER_NAME = SceneContainerNames.SYSTEM_UI_DEFAULT
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/fragment/src/main/java/org/robolectric/shadows/androidx/fragment/package-info.java b/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneTransitionModel.kt
similarity index 63%
copy from packages/SettingsLib/tests/robotests/fragment/src/main/java/org/robolectric/shadows/androidx/fragment/package-info.java
copy to packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneTransitionModel.kt
index dd89441..c8f46a7 100644
--- a/packages/SettingsLib/tests/robotests/fragment/src/main/java/org/robolectric/shadows/androidx/fragment/package-info.java
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneTransitionModel.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,10 +14,12 @@
  * limitations under the License.
  */
 
-/**
- * Testing infrastructure for androidx.fragment library.
- *
- * <p>To use this in your project, add the artifact {@code
- * org.robolectric:shadows-androidx-fragment} to your project.
- */
-package org.robolectric.shadows.androidx.fragment;
+package com.android.systemui.scene.shared.model
+
+/** Models a transition between two scenes. */
+data class SceneTransitionModel(
+    /** The scene we transitioned away from. */
+    val from: SceneKey,
+    /** The scene we transitioned into. */
+    val to: SceneKey,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt
index 2ad5429..c456be6 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt
@@ -2,19 +2,10 @@
 
 import android.content.Context
 import android.util.AttributeSet
-import androidx.activity.OnBackPressedDispatcher
-import androidx.activity.OnBackPressedDispatcherOwner
-import androidx.activity.setViewTreeOnBackPressedDispatcherOwner
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.lifecycleScope
-import androidx.lifecycle.repeatOnLifecycle
-import com.android.systemui.compose.ComposeFacade
-import com.android.systemui.lifecycle.repeatWhenAttached
+import android.view.View
 import com.android.systemui.scene.shared.model.Scene
 import com.android.systemui.scene.shared.model.SceneContainerConfig
-import com.android.systemui.scene.shared.model.SceneKey
 import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
-import kotlinx.coroutines.launch
 
 /** A root view of the main SysUI window that supports scenes. */
 class SceneWindowRootView(
@@ -30,45 +21,19 @@
         containerConfig: SceneContainerConfig,
         scenes: Set<Scene>,
     ) {
-        val unsortedSceneByKey: Map<SceneKey, Scene> = scenes.associateBy { scene -> scene.key }
-        val sortedSceneByKey: Map<SceneKey, Scene> = buildMap {
-            containerConfig.sceneKeys.forEach { sceneKey ->
-                val scene =
-                    checkNotNull(unsortedSceneByKey[sceneKey]) {
-                        "Scene not found for key \"$sceneKey\"!"
-                    }
-
-                put(sceneKey, scene)
+        SceneWindowRootViewBinder.bind(
+            view = this@SceneWindowRootView,
+            viewModel = viewModel,
+            containerConfig = containerConfig,
+            scenes = scenes,
+            onVisibilityChangedInternal = { isVisible ->
+                super.setVisibility(if (isVisible) View.VISIBLE else View.INVISIBLE)
             }
-        }
+        )
+    }
 
-        repeatWhenAttached {
-            lifecycleScope.launch {
-                repeatOnLifecycle(Lifecycle.State.CREATED) {
-                    setViewTreeOnBackPressedDispatcherOwner(
-                        object : OnBackPressedDispatcherOwner {
-                            override val onBackPressedDispatcher =
-                                OnBackPressedDispatcher().apply {
-                                    setOnBackInvokedDispatcher(viewRootImpl.onBackInvokedDispatcher)
-                                }
-
-                            override val lifecycle: Lifecycle =
-                                this@repeatWhenAttached.lifecycle
-                        }
-                    )
-
-                    addView(
-                        ComposeFacade.createSceneContainerView(
-                            context = context,
-                            viewModel = viewModel,
-                            sceneByKey = sortedSceneByKey,
-                        )
-                    )
-                }
-
-                // Here when destroyed.
-                removeAllViews()
-            }
-        }
+    override fun setVisibility(visibility: Int) {
+        // Do nothing. We don't want external callers to invoke this. Instead, we drive our own
+        // visibility from our view-binder.
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt
new file mode 100644
index 0000000..5aa5fee
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+
+package com.android.systemui.scene.ui.view
+
+import android.view.ViewGroup
+import androidx.activity.OnBackPressedDispatcher
+import androidx.activity.OnBackPressedDispatcherOwner
+import androidx.activity.setViewTreeOnBackPressedDispatcherOwner
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import com.android.systemui.compose.ComposeFacade
+import com.android.systemui.lifecycle.repeatWhenAttached
+import com.android.systemui.scene.shared.model.Scene
+import com.android.systemui.scene.shared.model.SceneContainerConfig
+import com.android.systemui.scene.shared.model.SceneKey
+import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
+import kotlinx.coroutines.launch
+
+object SceneWindowRootViewBinder {
+
+    /** Binds between the view and view-model pertaining to a specific scene container. */
+    fun bind(
+        view: ViewGroup,
+        viewModel: SceneContainerViewModel,
+        containerConfig: SceneContainerConfig,
+        scenes: Set<Scene>,
+        onVisibilityChangedInternal: (isVisible: Boolean) -> Unit,
+    ) {
+        val unsortedSceneByKey: Map<SceneKey, Scene> = scenes.associateBy { scene -> scene.key }
+        val sortedSceneByKey: Map<SceneKey, Scene> = buildMap {
+            containerConfig.sceneKeys.forEach { sceneKey ->
+                val scene =
+                    checkNotNull(unsortedSceneByKey[sceneKey]) {
+                        "Scene not found for key \"$sceneKey\"!"
+                    }
+
+                put(sceneKey, scene)
+            }
+        }
+
+        view.repeatWhenAttached {
+            lifecycleScope.launch {
+                repeatOnLifecycle(Lifecycle.State.CREATED) {
+                    view.setViewTreeOnBackPressedDispatcherOwner(
+                        object : OnBackPressedDispatcherOwner {
+                            override val onBackPressedDispatcher =
+                                OnBackPressedDispatcher().apply {
+                                    setOnBackInvokedDispatcher(
+                                        view.viewRootImpl.onBackInvokedDispatcher
+                                    )
+                                }
+
+                            override val lifecycle: Lifecycle = this@repeatWhenAttached.lifecycle
+                        }
+                    )
+
+                    view.addView(
+                        ComposeFacade.createSceneContainerView(
+                            context = view.context,
+                            viewModel = viewModel,
+                            sceneByKey = sortedSceneByKey,
+                        )
+                    )
+
+                    launch {
+                        viewModel.isVisible.collect { isVisible ->
+                            onVisibilityChangedInternal(isVisible)
+                        }
+                    }
+                }
+
+                // Here when destroyed.
+                view.removeAllViews()
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java b/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java
index 3aefcb3..7e234ae 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java
@@ -71,6 +71,8 @@
             ActivityOptions opts = ActivityOptions.makeBasic();
             opts.setDisallowEnterPictureInPictureWhileLaunching(
                     intent.getBooleanExtra(EXTRA_DISALLOW_ENTER_PIP, false));
+            opts.setPendingIntentBackgroundActivityStartMode(
+                    ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
             try {
                 actionIntent.send(context, 0, null, null, null, null, opts.toBundle());
                 if (intent.getBooleanExtra(ScreenshotController.EXTRA_OVERRIDE_TRANSITION, false)) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java b/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
index a9cecaa..6f2256e 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
@@ -117,18 +117,22 @@
 
     @Override
     protected Parcelable onSaveInstanceState() {
+        Log.d(TAG, "onSaveInstanceState");
         Parcelable superState = super.onSaveInstanceState();
 
         SavedState ss = new SavedState(superState);
         ss.mCrop = mCrop;
+        Log.d(TAG, "saving mCrop=" + mCrop);
+
         return ss;
     }
 
     @Override
     protected void onRestoreInstanceState(Parcelable state) {
+        Log.d(TAG, "onRestoreInstanceState");
         SavedState ss = (SavedState) state;
         super.onRestoreInstanceState(ss.getSuperState());
-
+        Log.d(TAG, "restoring mCrop=" + ss.mCrop + " (was " + mCrop + ")");
         mCrop = ss.mCrop;
     }
 
@@ -242,6 +246,7 @@
      * Set the given boundary to the given value without animation.
      */
     public void setBoundaryPosition(CropBoundary boundary, float position) {
+        Log.i(TAG, "setBoundaryPosition: " + boundary + ", position=" + position);
         position = (float) getAllowedValues(boundary).clamp(position);
         switch (boundary) {
             case TOP:
@@ -260,6 +265,7 @@
                 Log.w(TAG, "No boundary selected");
                 break;
         }
+        Log.i(TAG,  "Updated mCrop: " + mCrop);
 
         invalidate();
     }
@@ -350,26 +356,31 @@
         mCropInteractionListener = listener;
     }
 
-    private Range getAllowedValues(CropBoundary boundary) {
+    private Range<Float> getAllowedValues(CropBoundary boundary) {
+        float upper = 0f;
+        float lower = 1f;
         switch (boundary) {
             case TOP:
-                return new Range<>(0f,
-                        mCrop.bottom - pixelDistanceToFraction(mCropTouchMargin,
-                                CropBoundary.BOTTOM));
+                lower = 0f;
+                upper = mCrop.bottom - pixelDistanceToFraction(mCropTouchMargin,
+                        CropBoundary.BOTTOM);
+                break;
             case BOTTOM:
-                return new Range<>(
-                        mCrop.top + pixelDistanceToFraction(mCropTouchMargin,
-                                CropBoundary.TOP), 1f);
+                lower = mCrop.top + pixelDistanceToFraction(mCropTouchMargin, CropBoundary.TOP);
+                upper = 1;
+                break;
             case LEFT:
-                return new Range<>(0f,
-                        mCrop.right - pixelDistanceToFraction(mCropTouchMargin,
-                                CropBoundary.RIGHT));
+                lower = 0f;
+                upper = mCrop.right - pixelDistanceToFraction(mCropTouchMargin, CropBoundary.RIGHT);
+                break;
             case RIGHT:
-                return new Range<>(
-                        mCrop.left + pixelDistanceToFraction(mCropTouchMargin,
-                                CropBoundary.LEFT), 1f);
+                lower = mCrop.left + pixelDistanceToFraction(mCropTouchMargin, CropBoundary.LEFT);
+                upper = 1;
+                break;
         }
-        return null;
+        Log.i(TAG, "getAllowedValues: " + boundary + ", "
+                + "result=[lower=" + lower + ", upper=" + upper + "]");
+        return new Range<>(lower, upper);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
index 4bc7ec8..e6e1fac 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
@@ -36,17 +36,18 @@
 import android.util.Log;
 import android.view.ScrollCaptureResponse;
 import android.view.View;
-import android.view.ViewTreeObserver;
 import android.widget.ImageView;
 
 import androidx.constraintlayout.widget.ConstraintLayout;
 
 import com.android.internal.app.ChooserActivity;
 import com.android.internal.logging.UiEventLogger;
+import com.android.internal.view.OneShotPreDrawListener;
 import com.android.systemui.R;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.screenshot.CropView.CropBoundary;
 import com.android.systemui.screenshot.ScrollCaptureController.LongScreenshot;
 import com.android.systemui.settings.UserTracker;
 
@@ -215,6 +216,7 @@
         mPreview.setImageDrawable(drawable);
         mMagnifierView.setDrawable(mLongScreenshot.getDrawable(),
                 mLongScreenshot.getWidth(), mLongScreenshot.getHeight());
+        Log.i(TAG, "Completed: " + longScreenshot);
         // Original boundaries go from the image tile set's y=0 to y=pageSize, so
         // we animate to that as a starting crop position.
         float topFraction = Math.max(0,
@@ -223,31 +225,26 @@
                 1 - (mLongScreenshot.getBottom() - mLongScreenshot.getPageHeight())
                         / (float) mLongScreenshot.getHeight());
 
+        Log.i(TAG, "topFraction: " + topFraction);
+        Log.i(TAG, "bottomFraction: " + bottomFraction);
+
         mEnterTransitionView.setImageDrawable(drawable);
-        mEnterTransitionView.getViewTreeObserver().addOnPreDrawListener(
-                new ViewTreeObserver.OnPreDrawListener() {
-                    @Override
-                    public boolean onPreDraw() {
-                        mEnterTransitionView.getViewTreeObserver().removeOnPreDrawListener(this);
-                        updateImageDimensions();
-                        mEnterTransitionView.post(() -> {
-                            Rect dest = new Rect();
-                            mEnterTransitionView.getBoundsOnScreen(dest);
-                            mLongScreenshotHolder.takeTransitionDestinationCallback()
-                                    .setTransitionDestination(dest, () -> {
-                                        mPreview.animate().alpha(1f);
-                                        mCropView.setBoundaryPosition(
-                                                CropView.CropBoundary.TOP, topFraction);
-                                        mCropView.setBoundaryPosition(
-                                                CropView.CropBoundary.BOTTOM, bottomFraction);
-                                        mCropView.animateEntrance();
-                                        mCropView.setVisibility(View.VISIBLE);
-                                        setButtonsEnabled(true);
-                                    });
+        OneShotPreDrawListener.add(mEnterTransitionView, () -> {
+            updateImageDimensions();
+            mEnterTransitionView.post(() -> {
+                Rect dest = new Rect();
+                mEnterTransitionView.getBoundsOnScreen(dest);
+                mLongScreenshotHolder.takeTransitionDestinationCallback()
+                        .setTransitionDestination(dest, () -> {
+                            mPreview.animate().alpha(1f);
+                            mCropView.setBoundaryPosition(CropBoundary.TOP, topFraction);
+                            mCropView.setBoundaryPosition(CropBoundary.BOTTOM, bottomFraction);
+                            mCropView.animateEntrance();
+                            mCropView.setVisibility(View.VISIBLE);
+                            setButtonsEnabled(true);
                         });
-                        return true;
-                    }
-                });
+            });
+        });
 
         // Immediately export to temp image file for saved state
         mCacheSaveFuture = mImageExporter.exportToRawFile(mBackgroundExecutor,
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/OverlayActionChip.java b/packages/SystemUI/src/com/android/systemui/screenshot/OverlayActionChip.java
index 13678b0..9e8ea3a 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/OverlayActionChip.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/OverlayActionChip.java
@@ -99,6 +99,8 @@
             try {
                 BroadcastOptions options = BroadcastOptions.makeBasic();
                 options.setInteractive(true);
+                options.setPendingIntentBackgroundActivityStartMode(
+                        BroadcastOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
                 intent.send(options.toBundle());
                 finisher.run();
             } catch (PendingIntent.CanceledException e) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java
index 30a0b8f..bb34ede 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java
@@ -130,8 +130,14 @@
 
         @Override
         public String toString() {
-            return "LongScreenshot{w=" + mImageTileSet.getWidth()
-                    + ", h=" + mImageTileSet.getHeight() + "}";
+            return "LongScreenshot{"
+                    + "l=" + mImageTileSet.getLeft() + ", "
+                    + "t=" + mImageTileSet.getTop() + ", "
+                    + "r=" + mImageTileSet.getRight() + ", "
+                    + "b=" + mImageTileSet.getBottom() + ", "
+                    + "w=" + mImageTileSet.getWidth() + ", "
+                    + "h=" + mImageTileSet.getHeight()
+                    + "}";
         }
 
         public Drawable getDrawable() {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SmartActionsReceiver.java b/packages/SystemUI/src/com/android/systemui/screenshot/SmartActionsReceiver.java
index 9761f59..ef58b9d 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/SmartActionsReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/SmartActionsReceiver.java
@@ -55,7 +55,8 @@
             Log.d(TAG, "Executing smart action [" + actionType + "]:" + pendingIntent.getIntent());
         }
         ActivityOptions opts = ActivityOptions.makeBasic();
-
+        opts.setPendingIntentBackgroundActivityStartMode(
+                ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
         try {
             pendingIntent.send(context, 0, fillIn, null, null, null, opts.toBundle());
         } catch (PendingIntent.CanceledException e) {
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java
index 5199bd4..182e456 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java
@@ -18,6 +18,7 @@
 
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+import static android.view.WindowManagerPolicyConstants.EXTRA_FROM_BRIGHTNESS_KEY;
 
 import android.app.Activity;
 import android.graphics.Rect;
@@ -29,8 +30,10 @@
 import android.view.ViewGroup;
 import android.view.Window;
 import android.view.WindowManager;
+import android.view.accessibility.AccessibilityManager;
 import android.widget.FrameLayout;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
@@ -38,34 +41,42 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.settings.DisplayTracker;
 import com.android.systemui.settings.UserTracker;
+import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
+import com.android.systemui.util.concurrency.DelayableExecutor;
 
 import java.util.List;
-import java.util.concurrent.Executor;
 
 import javax.inject.Inject;
 
 /** A dialog that provides controls for adjusting the screen brightness. */
 public class BrightnessDialog extends Activity {
 
+    @VisibleForTesting
+    static final int DIALOG_TIMEOUT_MILLIS = 3000;
+
     private BrightnessController mBrightnessController;
     private final BrightnessSliderController.Factory mToggleSliderFactory;
     private final UserTracker mUserTracker;
     private final DisplayTracker mDisplayTracker;
-    private final Executor mMainExecutor;
+    private final DelayableExecutor mMainExecutor;
     private final Handler mBackgroundHandler;
+    private final AccessibilityManagerWrapper mAccessibilityMgr;
+    private Runnable mCancelTimeoutRunnable;
 
     @Inject
     public BrightnessDialog(
             UserTracker userTracker,
             DisplayTracker displayTracker,
             BrightnessSliderController.Factory factory,
-            @Main Executor mainExecutor,
-            @Background Handler bgHandler) {
+            @Main DelayableExecutor mainExecutor,
+            @Background Handler bgHandler,
+            AccessibilityManagerWrapper accessibilityMgr) {
         mUserTracker = userTracker;
         mDisplayTracker = displayTracker;
         mToggleSliderFactory = factory;
         mMainExecutor = mainExecutor;
         mBackgroundHandler = bgHandler;
+        mAccessibilityMgr = accessibilityMgr;
     }
 
 
@@ -122,6 +133,14 @@
     }
 
     @Override
+    protected void onResume() {
+        super.onResume();
+        if (triggeredByBrightnessKey()) {
+            scheduleTimeout();
+        }
+    }
+
+    @Override
     protected void onPause() {
         super.onPause();
         overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
@@ -139,9 +158,25 @@
         if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
                 || keyCode == KeyEvent.KEYCODE_VOLUME_UP
                 || keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) {
+            if (mCancelTimeoutRunnable != null) {
+                mCancelTimeoutRunnable.run();
+            }
             finish();
         }
 
         return super.onKeyDown(keyCode, event);
     }
+
+    private boolean triggeredByBrightnessKey() {
+        return getIntent().getBooleanExtra(EXTRA_FROM_BRIGHTNESS_KEY, false);
+    }
+
+    private void scheduleTimeout() {
+        if (mCancelTimeoutRunnable != null) {
+            mCancelTimeoutRunnable.run();
+        }
+        final int timeout = mAccessibilityMgr.getRecommendedTimeoutMillis(DIALOG_TIMEOUT_MILLIS,
+                AccessibilityManager.FLAG_CONTENT_CONTROLS);
+        mCancelTimeoutRunnable = mMainExecutor.executeDelayed(this::finish, timeout);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
index 8105a145..481da52 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
@@ -480,7 +480,6 @@
 
     private void applyWindowLayoutParams() {
         if (mDeferWindowLayoutParams == 0 && mLp != null && mLp.copyFrom(mLpChanged) != 0) {
-            mLogger.logApplyingWindowLayoutParams(mLp);
             Trace.beginSection("updateViewLayout");
             mWindowManager.updateViewLayout(mWindowRootView, mLp);
             Trace.endSection();
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java b/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java
index 317d885..ebb9888 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java
@@ -18,6 +18,7 @@
 
 import android.view.MotionEvent;
 
+import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
@@ -39,16 +40,24 @@
     void instantCollapseShade();
 
     /** See {@link #animateCollapseShade(int, boolean, boolean, float)}. */
-    void animateCollapseShade();
+    default void animateCollapseShade() {
+        animateCollapseShade(CommandQueue.FLAG_EXCLUDE_NONE);
+    }
 
     /** See {@link #animateCollapseShade(int, boolean, boolean, float)}. */
-    void animateCollapseShade(int flags);
+    default void animateCollapseShade(int flags) {
+        animateCollapseShade(flags, false, false, 1.0f);
+    }
 
     /** See {@link #animateCollapseShade(int, boolean, boolean, float)}. */
-    void animateCollapseShadeForced();
+    default void animateCollapseShadeForced() {
+        animateCollapseShade(CommandQueue.FLAG_EXCLUDE_NONE, true, false, 1.0f);
+    }
 
     /** See {@link #animateCollapseShade(int, boolean, boolean, float)}. */
-    void animateCollapseShadeForcedDelayed();
+    default void animateCollapseShadeForcedDelayed() {
+        animateCollapseShade(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true, true, 1.0f);
+    }
 
     /**
      * Collapse the shade animated, showing the bouncer when on {@link StatusBarState#KEYGUARD} or
@@ -155,17 +164,17 @@
     void onLaunchAnimationEnd(boolean launchIsFullScreen);
 
     /** Sets the listener for when the visibility of the shade changes. */
-    void setVisibilityListener(ShadeVisibilityListener listener);
+    default void setVisibilityListener(ShadeVisibilityListener listener) {};
 
     /** */
-    void setNotificationPresenter(NotificationPresenter presenter);
+    default void setNotificationPresenter(NotificationPresenter presenter) {};
 
     /** */
-    void setNotificationShadeWindowViewController(
-            NotificationShadeWindowViewController notificationShadeWindowViewController);
+    default void setNotificationShadeWindowViewController(
+            NotificationShadeWindowViewController notificationShadeWindowViewController) {};
 
     /** */
-    void setShadeViewController(ShadeViewController shadeViewController);
+    default void setShadeViewController(ShadeViewController shadeViewController) {};
 
     /** Listens for shade visibility changes. */
     interface ShadeVisibilityListener {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerEmptyImpl.kt
new file mode 100644
index 0000000..4d05007
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerEmptyImpl.kt
@@ -0,0 +1,52 @@
+package com.android.systemui.shade
+
+import android.view.MotionEvent
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+
+/** Empty implementation of ShadeController for variants of Android without shades. */
+@SysUISingleton
+open class ShadeControllerEmptyImpl @Inject constructor() : ShadeController {
+    override fun instantExpandShade() {}
+    override fun instantCollapseShade() {}
+    override fun animateCollapseShade(
+        flags: Int,
+        force: Boolean,
+        delayed: Boolean,
+        speedUpFactor: Float
+    ) {}
+    override fun animateExpandShade() {}
+    override fun animateExpandQs() {}
+    override fun postAnimateCollapseShade() {}
+    override fun postAnimateForceCollapseShade() {}
+    override fun postAnimateExpandQs() {}
+    override fun cancelExpansionAndCollapseShade() {}
+    override fun closeShadeIfOpen(): Boolean {
+        return false
+    }
+    override fun isKeyguard(): Boolean {
+        return false
+    }
+    override fun isShadeFullyOpen(): Boolean {
+        return false
+    }
+    override fun isExpandingOrCollapsing(): Boolean {
+        return false
+    }
+    override fun postOnShadeExpanded(action: Runnable?) {}
+    override fun addPostCollapseAction(action: Runnable?) {}
+    override fun runPostCollapseRunnables() {}
+    override fun collapseShade(): Boolean {
+        return false
+    }
+    override fun collapseShade(animate: Boolean) {}
+    override fun collapseOnMainThread() {}
+    override fun makeExpandedInvisible() {}
+    override fun makeExpandedVisible(force: Boolean) {}
+    override fun isExpandedVisible(): Boolean {
+        return false
+    }
+    override fun onStatusBarTouch(event: MotionEvent?) {}
+    override fun onLaunchAnimationCancelled(isLaunchForActivity: Boolean) {}
+    override fun onLaunchAnimationEnd(launchIsFullScreen: Boolean) {}
+}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java
index b92afac..af74a8d 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java
@@ -112,26 +112,6 @@
     }
 
     @Override
-    public void animateCollapseShade() {
-        animateCollapseShade(CommandQueue.FLAG_EXCLUDE_NONE);
-    }
-
-    @Override
-    public void animateCollapseShade(int flags) {
-        animateCollapseShade(flags, false, false, 1.0f);
-    }
-
-    @Override
-    public void animateCollapseShadeForced() {
-        animateCollapseShade(CommandQueue.FLAG_EXCLUDE_NONE, true, false, 1.0f);
-    }
-
-    @Override
-    public void animateCollapseShadeForcedDelayed() {
-        animateCollapseShade(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true, true, 1.0f);
-    }
-
-    @Override
     public void animateCollapseShade(int flags, boolean force, boolean delayed,
             float speedUpFactor) {
         if (!force && mStatusBarStateController.getState() != StatusBarState.SHADE) {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt
index 8789a8b..411f91f 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt
@@ -131,6 +131,7 @@
     private val date: TextView = header.findViewById(R.id.date)
     private val iconContainer: StatusIconContainer = header.findViewById(R.id.statusIcons)
     private val mShadeCarrierGroup: ShadeCarrierGroup = header.findViewById(R.id.carrier_group)
+    private val systemIcons: View = header.findViewById(R.id.shade_header_system_icons)
 
     private var roundedCorners = 0
     private var cutout: DisplayCutout? = null
@@ -254,6 +255,14 @@
                     header.paddingRight,
                     header.paddingBottom
                 )
+                systemIcons.setPaddingRelative(
+                    resources.getDimensionPixelSize(
+                        R.dimen.shade_header_system_icons_padding_start
+                    ),
+                    systemIcons.paddingTop,
+                    resources.getDimensionPixelSize(R.dimen.shade_header_system_icons_padding_end),
+                    systemIcons.paddingBottom
+                )
             }
 
             override fun onDensityOrFontScaleChanged() {
@@ -266,6 +275,7 @@
                 lastInsets?.let { updateConstraintsForInsets(header, it) }
                 updateResources()
                 updateCarrierGroupPadding()
+                clock.onDensityOrFontScaleChanged()
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeWindowLogger.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeWindowLogger.kt
index 51a27cf..e7a397b 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeWindowLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeWindowLogger.kt
@@ -16,14 +16,13 @@
 
 package com.android.systemui.shade
 
-import android.view.WindowManager
-import com.android.systemui.log.dagger.ShadeWindowLog
 import com.android.systemui.log.ConstantStringsLogger
 import com.android.systemui.log.ConstantStringsLoggerImpl
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.core.LogLevel
 import com.android.systemui.log.core.LogLevel.DEBUG
 import com.android.systemui.log.core.LogMessage
+import com.android.systemui.log.dagger.ShadeWindowLog
 import javax.inject.Inject
 
 private const val TAG = "systemui.shadewindow"
@@ -31,15 +30,6 @@
 class ShadeWindowLogger @Inject constructor(@ShadeWindowLog private val buffer: LogBuffer) :
     ConstantStringsLogger by ConstantStringsLoggerImpl(buffer, TAG) {
 
-    fun logApplyingWindowLayoutParams(lp: WindowManager.LayoutParams) {
-        buffer.log(
-            TAG,
-            DEBUG,
-            { str1 = lp.toString() },
-            { "Applying new window layout params: $str1" }
-        )
-    }
-
     fun logNewState(state: Any) {
         buffer.log(
             TAG,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ConnectedDisplayChip.kt b/packages/SystemUI/src/com/android/systemui/statusbar/ConnectedDisplayChip.kt
new file mode 100644
index 0000000..76636ab8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ConnectedDisplayChip.kt
@@ -0,0 +1,55 @@
+/*
+ * 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.SuppressLint
+import android.content.Context
+import android.content.res.Configuration
+import android.util.AttributeSet
+import android.widget.FrameLayout
+import com.android.systemui.R
+import com.android.systemui.statusbar.events.BackgroundAnimatableView
+
+/** Chip that appears in the status bar when an external display is connected. */
+class ConnectedDisplayChip
+@JvmOverloads
+constructor(context: Context, attrs: AttributeSet? = null) :
+    FrameLayout(context, attrs), BackgroundAnimatableView {
+
+    private val iconContainer: FrameLayout
+    init {
+        inflate(context, R.layout.connected_display_chip, this)
+        iconContainer = requireViewById(R.id.icons_rounded_container)
+    }
+
+    /**
+     * 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) {
+        iconContainer.setLeftTopRightBottom(l - left, t - top, r - left, b - top)
+    }
+
+    override fun onConfigurationChanged(newConfig: Configuration) {
+        super.onConfigurationChanged(newConfig)
+        updateResources()
+    }
+
+    @SuppressLint("UseCompatLoadingForDrawables")
+    private fun updateResources() {
+        iconContainer.background = context.getDrawable(R.drawable.statusbar_chip_bg)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 42ebaa3..73d8445 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -29,6 +29,7 @@
 import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
 import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED;
 import static com.android.systemui.DejankUtils.whitelistIpcs;
+import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED;
 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.IMPORTANT_MSG_MIN_DURATION;
 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_ALIGNMENT;
 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BATTERY;
@@ -43,6 +44,7 @@
 import static com.android.systemui.keyguard.ScreenLifecycle.SCREEN_ON;
 import static com.android.systemui.log.core.LogLevel.ERROR;
 import static com.android.systemui.plugins.FalsingManager.LOW_PENALTY;
+import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
 
 import android.app.AlarmManager;
 import android.app.admin.DevicePolicyManager;
@@ -96,6 +98,7 @@
 import com.android.systemui.keyguard.KeyguardIndication;
 import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController;
 import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
 import com.android.systemui.keyguard.util.IndicationHelper;
 import com.android.systemui.log.core.LogLevel;
 import com.android.systemui.plugins.FalsingManager;
@@ -114,6 +117,7 @@
 import java.text.NumberFormat;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.function.Consumer;
 
 import javax.inject.Inject;
 
@@ -171,7 +175,7 @@
     public KeyguardIndicationRotateTextViewController mRotateTextViewController;
     private BroadcastReceiver mBroadcastReceiver;
     private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
-
+    private KeyguardInteractor mKeyguardInteractor;
     private String mPersistentUnlockMessage;
     private String mAlignmentIndication;
     private CharSequence mTrustGrantedIndication;
@@ -205,7 +209,17 @@
     private KeyguardUpdateMonitorCallback mUpdateMonitorCallback;
 
     private boolean mDozing;
+    private boolean mIsActiveDreamLockscreenHosted;
     private final ScreenLifecycle mScreenLifecycle;
+    @VisibleForTesting
+    final Consumer<Boolean> mIsActiveDreamLockscreenHostedCallback =
+            (Boolean isLockscreenHosted) -> {
+                if (mIsActiveDreamLockscreenHosted == isLockscreenHosted) {
+                    return;
+                }
+                mIsActiveDreamLockscreenHosted = isLockscreenHosted;
+                updateDeviceEntryIndication(false);
+            };
     private final ScreenLifecycle.Observer mScreenObserver =
             new ScreenLifecycle.Observer() {
         @Override
@@ -261,7 +275,8 @@
             UserTracker userTracker,
             BouncerMessageInteractor bouncerMessageInteractor,
             FeatureFlags flags,
-            IndicationHelper indicationHelper
+            IndicationHelper indicationHelper,
+            KeyguardInteractor keyguardInteractor
     ) {
         mContext = context;
         mBroadcastDispatcher = broadcastDispatcher;
@@ -289,6 +304,7 @@
         mBouncerMessageInteractor = bouncerMessageInteractor;
         mFeatureFlags = flags;
         mIndicationHelper = indicationHelper;
+        mKeyguardInteractor = keyguardInteractor;
 
         mFaceAcquiredMessageDeferral = faceHelpMessageDeferral;
         mCoExFaceAcquisitionMsgIdsToShow = new HashSet<>();
@@ -371,6 +387,10 @@
             intentFilter.addAction(Intent.ACTION_USER_REMOVED);
             mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, intentFilter);
         }
+        if (mFeatureFlags.isEnabled(LOCKSCREEN_WALLPAPER_DREAM_ENABLED)) {
+            collectFlow(mIndicationArea, mKeyguardInteractor.isActiveDreamLockscreenHosted(),
+                    mIsActiveDreamLockscreenHostedCallback);
+        }
     }
 
     /**
@@ -878,6 +898,12 @@
             return;
         }
 
+        // Device is dreaming and the dream is hosted in lockscreen
+        if (mIsActiveDreamLockscreenHosted) {
+            mIndicationArea.setVisibility(GONE);
+            return;
+        }
+
         // A few places might need to hide the indication, so always start by making it visible
         mIndicationArea.setVisibility(VISIBLE);
 
@@ -1069,6 +1095,7 @@
         pw.println("  mBiometricMessageFollowUp: " + mBiometricMessageFollowUp);
         pw.println("  mBatteryLevel: " + mBatteryLevel);
         pw.println("  mBatteryPresent: " + mBatteryPresent);
+        pw.println("  mIsActiveDreamLockscreenHosted: " + mIsActiveDreamLockscreenHosted);
         pw.println("  AOD text: " + (
                 mTopIndicationView == null ? null : mTopIndicationView.getText()));
         pw.println("  computePowerIndication(): " + computePowerIndication());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index e6e3e7e..ea5ca27 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -19,6 +19,7 @@
 
 import static com.android.systemui.DejankUtils.whitelistIpcs;
 
+import android.app.ActivityOptions;
 import android.app.KeyguardManager;
 import android.app.Notification;
 import android.app.admin.DevicePolicyManager;
@@ -158,7 +159,11 @@
                     final String notificationKey = intent.getStringExtra(Intent.EXTRA_INDEX);
                     if (intentSender != null) {
                         try {
-                            mContext.startIntentSender(intentSender, null, 0, 0, 0);
+                            ActivityOptions options = ActivityOptions.makeBasic();
+                            options.setPendingIntentBackgroundActivityStartMode(
+                                    ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
+                            mContext.startIntentSender(intentSender, null, 0, 0, 0,
+                                    options.toBundle());
                         } catch (IntentSender.SendIntentException e) {
                             /* ignore */
                         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 91c08a0..fbbee53 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -26,6 +26,7 @@
 import android.app.ActivityManager;
 import android.app.Notification;
 import android.content.Context;
+import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
@@ -41,18 +42,19 @@
 import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
 import android.text.TextUtils;
-import android.util.AttributeSet;
 import android.util.FloatProperty;
 import android.util.Log;
 import android.util.Property;
 import android.util.TypedValue;
 import android.view.ViewDebug;
+import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.Interpolator;
 
 import androidx.core.graphics.ColorUtils;
 
 import com.android.app.animation.Interpolators;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.internal.util.ContrastColorUtil;
 import com.android.systemui.R;
@@ -131,10 +133,12 @@
         }
     };
 
-    private boolean mAlwaysScaleIcon;
     private int mStatusBarIconDrawingSizeIncreased = 1;
-    private int mStatusBarIconDrawingSize = 1;
-    private int mStatusBarIconSize = 1;
+    @VisibleForTesting int mStatusBarIconDrawingSize = 1;
+
+    @VisibleForTesting int mOriginalStatusBarIconSize = 1;
+    @VisibleForTesting int mNewStatusBarIconSize = 1;
+    @VisibleForTesting float mScaleToFitNewIconSize = 1;
     private StatusBarIcon mIcon;
     @ViewDebug.ExportedProperty private String mSlot;
     private Drawable mNumberBackground;
@@ -144,7 +148,7 @@
     private String mNumberText;
     private StatusBarNotification mNotification;
     private final boolean mBlocked;
-    private int mDensity;
+    private Configuration mConfiguration;
     private boolean mNightMode;
     private float mIconScale = 1.0f;
     private final Paint mDotPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@@ -156,7 +160,6 @@
     private ObjectAnimator mIconAppearAnimator;
     private ObjectAnimator mDotAnimator;
     private float mDotAppearAmount;
-    private OnVisibilityChangedListener mOnVisibilityChangedListener;
     private int mDrawableColor;
     private int mIconColor;
     private int mDecorColor;
@@ -175,7 +178,6 @@
     private int mCachedContrastBackgroundColor = NO_COLOR;
     private float[] mMatrix;
     private ColorMatrixColorFilter mMatrixColorFilter;
-    private boolean mIsInShelf;
     private Runnable mLayoutRunnable;
     private boolean mDismissed;
     private Runnable mOnDismissListener;
@@ -198,30 +200,20 @@
         mNumberPain.setAntiAlias(true);
         setNotification(sbn);
         setScaleType(ScaleType.CENTER);
-        mDensity = context.getResources().getDisplayMetrics().densityDpi;
-        Configuration configuration = context.getResources().getConfiguration();
-        mNightMode = (configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK)
+        mConfiguration = new Configuration(context.getResources().getConfiguration());
+        mNightMode = (mConfiguration.uiMode & Configuration.UI_MODE_NIGHT_MASK)
                 == Configuration.UI_MODE_NIGHT_YES;
         initializeDecorColor();
         reloadDimens();
         maybeUpdateIconScaleDimens();
     }
 
-    public StatusBarIconView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        mDozer = new NotificationIconDozeHelper(context);
-        mBlocked = false;
-        mAlwaysScaleIcon = true;
-        reloadDimens();
-        maybeUpdateIconScaleDimens();
-        mDensity = context.getResources().getDisplayMetrics().densityDpi;
-    }
-
     /** Should always be preceded by {@link #reloadDimens()} */
-    private void maybeUpdateIconScaleDimens() {
+    @VisibleForTesting
+    public void maybeUpdateIconScaleDimens() {
         // We do not resize and scale system icons (on the right), only notification icons (on the
         // left).
-        if (mNotification != null || mAlwaysScaleIcon) {
+        if (isNotification()) {
             updateIconScaleForNotifications();
         } else {
             updateIconScaleForSystemIcons();
@@ -229,22 +221,63 @@
     }
 
     private void updateIconScaleForNotifications() {
+        float iconScale;
+        // we need to scale the image size to be same as the original size
+        // (fit mOriginalStatusBarIconSize), then we can scale it with mScaleToFitNewIconSize
+        // to fit mNewStatusBarIconSize
+        float scaleToOriginalDrawingSize = 1.0f;
+        ViewGroup.LayoutParams lp = getLayoutParams();
+        if (getDrawable() != null && (lp != null && lp.width > 0 && lp.height > 0)) {
+            final int iconViewWidth = lp.width;
+            final int iconViewHeight = lp.height;
+            // first we estimate the image exact size when put the drawable in scaled iconView size,
+            // then we can compute the scaleToOriginalDrawingSize to make the image size fit in
+            // mOriginalStatusBarIconSize
+            final int drawableWidth = getDrawable().getIntrinsicWidth();
+            final int drawableHeight = getDrawable().getIntrinsicHeight();
+            float scaleToFitIconView = Math.min(
+                    (float) iconViewWidth / drawableWidth,
+                    (float) iconViewHeight / drawableHeight);
+            // if the drawable size <= the icon view size, the drawable won't be scaled
+            if (scaleToFitIconView > 1.0f) {
+                scaleToFitIconView = 1.0f;
+            }
+            final float scaledImageWidth = drawableWidth * scaleToFitIconView;
+            final float scaledImageHeight = drawableHeight * scaleToFitIconView;
+            // if the scaled image size <= mOriginalStatusBarIconSize, we don't need to enlarge it
+            scaleToOriginalDrawingSize = Math.min(
+                    (float) mOriginalStatusBarIconSize / scaledImageWidth,
+                    (float) mOriginalStatusBarIconSize / scaledImageHeight);
+            if (scaleToOriginalDrawingSize > 1.0f) {
+                scaleToOriginalDrawingSize = 1.0f;
+            }
+        }
+        iconScale = scaleToOriginalDrawingSize;
+
         final float imageBounds = mIncreasedSize ?
                 mStatusBarIconDrawingSizeIncreased : mStatusBarIconDrawingSize;
-        final int outerBounds = mStatusBarIconSize;
-        mIconScale = imageBounds / (float)outerBounds;
+        final int originalOuterBounds = mOriginalStatusBarIconSize;
+        iconScale = iconScale * (imageBounds / (float) originalOuterBounds);
+
+        // scale image to fit new icon size
+        mIconScale = iconScale * mScaleToFitNewIconSize;
+
         updatePivot();
     }
 
     // Makes sure that all icons are scaled to the same height (15dp). If we cannot get a height
     // for the icon, it uses the default SCALE (15f / 17f) which is the old behavior
     private void updateIconScaleForSystemIcons() {
+        float iconScale;
         float iconHeight = getIconHeight();
         if (iconHeight != 0) {
-            mIconScale = mSystemIconDesiredHeight / iconHeight;
+            iconScale = mSystemIconDesiredHeight / iconHeight;
         } else {
-            mIconScale = mSystemIconDefaultScale;
+            iconScale = mSystemIconDefaultScale;
         }
+
+        // scale image to fit new icon size
+        mIconScale = iconScale * mScaleToFitNewIconSize;
     }
 
     private float getIconHeight() {
@@ -267,12 +300,10 @@
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
-        int density = newConfig.densityDpi;
-        if (density != mDensity) {
-            mDensity = density;
-            reloadDimens();
-            updateDrawable();
-            maybeUpdateIconScaleDimens();
+        final int configDiff = newConfig.diff(mConfiguration);
+        mConfiguration.setTo(newConfig);
+        if ((configDiff & (ActivityInfo.CONFIG_DENSITY | ActivityInfo.CONFIG_FONT_SCALE)) != 0) {
+            updateIconDimens();
         }
         boolean nightMode = (newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK)
                 == Configuration.UI_MODE_NIGHT_YES;
@@ -282,11 +313,22 @@
         }
     }
 
+    /**
+     * Update the icon dimens and drawable with current resources
+     */
+    public void updateIconDimens() {
+        reloadDimens();
+        updateDrawable();
+        maybeUpdateIconScaleDimens();
+    }
+
     private void reloadDimens() {
         boolean applyRadius = mDotRadius == mStaticDotRadius;
         Resources res = getResources();
         mStaticDotRadius = res.getDimensionPixelSize(R.dimen.overflow_dot_radius);
-        mStatusBarIconSize = res.getDimensionPixelSize(R.dimen.status_bar_icon_size);
+        mOriginalStatusBarIconSize = res.getDimensionPixelSize(R.dimen.status_bar_icon_size);
+        mNewStatusBarIconSize = res.getDimensionPixelSize(R.dimen.status_bar_icon_size_sp);
+        mScaleToFitNewIconSize = (float) mNewStatusBarIconSize / mOriginalStatusBarIconSize;
         mStatusBarIconDrawingSizeIncreased =
                 res.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size_dark);
         mStatusBarIconDrawingSize =
@@ -309,17 +351,8 @@
         maybeUpdateIconScaleDimens();
     }
 
-    private static boolean streq(String a, String b) {
-        if (a == b) {
-            return true;
-        }
-        if (a == null && b != null) {
-            return false;
-        }
-        if (a != null && b == null) {
-            return false;
-        }
-        return a.equals(b);
+    private boolean isNotification() {
+        return mNotification != null;
     }
 
     public boolean equalIcons(Icon a, Icon b) {
@@ -416,7 +449,7 @@
 
     Drawable getIcon(StatusBarIcon icon) {
         Context notifContext = getContext();
-        if (mNotification != null) {
+        if (isNotification()) {
             notifContext = mNotification.getPackageContext(getContext());
         }
         return getIcon(getContext(), notifContext != null ? notifContext : getContext(), icon);
@@ -471,7 +504,7 @@
     @Override
     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
         super.onInitializeAccessibilityEvent(event);
-        if (mNotification != null) {
+        if (isNotification()) {
             event.setParcelableData(mNotification.getNotification());
         }
     }
@@ -491,11 +524,29 @@
     }
 
     @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+        if (!isNotification()) {
+            // for system icons, calculated measured width from super is for image drawable real
+            // width (17dp). We may scale the image with font scale, so we also need to scale the
+            // measured width so that scaled measured width and image width would be fit.
+            int measuredWidth = getMeasuredWidth();
+            int measuredHeight = getMeasuredHeight();
+            setMeasuredDimension((int) (measuredWidth * mScaleToFitNewIconSize), measuredHeight);
+        }
+    }
+
+    @Override
     protected void onDraw(Canvas canvas) {
+        // In this method, for width/height division computation we intend to discard the
+        // fractional part as the original behavior.
         if (mIconAppearAmount > 0.0f) {
             canvas.save();
+            int px = getWidth() / 2;
+            int py = getHeight() / 2;
             canvas.scale(mIconScale * mIconAppearAmount, mIconScale * mIconAppearAmount,
-                    getWidth() / 2, getHeight() / 2);
+                    (float) px, (float) py);
             super.onDraw(canvas);
             canvas.restore();
         }
@@ -512,10 +563,15 @@
             } else {
                 float fadeOutAmount = mDotAppearAmount - 1.0f;
                 alpha = alpha * (1.0f - fadeOutAmount);
-                radius = NotificationUtils.interpolate(mDotRadius, getWidth() / 4, fadeOutAmount);
+                int end = getWidth() / 4;
+                radius = NotificationUtils.interpolate(mDotRadius, (float) end, fadeOutAmount);
             }
             mDotPaint.setAlpha((int) (alpha * 255));
-            canvas.drawCircle(mStatusBarIconSize / 2, getHeight() / 2, radius, mDotPaint);
+            int cx = mNewStatusBarIconSize / 2;
+            int cy = getHeight() / 2;
+            canvas.drawCircle(
+                    (float) cx, (float) cy,
+                    radius, mDotPaint);
         }
     }
 
@@ -624,7 +680,7 @@
     }
 
     private void initializeDecorColor() {
-        if (mNotification != null) {
+        if (isNotification()) {
             setDecorColor(getContext().getColor(mNightMode
                     ? com.android.internal.R.color.notification_default_color_dark
                     : com.android.internal.R.color.notification_default_color_light));
@@ -837,7 +893,7 @@
                 if (targetAmount != currentAmount) {
                     mDotAnimator = ObjectAnimator.ofFloat(this, DOT_APPEAR_AMOUNT,
                             currentAmount, targetAmount);
-                    mDotAnimator.setInterpolator(interpolator);;
+                    mDotAnimator.setInterpolator(interpolator);
                     mDotAnimator.setDuration(duration == 0 ? ANIMATION_DURATION_FAST
                             : duration);
                     final boolean runRunnable = !runnableAdded;
@@ -894,22 +950,10 @@
         }
     }
 
-    @Override
-    public void setVisibility(int visibility) {
-        super.setVisibility(visibility);
-        if (mOnVisibilityChangedListener != null) {
-            mOnVisibilityChangedListener.onVisibilityChanged(visibility);
-        }
-    }
-
     public float getDotAppearAmount() {
         return mDotAppearAmount;
     }
 
-    public void setOnVisibilityChangedListener(OnVisibilityChangedListener listener) {
-        mOnVisibilityChangedListener = listener;
-    }
-
     public void setDozing(boolean dozing, boolean fade, long delay) {
         mDozer.setDozing(f -> {
             mDozeAmount = f;
@@ -943,14 +987,6 @@
         outRect.bottom += translationY;
     }
 
-    public void setIsInShelf(boolean isInShelf) {
-        mIsInShelf = isInShelf;
-    }
-
-    public boolean isInShelf() {
-        return mIsInShelf;
-    }
-
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
@@ -1032,8 +1068,4 @@
     public boolean showsConversation() {
         return mShowsConversation;
     }
-
-    public interface OnVisibilityChangedListener {
-        void onVisibilityChanged(int newVisibility);
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
index fdad101..d6f6c2c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
@@ -135,7 +135,7 @@
         mDotView = new StatusBarIconView(mContext, mSlot, null);
         mDotView.setVisibleState(STATE_DOT);
 
-        int width = mContext.getResources().getDimensionPixelSize(R.dimen.status_bar_icon_size);
+        int width = mContext.getResources().getDimensionPixelSize(R.dimen.status_bar_icon_size_sp);
         LayoutParams lp = new LayoutParams(width, width);
         lp.gravity = Gravity.CENTER_VERTICAL | Gravity.START;
         addView(mDotView, lp);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java
index decc70d..8d7214d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java
@@ -164,7 +164,7 @@
         mDotView = new StatusBarIconView(mContext, mSlot, null);
         mDotView.setVisibleState(STATE_DOT);
 
-        int width = mContext.getResources().getDimensionPixelSize(R.dimen.status_bar_icon_size);
+        int width = mContext.getResources().getDimensionPixelSize(R.dimen.status_bar_icon_size_sp);
         LayoutParams lp = new LayoutParams(width, width);
         lp.gravity = Gravity.CENTER_VERTICAL | Gravity.START;
         addView(mDotView, lp);
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 e5849c0..bde298d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt
@@ -24,6 +24,7 @@
 import com.android.systemui.privacy.OngoingPrivacyChip
 import com.android.systemui.privacy.PrivacyItem
 import com.android.systemui.statusbar.BatteryStatusChip
+import com.android.systemui.statusbar.ConnectedDisplayChip
 
 typealias ViewCreator = (context: Context) -> BackgroundAnimatableView
 
@@ -87,6 +88,23 @@
     }
 }
 
+/** Event that triggers a connected display chip in the status bar. */
+class ConnectedDisplayEvent : StatusEvent {
+    /** Priority is set higher than [BatteryEvent]. */
+    override val priority = 60
+    override var forceVisible = false
+    override val showAnimation = true
+    override var contentDescription: String? = ""
+
+    override val viewCreator: ViewCreator = { context ->
+        ConnectedDisplayChip(context)
+    }
+
+    override fun toString(): String {
+        return javaClass.simpleName
+    }
+}
+
 /** open only for testing purposes. (See [FakeStatusEvent.kt]) */
 open class PrivacyEvent(override val showAnimation: Boolean = true) : StatusEvent {
     override var contentDescription: String? = null
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 776956a..5639000 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
@@ -30,9 +30,11 @@
 import androidx.core.animation.AnimatorListenerAdapter
 import androidx.core.animation.AnimatorSet
 import androidx.core.animation.ValueAnimator
+import com.android.internal.annotations.VisibleForTesting
 import com.android.systemui.R
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
+import com.android.systemui.statusbar.phone.StatusBarContentInsetsChangedListener
 import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
 import com.android.systemui.statusbar.window.StatusBarWindowController
 import com.android.systemui.util.animation.AnimationUtil.Companion.frames
@@ -46,7 +48,7 @@
     private val context: Context,
     private val statusBarWindowController: StatusBarWindowController,
     private val contentInsetsProvider: StatusBarContentInsetsProvider,
-    private val featureFlags: FeatureFlags
+    private val featureFlags: FeatureFlags,
 ) : SystemStatusAnimationCallback {
 
     private lateinit var animationWindowView: FrameLayout
@@ -56,7 +58,8 @@
 
     // Left for LTR, Right for RTL
     private var animationDirection = LEFT
-    private var chipBounds = Rect()
+
+    @VisibleForTesting var chipBounds = Rect()
     private val chipWidth get() = chipBounds.width()
     private val chipRight get() = chipBounds.right
     private val chipLeft get() = chipBounds.left
@@ -69,7 +72,7 @@
     private var animRect = Rect()
 
     // TODO: move to dagger
-    private var initialized = false
+    @VisibleForTesting var initialized = false
 
     /**
      * Give the chip controller a chance to inflate and configure the chip view before we start
@@ -98,23 +101,7 @@
                     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()
-            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
-                }
-            }
-            chipBounds = Rect(chipLeft, chipTop, chipRight, chipBottom)
+            updateChipBounds(it, contentInsetsProvider.getStatusBarContentAreaForCurrentRotation())
         }
     }
 
@@ -253,16 +240,67 @@
         return animSet
     }
 
-    private fun init() {
+    fun init() {
         initialized = true
         themedContext = ContextThemeWrapper(context, R.style.Theme_SystemUI_QuickSettings)
         animationWindowView = LayoutInflater.from(themedContext)
                 .inflate(R.layout.system_event_animation_window, null) as FrameLayout
-        val lp = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
-        lp.gravity = Gravity.END or Gravity.CENTER_VERTICAL
+        // Matches status_bar.xml
+        val height = themedContext.resources.getDimensionPixelSize(R.dimen.status_bar_height)
+        val lp = FrameLayout.LayoutParams(MATCH_PARENT, height)
+        lp.gravity = Gravity.END or Gravity.TOP
         statusBarWindowController.addViewToWindow(animationWindowView, lp)
         animationWindowView.clipToPadding = false
         animationWindowView.clipChildren = false
+
+        // Use contentInsetsProvider rather than configuration controller, since we only care
+        // about status bar dimens
+        contentInsetsProvider.addCallback(object : StatusBarContentInsetsChangedListener {
+            override fun onStatusBarContentInsetsChanged() {
+                val newContentArea = contentInsetsProvider
+                    .getStatusBarContentAreaForCurrentRotation()
+                updateDimens(newContentArea)
+
+                // If we are currently animating, we have to re-solve for the chip bounds. If we're
+                // not animating then [prepareChipAnimation] will take care of it for us
+                currentAnimatedView?.let {
+                    updateChipBounds(it, newContentArea)
+                }
+            }
+        })
+    }
+
+    private fun updateDimens(contentArea: Rect) {
+        val lp = animationWindowView.layoutParams as FrameLayout.LayoutParams
+        lp.height = contentArea.height()
+
+        animationWindowView.layoutParams = lp
+    }
+
+    /**
+     * Use the current status bar content area and the current chip's measured size to update
+     * the animation rect and chipBounds. This method can be called at any time and will update
+     * the current animation values properly during e.g. a rotation.
+     */
+    private fun updateChipBounds(chip: BackgroundAnimatableView, contentArea: Rect) {
+        // decide which direction we're animating from, and then set some screen coordinates
+        val chipTop = (contentArea.bottom - chip.view.measuredHeight) / 2
+        val chipBottom = chipTop + chip.view.measuredHeight
+        val chipRight: Int
+        val chipLeft: Int
+
+        when (animationDirection) {
+            LEFT -> {
+                chipRight = contentArea.right
+                chipLeft = contentArea.right - chip.chipWidth
+            }
+            else /* RIGHT */ -> {
+                chipLeft = contentArea.left
+                chipRight = contentArea.left + chip.chipWidth
+            }
+        }
+        chipBounds = Rect(chipLeft, chipTop, chipRight, chipBottom)
+        animRect.set(chipBounds)
     }
 
     private fun layoutParamsDefault(marginEnd: Int): FrameLayout.LayoutParams =
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 26fd230..23edf17 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt
@@ -22,6 +22,9 @@
 import android.provider.DeviceConfig.NAMESPACE_PRIVACY
 import com.android.systemui.R
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor
+import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor.State
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.privacy.PrivacyChipBuilder
@@ -30,29 +33,45 @@
 import com.android.systemui.statusbar.policy.BatteryController
 import com.android.systemui.util.time.SystemClock
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
 
 /**
- * Listens for system events (battery, privacy, connectivity) and allows listeners
- * to show status bar animations when they happen
+ * Listens for system events (battery, privacy, connectivity) and allows listeners to show status
+ * bar animations when they happen
  */
 @SysUISingleton
-class SystemEventCoordinator @Inject constructor(
+class SystemEventCoordinator
+@Inject
+constructor(
     private val systemClock: SystemClock,
     private val batteryController: BatteryController,
     private val privacyController: PrivacyItemController,
     private val context: Context,
-    private val featureFlags: FeatureFlags
+    private val featureFlags: FeatureFlags,
+    @Application private val appScope: CoroutineScope,
+    connectedDisplayInteractor: ConnectedDisplayInteractor
 ) {
+    private val onDisplayConnectedFlow =
+        connectedDisplayInteractor.connectedDisplayState
+                .filter { it != State.DISCONNECTED }
+
+    private var connectedDisplayCollectionJob: Job? = null
     private lateinit var scheduler: SystemStatusAnimationScheduler
 
     fun startObserving() {
         batteryController.addCallback(batteryStateListener)
         privacyController.addCallback(privacyStateListener)
+        startConnectedDisplayCollection()
     }
 
     fun stopObserving() {
         batteryController.removeCallback(batteryStateListener)
         privacyController.removeCallback(privacyStateListener)
+        connectedDisplayCollectionJob?.cancel()
     }
 
     fun attachScheduler(s: SystemStatusAnimationScheduler) {
@@ -80,6 +99,13 @@
         scheduler.onStatusEvent(event)
     }
 
+    private fun startConnectedDisplayCollection() {
+        connectedDisplayCollectionJob =
+                onDisplayConnectedFlow
+                        .onEach { scheduler.onStatusEvent(ConnectedDisplayEvent()) }
+                        .launchIn(appScope)
+    }
+
     private val batteryStateListener = object : BatteryController.BatteryStateChangeCallback {
         private var plugged = false
         private var stateKnown = false
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
index 2fa070c..07eb8a00 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
@@ -28,12 +28,9 @@
 import com.android.systemui.keyguard.data.repository.KeyguardRepository
 import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
-import com.android.systemui.keyguard.shared.model.TransitionState
-import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.statusbar.StatusBarState
 import com.android.systemui.statusbar.expansionChanges
-import com.android.systemui.statusbar.notification.NotifPipelineFlags
 import com.android.systemui.statusbar.notification.collection.NotifPipeline
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
@@ -50,30 +47,29 @@
 import com.android.systemui.util.settings.SettingsProxyExt.observerFlow
 import java.io.PrintWriter
 import javax.inject.Inject
-import kotlin.time.Duration
 import kotlin.time.Duration.Companion.seconds
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.Job
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.collectLatest
 import kotlinx.coroutines.flow.conflate
 import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.emitAll
-import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.onStart
-import kotlinx.coroutines.flow.transformLatest
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.yield
 
 /**
  * Filters low priority and privacy-sensitive notifications from the lockscreen, and hides section
- * headers on the lockscreen.
+ * headers on the lockscreen. If enabled, it will also track and hide seen notifications on the
+ * lockscreen.
  */
 @CoordinatorScope
 class KeyguardCoordinator
@@ -86,7 +82,6 @@
     private val keyguardRepository: KeyguardRepository,
     private val keyguardTransitionRepository: KeyguardTransitionRepository,
     private val logger: KeyguardCoordinatorLogger,
-    private val notifPipelineFlags: NotifPipelineFlags,
     @Application private val scope: CoroutineScope,
     private val sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider,
     private val secureSettings: SecureSettings,
@@ -95,6 +90,8 @@
 ) : Coordinator, Dumpable {
 
     private val unseenNotifications = mutableSetOf<NotificationEntry>()
+    private val unseenEntryAdded = MutableSharedFlow<NotificationEntry>(extraBufferCapacity = 1)
+    private val unseenEntryRemoved = MutableSharedFlow<NotificationEntry>(extraBufferCapacity = 1)
     private var unseenFilterEnabled = false
 
     override fun attach(pipeline: NotifPipeline) {
@@ -109,79 +106,130 @@
     private fun attachUnseenFilter(pipeline: NotifPipeline) {
         pipeline.addFinalizeFilter(unseenNotifFilter)
         pipeline.addCollectionListener(collectionListener)
-        scope.launch { trackUnseenNotificationsWhileUnlocked() }
-        scope.launch { invalidateWhenUnseenSettingChanges() }
+        scope.launch { trackUnseenFilterSettingChanges() }
         dumpManager.registerDumpable(this)
     }
 
-    private suspend fun trackUnseenNotificationsWhileUnlocked() {
-        // Whether or not we're actively tracking unseen notifications to mark them as seen when
-        // appropriate.
-        val isTrackingUnseen: Flow<Boolean> =
-            keyguardRepository.isKeyguardShowing
-                // transformLatest so that we can cancel listening to keyguard transitions once
-                // isKeyguardShowing changes (after a successful transition to the keyguard).
-                .transformLatest { isShowing ->
-                    if (isShowing) {
-                        // If the keyguard is showing, we're not tracking unseen.
-                        emit(false)
-                    } else {
-                        // If the keyguard stops showing, then start tracking unseen notifications.
-                        emit(true)
-                        // If the screen is turning off, stop tracking, but if that transition is
-                        // cancelled, then start again.
-                        emitAll(
-                            keyguardTransitionRepository.transitions.map { step ->
-                                !step.isScreenTurningOff
-                            }
-                        )
-                    }
-                }
-                // Prevent double emit of `false` caused by transition to AOD, followed by keyguard
-                // showing
+    private suspend fun trackSeenNotifications() {
+        // Whether or not keyguard is visible (or occluded).
+        val isKeyguardPresent: Flow<Boolean> =
+            keyguardTransitionRepository.transitions
+                .map { step -> step.to != KeyguardState.GONE }
                 .distinctUntilChanged()
                 .onEach { trackingUnseen -> logger.logTrackingUnseen(trackingUnseen) }
 
-        // Use collectLatest so that trackUnseenNotifications() is cancelled when the keyguard is
-        // showing again
-        var clearUnseenOnBeginTracking = false
-        isTrackingUnseen.collectLatest { trackingUnseen ->
-            if (!trackingUnseen) {
-                // Wait for the user to spend enough time on the lock screen before clearing unseen
-                // set when unlocked
-                awaitTimeSpentNotDozing(SEEN_TIMEOUT)
-                clearUnseenOnBeginTracking = true
-                logger.logSeenOnLockscreen()
+        // Separately track seen notifications while the device is locked, applying once the device
+        // is unlocked.
+        val notificationsSeenWhileLocked = mutableSetOf<NotificationEntry>()
+
+        // Use [collectLatest] to cancel any running jobs when [trackingUnseen] changes.
+        isKeyguardPresent.collectLatest { isKeyguardPresent: Boolean ->
+            if (isKeyguardPresent) {
+                // Keyguard is not gone, notifications need to be visible for a certain threshold
+                // before being marked as seen
+                trackSeenNotificationsWhileLocked(notificationsSeenWhileLocked)
             } else {
-                if (clearUnseenOnBeginTracking) {
-                    clearUnseenOnBeginTracking = false
-                    logger.logAllMarkedSeenOnUnlock()
-                    unseenNotifications.clear()
+                // Mark all seen-while-locked notifications as seen for real.
+                if (notificationsSeenWhileLocked.isNotEmpty()) {
+                    unseenNotifications.removeAll(notificationsSeenWhileLocked)
+                    logger.logAllMarkedSeenOnUnlock(
+                        seenCount = notificationsSeenWhileLocked.size,
+                        remainingUnseenCount = unseenNotifications.size
+                    )
+                    notificationsSeenWhileLocked.clear()
                 }
                 unseenNotifFilter.invalidateList("keyguard no longer showing")
-                trackUnseenNotifications()
+                // Keyguard is gone, notifications can be immediately marked as seen when they
+                // become visible.
+                trackSeenNotificationsWhileUnlocked()
             }
         }
     }
 
-    private suspend fun awaitTimeSpentNotDozing(duration: Duration) {
-        keyguardRepository.isDozing
-            // Use transformLatest so that the timeout delay is cancelled if the device enters doze,
-            // and is restarted when doze ends.
-            .transformLatest { isDozing ->
-                if (!isDozing) {
-                    delay(duration)
-                    // Signal timeout has completed
-                    emit(Unit)
+    /**
+     * Keep [notificationsSeenWhileLocked] updated to represent which notifications have actually
+     * been "seen" while the device is on the keyguard.
+     */
+    private suspend fun trackSeenNotificationsWhileLocked(
+        notificationsSeenWhileLocked: MutableSet<NotificationEntry>,
+    ) = coroutineScope {
+        // Remove removed notifications from the set
+        launch {
+            unseenEntryRemoved.collect { entry ->
+                if (notificationsSeenWhileLocked.remove(entry)) {
+                    logger.logRemoveSeenOnLockscreen(entry)
                 }
             }
-            // Suspend until the first emission
-            .first()
+        }
+        // Use collectLatest so that the timeout delay is cancelled if the device enters doze, and
+        // is restarted when doze ends.
+        keyguardRepository.isDozing.collectLatest { isDozing ->
+            if (!isDozing) {
+                trackSeenNotificationsWhileLockedAndNotDozing(notificationsSeenWhileLocked)
+            }
+        }
     }
 
-    // Track "unseen" notifications, marking them as seen when either shade is expanded or the
+    /**
+     * Keep [notificationsSeenWhileLocked] updated to represent which notifications have actually
+     * been "seen" while the device is on the keyguard and not dozing. Any new and existing unseen
+     * notifications are not marked as seen until they are visible for the [SEEN_TIMEOUT] duration.
+     */
+    private suspend fun trackSeenNotificationsWhileLockedAndNotDozing(
+        notificationsSeenWhileLocked: MutableSet<NotificationEntry>
+    ) = coroutineScope {
+        // All child tracking jobs will be cancelled automatically when this is cancelled.
+        val trackingJobsByEntry = mutableMapOf<NotificationEntry, Job>()
+
+        /**
+         * Wait for the user to spend enough time on the lock screen before removing notification
+         * from unseen set upon unlock.
+         */
+        suspend fun trackSeenDurationThreshold(entry: NotificationEntry) {
+            if (notificationsSeenWhileLocked.remove(entry)) {
+                logger.logResetSeenOnLockscreen(entry)
+            }
+            delay(SEEN_TIMEOUT)
+            notificationsSeenWhileLocked.add(entry)
+            trackingJobsByEntry.remove(entry)
+            logger.logSeenOnLockscreen(entry)
+        }
+
+        /** Stop any unseen tracking when a notification is removed. */
+        suspend fun stopTrackingRemovedNotifs(): Nothing =
+            unseenEntryRemoved.collect { entry ->
+                trackingJobsByEntry.remove(entry)?.let {
+                    it.cancel()
+                    logger.logStopTrackingLockscreenSeenDuration(entry)
+                }
+            }
+
+        /** Start tracking new notifications when they are posted. */
+        suspend fun trackNewUnseenNotifs(): Nothing = coroutineScope {
+            unseenEntryAdded.collect { entry ->
+                logger.logTrackingLockscreenSeenDuration(entry)
+                // If this is an update, reset the tracking.
+                trackingJobsByEntry[entry]?.let {
+                    it.cancel()
+                    logger.logResetSeenOnLockscreen(entry)
+                }
+                trackingJobsByEntry[entry] = launch { trackSeenDurationThreshold(entry) }
+            }
+        }
+
+        // Start tracking for all notifications that are currently unseen.
+        logger.logTrackingLockscreenSeenDuration(unseenNotifications)
+        unseenNotifications.forEach { entry ->
+            trackingJobsByEntry[entry] = launch { trackSeenDurationThreshold(entry) }
+        }
+
+        launch { trackNewUnseenNotifs() }
+        launch { stopTrackingRemovedNotifs() }
+    }
+
+    // Track "seen" notifications, marking them as such when either shade is expanded or the
     // notification becomes heads up.
-    private suspend fun trackUnseenNotifications() {
+    private suspend fun trackSeenNotificationsWhileUnlocked() {
         coroutineScope {
             launch { clearUnseenNotificationsWhenShadeIsExpanded() }
             launch { markHeadsUpNotificationsAsSeen() }
@@ -212,7 +260,7 @@
         }
     }
 
-    private suspend fun invalidateWhenUnseenSettingChanges() {
+    private suspend fun trackUnseenFilterSettingChanges() {
         secureSettings
             // emit whenever the setting has changed
             .observerFlow(
@@ -228,17 +276,23 @@
                     UserHandle.USER_CURRENT,
                 ) == 1
             }
+            // don't emit anything if nothing has changed
+            .distinctUntilChanged()
             // perform lookups on the bg thread pool
             .flowOn(bgDispatcher)
             // only track the most recent emission, if events are happening faster than they can be
             // consumed
             .conflate()
-            // update local field and invalidate if necessary
-            .collect { setting ->
+            .collectLatest { setting ->
+                // update local field and invalidate if necessary
                 if (setting != unseenFilterEnabled) {
                     unseenFilterEnabled = setting
                     unseenNotifFilter.invalidateList("unseen setting changed")
                 }
+                // if the setting is enabled, then start tracking and filtering unseen notifications
+                if (setting) {
+                    trackSeenNotifications()
+                }
             }
     }
 
@@ -250,6 +304,7 @@
                 ) {
                     logger.logUnseenAdded(entry.key)
                     unseenNotifications.add(entry)
+                    unseenEntryAdded.tryEmit(entry)
                 }
             }
 
@@ -259,12 +314,14 @@
                 ) {
                     logger.logUnseenUpdated(entry.key)
                     unseenNotifications.add(entry)
+                    unseenEntryAdded.tryEmit(entry)
                 }
             }
 
             override fun onEntryRemoved(entry: NotificationEntry, reason: Int) {
                 if (unseenNotifications.remove(entry)) {
                     logger.logUnseenRemoved(entry.key)
+                    unseenEntryRemoved.tryEmit(entry)
                 }
             }
         }
@@ -347,6 +404,3 @@
         private val SEEN_TIMEOUT = 5.seconds
     }
 }
-
-private val TransitionStep.isScreenTurningOff: Boolean
-    get() = transitionState == TransitionState.STARTED && to != KeyguardState.GONE
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorLogger.kt
index 4c33524..788659e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorLogger.kt
@@ -19,6 +19,7 @@
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.core.LogLevel
 import com.android.systemui.log.dagger.UnseenNotificationLog
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import javax.inject.Inject
 
 private const val TAG = "KeyguardCoordinator"
@@ -28,11 +29,14 @@
 constructor(
     @UnseenNotificationLog private val buffer: LogBuffer,
 ) {
-    fun logSeenOnLockscreen() =
+    fun logSeenOnLockscreen(entry: NotificationEntry) =
         buffer.log(
             TAG,
             LogLevel.DEBUG,
-            "Notifications on lockscreen will be marked as seen when unlocked."
+            messageInitializer = { str1 = entry.key },
+            messagePrinter = {
+                "Notification [$str1] on lockscreen will be marked as seen when unlocked."
+            },
         )
 
     fun logTrackingUnseen(trackingUnseen: Boolean) =
@@ -43,11 +47,21 @@
             messagePrinter = { "${if (bool1) "Start" else "Stop"} tracking unseen notifications." },
         )
 
-    fun logAllMarkedSeenOnUnlock() =
+    fun logAllMarkedSeenOnUnlock(
+        seenCount: Int,
+        remainingUnseenCount: Int,
+    ) =
         buffer.log(
             TAG,
             LogLevel.DEBUG,
-            "Notifications have been marked as seen now that device is unlocked."
+            messageInitializer = {
+                int1 = seenCount
+                int2 = remainingUnseenCount
+            },
+            messagePrinter = {
+                "$int1 Notifications have been marked as seen now that device is unlocked. " +
+                    "$int2 notifications remain unseen."
+            },
         )
 
     fun logShadeExpanded() =
@@ -96,4 +110,60 @@
             messageInitializer = { str1 = key },
             messagePrinter = { "Unseen notif has become heads up: $str1" },
         )
+
+    fun logTrackingLockscreenSeenDuration(unseenNotifications: Set<NotificationEntry>) {
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            messageInitializer = {
+                str1 = unseenNotifications.joinToString { it.key }
+                int1 = unseenNotifications.size
+            },
+            messagePrinter = {
+                "Tracking $int1 unseen notifications for lockscreen seen duration threshold: $str1"
+            },
+        )
+    }
+
+    fun logTrackingLockscreenSeenDuration(entry: NotificationEntry) {
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            messageInitializer = { str1 = entry.key },
+            messagePrinter = {
+                "Tracking new notification for lockscreen seen duration threshold: $str1"
+            },
+        )
+    }
+
+    fun logStopTrackingLockscreenSeenDuration(entry: NotificationEntry) {
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            messageInitializer = { str1 = entry.key },
+            messagePrinter = {
+                "Stop tracking removed notification for lockscreen seen duration threshold: $str1"
+            },
+        )
+    }
+
+    fun logResetSeenOnLockscreen(entry: NotificationEntry) {
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            messageInitializer = { str1 = entry.key },
+            messagePrinter = {
+                "Reset tracking updated notification for lockscreen seen duration threshold: $str1"
+            },
+        )
+    }
+
+    fun logRemoveSeenOnLockscreen(entry: NotificationEntry) {
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            messageInitializer = { str1 = entry.key },
+            messagePrinter = { "Notification marked as seen on lockscreen removed: $str1" },
+        )
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifLayoutInflaterFactory.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifLayoutInflaterFactory.kt
new file mode 100644
index 0000000..4429939
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifLayoutInflaterFactory.kt
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.row
+
+import android.content.Context
+import android.util.AttributeSet
+import android.util.Log
+import android.view.LayoutInflater
+import android.view.View
+import com.android.systemui.Dumpable
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.notification.row.NotificationRowModule.NOTIF_REMOTEVIEWS_FACTORIES
+import com.android.systemui.util.asIndenting
+import com.android.systemui.util.withIncreasedIndent
+import java.io.PrintWriter
+import javax.inject.Inject
+import javax.inject.Named
+
+/**
+ * Implementation of [NotifLayoutInflaterFactory]. This class uses a set of
+ * [NotifRemoteViewsFactory] objects to create replacement views for Notification RemoteViews.
+ */
+open class NotifLayoutInflaterFactory
+@Inject
+constructor(
+    dumpManager: DumpManager,
+    @Named(NOTIF_REMOTEVIEWS_FACTORIES)
+    private val remoteViewsFactories: Set<@JvmSuppressWildcards NotifRemoteViewsFactory>
+) : LayoutInflater.Factory2, Dumpable {
+    init {
+        dumpManager.registerNormalDumpable(TAG, this)
+    }
+
+    override fun onCreateView(
+        parent: View?,
+        name: String,
+        context: Context,
+        attrs: AttributeSet
+    ): View? {
+        var view: View? = null
+        var handledFactory: NotifRemoteViewsFactory? = null
+        for (layoutFactory in remoteViewsFactories) {
+            view = layoutFactory.instantiate(parent, name, context, attrs)
+            if (view != null) {
+                check(handledFactory == null) {
+                    "${layoutFactory.javaClass.name} tries to produce view. However, " +
+                        "${handledFactory?.javaClass?.name} produced view for $name before."
+                }
+                handledFactory = layoutFactory
+            }
+        }
+        logOnCreateView(name, view, handledFactory)
+        return view
+    }
+
+    override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? =
+        onCreateView(null, name, context, attrs)
+
+    override fun dump(pw: PrintWriter, args: Array<out String>) {
+        val indentingPW = pw.asIndenting()
+
+        indentingPW.appendLine("$TAG ReplacementFactories:")
+        indentingPW.withIncreasedIndent {
+            remoteViewsFactories.forEach { indentingPW.appendLine(it.javaClass.simpleName) }
+        }
+    }
+
+    private fun logOnCreateView(
+        name: String,
+        replacedView: View?,
+        factory: NotifRemoteViewsFactory?
+    ) {
+        if (SPEW && replacedView != null && factory != null) {
+            Log.d(TAG, "$factory produced view for $name: $replacedView")
+        }
+    }
+
+    private companion object {
+        private const val TAG = "NotifLayoutInflaterFac"
+        private val SPEW = Log.isLoggable(TAG, Log.VERBOSE)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifRemoteViewsFactory.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifRemoteViewsFactory.kt
new file mode 100644
index 0000000..eebd4d4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifRemoteViewsFactory.kt
@@ -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.systemui.statusbar.notification.row
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.View
+
+/** Interface used to create replacement view instances in Notification RemoteViews. */
+interface NotifRemoteViewsFactory {
+
+    /** return the replacement view instance for the given view name */
+    fun instantiate(parent: View?, name: String, context: Context, attrs: AttributeSet): View?
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
index 13d1978..0ad77bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
@@ -79,6 +79,7 @@
     private final ConversationNotificationProcessor mConversationProcessor;
     private final Executor mBgExecutor;
     private final SmartReplyStateInflater mSmartReplyStateInflater;
+    private final NotifLayoutInflaterFactory mNotifLayoutInflaterFactory;
 
     @Inject
     NotificationContentInflater(
@@ -87,13 +88,15 @@
             ConversationNotificationProcessor conversationProcessor,
             MediaFeatureFlag mediaFeatureFlag,
             @Background Executor bgExecutor,
-            SmartReplyStateInflater smartRepliesInflater) {
+            SmartReplyStateInflater smartRepliesInflater,
+            NotifLayoutInflaterFactory notifLayoutInflaterFactory) {
         mRemoteViewCache = remoteViewCache;
         mRemoteInputManager = remoteInputManager;
         mConversationProcessor = conversationProcessor;
         mIsMediaInQS = mediaFeatureFlag.getEnabled();
         mBgExecutor = bgExecutor;
         mSmartReplyStateInflater = smartRepliesInflater;
+        mNotifLayoutInflaterFactory = notifLayoutInflaterFactory;
     }
 
     @Override
@@ -137,7 +140,8 @@
                 callback,
                 mRemoteInputManager.getRemoteViewsOnClickHandler(),
                 mIsMediaInQS,
-                mSmartReplyStateInflater);
+                mSmartReplyStateInflater,
+                mNotifLayoutInflaterFactory);
         if (mInflateSynchronously) {
             task.onPostExecute(task.doInBackground());
         } else {
@@ -160,7 +164,8 @@
                 bindParams.isLowPriority,
                 bindParams.usesIncreasedHeight,
                 bindParams.usesIncreasedHeadsUpHeight,
-                packageContext);
+                packageContext,
+                mNotifLayoutInflaterFactory);
 
         result = inflateSmartReplyViews(result, reInflateFlags, entry,
                 row.getContext(), packageContext,
@@ -298,7 +303,8 @@
 
     private static InflationProgress createRemoteViews(@InflationFlag int reInflateFlags,
             Notification.Builder builder, boolean isLowPriority, boolean usesIncreasedHeight,
-            boolean usesIncreasedHeadsUpHeight, Context packageContext) {
+            boolean usesIncreasedHeadsUpHeight, Context packageContext,
+            NotifLayoutInflaterFactory notifLayoutInflaterFactory) {
         InflationProgress result = new InflationProgress();
 
         if ((reInflateFlags & FLAG_CONTENT_VIEW_CONTRACTED) != 0) {
@@ -316,7 +322,7 @@
         if ((reInflateFlags & FLAG_CONTENT_VIEW_PUBLIC) != 0) {
             result.newPublicView = builder.makePublicContentView(isLowPriority);
         }
-
+        setNotifsViewsInflaterFactory(result, notifLayoutInflaterFactory);
         result.packageContext = packageContext;
         result.headsUpStatusBarText = builder.getHeadsUpStatusBarText(false /* showingPublic */);
         result.headsUpStatusBarTextPublic = builder.getHeadsUpStatusBarText(
@@ -324,6 +330,22 @@
         return result;
     }
 
+    private static void setNotifsViewsInflaterFactory(InflationProgress result,
+            NotifLayoutInflaterFactory notifLayoutInflaterFactory) {
+        setRemoteViewsInflaterFactory(result.newContentView, notifLayoutInflaterFactory);
+        setRemoteViewsInflaterFactory(result.newExpandedView,
+                notifLayoutInflaterFactory);
+        setRemoteViewsInflaterFactory(result.newHeadsUpView, notifLayoutInflaterFactory);
+        setRemoteViewsInflaterFactory(result.newPublicView, notifLayoutInflaterFactory);
+    }
+
+    private static void setRemoteViewsInflaterFactory(RemoteViews remoteViews,
+            NotifLayoutInflaterFactory notifLayoutInflaterFactory) {
+        if (remoteViews != null) {
+            remoteViews.setLayoutInflaterFactory(notifLayoutInflaterFactory);
+        }
+    }
+
     private static CancellationSignal apply(
             Executor bgExecutor,
             boolean inflateSynchronously,
@@ -348,7 +370,6 @@
                 public void setResultView(View v) {
                     result.inflatedContentView = v;
                 }
-
                 @Override
                 public RemoteViews getRemoteView() {
                     return result.newContentView;
@@ -356,7 +377,7 @@
             };
             applyRemoteView(bgExecutor, inflateSynchronously, result, reInflateFlags, flag,
                     remoteViewCache, entry, row, isNewView, remoteViewClickHandler, callback,
-                    privateLayout,  privateLayout.getContractedChild(),
+                    privateLayout, privateLayout.getContractedChild(),
                     privateLayout.getVisibleWrapper(
                             NotificationContentView.VISIBLE_TYPE_CONTRACTED),
                     runningInflations, applyCallback);
@@ -758,8 +779,8 @@
      * @param oldView The old view that was applied to the existing view before
      * @return {@code true} if the RemoteViews are the same and the view can be reused to reapply.
      */
-     @VisibleForTesting
-     static boolean canReapplyRemoteView(final RemoteViews newView,
+    @VisibleForTesting
+    static boolean canReapplyRemoteView(final RemoteViews newView,
             final RemoteViews oldView) {
         return (newView == null && oldView == null) ||
                 (newView != null && oldView != null
@@ -800,6 +821,7 @@
         private final ConversationNotificationProcessor mConversationProcessor;
         private final boolean mIsMediaInQS;
         private final SmartReplyStateInflater mSmartRepliesInflater;
+        private final NotifLayoutInflaterFactory mNotifLayoutInflaterFactory;
 
         private AsyncInflationTask(
                 Executor bgExecutor,
@@ -815,7 +837,8 @@
                 InflationCallback callback,
                 RemoteViews.InteractionHandler remoteViewClickHandler,
                 boolean isMediaFlagEnabled,
-                SmartReplyStateInflater smartRepliesInflater) {
+                SmartReplyStateInflater smartRepliesInflater,
+                NotifLayoutInflaterFactory notifLayoutInflaterFactory) {
             mEntry = entry;
             mRow = row;
             mBgExecutor = bgExecutor;
@@ -831,6 +854,7 @@
             mCallback = callback;
             mConversationProcessor = conversationProcessor;
             mIsMediaInQS = isMediaFlagEnabled;
+            mNotifLayoutInflaterFactory = notifLayoutInflaterFactory;
             entry.setInflationTask(this);
         }
 
@@ -874,7 +898,8 @@
                 }
                 InflationProgress inflationProgress = createRemoteViews(mReInflateFlags,
                         recoveredBuilder, mIsLowPriority, mUsesIncreasedHeight,
-                        mUsesIncreasedHeadsUpHeight, packageContext);
+                        mUsesIncreasedHeadsUpHeight, packageContext,
+                        mNotifLayoutInflaterFactory);
                 InflatedSmartReplyState previousSmartReplyState = mRow.getExistingSmartReplyState();
                 InflationProgress result = inflateSmartReplyViews(
                         inflationProgress,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowModule.java
index 111b575..b2a3780 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowModule.java
@@ -17,15 +17,26 @@
 package com.android.systemui.statusbar.notification.row;
 
 import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.flags.FeatureFlags;
 
 import dagger.Binds;
 import dagger.Module;
+import dagger.Provides;
+import dagger.multibindings.ElementsIntoSet;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.inject.Named;
 
 /**
  * Dagger Module containing notification row and view inflation implementations.
  */
 @Module
 public abstract class NotificationRowModule {
+    public static final String NOTIF_REMOTEVIEWS_FACTORIES =
+            "notif_remoteviews_factories";
+
     /**
      * Provides notification row content binder instance.
      */
@@ -41,4 +52,15 @@
     @SysUISingleton
     public abstract NotifRemoteViewCache provideNotifRemoteViewCache(
             NotifRemoteViewCacheImpl cacheImpl);
+
+    /** Provides view factories to be inflated in notification content. */
+    @Provides
+    @ElementsIntoSet
+    @Named(NOTIF_REMOTEVIEWS_FACTORIES)
+    static Set<NotifRemoteViewsFactory> provideNotifRemoteViewsFactories(
+            FeatureFlags featureFlags
+    ) {
+        final Set<NotifRemoteViewsFactory> replacementFactories = new HashSet<>();
+        return replacementFactories;
+    }
 }
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 479fbdb..8063c8c 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
@@ -5919,7 +5919,17 @@
         Trace.beginSection("NSSL.resetAllSwipeState()");
         mSwipeHelper.resetTouchState();
         for (int i = 0; i < getChildCount(); i++) {
-            mSwipeHelper.forceResetSwipeState(getChildAt(i));
+            View child = getChildAt(i);
+            mSwipeHelper.forceResetSwipeState(child);
+            if (child instanceof ExpandableNotificationRow) {
+                ExpandableNotificationRow childRow = (ExpandableNotificationRow) child;
+                List<ExpandableNotificationRow> grandchildren = childRow.getAttachedChildren();
+                if (grandchildren != null) {
+                    for (ExpandableNotificationRow grandchild : grandchildren) {
+                        mSwipeHelper.forceResetSwipeState(grandchild);
+                    }
+                }
+            }
         }
         updateContinuousShadowDrawing();
         Trace.endSection();
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 0d3dfae..8902a18 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -42,6 +42,7 @@
 
 import android.annotation.Nullable;
 import android.app.ActivityManager;
+import android.app.ActivityOptions;
 import android.app.IWallpaperManager;
 import android.app.KeyguardManager;
 import android.app.Notification;
@@ -1773,7 +1774,10 @@
                     EventLog.writeEvent(EventLogTags.SYSUI_HEADS_UP_ESCALATION,
                             sbn.getKey());
                     wakeUpForFullScreenIntent();
-                    notification.fullScreenIntent.send();
+                    ActivityOptions opts = ActivityOptions.makeBasic();
+                    opts.setPendingIntentBackgroundActivityStartMode(
+                            ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
+                    notification.fullScreenIntent.send(opts.toBundle());
                     entry.notifyFullScreenIntentLaunched();
                 } catch (PendingIntent.CanceledException e) {
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index 2fd244e..e18c9d8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -33,14 +33,11 @@
 import com.android.systemui.statusbar.NotificationShelfController;
 import com.android.systemui.statusbar.StatusBarIconView;
 import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.notification.AnimatableProperty;
 import com.android.systemui.statusbar.notification.NotificationUtils;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
-import com.android.systemui.statusbar.notification.PropertyAnimator;
 import com.android.systemui.statusbar.notification.collection.ListEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider;
-import com.android.systemui.statusbar.notification.stack.AnimationProperties;
 import com.android.systemui.statusbar.window.StatusBarWindowController;
 import com.android.wm.shell.bubbles.Bubbles;
 
@@ -91,8 +88,6 @@
     private final ArrayList<Rect> mTintAreas = new ArrayList<>();
     private final Context mContext;
 
-    private final DemoModeController mDemoModeController;
-
     private final FeatureFlags mFeatureFlags;
 
     private int mAodIconAppearTranslation;
@@ -139,8 +134,7 @@
         wakeUpCoordinator.addListener(this);
         mBypassController = keyguardBypassController;
         mBubblesOptional = bubblesOptional;
-        mDemoModeController = demoModeController;
-        mDemoModeController.addCallback(this);
+        demoModeController.addCallback(this);
         mStatusBarWindowController = statusBarWindowController;
         mScreenOffAnimationController = screenOffAnimationController;
         notificationListener.addNotificationSettingsListener(mSettingsListener);
@@ -163,7 +157,6 @@
         LayoutInflater layoutInflater = LayoutInflater.from(context);
         mNotificationIconArea = inflateIconArea(layoutInflater);
         mNotificationIcons = mNotificationIconArea.findViewById(R.id.notificationIcons);
-
     }
 
     /**
@@ -185,16 +178,6 @@
         updateIconLayoutParams(mContext);
     }
 
-    /**
-     * Update position of the view, with optional animation
-     */
-    public void updatePosition(int x, AnimationProperties props, boolean animate) {
-        if (mAodIcons != null) {
-            PropertyAnimator.setProperty(mAodIcons, AnimatableProperty.TRANSLATION_X, x, props,
-                    animate);
-        }
-    }
-
     public void setupShelf(NotificationShelfController notificationShelfController) {
         NotificationShelfController.assertRefactorFlagDisabled(mFeatureFlags);
         mShelfIcons = notificationShelfController.getShelfIcons();
@@ -239,7 +222,7 @@
 
     private void reloadDimens(Context context) {
         Resources res = context.getResources();
-        mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
+        mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size_sp);
         mIconHPadding = res.getDimensionPixelSize(R.dimen.status_bar_icon_horizontal_margin);
         mAodIconAppearTranslation = res.getDimensionPixelSize(
                 R.dimen.shelf_appear_translation);
@@ -303,6 +286,7 @@
         }
         return true;
     }
+
     /**
      * Updates the notifications with the given list of notifications to display.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index bef422c..3770c1d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -54,19 +54,13 @@
  * correctly on the screen.
  */
 public class NotificationIconContainer extends ViewGroup {
-    /**
-     * A float value indicating how much before the overflow start the icons should transform into
-     * a dot. A value of 0 means that they are exactly at the end and a value of 1 means it starts
-     * 1 icon width early.
-     */
-    public static final float OVERFLOW_EARLY_AMOUNT = 0.2f;
     private static final int NO_VALUE = Integer.MIN_VALUE;
     private static final String TAG = "NotificationIconContainer";
     private static final boolean DEBUG = false;
     private static final boolean DEBUG_OVERFLOW = false;
     private static final int CANNED_ANIMATION_DURATION = 100;
     private static final AnimationProperties DOT_ANIMATION_PROPERTIES = new AnimationProperties() {
-        private AnimationFilter mAnimationFilter = new AnimationFilter().animateX();
+        private final AnimationFilter mAnimationFilter = new AnimationFilter().animateX();
 
         @Override
         public AnimationFilter getAnimationFilter() {
@@ -75,7 +69,7 @@
     }.setDuration(200);
 
     private static final AnimationProperties ICON_ANIMATION_PROPERTIES = new AnimationProperties() {
-        private AnimationFilter mAnimationFilter = new AnimationFilter()
+        private final AnimationFilter mAnimationFilter = new AnimationFilter()
                 .animateX()
                 .animateY()
                 .animateAlpha()
@@ -92,7 +86,7 @@
      * Temporary AnimationProperties to avoid unnecessary allocations.
      */
     private static final AnimationProperties sTempProperties = new AnimationProperties() {
-        private AnimationFilter mAnimationFilter = new AnimationFilter();
+        private final AnimationFilter mAnimationFilter = new AnimationFilter();
 
         @Override
         public AnimationFilter getAnimationFilter() {
@@ -101,7 +95,7 @@
     };
 
     private static final AnimationProperties ADD_ICON_PROPERTIES = new AnimationProperties() {
-        private AnimationFilter mAnimationFilter = new AnimationFilter().animateAlpha();
+        private final AnimationFilter mAnimationFilter = new AnimationFilter().animateAlpha();
 
         @Override
         public AnimationFilter getAnimationFilter() {
@@ -115,7 +109,7 @@
      */
     private static final AnimationProperties UNISOLATION_PROPERTY_OTHERS
             = new AnimationProperties() {
-        private AnimationFilter mAnimationFilter = new AnimationFilter().animateAlpha();
+        private final AnimationFilter mAnimationFilter = new AnimationFilter().animateAlpha();
 
         @Override
         public AnimationFilter getAnimationFilter() {
@@ -128,7 +122,7 @@
      * This animates the translation back to the right position.
      */
     private static final AnimationProperties UNISOLATION_PROPERTY = new AnimationProperties() {
-        private AnimationFilter mAnimationFilter = new AnimationFilter().animateX();
+        private final AnimationFilter mAnimationFilter = new AnimationFilter().animateX();
 
         @Override
         public AnimationFilter getAnimationFilter() {
@@ -147,7 +141,6 @@
     private boolean mIsStaticLayout = true;
     private final HashMap<View, IconState> mIconStates = new HashMap<>();
     private int mDotPadding;
-    private int mStaticDotRadius;
     private int mStaticDotDiameter;
     private int mActualLayoutWidth = NO_VALUE;
     private float mActualPaddingEnd = NO_VALUE;
@@ -170,7 +163,7 @@
     private boolean mIsShowingOverflowDot;
     private StatusBarIconView mIsolatedIcon;
     private Rect mIsolatedIconLocation;
-    private int[] mAbsolutePosition = new int[2];
+    private final int[] mAbsolutePosition = new int[2];
     private View mIsolatedIconForAnimation;
     private int mThemedTextColorPrimary;
 
@@ -186,8 +179,8 @@
         mMaxStaticIcons = getResources().getInteger(R.integer.max_notif_static_icons);
 
         mDotPadding = getResources().getDimensionPixelSize(R.dimen.overflow_icon_dot_padding);
-        mStaticDotRadius = getResources().getDimensionPixelSize(R.dimen.overflow_dot_radius);
-        mStaticDotDiameter = 2 * mStaticDotRadius;
+        int staticDotRadius = getResources().getDimensionPixelSize(R.dimen.overflow_dot_radius);
+        mStaticDotDiameter = 2 * staticDotRadius;
 
         final Context themedContext = new ContextThemeWrapper(getContext(),
                 com.android.internal.R.style.Theme_DeviceDefault_DayNight);
@@ -339,6 +332,7 @@
             }
         }
         if (child instanceof StatusBarIconView) {
+            ((StatusBarIconView) child).updateIconDimens();
             ((StatusBarIconView) child).setDozing(mDozing, false, 0);
         }
     }
@@ -447,9 +441,14 @@
     @VisibleForTesting
     boolean isOverflowing(boolean isLastChild, float translationX, float layoutEnd,
             float iconSize) {
-        // Layout end, as used here, does not include padding end.
-        final float overflowX = isLastChild ? layoutEnd : layoutEnd - iconSize;
-        return translationX >= overflowX;
+        if (isLastChild) {
+            return translationX + iconSize > layoutEnd;
+        } else {
+            // If the child is not the last child, we need to ensure that we have room for the next
+            // icon and the dot. The dot could be as large as an icon, so verify that we have room
+            // for 2 icons.
+            return translationX + iconSize * 2f > layoutEnd;
+        }
     }
 
     /**
@@ -489,10 +488,7 @@
             // First icon to overflow.
             if (firstOverflowIndex == -1 && isOverflowing) {
                 firstOverflowIndex = i;
-                mVisualOverflowStart = layoutEnd - mIconSize;
-                if (forceOverflow || mIsStaticLayout) {
-                    mVisualOverflowStart = Math.min(translationX, mVisualOverflowStart);
-                }
+                mVisualOverflowStart = translationX;
             }
             final float drawingScale = mOnLockScreen && view instanceof StatusBarIconView
                     ? ((StatusBarIconView) view).getIconScaleIncreased()
@@ -537,9 +533,10 @@
             IconState iconState = mIconStates.get(mIsolatedIcon);
             if (iconState != null) {
                 // Most of the time the icon isn't yet added when this is called but only happening
-                // later
-                iconState.setXTranslation(mIsolatedIconLocation.left - mAbsolutePosition[0]
-                        - (1 - mIsolatedIcon.getIconScale()) * mIsolatedIcon.getWidth() / 2.0f);
+                // later. The isolated icon position left should equal to the mIsolatedIconLocation
+                // to ensure the icon be put at the center of the HUN icon placeholder,
+                // {@See HeadsUpAppearanceController#updateIsolatedIconLocation}.
+                iconState.setXTranslation(mIsolatedIconLocation.left - mAbsolutePosition[0]);
                 iconState.visibleState = StatusBarIconView.STATE_ICON;
             }
         }
@@ -695,7 +692,6 @@
     }
 
     public class IconState extends ViewState {
-        public static final int NO_VALUE = NotificationIconContainer.NO_VALUE;
         public float iconAppearAmount = 1.0f;
         public float clampedAppearAmount = 1.0f;
         public int visibleState;
@@ -813,8 +809,6 @@
                     super.applyToView(view);
                 }
                 sTempProperties.setAnimationEndAction(null);
-                boolean inShelf = iconAppearAmount == 1.0f;
-                icon.setIsInShelf(inShelf);
             }
             justAdded = false;
             justReplaced = false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index c16e13c..e4e912e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -52,6 +52,7 @@
 import com.android.systemui.Dumpable;
 import com.android.systemui.R;
 import com.android.systemui.animation.ShadeInterpolation;
+import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dock.DockManager;
@@ -59,7 +60,6 @@
 import com.android.systemui.flags.Flags;
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
-import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants;
 import com.android.systemui.keyguard.shared.model.ScrimAlpha;
 import com.android.systemui.keyguard.shared.model.TransitionState;
 import com.android.systemui.keyguard.shared.model.TransitionStep;
@@ -1492,6 +1492,13 @@
             mColors.setSupportsDarkText(
                     ColorUtils.calculateContrast(mColors.getMainColor(), Color.WHITE) > 4.5);
         }
+
+        int surface = Utils.getColorAttr(mScrimBehind.getContext(),
+                com.android.internal.R.attr.materialColorSurface).getDefaultColor();
+        for (ScrimState state : ScrimState.values()) {
+            state.setSurfaceColor(surface);
+        }
+
         mNeedsDrawableColorUpdate = true;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index 7b20283..e3b65ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -122,11 +122,19 @@
         @Override
         public void prepare(ScrimState previousState) {
             mBehindAlpha = mClipQsScrim ? 1 : mDefaultScrimAlpha;
-            mBehindTint = mClipQsScrim ? Color.BLACK : Color.TRANSPARENT;
+            mBehindTint = mClipQsScrim ? Color.BLACK : mSurfaceColor;
             mNotifAlpha = mClipQsScrim ? mDefaultScrimAlpha : 0;
             mNotifTint = Color.TRANSPARENT;
             mFrontAlpha = 0f;
         }
+
+        @Override
+        public void setSurfaceColor(int surfaceColor) {
+            super.setSurfaceColor(surfaceColor);
+            if (!mClipQsScrim) {
+                mBehindTint = mSurfaceColor;
+            }
+        }
     },
 
     /**
@@ -295,6 +303,7 @@
     int mFrontTint = Color.TRANSPARENT;
     int mBehindTint = Color.TRANSPARENT;
     int mNotifTint = Color.TRANSPARENT;
+    int mSurfaceColor = Color.TRANSPARENT;
 
     boolean mAnimateChange = true;
     float mAodFrontScrimAlpha;
@@ -409,6 +418,10 @@
         mDefaultScrimAlpha = defaultScrimAlpha;
     }
 
+    public void setSurfaceColor(int surfaceColor) {
+        mSurfaceColor = surfaceColor;
+    }
+
     public void setWallpaperSupportsAmbientMode(boolean wallpaperSupportsAmbientMode) {
         mWallpaperSupportsAmbientMode = wallpaperSupportsAmbientMode;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index b14fe90..59583dd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -370,7 +370,7 @@
         private final MobileIconsViewModel mMobileIconsViewModel;
 
         protected final Context mContext;
-        protected final int mIconSize;
+        protected int mIconSize;
         // Whether or not these icons show up in dumpsys
         protected boolean mShouldLog = false;
         private StatusBarIconController mController;
@@ -395,10 +395,10 @@
             mStatusBarPipelineFlags = statusBarPipelineFlags;
             mMobileContextProvider = mobileContextProvider;
             mContext = group.getContext();
-            mIconSize = mContext.getResources().getDimensionPixelSize(
-                    com.android.internal.R.dimen.status_bar_icon_size);
             mLocation = location;
 
+            reloadDimens();
+
             if (statusBarPipelineFlags.runNewMobileIconsBackend()) {
                 // This starts the flow for the new pipeline, and will notify us of changes if
                 // {@link StatusBarPipelineFlags#useNewMobileIcons} is also true.
@@ -609,13 +609,9 @@
             mGroup.removeAllViews();
         }
 
-        protected void onDensityOrFontScaleChanged() {
-            for (int i = 0; i < mGroup.getChildCount(); i++) {
-                View child = mGroup.getChildAt(i);
-                LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
-                        ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize);
-                child.setLayoutParams(lp);
-            }
+        protected void reloadDimens() {
+            mIconSize = mContext.getResources().getDimensionPixelSize(
+                    com.android.internal.R.dimen.status_bar_icon_size_sp);
         }
 
         private void setHeightAndCenter(ImageView imageView, int height) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
index 3a18423..80d5651 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
@@ -109,6 +109,7 @@
         }
 
         group.setController(this);
+        group.reloadDimens();
         mIconGroups.add(group);
         List<Slot> allSlots = mStatusBarIconList.getSlots();
         for (int i = 0; i < allSlots.size(); i++) {
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 cb2a78d..5c1dfbe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -51,6 +51,7 @@
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.keyguard.KeyguardViewController;
+import com.android.keyguard.TrustGrantFlags;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor;
 import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
@@ -306,6 +307,16 @@
     @Nullable private TaskbarDelegate mTaskbarDelegate;
     private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
             new KeyguardUpdateMonitorCallback() {
+                @Override
+                public void onTrustGrantedForCurrentUser(
+                        boolean dismissKeyguard,
+                        boolean newlyUnlocked,
+                        @NonNull TrustGrantFlags flags,
+                        @Nullable String message
+                ) {
+                    updateAlternateBouncerShowing(mAlternateBouncerInteractor.maybeHide());
+                }
+
         @Override
         public void onEmergencyCallAction() {
             // Since we won't get a setOccluded call we have to reset the view manually such that
@@ -431,7 +442,6 @@
             mDockManager.addListener(mDockEventListener);
             mIsDocked = mDockManager.isDocked();
         }
-        mKeyguardStateController.addCallback(mKeyguardStateControllerCallback);
     }
 
     /** Register a callback, to be invoked by the Predictive Back system. */
@@ -1570,14 +1580,6 @@
                 || mode == KeyguardSecurityModel.SecurityMode.SimPuk;
     }
 
-    private KeyguardStateController.Callback mKeyguardStateControllerCallback =
-            new KeyguardStateController.Callback() {
-        @Override
-        public void onUnlockedChanged() {
-            updateAlternateBouncerShowing(mAlternateBouncerInteractor.maybeHide());
-        }
-    };
-
     /**
      * Delegate used to send show and hide events to an alternate authentication method instead of
      * the regular pin/pattern/password bouncer.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
index 604b1f5..d83664f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
@@ -22,6 +22,8 @@
 
 import android.annotation.Nullable;
 import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
@@ -73,13 +75,16 @@
     // Any ignored icon will never be added as a child
     private ArrayList<String> mIgnoredSlots = new ArrayList<>();
 
+    private Configuration mConfiguration;
+
     public StatusIconContainer(Context context) {
         this(context, null);
     }
 
     public StatusIconContainer(Context context, AttributeSet attrs) {
         super(context, attrs);
-        initDimens();
+        mConfiguration = new Configuration(context.getResources().getConfiguration());
+        reloadDimens();
         setWillNotDraw(!DEBUG_OVERFLOW);
     }
 
@@ -100,10 +105,10 @@
         return mShouldRestrictIcons;
     }
 
-    private void initDimens() {
+    private void reloadDimens() {
         // This is the same value that StatusBarIconView uses
         mIconDotFrameWidth = getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.status_bar_icon_size);
+                com.android.internal.R.dimen.status_bar_icon_size_sp);
         mDotPadding = getResources().getDimensionPixelSize(R.dimen.overflow_icon_dot_padding);
         mIconSpacing = getResources().getDimensionPixelSize(R.dimen.status_bar_system_icon_spacing);
         int radius = getResources().getDimensionPixelSize(R.dimen.overflow_dot_radius);
@@ -233,6 +238,16 @@
         child.setTag(R.id.status_bar_view_state_tag, null);
     }
 
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        final int configDiff = newConfig.diff(mConfiguration);
+        mConfiguration.setTo(newConfig);
+        if ((configDiff & (ActivityInfo.CONFIG_DENSITY | ActivityInfo.CONFIG_FONT_SCALE)) != 0) {
+            reloadDimens();
+        }
+    }
+
     /**
      * Add a name of an icon slot to be ignored. It will not show up nor be measured
      * @param slotName name of the icon as it exists in
@@ -342,13 +357,17 @@
         int totalVisible = mLayoutStates.size();
         int maxVisible = totalVisible <= MAX_ICONS ? MAX_ICONS : MAX_ICONS - 1;
 
-        mUnderflowStart = 0;
+        // Init mUnderflowStart value with the offset to let the dot be placed next to battery icon.
+        // This is to prevent if the underflow happens at rightest(totalVisible - 1) child then
+        // break the for loop with mUnderflowStart staying 0(initial value), causing the dot be
+        // placed at the leftest side.
+        mUnderflowStart = (int) Math.max(contentStart, width - getPaddingEnd() - mUnderflowWidth);
         int visible = 0;
         int firstUnderflowIndex = -1;
         for (int i = totalVisible - 1; i >= 0; i--) {
             StatusIconState state = mLayoutStates.get(i);
             // Allow room for underflow if we found we need it in onMeasure
-            if (mNeedsUnderflow && (state.getXTranslation() < (contentStart + mUnderflowWidth))
+            if ((mNeedsUnderflow && (state.getXTranslation() < (contentStart + mUnderflowWidth)))
                     || (mShouldRestrictIcons && (visible >= maxVisible))) {
                 firstUnderflowIndex = i;
                 break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt
index 1a13404..8373854 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt
@@ -118,7 +118,7 @@
                 it.visibleState = STATE_DOT
             }
 
-        val width = mContext.resources.getDimensionPixelSize(R.dimen.status_bar_icon_size)
+        val width = mContext.resources.getDimensionPixelSize(R.dimen.status_bar_icon_size_sp)
         val lp = LayoutParams(width, width)
         lp.gravity = Gravity.CENTER_VERTICAL or Gravity.START
         addView(dotView, lp)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt
index 4e52be9..7f35dfb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt
@@ -34,6 +34,7 @@
 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.dagger.qualifiers.Main
 import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.log.table.logDiffsForTable
@@ -48,6 +49,7 @@
 import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
 import java.util.concurrent.Executor
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.channels.awaitClose
@@ -60,7 +62,9 @@
 import kotlinx.coroutines.flow.mapLatest
 import kotlinx.coroutines.flow.merge
 import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.withContext
 
 /** Real implementation of [WifiRepository]. */
 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
@@ -76,8 +80,9 @@
     logger: WifiInputLogger,
     @WifiTableLog wifiTableLogBuffer: TableLogBuffer,
     @Main mainExecutor: Executor,
+    @Background private val bgDispatcher: CoroutineDispatcher,
     @Application scope: CoroutineScope,
-    wifiManager: WifiManager,
+    private val wifiManager: WifiManager,
 ) : RealWifiRepository {
 
     private val wifiStateChangeEvents: Flow<Unit> =
@@ -93,20 +98,25 @@
     // have changed.
     override val isWifiEnabled: StateFlow<Boolean> =
         merge(wifiNetworkChangeEvents, wifiStateChangeEvents)
-            .mapLatest { wifiManager.isWifiEnabled }
+            .onStart { emit(Unit) }
+            .mapLatest { isWifiEnabled() }
             .distinctUntilChanged()
             .logDiffsForTable(
                 wifiTableLogBuffer,
                 columnPrefix = "",
                 columnName = "isEnabled",
-                initialValue = wifiManager.isWifiEnabled,
+                initialValue = false,
             )
             .stateIn(
                 scope = scope,
-                started = SharingStarted.WhileSubscribed(),
-                initialValue = wifiManager.isWifiEnabled,
+                started = SharingStarted.Eagerly,
+                initialValue = false,
             )
 
+    // [WifiManager.isWifiEnabled] is a blocking IPC call, so fetch it in the background.
+    private suspend fun isWifiEnabled(): Boolean =
+        withContext(bgDispatcher) { wifiManager.isWifiEnabled }
+
     override val isWifiDefault: StateFlow<Boolean> =
         connectivityRepository.defaultConnections
             // TODO(b/274493701): Should wifi be considered default if it's carrier merged?
@@ -289,6 +299,7 @@
         private val logger: WifiInputLogger,
         @WifiTableLog private val wifiTableLogBuffer: TableLogBuffer,
         @Main private val mainExecutor: Executor,
+        @Background private val bgDispatcher: CoroutineDispatcher,
         @Application private val scope: CoroutineScope,
     ) {
         fun create(wifiManager: WifiManager): WifiRepositoryImpl {
@@ -299,6 +310,7 @@
                 logger,
                 wifiTableLogBuffer,
                 mainExecutor,
+                bgDispatcher,
                 scope,
                 wifiManager,
             )
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index 6875b52..f994372 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -374,6 +374,13 @@
 
     @Override
     public void onDensityOrFontScaleChanged() {
+        reloadDimens();
+    }
+
+    private void reloadDimens() {
+        // reset mCachedWidth so the new width would be updated properly when next onMeasure
+        mCachedWidth = -1;
+
         FontSizeUtils.updateFontSize(this, R.dimen.status_bar_clock_size);
         setPaddingRelative(
                 mContext.getResources().getDimensionPixelSize(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt
index 22b4c9d..736b145 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.policy
 
+import android.app.ActivityOptions
 import android.app.Notification
 import android.app.PendingIntent
 import android.app.RemoteInput
@@ -275,7 +276,10 @@
                 entry.sbn.instanceId)
 
         try {
-            pendingIntent.send(view.context, 0, intent)
+            val options = ActivityOptions.makeBasic()
+            options.setPendingIntentBackgroundActivityStartMode(
+                    ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
+            pendingIntent.send(view.context, 0, intent, null, null, null, options.toBundle())
         } catch (e: PendingIntent.CanceledException) {
             Log.i(TAG, "Unable to send remote input result", e)
             uiEventLogger.logWithInstanceId(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt
index cac5e32..1776e5b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.policy
 
+import android.app.ActivityOptions
 import android.app.Notification
 import android.app.Notification.Action.SEMANTIC_ACTION_MARK_CONVERSATION_AS_PRIORITY
 import android.app.PendingIntent
@@ -491,7 +492,11 @@
             entry.setHasSentReply()
             try {
                 val intent = createRemoteInputIntent(smartReplies, choice)
-                smartReplies.pendingIntent.send(context, 0, intent)
+                val opts = ActivityOptions.makeBasic()
+                opts.setPendingIntentBackgroundActivityStartMode(
+                        ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
+                smartReplies.pendingIntent.send(context, 0, intent, /* onFinished */null,
+                        /* handler */ null, /* requiredPermission */ null, opts.toBundle())
             } catch (e: PendingIntent.CanceledException) {
                 Log.w(TAG, "Unable to send smart reply", e)
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationAdapter.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationAdapter.java
index 3362097..fd7c30f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationAdapter.java
@@ -103,6 +103,8 @@
                 if (mPendingIntent != null) {
                     BroadcastOptions options = BroadcastOptions.makeBasic();
                     options.setInteractive(true);
+                    options.setPendingIntentBackgroundActivityStartMode(
+                            BroadcastOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
                     mPendingIntent.send(options.toBundle());
                 }
             } catch (PendingIntent.CanceledException e) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java
index 4a9921e..bcf3b0c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java
@@ -240,10 +240,8 @@
                     Insets.of(0, safeTouchRegionHeight, 0, 0));
         }
         lp.providedInsets = new InsetsFrameProvider[] {
-                new InsetsFrameProvider(mInsetsSourceOwner, 0, statusBars())
-                        .setInsetsSize(Insets.of(0, height, 0, 0)),
-                new InsetsFrameProvider(mInsetsSourceOwner, 0, tappableElement())
-                        .setInsetsSize(Insets.of(0, height, 0, 0)),
+                new InsetsFrameProvider(mInsetsSourceOwner, 0, statusBars()),
+                new InsetsFrameProvider(mInsetsSourceOwner, 0, tappableElement()),
                 gestureInsetsProvider
         };
         return lp;
diff --git a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt
index a487f53..4d506f0 100644
--- a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt
@@ -27,6 +27,7 @@
 import android.graphics.drawable.BitmapDrawable
 import android.graphics.drawable.Drawable
 import android.graphics.drawable.Icon
+import android.os.Process
 import android.os.RemoteException
 import android.os.UserHandle
 import android.os.UserManager
@@ -334,6 +335,7 @@
                 onBroadcastReceived(intent, previousSelectedUser)
             }
             .launchIn(applicationScope)
+        restartSecondaryService(repository.getSelectedUserInfo().id)
         keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
     }
 
@@ -530,6 +532,12 @@
         }
     }
 
+    /** Returns the ID of the currently-selected user. */
+    @UserIdInt
+    fun getSelectedUserId(): Int {
+        return repository.getSelectedUserInfo().id
+    }
+
     private fun showDialog(request: ShowDialogRequestModel) {
         _dialogShowRequests.value = request
     }
@@ -646,7 +654,7 @@
 
         // Connect to the new secondary user's service (purely to ensure that a persistent
         // SystemUI application is created for that user)
-        if (userId != UserHandle.USER_SYSTEM) {
+        if (userId != Process.myUserHandle().identifier) {
             applicationContext.startServiceAsUser(
                 intent,
                 UserHandle.of(userId),
@@ -772,17 +780,16 @@
         }
 
         // TODO(b/246631653): cache the bitmaps to avoid the background work to fetch them.
-        val userIcon = withContext(backgroundDispatcher) {
-            manager.getUserIcon(userId)
-                ?.let { bitmap ->
+        val userIcon =
+            withContext(backgroundDispatcher) {
+                manager.getUserIcon(userId)?.let { bitmap ->
                     val iconSize =
-                        applicationContext
-                            .resources
-                            .getDimensionPixelSize(R.dimen.bouncer_user_switcher_icon_size)
+                        applicationContext.resources.getDimensionPixelSize(
+                            R.dimen.bouncer_user_switcher_icon_size
+                        )
                     Icon.scaleDownIfNecessary(bitmap, iconSize, iconSize)
                 }
-        }
-
+            }
 
         if (userIcon != null) {
             return BitmapDrawable(userIcon)
diff --git a/packages/SystemUI/src/com/android/systemui/util/wrapper/LottieViewWrapper.kt b/packages/SystemUI/src/com/android/systemui/util/wrapper/LottieViewWrapper.kt
new file mode 100644
index 0000000..a804923
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/wrapper/LottieViewWrapper.kt
@@ -0,0 +1,39 @@
+/*
+ * 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.util.wrapper
+
+import android.content.Context
+import android.util.AttributeSet
+import com.airbnb.lottie.LottieAnimationView
+import com.android.systemui.util.traceSection
+
+/** LottieAnimationView that traces each call to invalidate. */
+open class LottieViewWrapper : LottieAnimationView {
+    constructor(context: Context?) : super(context)
+    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
+    constructor(
+        context: Context?,
+        attrs: AttributeSet?,
+        defStyleAttr: Int
+    ) : super(context, attrs, defStyleAttr)
+
+    override fun invalidate() {
+        traceSection<Any?>("${this::class} invalidate") {
+            super.invalidate()
+            null
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
index 2318988..b67f280 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
@@ -18,7 +18,8 @@
 import android.content.BroadcastReceiver
 import android.testing.AndroidTestingRunner
 import android.view.View
-import android.widget.TextView
+import android.view.ViewTreeObserver
+import android.widget.FrameLayout
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
@@ -83,7 +84,13 @@
     @Mock private lateinit var bgExecutor: Executor
     @Mock private lateinit var featureFlags: FeatureFlags
     @Mock private lateinit var smallClockController: ClockFaceController
+    @Mock private lateinit var smallClockView: View
+    @Mock private lateinit var smallClockViewTreeObserver: ViewTreeObserver
+    @Mock private lateinit var smallClockFrame: FrameLayout
+    @Mock private lateinit var smallClockFrameViewTreeObserver: ViewTreeObserver
     @Mock private lateinit var largeClockController: ClockFaceController
+    @Mock private lateinit var largeClockView: View
+    @Mock private lateinit var largeClockViewTreeObserver: ViewTreeObserver
     @Mock private lateinit var smallClockEvents: ClockFaceEvents
     @Mock private lateinit var largeClockEvents: ClockFaceEvents
     @Mock private lateinit var parentView: View
@@ -99,8 +106,12 @@
     fun setUp() {
         whenever(clock.smallClock).thenReturn(smallClockController)
         whenever(clock.largeClock).thenReturn(largeClockController)
-        whenever(smallClockController.view).thenReturn(TextView(context))
-        whenever(largeClockController.view).thenReturn(TextView(context))
+        whenever(smallClockController.view).thenReturn(smallClockView)
+        whenever(smallClockView.parent).thenReturn(smallClockFrame)
+        whenever(smallClockView.viewTreeObserver).thenReturn(smallClockViewTreeObserver)
+        whenever(smallClockFrame.viewTreeObserver).thenReturn(smallClockFrameViewTreeObserver)
+        whenever(largeClockController.view).thenReturn(largeClockView)
+        whenever(largeClockView.viewTreeObserver).thenReturn(largeClockViewTreeObserver)
         whenever(smallClockController.events).thenReturn(smallClockEvents)
         whenever(largeClockController.events).thenReturn(largeClockEvents)
         whenever(clock.events).thenReturn(events)
@@ -302,8 +313,38 @@
         verify(configurationController).removeCallback(any())
         verify(batteryController).removeCallback(any())
         verify(keyguardUpdateMonitor).removeCallback(any())
+        verify(smallClockController.view)
+                .removeOnAttachStateChangeListener(underTest.smallClockOnAttachStateChangeListener)
+        verify(largeClockController.view)
+                .removeOnAttachStateChangeListener(underTest.largeClockOnAttachStateChangeListener)
     }
 
+    @Test
+    fun registerOnAttachStateChangeListener_validate() = runBlocking(IMMEDIATE) {
+        verify(smallClockController.view)
+            .addOnAttachStateChangeListener(underTest.smallClockOnAttachStateChangeListener)
+        verify(largeClockController.view)
+            .addOnAttachStateChangeListener(underTest.largeClockOnAttachStateChangeListener)
+    }
+
+    @Test
+    fun registerAndRemoveOnGlobalLayoutListener_correctly() = runBlocking(IMMEDIATE) {
+        underTest.smallClockOnAttachStateChangeListener!!.onViewAttachedToWindow(smallClockView)
+        verify(smallClockFrame.viewTreeObserver).addOnGlobalLayoutListener(any())
+        underTest.smallClockOnAttachStateChangeListener!!.onViewDetachedFromWindow(smallClockView)
+        verify(smallClockFrame.viewTreeObserver).removeOnGlobalLayoutListener(any())
+    }
+
+    @Test
+    fun registerOnGlobalLayoutListener_RemoveOnAttachStateChangeListener_correctly() =
+        runBlocking(IMMEDIATE) {
+            underTest.smallClockOnAttachStateChangeListener!!
+                .onViewAttachedToWindow(smallClockView)
+            verify(smallClockFrame.viewTreeObserver).addOnGlobalLayoutListener(any())
+            underTest.unregisterListeners()
+            verify(smallClockFrame.viewTreeObserver).removeOnGlobalLayoutListener(any())
+        }
+
     companion object {
         private val IMMEDIATE = Dispatchers.Main.immediate
     }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java
new file mode 100644
index 0000000..ac04bc4
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java
@@ -0,0 +1,210 @@
+/*
+ * 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 static android.view.View.INVISIBLE;
+
+import static com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR;
+import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.res.Resources;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.FakeFeatureFlags;
+import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory;
+import com.android.systemui.log.LogBuffer;
+import com.android.systemui.plugins.ClockAnimations;
+import com.android.systemui.plugins.ClockController;
+import com.android.systemui.plugins.ClockEvents;
+import com.android.systemui.plugins.ClockFaceConfig;
+import com.android.systemui.plugins.ClockFaceController;
+import com.android.systemui.plugins.ClockFaceEvents;
+import com.android.systemui.plugins.ClockTickRate;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shared.clocks.AnimatableClockView;
+import com.android.systemui.shared.clocks.ClockRegistry;
+import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController;
+import com.android.systemui.statusbar.phone.NotificationIconAreaController;
+import com.android.systemui.statusbar.phone.NotificationIconContainer;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.settings.SecureSettings;
+import com.android.systemui.util.time.FakeSystemClock;
+
+import org.junit.Before;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class KeyguardClockSwitchControllerBaseTest extends SysuiTestCase {
+
+    @Mock
+    protected KeyguardClockSwitch mView;
+    @Mock
+    protected StatusBarStateController mStatusBarStateController;
+    @Mock
+    protected ClockRegistry mClockRegistry;
+    @Mock
+    KeyguardSliceViewController mKeyguardSliceViewController;
+    @Mock
+    NotificationIconAreaController mNotificationIconAreaController;
+    @Mock
+    LockscreenSmartspaceController mSmartspaceController;
+
+    @Mock
+    Resources mResources;
+    @Mock
+    KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
+    @Mock
+    protected ClockController mClockController;
+    @Mock
+    protected ClockFaceController mLargeClockController;
+    @Mock
+    protected ClockFaceController mSmallClockController;
+    @Mock
+    protected ClockAnimations mClockAnimations;
+    @Mock
+    protected ClockEvents mClockEvents;
+    @Mock
+    protected ClockFaceEvents mClockFaceEvents;
+    @Mock
+    DumpManager mDumpManager;
+    @Mock
+    ClockEventController mClockEventController;
+
+    @Mock
+    protected NotificationIconContainer mNotificationIcons;
+    @Mock
+    protected AnimatableClockView mSmallClockView;
+    @Mock
+    protected AnimatableClockView mLargeClockView;
+    @Mock
+    protected FrameLayout mSmallClockFrame;
+    @Mock
+    protected FrameLayout mLargeClockFrame;
+    @Mock
+    protected SecureSettings mSecureSettings;
+    @Mock
+    protected LogBuffer mLogBuffer;
+
+    protected final View mFakeDateView = (View) (new ViewGroup(mContext) {
+        @Override
+        protected void onLayout(boolean changed, int l, int t, int r, int b) {}
+    });
+    protected final View mFakeWeatherView = new View(mContext);
+    protected final View mFakeSmartspaceView = new View(mContext);
+
+    protected KeyguardClockSwitchController mController;
+    protected View mSliceView;
+    protected LinearLayout mStatusArea;
+    protected FakeExecutor mExecutor;
+    protected FakeFeatureFlags mFakeFeatureFlags;
+    @Captor protected ArgumentCaptor<View.OnAttachStateChangeListener> mAttachCaptor =
+            ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class);
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+
+        when(mView.findViewById(R.id.left_aligned_notification_icon_container))
+                .thenReturn(mNotificationIcons);
+        when(mNotificationIcons.getLayoutParams()).thenReturn(
+                mock(RelativeLayout.LayoutParams.class));
+        when(mView.getContext()).thenReturn(getContext());
+        when(mView.getResources()).thenReturn(mResources);
+        when(mResources.getDimensionPixelSize(R.dimen.keyguard_clock_top_margin))
+                .thenReturn(100);
+        when(mResources.getDimensionPixelSize(R.dimen.keyguard_large_clock_top_margin))
+                .thenReturn(-200);
+        when(mResources.getInteger(R.integer.keyguard_date_weather_view_invisibility))
+                .thenReturn(INVISIBLE);
+
+        when(mView.findViewById(R.id.lockscreen_clock_view_large)).thenReturn(mLargeClockFrame);
+        when(mView.findViewById(R.id.lockscreen_clock_view)).thenReturn(mSmallClockFrame);
+        when(mSmallClockView.getContext()).thenReturn(getContext());
+        when(mLargeClockView.getContext()).thenReturn(getContext());
+
+        when(mView.isAttachedToWindow()).thenReturn(true);
+        when(mSmartspaceController.buildAndConnectDateView(any())).thenReturn(mFakeDateView);
+        when(mSmartspaceController.buildAndConnectWeatherView(any())).thenReturn(mFakeWeatherView);
+        when(mSmartspaceController.buildAndConnectView(any())).thenReturn(mFakeSmartspaceView);
+        mExecutor = new FakeExecutor(new FakeSystemClock());
+        mFakeFeatureFlags = new FakeFeatureFlags();
+        mFakeFeatureFlags.set(FACE_AUTH_REFACTOR, false);
+        mFakeFeatureFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false);
+        mController = new KeyguardClockSwitchController(
+                mView,
+                mStatusBarStateController,
+                mClockRegistry,
+                mKeyguardSliceViewController,
+                mNotificationIconAreaController,
+                mSmartspaceController,
+                mKeyguardUnlockAnimationController,
+                mSecureSettings,
+                mExecutor,
+                mDumpManager,
+                mClockEventController,
+                mLogBuffer,
+                KeyguardInteractorFactory.create(mFakeFeatureFlags).getKeyguardInteractor(),
+                mFakeFeatureFlags
+        );
+
+        when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
+        when(mLargeClockController.getView()).thenReturn(mLargeClockView);
+        when(mSmallClockController.getView()).thenReturn(mSmallClockView);
+        when(mClockController.getLargeClock()).thenReturn(mLargeClockController);
+        when(mClockController.getSmallClock()).thenReturn(mSmallClockController);
+        when(mClockController.getEvents()).thenReturn(mClockEvents);
+        when(mSmallClockController.getEvents()).thenReturn(mClockFaceEvents);
+        when(mLargeClockController.getEvents()).thenReturn(mClockFaceEvents);
+        when(mLargeClockController.getAnimations()).thenReturn(mClockAnimations);
+        when(mSmallClockController.getAnimations()).thenReturn(mClockAnimations);
+        when(mClockRegistry.createCurrentClock()).thenReturn(mClockController);
+        when(mClockEventController.getClock()).thenReturn(mClockController);
+        when(mSmallClockController.getConfig())
+                .thenReturn(new ClockFaceConfig(ClockTickRate.PER_MINUTE, false, false));
+        when(mLargeClockController.getConfig())
+                .thenReturn(new ClockFaceConfig(ClockTickRate.PER_MINUTE, false, false));
+
+        mSliceView = new View(getContext());
+        when(mView.findViewById(R.id.keyguard_slice_view)).thenReturn(mSliceView);
+        mStatusArea = new LinearLayout(getContext());
+        when(mView.findViewById(R.id.keyguard_status_area)).thenReturn(mStatusArea);
+    }
+
+    protected void init() {
+        mController.init();
+
+        verify(mView, atLeast(1)).addOnAttachStateChangeListener(mAttachCaptor.capture());
+        mAttachCaptor.getValue().onViewAttachedToWindow(mView);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
index 9e561ed..e64ef04 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
@@ -21,186 +21,33 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.eq;
-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.content.res.Resources;
 import android.database.ContentObserver;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.testing.AndroidTestingRunner;
 import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-import android.widget.RelativeLayout;
 
 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.keyguard.KeyguardUnlockAnimationController;
-import com.android.systemui.log.LogBuffer;
-import com.android.systemui.plugins.ClockAnimations;
-import com.android.systemui.plugins.ClockController;
-import com.android.systemui.plugins.ClockEvents;
 import com.android.systemui.plugins.ClockFaceConfig;
-import com.android.systemui.plugins.ClockFaceController;
-import com.android.systemui.plugins.ClockFaceEvents;
 import com.android.systemui.plugins.ClockTickRate;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.shared.clocks.AnimatableClockView;
 import com.android.systemui.shared.clocks.ClockRegistry;
 import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController;
-import com.android.systemui.statusbar.phone.NotificationIconAreaController;
-import com.android.systemui.statusbar.phone.NotificationIconContainer;
-import com.android.systemui.util.concurrency.FakeExecutor;
-import com.android.systemui.util.settings.SecureSettings;
-import com.android.systemui.util.time.FakeSystemClock;
 
-import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
 import org.mockito.verification.VerificationMode;
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
-public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
-
-    @Mock
-    private KeyguardClockSwitch mView;
-    @Mock
-    private StatusBarStateController mStatusBarStateController;
-    @Mock
-    private ClockRegistry mClockRegistry;
-    @Mock
-    KeyguardSliceViewController mKeyguardSliceViewController;
-    @Mock
-    NotificationIconAreaController mNotificationIconAreaController;
-    @Mock
-    LockscreenSmartspaceController mSmartspaceController;
-
-    @Mock
-    Resources mResources;
-    @Mock
-    KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
-    @Mock
-    private ClockController mClockController;
-    @Mock
-    private ClockFaceController mLargeClockController;
-    @Mock
-    private ClockFaceController mSmallClockController;
-    @Mock
-    private ClockAnimations mClockAnimations;
-    @Mock
-    private ClockEvents mClockEvents;
-    @Mock
-    private ClockFaceEvents mClockFaceEvents;
-    @Mock
-    DumpManager mDumpManager;
-    @Mock
-    ClockEventController mClockEventController;
-
-    @Mock
-    private NotificationIconContainer mNotificationIcons;
-    @Mock
-    private AnimatableClockView mSmallClockView;
-    @Mock
-    private AnimatableClockView mLargeClockView;
-    @Mock
-    private FrameLayout mSmallClockFrame;
-    @Mock
-    private FrameLayout mLargeClockFrame;
-    @Mock
-    private SecureSettings mSecureSettings;
-    @Mock
-    private LogBuffer mLogBuffer;
-
-    private final View mFakeDateView = (View) (new ViewGroup(mContext) {
-        @Override
-        protected void onLayout(boolean changed, int l, int t, int r, int b) {}
-    });
-    private final View mFakeWeatherView = new View(mContext);
-    private final View mFakeSmartspaceView = new View(mContext);
-
-    private KeyguardClockSwitchController mController;
-    private View mSliceView;
-    private FakeExecutor mExecutor;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-
-        when(mView.findViewById(R.id.left_aligned_notification_icon_container))
-                .thenReturn(mNotificationIcons);
-        when(mNotificationIcons.getLayoutParams()).thenReturn(
-                mock(RelativeLayout.LayoutParams.class));
-        when(mView.getContext()).thenReturn(getContext());
-        when(mView.getResources()).thenReturn(mResources);
-        when(mResources.getDimensionPixelSize(R.dimen.keyguard_clock_top_margin))
-                .thenReturn(100);
-        when(mResources.getDimensionPixelSize(R.dimen.keyguard_large_clock_top_margin))
-                .thenReturn(-200);
-        when(mResources.getInteger(R.integer.keyguard_date_weather_view_invisibility))
-                .thenReturn(View.INVISIBLE);
-
-        when(mView.findViewById(R.id.lockscreen_clock_view_large)).thenReturn(mLargeClockFrame);
-        when(mView.findViewById(R.id.lockscreen_clock_view)).thenReturn(mSmallClockFrame);
-        when(mSmallClockView.getContext()).thenReturn(getContext());
-        when(mLargeClockView.getContext()).thenReturn(getContext());
-
-        when(mView.isAttachedToWindow()).thenReturn(true);
-        when(mSmartspaceController.buildAndConnectDateView(any())).thenReturn(mFakeDateView);
-        when(mSmartspaceController.buildAndConnectWeatherView(any())).thenReturn(mFakeWeatherView);
-        when(mSmartspaceController.buildAndConnectView(any())).thenReturn(mFakeSmartspaceView);
-        mExecutor = new FakeExecutor(new FakeSystemClock());
-        mController = new KeyguardClockSwitchController(
-                mView,
-                mStatusBarStateController,
-                mClockRegistry,
-                mKeyguardSliceViewController,
-                mNotificationIconAreaController,
-                mSmartspaceController,
-                mKeyguardUnlockAnimationController,
-                mSecureSettings,
-                mExecutor,
-                mDumpManager,
-                mClockEventController,
-                mLogBuffer
-        );
-
-        when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
-        when(mLargeClockController.getView()).thenReturn(mLargeClockView);
-        when(mSmallClockController.getView()).thenReturn(mSmallClockView);
-        when(mClockController.getLargeClock()).thenReturn(mLargeClockController);
-        when(mClockController.getSmallClock()).thenReturn(mSmallClockController);
-        when(mClockController.getEvents()).thenReturn(mClockEvents);
-        when(mSmallClockController.getEvents()).thenReturn(mClockFaceEvents);
-        when(mLargeClockController.getEvents()).thenReturn(mClockFaceEvents);
-        when(mLargeClockController.getAnimations()).thenReturn(mClockAnimations);
-        when(mSmallClockController.getAnimations()).thenReturn(mClockAnimations);
-        when(mClockRegistry.createCurrentClock()).thenReturn(mClockController);
-        when(mClockEventController.getClock()).thenReturn(mClockController);
-        when(mSmallClockController.getConfig())
-                .thenReturn(new ClockFaceConfig(ClockTickRate.PER_MINUTE, false, false));
-        when(mLargeClockController.getConfig())
-                .thenReturn(new ClockFaceConfig(ClockTickRate.PER_MINUTE, false, false));
-
-        mSliceView = new View(getContext());
-        when(mView.findViewById(R.id.keyguard_slice_view)).thenReturn(mSliceView);
-        when(mView.findViewById(R.id.keyguard_status_area)).thenReturn(
-                new LinearLayout(getContext()));
-    }
-
+public class KeyguardClockSwitchControllerTest extends KeyguardClockSwitchControllerBaseTest {
     @Test
     public void testInit_viewAlreadyAttached() {
         mController.init();
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerWithCoroutinesTest.kt
new file mode 100644
index 0000000..9a1a4e2
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerWithCoroutinesTest.kt
@@ -0,0 +1,62 @@
+/*
+ * 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.testing.AndroidTestingRunner
+import android.view.View
+import androidx.test.filters.SmallTest
+import com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.runBlocking
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class KeyguardClockSwitchControllerWithCoroutinesTest : KeyguardClockSwitchControllerBaseTest() {
+
+    @Test
+    fun testStatusAreaVisibility_onLockscreenHostedDreamStateChanged() =
+        runBlocking(IMMEDIATE) {
+            // GIVEN starting state for the keyguard clock and wallpaper dream enabled
+            mFakeFeatureFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, true)
+            init()
+
+            // WHEN dreaming starts
+            mController.mIsActiveDreamLockscreenHostedCallback.accept(
+                true /* isActiveDreamLockscreenHosted */
+            )
+
+            // THEN the status area is hidden
+            mExecutor.runAllReady()
+            assertEquals(View.INVISIBLE, mStatusArea.visibility)
+
+            // WHEN dreaming stops
+            mController.mIsActiveDreamLockscreenHostedCallback.accept(
+                false /* isActiveDreamLockscreenHosted */
+            )
+            mExecutor.runAllReady()
+
+            // THEN status area view is visible
+            assertEquals(View.VISIBLE, mStatusArea.visibility)
+        }
+
+    companion object {
+        private val IMMEDIATE = Dispatchers.Main.immediate
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
index 2eea9eb..5d75428 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
@@ -32,15 +32,18 @@
 import com.android.systemui.flags.Flags
 import com.android.systemui.statusbar.policy.DevicePostureController
 import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_HALF_OPENED
+import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_OPENED
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
 import org.mockito.ArgumentMatchers.anyBoolean
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.ArgumentMatchers.anyString
+import org.mockito.Captor
 import org.mockito.Mock
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
@@ -78,6 +81,9 @@
   private lateinit var mKeyguardPatternViewController: KeyguardPatternViewController
   private lateinit var fakeFeatureFlags: FakeFeatureFlags
 
+  @Captor
+  lateinit var postureCallbackCaptor: ArgumentCaptor<DevicePostureController.Callback>
+
     @Before
     fun setup() {
         MockitoAnnotations.initMocks(this)
@@ -107,7 +113,7 @@
     }
 
     @Test
-    fun tabletopPostureIsDetectedFromStart() {
+    fun onViewAttached_deviceHalfFolded_propagatedToPatternView() {
         overrideResource(R.dimen.half_opened_bouncer_height_ratio, 0.5f)
         whenever(mPostureController.devicePosture).thenReturn(DEVICE_POSTURE_HALF_OPENED)
 
@@ -116,6 +122,26 @@
         assertThat(getPatternTopGuideline()).isEqualTo(getExpectedTopGuideline())
     }
 
+    @Test
+    fun onDevicePostureChanged_deviceOpened_propagatedToPatternView() {
+        overrideResource(R.dimen.half_opened_bouncer_height_ratio, 0.5f)
+        whenever(mPostureController.devicePosture)
+                .thenReturn(DEVICE_POSTURE_HALF_OPENED)
+
+        mKeyguardPatternViewController.onViewAttached()
+
+        // Verify view begins in posture state DEVICE_POSTURE_HALF_OPENED
+        assertThat(getPatternTopGuideline()).isEqualTo(getExpectedTopGuideline())
+
+        // Simulate posture change to state DEVICE_POSTURE_OPENED with callback
+        verify(mPostureController).addCallback(postureCallbackCaptor.capture())
+        val postureCallback: DevicePostureController.Callback = postureCallbackCaptor.value
+        postureCallback.onPostureChanged(DEVICE_POSTURE_OPENED)
+
+        // Verify view is now in posture state DEVICE_POSTURE_OPENED
+        assertThat(getPatternTopGuideline()).isNotEqualTo(getExpectedTopGuideline())
+    }
+
     private fun getPatternTopGuideline(): Float {
         val cs = ConstraintSet()
         val container =
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt
index d3b4190..9db267c 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt
@@ -30,12 +30,16 @@
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.statusbar.policy.DevicePostureController
+import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_HALF_OPENED
+import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_OPENED
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
 import org.mockito.ArgumentMatchers.anyBoolean
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.ArgumentMatchers.anyString
+import org.mockito.Captor
 import org.mockito.Mock
 import org.mockito.Mockito
 import org.mockito.Mockito.any
@@ -79,7 +83,9 @@
     @Mock lateinit var deleteButton: NumPadButton
     @Mock lateinit var enterButton: View
 
-    lateinit var pinViewController: KeyguardPinViewController
+    private lateinit var pinViewController: KeyguardPinViewController
+
+    @Captor lateinit var postureCallbackCaptor: ArgumentCaptor<DevicePostureController.Callback>
 
     @Before
     fun setup() {
@@ -97,6 +103,9 @@
         `when`(keyguardPinView.findViewById<NumPadButton>(R.id.delete_button))
             .thenReturn(deleteButton)
         `when`(keyguardPinView.findViewById<View>(R.id.key_enter)).thenReturn(enterButton)
+        // For posture tests:
+        `when`(keyguardPinView.buttons).thenReturn(arrayOf())
+
         pinViewController =
             KeyguardPinViewController(
                 keyguardPinView,
@@ -115,6 +124,33 @@
     }
 
     @Test
+    fun onViewAttached_deviceHalfFolded_propagatedToPinView() {
+        `when`(postureController.devicePosture).thenReturn(DEVICE_POSTURE_HALF_OPENED)
+
+        pinViewController.onViewAttached()
+
+        verify(keyguardPinView).onDevicePostureChanged(DEVICE_POSTURE_HALF_OPENED)
+    }
+
+    @Test
+    fun onDevicePostureChanged_deviceHalfFolded_propagatedToPinView() {
+        `when`(postureController.devicePosture).thenReturn(DEVICE_POSTURE_HALF_OPENED)
+
+        // Verify view begins in posture state DEVICE_POSTURE_HALF_OPENED
+        pinViewController.onViewAttached()
+
+        verify(keyguardPinView).onDevicePostureChanged(DEVICE_POSTURE_HALF_OPENED)
+
+        // Simulate posture change to state DEVICE_POSTURE_OPENED with callback
+        verify(postureController).addCallback(postureCallbackCaptor.capture())
+        val postureCallback: DevicePostureController.Callback = postureCallbackCaptor.value
+        postureCallback.onPostureChanged(DEVICE_POSTURE_OPENED)
+
+        // Verify view is now in posture state DEVICE_POSTURE_OPENED
+        verify(keyguardPinView).onDevicePostureChanged(DEVICE_POSTURE_OPENED)
+    }
+
+    @Test
     fun startAppearAnimation() {
         pinViewController.startAppearAnimation()
         verify(keyguardMessageAreaController)
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
deleted file mode 100644
index 58b1edc..0000000
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
+++ /dev/null
@@ -1,732 +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 static com.android.keyguard.KeyguardSecurityContainer.MODE_DEFAULT;
-import static com.android.keyguard.KeyguardSecurityContainer.MODE_ONE_HANDED;
-import static com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.EXPANSION_VISIBLE;
-
-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.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.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.hardware.biometrics.BiometricOverlayConstants;
-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.WindowInsetsController;
-import android.widget.FrameLayout;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.UiEventLogger;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.biometrics.SideFpsController;
-import com.android.systemui.biometrics.SideFpsUiRequestSource;
-import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor;
-import com.android.systemui.classifier.FalsingA11yDelegate;
-import com.android.systemui.classifier.FalsingCollector;
-import com.android.systemui.flags.FakeFeatureFlags;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
-import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor;
-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;
-import com.android.systemui.statusbar.policy.UserSwitcherController;
-import com.android.systemui.util.settings.GlobalSettings;
-
-import org.junit.Before;
-import org.junit.Rule;
-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;
-import org.mockito.junit.MockitoRule;
-
-import java.util.Optional;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@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
-    private AdminSecondaryLockScreenController.Factory mAdminSecondaryLockScreenControllerFactory;
-    @Mock
-    private AdminSecondaryLockScreenController mAdminSecondaryLockScreenController;
-    @Mock
-    private LockPatternUtils mLockPatternUtils;
-    @Mock
-    private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
-    @Mock
-    private KeyguardSecurityModel mKeyguardSecurityModel;
-    @Mock
-    private MetricsLogger mMetricsLogger;
-    @Mock
-    private UiEventLogger mUiEventLogger;
-    @Mock
-    private KeyguardStateController mKeyguardStateController;
-    @Mock
-    private KeyguardInputViewController mInputViewController;
-    @Mock
-    private WindowInsetsController mWindowInsetsController;
-    @Mock
-    private KeyguardSecurityViewFlipper mSecurityViewFlipper;
-    @Mock
-    private KeyguardSecurityViewFlipperController mKeyguardSecurityViewFlipperController;
-    @Mock
-    private KeyguardMessageAreaController.Factory mKeyguardMessageAreaControllerFactory;
-    @Mock
-    private KeyguardMessageAreaController mKeyguardMessageAreaController;
-    @Mock
-    private BouncerKeyguardMessageArea mKeyguardMessageArea;
-    @Mock
-    private ConfigurationController mConfigurationController;
-    @Mock
-    private EmergencyButtonController mEmergencyButtonController;
-    @Mock
-    private FalsingCollector mFalsingCollector;
-    @Mock
-    private FalsingManager mFalsingManager;
-    @Mock
-    private GlobalSettings mGlobalSettings;
-    @Mock
-    private FeatureFlags mFeatureFlags;
-    @Mock
-    private UserSwitcherController mUserSwitcherController;
-    @Mock
-    private SessionTracker mSessionTracker;
-    @Mock
-    private KeyguardViewController mKeyguardViewController;
-    @Mock
-    private SideFpsController mSideFpsController;
-    @Mock
-    private KeyguardPasswordViewController mKeyguardPasswordViewControllerMock;
-    @Mock
-    private FalsingA11yDelegate mFalsingA11yDelegate;
-    @Mock
-    private TelephonyManager mTelephonyManager;
-    @Mock
-    private ViewMediatorCallback mViewMediatorCallback;
-    @Mock
-    private AudioManager mAudioManager;
-
-    @Captor
-    private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallback;
-    @Captor
-    private ArgumentCaptor<KeyguardSecurityContainer.SwipeListener> mSwipeListenerArgumentCaptor;
-
-    @Captor
-    private ArgumentCaptor<KeyguardSecurityViewFlipperController.OnViewInflatedCallback>
-            mOnViewInflatedCallbackArgumentCaptor;
-
-    private KeyguardSecurityContainerController mKeyguardSecurityContainerController;
-    private KeyguardPasswordViewController mKeyguardPasswordViewController;
-    private KeyguardPasswordView mKeyguardPasswordView;
-    private TestableResources mTestableResources;
-
-    @Before
-    public void setup() {
-        mTestableResources = mContext.getOrCreateTestableResources();
-        mTestableResources.getResources().getConfiguration().orientation =
-                Configuration.ORIENTATION_UNDEFINED;
-
-        when(mView.getContext()).thenReturn(mContext);
-        when(mView.getResources()).thenReturn(mTestableResources.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);
-        mKeyguardPasswordView = spy((KeyguardPasswordView) LayoutInflater.from(mContext).inflate(
-                R.layout.keyguard_password_view, null));
-        when(mKeyguardPasswordView.getRootView()).thenReturn(mSecurityViewFlipper);
-        when(mKeyguardPasswordView.requireViewById(R.id.bouncer_message_area))
-                .thenReturn(mKeyguardMessageArea);
-        when(mKeyguardMessageAreaControllerFactory.create(any(KeyguardMessageArea.class)))
-                .thenReturn(mKeyguardMessageAreaController);
-        when(mKeyguardPasswordView.getWindowInsetsController()).thenReturn(mWindowInsetsController);
-        when(mKeyguardSecurityModel.getSecurityMode(anyInt())).thenReturn(SecurityMode.PIN);
-        when(mKeyguardStateController.canDismissLockScreen()).thenReturn(true);
-        FakeFeatureFlags featureFlags = new FakeFeatureFlags();
-        featureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, true);
-
-        mKeyguardPasswordViewController = new KeyguardPasswordViewController(
-                (KeyguardPasswordView) mKeyguardPasswordView, mKeyguardUpdateMonitor,
-                SecurityMode.Password, mLockPatternUtils, null,
-                mKeyguardMessageAreaControllerFactory, null, null, mEmergencyButtonController,
-                null, mock(Resources.class), null, mKeyguardViewController,
-                featureFlags);
-
-        mKeyguardSecurityContainerController = new KeyguardSecurityContainerController(
-                mView, mAdminSecondaryLockScreenControllerFactory, mLockPatternUtils,
-                mKeyguardUpdateMonitor, mKeyguardSecurityModel, mMetricsLogger, mUiEventLogger,
-                mKeyguardStateController, mKeyguardSecurityViewFlipperController,
-                mConfigurationController, mFalsingCollector, mFalsingManager,
-                mUserSwitcherController, mFeatureFlags, mGlobalSettings,
-                mSessionTracker, Optional.of(mSideFpsController), mFalsingA11yDelegate,
-                mTelephonyManager, mViewMediatorCallback, mAudioManager,
-                mock(KeyguardFaceAuthInteractor.class),
-                mock(BouncerMessageInteractor.class));
-    }
-
-    @Test
-    public void onInitConfiguresViewMode() {
-        mKeyguardSecurityContainerController.onInit();
-        verify(mView).initMode(eq(MODE_DEFAULT), eq(mGlobalSettings), eq(mFalsingManager),
-                eq(mUserSwitcherController),
-                any(KeyguardSecurityContainer.UserSwitcherViewMode.UserSwitcherCallback.class),
-                eq(mFalsingA11yDelegate));
-    }
-
-    @Test
-    public void showSecurityScreen_canInflateAllModes() {
-        SecurityMode[] modes = SecurityMode.values();
-        for (SecurityMode mode : modes) {
-            when(mInputViewController.getSecurityMode()).thenReturn(mode);
-            mKeyguardSecurityContainerController.showSecurityScreen(mode);
-            if (mode == SecurityMode.Invalid) {
-                verify(mKeyguardSecurityViewFlipperController, never()).getSecurityView(
-                        any(SecurityMode.class), any(KeyguardSecurityCallback.class), any(
-                                KeyguardSecurityViewFlipperController.OnViewInflatedCallback.class)
-                );
-            } else {
-                verify(mKeyguardSecurityViewFlipperController).getSecurityView(
-                        eq(mode), any(KeyguardSecurityCallback.class), any(
-                                KeyguardSecurityViewFlipperController.OnViewInflatedCallback.class)
-                );
-            }
-        }
-    }
-
-    @Test
-    public void onResourcesUpdate_callsThroughOnRotationChange() {
-        clearInvocations(mView);
-
-        // Rotation is the same, shouldn't cause an update
-        mKeyguardSecurityContainerController.updateResources();
-        verify(mView, never()).initMode(eq(MODE_DEFAULT), eq(mGlobalSettings), eq(mFalsingManager),
-                eq(mUserSwitcherController),
-                any(KeyguardSecurityContainer.UserSwitcherViewMode.UserSwitcherCallback.class),
-                eq(mFalsingA11yDelegate));
-
-        // Update rotation. Should trigger update
-        mTestableResources.getResources().getConfiguration().orientation =
-                Configuration.ORIENTATION_LANDSCAPE;
-
-        mKeyguardSecurityContainerController.updateResources();
-        verify(mView).initMode(eq(MODE_DEFAULT), eq(mGlobalSettings), eq(mFalsingManager),
-                eq(mUserSwitcherController),
-                any(KeyguardSecurityContainer.UserSwitcherViewMode.UserSwitcherCallback.class),
-                eq(mFalsingA11yDelegate));
-    }
-
-    private void touchDown() {
-        mKeyguardSecurityContainerController.mGlobalTouchListener.onTouchEvent(
-                MotionEvent.obtain(
-                        /* downTime= */0,
-                        /* eventTime= */0,
-                        MotionEvent.ACTION_DOWN,
-                        /* x= */0,
-                        /* y= */0,
-                        /* metaState= */0));
-    }
-
-    @Test
-    public void onInterceptTap_inhibitsFalsingInSidedSecurityMode() {
-
-        when(mView.isTouchOnTheOtherSideOfSecurity(any())).thenReturn(false);
-        touchDown();
-        verify(mFalsingCollector, never()).avoidGesture();
-
-        when(mView.isTouchOnTheOtherSideOfSecurity(any())).thenReturn(true);
-        touchDown();
-        verify(mFalsingCollector).avoidGesture();
-    }
-
-    @Test
-    public void showSecurityScreen_oneHandedMode_flagDisabled_noOneHandedMode() {
-        mTestableResources.addOverride(R.bool.can_use_one_handed_bouncer, false);
-        setupGetSecurityView(SecurityMode.Pattern);
-
-        mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.Pattern);
-        verify(mView).initMode(eq(MODE_DEFAULT), eq(mGlobalSettings), eq(mFalsingManager),
-                eq(mUserSwitcherController),
-                any(KeyguardSecurityContainer.UserSwitcherViewMode.UserSwitcherCallback.class),
-                eq(mFalsingA11yDelegate));
-    }
-
-    @Test
-    public void showSecurityScreen_oneHandedMode_flagEnabled_oneHandedMode() {
-        mTestableResources.addOverride(R.bool.can_use_one_handed_bouncer, true);
-        setupGetSecurityView(SecurityMode.Pattern);
-        verify(mView).initMode(eq(MODE_ONE_HANDED), eq(mGlobalSettings), eq(mFalsingManager),
-                eq(mUserSwitcherController),
-                any(KeyguardSecurityContainer.UserSwitcherViewMode.UserSwitcherCallback.class),
-                eq(mFalsingA11yDelegate));
-    }
-
-    @Test
-    public void showSecurityScreen_twoHandedMode_flagEnabled_noOneHandedMode() {
-        mTestableResources.addOverride(R.bool.can_use_one_handed_bouncer, true);
-        setupGetSecurityView(SecurityMode.Password);
-
-        verify(mView).initMode(eq(MODE_DEFAULT), eq(mGlobalSettings), eq(mFalsingManager),
-                eq(mUserSwitcherController),
-                any(KeyguardSecurityContainer.UserSwitcherViewMode.UserSwitcherCallback.class),
-                eq(mFalsingA11yDelegate));
-    }
-
-    @Test
-    public void addUserSwitcherCallback() {
-        ArgumentCaptor<KeyguardSecurityContainer.UserSwitcherViewMode.UserSwitcherCallback>
-                captor = ArgumentCaptor.forClass(
-                KeyguardSecurityContainer.UserSwitcherViewMode.UserSwitcherCallback.class);
-        setupGetSecurityView(SecurityMode.Password);
-
-        verify(mView).initMode(anyInt(), any(GlobalSettings.class), any(FalsingManager.class),
-                any(UserSwitcherController.class),
-                captor.capture(),
-                eq(mFalsingA11yDelegate));
-        captor.getValue().showUnlockToContinueMessage();
-        getViewControllerImmediately();
-        verify(mKeyguardPasswordViewControllerMock).showMessage(
-                /* message= */ getContext().getString(R.string.keyguard_unlock_to_continue),
-                /* colorState= */ null,
-                /* animated= */ true);
-    }
-
-    @Test
-    public void addUserSwitchCallback() {
-        mKeyguardSecurityContainerController.onViewAttached();
-        verify(mUserSwitcherController)
-                .addUserSwitchCallback(any(UserSwitcherController.UserSwitchCallback.class));
-        mKeyguardSecurityContainerController.onViewDetached();
-        verify(mUserSwitcherController)
-                .removeUserSwitchCallback(any(UserSwitcherController.UserSwitchCallback.class));
-    }
-
-    @Test
-    public void onBouncerVisibilityChanged_resetsScale() {
-        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(false);
-        verify(mView).resetScale();
-    }
-
-    @Test
-    public void showNextSecurityScreenOrFinish_setsSecurityScreenToPinAfterSimPinUnlock() {
-        // GIVEN the current security method is SimPin
-        when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(false);
-        when(mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(TARGET_USER_ID)).thenReturn(false);
-        mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.SimPin);
-
-        // WHEN a request is made from the SimPin screens to show the next security method
-        when(mKeyguardSecurityModel.getSecurityMode(TARGET_USER_ID)).thenReturn(SecurityMode.PIN);
-        mKeyguardSecurityContainerController.showNextSecurityScreenOrFinish(
-                /* authenticated= */true,
-                TARGET_USER_ID,
-                /* bypassSecondaryLockScreen= */true,
-                SecurityMode.SimPin);
-
-        // THEN the next security method of PIN is set, and the keyguard is not marked as done
-
-        verify(mViewMediatorCallback, never()).keyguardDonePending(anyBoolean(), anyInt());
-        verify(mViewMediatorCallback, never()).keyguardDone(anyBoolean(), anyInt());
-        assertThat(mKeyguardSecurityContainerController.getCurrentSecurityMode())
-                .isEqualTo(SecurityMode.PIN);
-    }
-
-    @Test
-    public void showNextSecurityScreenOrFinish_DeviceNotSecure() {
-        // GIVEN the current security method is SimPin
-        when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(false);
-        when(mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(TARGET_USER_ID)).thenReturn(false);
-        mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.SimPin);
-
-        // WHEN a request is made from the SimPin screens to show the next security method
-        when(mKeyguardSecurityModel.getSecurityMode(TARGET_USER_ID)).thenReturn(SecurityMode.None);
-        when(mLockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(true);
-        mKeyguardSecurityContainerController.showNextSecurityScreenOrFinish(
-                /* authenticated= */true,
-                TARGET_USER_ID,
-                /* bypassSecondaryLockScreen= */true,
-                SecurityMode.SimPin);
-
-        // THEN the next security method of None will dismiss keyguard.
-        verify(mViewMediatorCallback).keyguardDone(anyBoolean(), anyInt());
-    }
-
-    @Test
-    public void showNextSecurityScreenOrFinish_ignoresCallWhenSecurityMethodHasChanged() {
-        //GIVEN current security mode has been set to PIN
-        mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.PIN);
-
-        //WHEN a request comes from SimPin to dismiss the security screens
-        boolean keyguardDone = mKeyguardSecurityContainerController.showNextSecurityScreenOrFinish(
-                /* authenticated= */true,
-                TARGET_USER_ID,
-                /* bypassSecondaryLockScreen= */true,
-                SecurityMode.SimPin);
-
-        //THEN no action has happened, which will not dismiss the security screens
-        assertThat(keyguardDone).isEqualTo(false);
-        verify(mKeyguardUpdateMonitor, never()).getUserHasTrust(anyInt());
-    }
-
-    @Test
-    public void showNextSecurityScreenOrFinish_SimPin_Swipe() {
-        // GIVEN the current security method is SimPin
-        when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(false);
-        when(mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(TARGET_USER_ID)).thenReturn(false);
-        mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.SimPin);
-
-        // WHEN a request is made from the SimPin screens to show the next security method
-        when(mKeyguardSecurityModel.getSecurityMode(TARGET_USER_ID)).thenReturn(SecurityMode.None);
-        // WHEN security method is SWIPE
-        when(mLockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false);
-        mKeyguardSecurityContainerController.showNextSecurityScreenOrFinish(
-                /* authenticated= */true,
-                TARGET_USER_ID,
-                /* bypassSecondaryLockScreen= */true,
-                SecurityMode.SimPin);
-
-        // THEN the next security method of None will dismiss keyguard.
-        verify(mViewMediatorCallback, never()).keyguardDone(anyBoolean(), anyInt());
-    }
-
-
-    @Test
-    public void onSwipeUp_whenFaceDetectionIsNotRunning_initiatesFaceAuth() {
-        KeyguardSecurityContainer.SwipeListener registeredSwipeListener =
-                getRegisteredSwipeListener();
-        when(mKeyguardUpdateMonitor.isFaceDetectionRunning()).thenReturn(false);
-        setupGetSecurityView(SecurityMode.Password);
-
-        registeredSwipeListener.onSwipeUp();
-
-        verify(mKeyguardUpdateMonitor).requestFaceAuth(
-                FaceAuthApiRequestReason.SWIPE_UP_ON_BOUNCER);
-    }
-
-    @Test
-    public void onSwipeUp_whenFaceDetectionIsRunning_doesNotInitiateFaceAuth() {
-        KeyguardSecurityContainer.SwipeListener registeredSwipeListener =
-                getRegisteredSwipeListener();
-        when(mKeyguardUpdateMonitor.isFaceDetectionRunning()).thenReturn(true);
-
-        registeredSwipeListener.onSwipeUp();
-
-        verify(mKeyguardUpdateMonitor, never())
-                .requestFaceAuth(FaceAuthApiRequestReason.SWIPE_UP_ON_BOUNCER);
-    }
-
-    @Test
-    public void onSwipeUp_whenFaceDetectionIsTriggered_hidesBouncerMessage() {
-        KeyguardSecurityContainer.SwipeListener registeredSwipeListener =
-                getRegisteredSwipeListener();
-        when(mKeyguardUpdateMonitor.requestFaceAuth(FaceAuthApiRequestReason.SWIPE_UP_ON_BOUNCER))
-                .thenReturn(true);
-        setupGetSecurityView(SecurityMode.Password);
-
-        clearInvocations(mKeyguardSecurityViewFlipperController);
-        registeredSwipeListener.onSwipeUp();
-        getViewControllerImmediately();
-
-        verify(mKeyguardPasswordViewControllerMock).showMessage(/* message= */
-                null, /* colorState= */ null, /* animated= */ true);
-    }
-
-    @Test
-    public void onSwipeUp_whenFaceDetectionIsNotTriggered_retainsBouncerMessage() {
-        KeyguardSecurityContainer.SwipeListener registeredSwipeListener =
-                getRegisteredSwipeListener();
-        when(mKeyguardUpdateMonitor.requestFaceAuth(FaceAuthApiRequestReason.SWIPE_UP_ON_BOUNCER))
-                .thenReturn(false);
-        setupGetSecurityView(SecurityMode.Password);
-
-        registeredSwipeListener.onSwipeUp();
-
-        verify(mKeyguardPasswordViewControllerMock, never()).showMessage(/* message= */
-                null, /* colorState= */ null, /* animated= */ true);
-    }
-
-    @Test
-    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(mKeyguardSecurityViewFlipperController).clearViews();
-        verify(mKeyguardSecurityViewFlipperController).asynchronouslyInflateView(
-                eq(SecurityMode.PIN),
-                any(KeyguardSecurityCallback.class),
-                mOnViewInflatedCallbackArgumentCaptor.capture());
-
-        mOnViewInflatedCallbackArgumentCaptor.getValue().onViewInflated(mInputViewController);
-
-        verify(mView).onDensityOrFontScaleChanged();
-    }
-
-    @Test
-    public void onThemeChanged() {
-        ArgumentCaptor<ConfigurationController.ConfigurationListener>
-                configurationListenerArgumentCaptor = ArgumentCaptor.forClass(
-                ConfigurationController.ConfigurationListener.class);
-        mKeyguardSecurityContainerController.onViewAttached();
-        verify(mConfigurationController).addCallback(configurationListenerArgumentCaptor.capture());
-        clearInvocations(mKeyguardSecurityViewFlipperController);
-
-        configurationListenerArgumentCaptor.getValue().onThemeChanged();
-
-        verify(mKeyguardSecurityViewFlipperController).clearViews();
-        verify(mKeyguardSecurityViewFlipperController).asynchronouslyInflateView(
-                eq(SecurityMode.PIN),
-                any(KeyguardSecurityCallback.class),
-                mOnViewInflatedCallbackArgumentCaptor.capture());
-
-        mOnViewInflatedCallbackArgumentCaptor.getValue().onViewInflated(mInputViewController);
-
-        verify(mView).reset();
-        verify(mKeyguardSecurityViewFlipperController).reset();
-        verify(mView).reloadColors();
-    }
-
-    @Test
-    public void onUiModeChanged() {
-        ArgumentCaptor<ConfigurationController.ConfigurationListener>
-                configurationListenerArgumentCaptor = ArgumentCaptor.forClass(
-                ConfigurationController.ConfigurationListener.class);
-        mKeyguardSecurityContainerController.onViewAttached();
-        verify(mConfigurationController).addCallback(configurationListenerArgumentCaptor.capture());
-        clearInvocations(mKeyguardSecurityViewFlipperController);
-
-        configurationListenerArgumentCaptor.getValue().onUiModeChanged();
-
-        verify(mKeyguardSecurityViewFlipperController).clearViews();
-        verify(mKeyguardSecurityViewFlipperController).asynchronouslyInflateView(
-                eq(SecurityMode.PIN),
-                any(KeyguardSecurityCallback.class),
-                mOnViewInflatedCallbackArgumentCaptor.capture());
-
-        mOnViewInflatedCallbackArgumentCaptor.getValue().onViewInflated(mInputViewController);
-
-        verify(mView).reloadColors();
-    }
-
-    @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 testWillRunDismissFromKeyguardIsTrue() {
-        ActivityStarter.OnDismissAction action = mock(ActivityStarter.OnDismissAction.class);
-        when(action.willRunAnimationOnKeyguard()).thenReturn(true);
-        mKeyguardSecurityContainerController.setOnDismissAction(action, null /* cancelAction */);
-
-        mKeyguardSecurityContainerController.finish(false /* strongAuth */, 0 /* currentUser */);
-
-        assertThat(mKeyguardSecurityContainerController.willRunDismissFromKeyguard()).isTrue();
-    }
-
-    @Test
-    public void testWillRunDismissFromKeyguardIsFalse() {
-        ActivityStarter.OnDismissAction action = mock(ActivityStarter.OnDismissAction.class);
-        when(action.willRunAnimationOnKeyguard()).thenReturn(false);
-        mKeyguardSecurityContainerController.setOnDismissAction(action, null /* cancelAction */);
-
-        mKeyguardSecurityContainerController.finish(false /* strongAuth */, 0 /* currentUser */);
-
-        assertThat(mKeyguardSecurityContainerController.willRunDismissFromKeyguard()).isFalse();
-    }
-
-    @Test
-    public void testWillRunDismissFromKeyguardIsFalseWhenNoDismissActionSet() {
-        mKeyguardSecurityContainerController.setOnDismissAction(null /* action */,
-                null /* cancelAction */);
-
-        mKeyguardSecurityContainerController.finish(false /* strongAuth */, 0 /* currentUser */);
-
-        assertThat(mKeyguardSecurityContainerController.willRunDismissFromKeyguard()).isFalse();
-    }
-
-    @Test
-    public void testOnStartingToHide() {
-        mKeyguardSecurityContainerController.onStartingToHide();
-        verify(mKeyguardSecurityViewFlipperController).getSecurityView(any(SecurityMode.class),
-                any(KeyguardSecurityCallback.class),
-                mOnViewInflatedCallbackArgumentCaptor.capture());
-
-        mOnViewInflatedCallbackArgumentCaptor.getValue().onViewInflated(mInputViewController);
-        verify(mInputViewController).onStartingToHide();
-    }
-
-    @Test
-    public void testGravityReappliedOnConfigurationChange() {
-        // Set initial gravity
-        mTestableResources.addOverride(R.integer.keyguard_host_view_gravity,
-                Gravity.CENTER);
-        mTestableResources.addOverride(
-                R.bool.can_use_one_handed_bouncer, false);
-
-        // Kick off the initial pass...
-        mKeyguardSecurityContainerController.onInit();
-        verify(mView).setLayoutParams(any());
-        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(any());
-    }
-
-    @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() {
-        KeyguardSecurityViewFlipperController.OnViewInflatedCallback onViewInflatedCallback =
-                controller -> {
-                };
-        mKeyguardSecurityContainerController.reinflateViewFlipper(onViewInflatedCallback);
-        verify(mKeyguardSecurityViewFlipperController).clearViews();
-        verify(mKeyguardSecurityViewFlipperController).asynchronouslyInflateView(
-                any(SecurityMode.class),
-                any(KeyguardSecurityCallback.class), eq(onViewInflatedCallback));
-    }
-
-    @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);
-    }
-
-    @Test
-    public void setExpansion_setsAlpha() {
-        mKeyguardSecurityContainerController.setExpansion(EXPANSION_VISIBLE);
-
-        verify(mView).setAlpha(1f);
-        verify(mView).setTranslationY(0f);
-    }
-
-    private KeyguardSecurityContainer.SwipeListener getRegisteredSwipeListener() {
-        mKeyguardSecurityContainerController.onViewAttached();
-        verify(mView).setSwipeListener(mSwipeListenerArgumentCaptor.capture());
-        return mSwipeListenerArgumentCaptor.getValue();
-    }
-
-    private void setupGetSecurityView(SecurityMode securityMode) {
-        mKeyguardSecurityContainerController.showSecurityScreen(securityMode);
-        getViewControllerImmediately();
-    }
-
-    private void getViewControllerImmediately() {
-        verify(mKeyguardSecurityViewFlipperController, atLeastOnce()).getSecurityView(
-                any(SecurityMode.class), any(),
-                mOnViewInflatedCallbackArgumentCaptor.capture());
-        mOnViewInflatedCallbackArgumentCaptor.getValue().onViewInflated(
-                (KeyguardInputViewController) mKeyguardPasswordViewControllerMock);
-
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
new file mode 100644
index 0000000..d447174
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
@@ -0,0 +1,810 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.keyguard
+
+import android.content.res.Configuration
+import android.hardware.biometrics.BiometricOverlayConstants
+import android.media.AudioManager
+import android.telephony.TelephonyManager
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import android.testing.TestableResources
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.MotionEvent
+import android.view.WindowInsetsController
+import android.widget.FrameLayout
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.MetricsLogger
+import com.android.internal.logging.UiEventLogger
+import com.android.internal.widget.LockPatternUtils
+import com.android.keyguard.KeyguardSecurityContainer.UserSwitcherViewMode.UserSwitcherCallback
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.SideFpsController
+import com.android.systemui.biometrics.SideFpsUiRequestSource
+import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants
+import com.android.systemui.classifier.FalsingA11yDelegate
+import com.android.systemui.classifier.FalsingCollector
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.log.SessionTracker
+import com.android.systemui.plugins.ActivityStarter.OnDismissAction
+import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.scene.SceneTestUtils
+import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.model.SceneKey
+import com.android.systemui.scene.shared.model.SceneModel
+import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.statusbar.policy.UserSwitcherController
+import com.android.systemui.user.domain.interactor.UserInteractor
+import com.android.systemui.util.kotlin.JavaAdapter
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.argThat
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.settings.GlobalSettings
+import com.google.common.truth.Truth
+import java.util.Optional
+import junit.framework.Assert
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatcher
+import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.atLeastOnce
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.never
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper
+class KeyguardSecurityContainerControllerTest : SysuiTestCase() {
+
+    @Mock private lateinit var view: KeyguardSecurityContainer
+    @Mock
+    private lateinit var adminSecondaryLockScreenControllerFactory:
+        AdminSecondaryLockScreenController.Factory
+    @Mock
+    private lateinit var adminSecondaryLockScreenController: AdminSecondaryLockScreenController
+    @Mock private lateinit var lockPatternUtils: LockPatternUtils
+    @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
+    @Mock private lateinit var keyguardSecurityModel: KeyguardSecurityModel
+    @Mock private lateinit var metricsLogger: MetricsLogger
+    @Mock private lateinit var uiEventLogger: UiEventLogger
+    @Mock private lateinit var keyguardStateController: KeyguardStateController
+    @Mock private lateinit var inputViewController: KeyguardInputViewController<KeyguardInputView>
+    @Mock private lateinit var windowInsetsController: WindowInsetsController
+    @Mock private lateinit var securityViewFlipper: KeyguardSecurityViewFlipper
+    @Mock private lateinit var viewFlipperController: KeyguardSecurityViewFlipperController
+    @Mock private lateinit var messageAreaControllerFactory: KeyguardMessageAreaController.Factory
+    @Mock private lateinit var keyguardMessageAreaController: KeyguardMessageAreaController<*>
+    @Mock private lateinit var keyguardMessageArea: BouncerKeyguardMessageArea
+    @Mock private lateinit var configurationController: ConfigurationController
+    @Mock private lateinit var emergencyButtonController: EmergencyButtonController
+    @Mock private lateinit var falsingCollector: FalsingCollector
+    @Mock private lateinit var falsingManager: FalsingManager
+    @Mock private lateinit var globalSettings: GlobalSettings
+    @Mock private lateinit var userSwitcherController: UserSwitcherController
+    @Mock private lateinit var sessionTracker: SessionTracker
+    @Mock private lateinit var keyguardViewController: KeyguardViewController
+    @Mock private lateinit var sideFpsController: SideFpsController
+    @Mock private lateinit var keyguardPasswordViewControllerMock: KeyguardPasswordViewController
+    @Mock private lateinit var falsingA11yDelegate: FalsingA11yDelegate
+    @Mock private lateinit var telephonyManager: TelephonyManager
+    @Mock private lateinit var viewMediatorCallback: ViewMediatorCallback
+    @Mock private lateinit var audioManager: AudioManager
+    @Mock private lateinit var userInteractor: UserInteractor
+
+    @Captor
+    private lateinit var swipeListenerArgumentCaptor:
+        ArgumentCaptor<KeyguardSecurityContainer.SwipeListener>
+    @Captor
+    private lateinit var onViewInflatedCallbackArgumentCaptor:
+        ArgumentCaptor<KeyguardSecurityViewFlipperController.OnViewInflatedCallback>
+
+    private lateinit var featureFlags: FakeFeatureFlags
+    private lateinit var keyguardPasswordViewController: KeyguardPasswordViewController
+    private lateinit var keyguardPasswordView: KeyguardPasswordView
+    private lateinit var testableResources: TestableResources
+    private lateinit var sceneTestUtils: SceneTestUtils
+    private lateinit var sceneInteractor: SceneInteractor
+
+    private lateinit var underTest: KeyguardSecurityContainerController
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+
+        testableResources = mContext.getOrCreateTestableResources()
+        testableResources.resources.configuration.orientation = Configuration.ORIENTATION_UNDEFINED
+        whenever(view.context).thenReturn(mContext)
+        whenever(view.resources).thenReturn(testableResources.resources)
+
+        val lp = FrameLayout.LayoutParams(/* width=  */ 0, /* height= */ 0)
+        lp.gravity = 0
+        whenever(view.layoutParams).thenReturn(lp)
+
+        whenever(adminSecondaryLockScreenControllerFactory.create(any()))
+            .thenReturn(adminSecondaryLockScreenController)
+        whenever(securityViewFlipper.windowInsetsController).thenReturn(windowInsetsController)
+        keyguardPasswordView =
+            spy(
+                LayoutInflater.from(mContext).inflate(R.layout.keyguard_password_view, null)
+                    as KeyguardPasswordView
+            )
+        whenever(keyguardPasswordView.rootView).thenReturn(securityViewFlipper)
+        whenever<Any?>(keyguardPasswordView.requireViewById(R.id.bouncer_message_area))
+            .thenReturn(keyguardMessageArea)
+        whenever(messageAreaControllerFactory.create(any()))
+            .thenReturn(keyguardMessageAreaController)
+        whenever(keyguardPasswordView.windowInsetsController).thenReturn(windowInsetsController)
+        whenever(keyguardSecurityModel.getSecurityMode(anyInt())).thenReturn(SecurityMode.PIN)
+        whenever(keyguardStateController.canDismissLockScreen()).thenReturn(true)
+
+        featureFlags = FakeFeatureFlags()
+        featureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, true)
+        featureFlags.set(Flags.SCENE_CONTAINER, false)
+        featureFlags.set(Flags.BOUNCER_USER_SWITCHER, false)
+
+        keyguardPasswordViewController =
+            KeyguardPasswordViewController(
+                keyguardPasswordView,
+                keyguardUpdateMonitor,
+                SecurityMode.Password,
+                lockPatternUtils,
+                null,
+                messageAreaControllerFactory,
+                null,
+                null,
+                emergencyButtonController,
+                null,
+                mock(),
+                null,
+                keyguardViewController,
+                featureFlags
+            )
+
+        whenever(userInteractor.getSelectedUserId()).thenReturn(TARGET_USER_ID)
+        sceneTestUtils = SceneTestUtils(this)
+        sceneInteractor = sceneTestUtils.sceneInteractor()
+
+        underTest =
+            KeyguardSecurityContainerController(
+                view,
+                adminSecondaryLockScreenControllerFactory,
+                lockPatternUtils,
+                keyguardUpdateMonitor,
+                keyguardSecurityModel,
+                metricsLogger,
+                uiEventLogger,
+                keyguardStateController,
+                viewFlipperController,
+                configurationController,
+                falsingCollector,
+                falsingManager,
+                userSwitcherController,
+                featureFlags,
+                globalSettings,
+                sessionTracker,
+                Optional.of(sideFpsController),
+                falsingA11yDelegate,
+                telephonyManager,
+                viewMediatorCallback,
+                audioManager,
+                mock(),
+                mock(),
+                { JavaAdapter(sceneTestUtils.testScope.backgroundScope) },
+                userInteractor,
+            ) {
+                sceneInteractor
+            }
+    }
+
+    @Test
+    fun onInitConfiguresViewMode() {
+        underTest.onInit()
+        verify(view)
+            .initMode(
+                eq(KeyguardSecurityContainer.MODE_DEFAULT),
+                eq(globalSettings),
+                eq(falsingManager),
+                eq(userSwitcherController),
+                any(),
+                eq(falsingA11yDelegate)
+            )
+    }
+
+    @Test
+    fun showSecurityScreen_canInflateAllModes() {
+        val modes = SecurityMode.values()
+        for (mode in modes) {
+            whenever(inputViewController.securityMode).thenReturn(mode)
+            underTest.showSecurityScreen(mode)
+            if (mode == SecurityMode.Invalid) {
+                verify(viewFlipperController, never()).getSecurityView(any(), any(), any())
+            } else {
+                verify(viewFlipperController).getSecurityView(eq(mode), any(), any())
+            }
+        }
+    }
+
+    @Test
+    fun onResourcesUpdate_callsThroughOnRotationChange() {
+        clearInvocations(view)
+
+        // Rotation is the same, shouldn't cause an update
+        underTest.updateResources()
+        verify(view, never())
+            .initMode(
+                eq(KeyguardSecurityContainer.MODE_DEFAULT),
+                eq(globalSettings),
+                eq(falsingManager),
+                eq(userSwitcherController),
+                any(),
+                eq(falsingA11yDelegate)
+            )
+
+        // Update rotation. Should trigger update
+        testableResources.resources.configuration.orientation = Configuration.ORIENTATION_LANDSCAPE
+        underTest.updateResources()
+        verify(view)
+            .initMode(
+                eq(KeyguardSecurityContainer.MODE_DEFAULT),
+                eq(globalSettings),
+                eq(falsingManager),
+                eq(userSwitcherController),
+                any(),
+                eq(falsingA11yDelegate)
+            )
+    }
+
+    private fun touchDown() {
+        underTest.mGlobalTouchListener.onTouchEvent(
+            MotionEvent.obtain(
+                /* downTime= */ 0,
+                /* eventTime= */ 0,
+                MotionEvent.ACTION_DOWN,
+                /* x= */ 0f,
+                /* y= */ 0f,
+                /* metaState= */ 0
+            )
+        )
+    }
+
+    @Test
+    fun onInterceptTap_inhibitsFalsingInSidedSecurityMode() {
+        whenever(view.isTouchOnTheOtherSideOfSecurity(any())).thenReturn(false)
+        touchDown()
+        verify(falsingCollector, never()).avoidGesture()
+        whenever(view.isTouchOnTheOtherSideOfSecurity(any())).thenReturn(true)
+        touchDown()
+        verify(falsingCollector).avoidGesture()
+    }
+
+    @Test
+    fun showSecurityScreen_oneHandedMode_flagDisabled_noOneHandedMode() {
+        testableResources.addOverride(R.bool.can_use_one_handed_bouncer, false)
+        setupGetSecurityView(SecurityMode.Pattern)
+        underTest.showSecurityScreen(SecurityMode.Pattern)
+        verify(view)
+            .initMode(
+                eq(KeyguardSecurityContainer.MODE_DEFAULT),
+                eq(globalSettings),
+                eq(falsingManager),
+                eq(userSwitcherController),
+                any(),
+                eq(falsingA11yDelegate)
+            )
+    }
+
+    @Test
+    fun showSecurityScreen_oneHandedMode_flagEnabled_oneHandedMode() {
+        testableResources.addOverride(R.bool.can_use_one_handed_bouncer, true)
+        setupGetSecurityView(SecurityMode.Pattern)
+        verify(view)
+            .initMode(
+                eq(KeyguardSecurityContainer.MODE_ONE_HANDED),
+                eq(globalSettings),
+                eq(falsingManager),
+                eq(userSwitcherController),
+                any(),
+                eq(falsingA11yDelegate)
+            )
+    }
+
+    @Test
+    fun showSecurityScreen_twoHandedMode_flagEnabled_noOneHandedMode() {
+        testableResources.addOverride(R.bool.can_use_one_handed_bouncer, true)
+        setupGetSecurityView(SecurityMode.Password)
+        verify(view)
+            .initMode(
+                eq(KeyguardSecurityContainer.MODE_DEFAULT),
+                eq(globalSettings),
+                eq(falsingManager),
+                eq(userSwitcherController),
+                any(),
+                eq(falsingA11yDelegate)
+            )
+    }
+
+    @Test
+    fun addUserSwitcherCallback() {
+        val captor = ArgumentCaptor.forClass(UserSwitcherCallback::class.java)
+        setupGetSecurityView(SecurityMode.Password)
+        verify(view)
+            .initMode(anyInt(), any(), any(), any(), captor.capture(), eq(falsingA11yDelegate))
+        captor.value.showUnlockToContinueMessage()
+        viewControllerImmediately
+        verify(keyguardPasswordViewControllerMock)
+            .showMessage(
+                /* message= */ context.getString(R.string.keyguard_unlock_to_continue),
+                /* colorState= */ null,
+                /* animated= */ true
+            )
+    }
+
+    @Test
+    fun addUserSwitchCallback() {
+        underTest.onViewAttached()
+        verify(userSwitcherController).addUserSwitchCallback(any())
+        underTest.onViewDetached()
+        verify(userSwitcherController).removeUserSwitchCallback(any())
+    }
+
+    @Test
+    fun onBouncerVisibilityChanged_resetsScale() {
+        underTest.onBouncerVisibilityChanged(false)
+        verify(view).resetScale()
+    }
+
+    @Test
+    fun showNextSecurityScreenOrFinish_setsSecurityScreenToPinAfterSimPinUnlock() {
+        // GIVEN the current security method is SimPin
+        whenever(keyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(false)
+        whenever(keyguardUpdateMonitor.getUserUnlockedWithBiometric(TARGET_USER_ID))
+            .thenReturn(false)
+        underTest.showSecurityScreen(SecurityMode.SimPin)
+
+        // WHEN a request is made from the SimPin screens to show the next security method
+        whenever(keyguardSecurityModel.getSecurityMode(TARGET_USER_ID)).thenReturn(SecurityMode.PIN)
+        underTest.showNextSecurityScreenOrFinish(
+            /* authenticated= */ true,
+            TARGET_USER_ID,
+            /* bypassSecondaryLockScreen= */ true,
+            SecurityMode.SimPin
+        )
+
+        // THEN the next security method of PIN is set, and the keyguard is not marked as done
+        verify(viewMediatorCallback, never()).keyguardDonePending(anyBoolean(), anyInt())
+        verify(viewMediatorCallback, never()).keyguardDone(anyBoolean(), anyInt())
+        Truth.assertThat(underTest.currentSecurityMode).isEqualTo(SecurityMode.PIN)
+    }
+
+    @Test
+    fun showNextSecurityScreenOrFinish_DeviceNotSecure() {
+        // GIVEN the current security method is SimPin
+        whenever(keyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(false)
+        whenever(keyguardUpdateMonitor.getUserUnlockedWithBiometric(TARGET_USER_ID))
+            .thenReturn(false)
+        underTest.showSecurityScreen(SecurityMode.SimPin)
+
+        // WHEN a request is made from the SimPin screens to show the next security method
+        whenever(keyguardSecurityModel.getSecurityMode(TARGET_USER_ID))
+            .thenReturn(SecurityMode.None)
+        whenever(lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(true)
+        underTest.showNextSecurityScreenOrFinish(
+            /* authenticated= */ true,
+            TARGET_USER_ID,
+            /* bypassSecondaryLockScreen= */ true,
+            SecurityMode.SimPin
+        )
+
+        // THEN the next security method of None will dismiss keyguard.
+        verify(viewMediatorCallback).keyguardDone(anyBoolean(), anyInt())
+    }
+
+    @Test
+    fun showNextSecurityScreenOrFinish_ignoresCallWhenSecurityMethodHasChanged() {
+        // GIVEN current security mode has been set to PIN
+        underTest.showSecurityScreen(SecurityMode.PIN)
+
+        // WHEN a request comes from SimPin to dismiss the security screens
+        val keyguardDone =
+            underTest.showNextSecurityScreenOrFinish(
+                /* authenticated= */ true,
+                TARGET_USER_ID,
+                /* bypassSecondaryLockScreen= */ true,
+                SecurityMode.SimPin
+            )
+
+        // THEN no action has happened, which will not dismiss the security screens
+        Truth.assertThat(keyguardDone).isEqualTo(false)
+        verify(keyguardUpdateMonitor, never()).getUserHasTrust(anyInt())
+    }
+
+    @Test
+    fun showNextSecurityScreenOrFinish_SimPin_Swipe() {
+        // GIVEN the current security method is SimPin
+        whenever(keyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(false)
+        whenever(keyguardUpdateMonitor.getUserUnlockedWithBiometric(TARGET_USER_ID))
+            .thenReturn(false)
+        underTest.showSecurityScreen(SecurityMode.SimPin)
+
+        // WHEN a request is made from the SimPin screens to show the next security method
+        whenever(keyguardSecurityModel.getSecurityMode(TARGET_USER_ID))
+            .thenReturn(SecurityMode.None)
+        // WHEN security method is SWIPE
+        whenever(lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false)
+        underTest.showNextSecurityScreenOrFinish(
+            /* authenticated= */ true,
+            TARGET_USER_ID,
+            /* bypassSecondaryLockScreen= */ true,
+            SecurityMode.SimPin
+        )
+
+        // THEN the next security method of None will dismiss keyguard.
+        verify(viewMediatorCallback, never()).keyguardDone(anyBoolean(), anyInt())
+    }
+
+    @Test
+    fun onSwipeUp_whenFaceDetectionIsNotRunning_initiatesFaceAuth() {
+        val registeredSwipeListener = registeredSwipeListener
+        whenever(keyguardUpdateMonitor.isFaceDetectionRunning).thenReturn(false)
+        setupGetSecurityView(SecurityMode.Password)
+        registeredSwipeListener.onSwipeUp()
+        verify(keyguardUpdateMonitor).requestFaceAuth(FaceAuthApiRequestReason.SWIPE_UP_ON_BOUNCER)
+    }
+
+    @Test
+    fun onSwipeUp_whenFaceDetectionIsRunning_doesNotInitiateFaceAuth() {
+        val registeredSwipeListener = registeredSwipeListener
+        whenever(keyguardUpdateMonitor.isFaceDetectionRunning).thenReturn(true)
+        registeredSwipeListener.onSwipeUp()
+        verify(keyguardUpdateMonitor, never())
+            .requestFaceAuth(FaceAuthApiRequestReason.SWIPE_UP_ON_BOUNCER)
+    }
+
+    @Test
+    fun onSwipeUp_whenFaceDetectionIsTriggered_hidesBouncerMessage() {
+        val registeredSwipeListener = registeredSwipeListener
+        whenever(
+                keyguardUpdateMonitor.requestFaceAuth(FaceAuthApiRequestReason.SWIPE_UP_ON_BOUNCER)
+            )
+            .thenReturn(true)
+        setupGetSecurityView(SecurityMode.Password)
+        clearInvocations(viewFlipperController)
+        registeredSwipeListener.onSwipeUp()
+        viewControllerImmediately
+        verify(keyguardPasswordViewControllerMock)
+            .showMessage(/* message= */ null, /* colorState= */ null, /* animated= */ true)
+    }
+
+    @Test
+    fun onSwipeUp_whenFaceDetectionIsNotTriggered_retainsBouncerMessage() {
+        val registeredSwipeListener = registeredSwipeListener
+        whenever(
+                keyguardUpdateMonitor.requestFaceAuth(FaceAuthApiRequestReason.SWIPE_UP_ON_BOUNCER)
+            )
+            .thenReturn(false)
+        setupGetSecurityView(SecurityMode.Password)
+        registeredSwipeListener.onSwipeUp()
+        verify(keyguardPasswordViewControllerMock, never())
+            .showMessage(/* message= */ null, /* colorState= */ null, /* animated= */ true)
+    }
+
+    @Test
+    fun onDensityOrFontScaleChanged() {
+        val configurationListenerArgumentCaptor =
+            ArgumentCaptor.forClass(ConfigurationController.ConfigurationListener::class.java)
+        underTest.onViewAttached()
+        verify(configurationController).addCallback(configurationListenerArgumentCaptor.capture())
+        clearInvocations(viewFlipperController)
+        configurationListenerArgumentCaptor.value.onDensityOrFontScaleChanged()
+        verify(viewFlipperController).clearViews()
+        verify(viewFlipperController)
+            .asynchronouslyInflateView(
+                eq(SecurityMode.PIN),
+                any(),
+                onViewInflatedCallbackArgumentCaptor.capture()
+            )
+        onViewInflatedCallbackArgumentCaptor.value.onViewInflated(inputViewController)
+        verify(view).onDensityOrFontScaleChanged()
+    }
+
+    @Test
+    fun onThemeChanged() {
+        val configurationListenerArgumentCaptor =
+            ArgumentCaptor.forClass(ConfigurationController.ConfigurationListener::class.java)
+        underTest.onViewAttached()
+        verify(configurationController).addCallback(configurationListenerArgumentCaptor.capture())
+        clearInvocations(viewFlipperController)
+        configurationListenerArgumentCaptor.value.onThemeChanged()
+        verify(viewFlipperController).clearViews()
+        verify(viewFlipperController)
+            .asynchronouslyInflateView(
+                eq(SecurityMode.PIN),
+                any(),
+                onViewInflatedCallbackArgumentCaptor.capture()
+            )
+        onViewInflatedCallbackArgumentCaptor.value.onViewInflated(inputViewController)
+        verify(view).reset()
+        verify(viewFlipperController).reset()
+        verify(view).reloadColors()
+    }
+
+    @Test
+    fun onUiModeChanged() {
+        val configurationListenerArgumentCaptor =
+            ArgumentCaptor.forClass(ConfigurationController.ConfigurationListener::class.java)
+        underTest.onViewAttached()
+        verify(configurationController).addCallback(configurationListenerArgumentCaptor.capture())
+        clearInvocations(viewFlipperController)
+        configurationListenerArgumentCaptor.value.onUiModeChanged()
+        verify(viewFlipperController).clearViews()
+        verify(viewFlipperController)
+            .asynchronouslyInflateView(
+                eq(SecurityMode.PIN),
+                any(),
+                onViewInflatedCallbackArgumentCaptor.capture()
+            )
+        onViewInflatedCallbackArgumentCaptor.value.onViewInflated(inputViewController)
+        verify(view).reloadColors()
+    }
+
+    @Test
+    fun hasDismissActions() {
+        Assert.assertFalse("Action not set yet", underTest.hasDismissActions())
+        underTest.setOnDismissAction(mock(), null /* cancelAction */)
+        Assert.assertTrue("Action should exist", underTest.hasDismissActions())
+    }
+
+    @Test
+    fun willRunDismissFromKeyguardIsTrue() {
+        val action: OnDismissAction = mock()
+        whenever(action.willRunAnimationOnKeyguard()).thenReturn(true)
+        underTest.setOnDismissAction(action, null /* cancelAction */)
+        underTest.finish(false /* strongAuth */, 0 /* currentUser */)
+        Truth.assertThat(underTest.willRunDismissFromKeyguard()).isTrue()
+    }
+
+    @Test
+    fun willRunDismissFromKeyguardIsFalse() {
+        val action: OnDismissAction = mock()
+        whenever(action.willRunAnimationOnKeyguard()).thenReturn(false)
+        underTest.setOnDismissAction(action, null /* cancelAction */)
+        underTest.finish(false /* strongAuth */, 0 /* currentUser */)
+        Truth.assertThat(underTest.willRunDismissFromKeyguard()).isFalse()
+    }
+
+    @Test
+    fun willRunDismissFromKeyguardIsFalseWhenNoDismissActionSet() {
+        underTest.setOnDismissAction(null /* action */, null /* cancelAction */)
+        underTest.finish(false /* strongAuth */, 0 /* currentUser */)
+        Truth.assertThat(underTest.willRunDismissFromKeyguard()).isFalse()
+    }
+
+    @Test
+    fun onStartingToHide() {
+        underTest.onStartingToHide()
+        verify(viewFlipperController)
+            .getSecurityView(any(), any(), onViewInflatedCallbackArgumentCaptor.capture())
+        onViewInflatedCallbackArgumentCaptor.value.onViewInflated(inputViewController)
+        verify(inputViewController).onStartingToHide()
+    }
+
+    @Test
+    fun gravityReappliedOnConfigurationChange() {
+        // Set initial gravity
+        testableResources.addOverride(R.integer.keyguard_host_view_gravity, Gravity.CENTER)
+        testableResources.addOverride(R.bool.can_use_one_handed_bouncer, false)
+
+        // Kick off the initial pass...
+        underTest.onInit()
+        verify(view).layoutParams = any()
+        clearInvocations(view)
+
+        // Now simulate a config change
+        testableResources.addOverride(
+            R.integer.keyguard_host_view_gravity,
+            Gravity.CENTER_HORIZONTAL or Gravity.BOTTOM
+        )
+        underTest.updateResources()
+        verify(view).layoutParams = any()
+    }
+
+    @Test
+    fun gravityUsesOneHandGravityWhenApplicable() {
+        testableResources.addOverride(R.integer.keyguard_host_view_gravity, Gravity.CENTER)
+        testableResources.addOverride(
+            R.integer.keyguard_host_view_one_handed_gravity,
+            Gravity.CENTER_HORIZONTAL or Gravity.BOTTOM
+        )
+
+        // Start disabled.
+        testableResources.addOverride(R.bool.can_use_one_handed_bouncer, false)
+        underTest.onInit()
+        verify(view).layoutParams =
+            argThat(
+                ArgumentMatcher { argument: FrameLayout.LayoutParams ->
+                    argument.gravity == Gravity.CENTER
+                }
+                    as ArgumentMatcher<FrameLayout.LayoutParams>
+            )
+        clearInvocations(view)
+
+        // And enable
+        testableResources.addOverride(R.bool.can_use_one_handed_bouncer, true)
+        underTest.updateResources()
+        verify(view).layoutParams =
+            argThat(
+                ArgumentMatcher { argument: FrameLayout.LayoutParams ->
+                    argument.gravity == Gravity.CENTER_HORIZONTAL or Gravity.BOTTOM
+                }
+                    as ArgumentMatcher<FrameLayout.LayoutParams>
+            )
+    }
+
+    @Test
+    fun updateKeyguardPositionDelegatesToSecurityContainer() {
+        underTest.updateKeyguardPosition(1.0f)
+        verify(view).updatePositionByTouchX(1.0f)
+    }
+
+    @Test
+    fun reinflateViewFlipper() {
+        val onViewInflatedCallback = KeyguardSecurityViewFlipperController.OnViewInflatedCallback {}
+        underTest.reinflateViewFlipper(onViewInflatedCallback)
+        verify(viewFlipperController).clearViews()
+        verify(viewFlipperController)
+            .asynchronouslyInflateView(any(), any(), eq(onViewInflatedCallback))
+    }
+
+    @Test
+    fun sideFpsControllerShow() {
+        underTest.updateSideFpsVisibility(/* isVisible= */ true)
+        verify(sideFpsController)
+            .show(
+                SideFpsUiRequestSource.PRIMARY_BOUNCER,
+                BiometricOverlayConstants.REASON_AUTH_KEYGUARD
+            )
+    }
+
+    @Test
+    fun sideFpsControllerHide() {
+        underTest.updateSideFpsVisibility(/* isVisible= */ false)
+        verify(sideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER)
+    }
+
+    @Test
+    fun setExpansion_setsAlpha() {
+        underTest.setExpansion(KeyguardBouncerConstants.EXPANSION_VISIBLE)
+        verify(view).alpha = 1f
+        verify(view).translationY = 0f
+    }
+
+    @Test
+    fun dismissesKeyguard_whenSceneChangesFromBouncerToGone() =
+        sceneTestUtils.testScope.runTest {
+            featureFlags.set(Flags.SCENE_CONTAINER, true)
+
+            // Upon init, we have never dismisses the keyguard.
+            underTest.onInit()
+            runCurrent()
+            verify(viewMediatorCallback, never()).keyguardDone(anyBoolean(), anyInt())
+
+            // Once the view is attached, we start listening but simply going to the bouncer scene
+            // is
+            // not enough to trigger a dismissal of the keyguard.
+            underTest.onViewAttached()
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Bouncer, null)
+            )
+            runCurrent()
+            verify(viewMediatorCallback, never()).keyguardDone(anyBoolean(), anyInt())
+
+            // While listening, going from the bouncer scene to the gone scene, does dismiss the
+            // keyguard.
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Gone, null)
+            )
+            runCurrent()
+            verify(viewMediatorCallback).keyguardDone(anyBoolean(), anyInt())
+
+            // While listening, moving back to the bouncer scene does not dismiss the keyguard
+            // again.
+            clearInvocations(viewMediatorCallback)
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Bouncer, null)
+            )
+            runCurrent()
+            verify(viewMediatorCallback, never()).keyguardDone(anyBoolean(), anyInt())
+
+            // Detaching the view stops listening, so moving from the bouncer scene to the gone
+            // scene
+            // does not dismiss the keyguard while we're not listening.
+            underTest.onViewDetached()
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Gone, null)
+            )
+            runCurrent()
+            verify(viewMediatorCallback, never()).keyguardDone(anyBoolean(), anyInt())
+
+            // While not listening, moving back to the bouncer does not dismiss the keyguard.
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Bouncer, null)
+            )
+            runCurrent()
+            verify(viewMediatorCallback, never()).keyguardDone(anyBoolean(), anyInt())
+
+            // Reattaching the view starts listening again so moving from the bouncer scene to the
+            // gone
+            // scene now does dismiss the keyguard again.
+            underTest.onViewAttached()
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Gone, null)
+            )
+            runCurrent()
+            verify(viewMediatorCallback).keyguardDone(anyBoolean(), anyInt())
+        }
+
+    private val registeredSwipeListener: KeyguardSecurityContainer.SwipeListener
+        get() {
+            underTest.onViewAttached()
+            verify(view).setSwipeListener(swipeListenerArgumentCaptor.capture())
+            return swipeListenerArgumentCaptor.value
+        }
+
+    private fun setupGetSecurityView(securityMode: SecurityMode) {
+        underTest.showSecurityScreen(securityMode)
+        viewControllerImmediately
+    }
+
+    private val viewControllerImmediately: Unit
+        get() {
+            verify(viewFlipperController, atLeastOnce())
+                .getSecurityView(any(), any(), onViewInflatedCallbackArgumentCaptor.capture())
+            @Suppress("UNCHECKED_CAST")
+            onViewInflatedCallbackArgumentCaptor.value.onViewInflated(
+                keyguardPasswordViewControllerMock as KeyguardInputViewController<KeyguardInputView>
+            )
+        }
+
+    companion object {
+        private const val TARGET_USER_ID = 100
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
index 75106e7..956e0b81 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
@@ -19,6 +19,7 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
 import static com.android.systemui.flags.Flags.DOZING_MIGRATION_1;
 import static com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR;
+import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED;
 import static com.android.systemui.flags.Flags.MIGRATE_LOCK_ICON;
 
 import static org.mockito.Mockito.any;
@@ -147,6 +148,7 @@
         mFeatureFlags = new FakeFeatureFlags();
         mFeatureFlags.set(FACE_AUTH_REFACTOR, false);
         mFeatureFlags.set(MIGRATE_LOCK_ICON, false);
+        mFeatureFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false);
         mUnderTest = new LockIconViewController(
                 mLockIconView,
                 mStatusBarStateController,
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerWithCoroutinesTest.kt
index d2c54b4..c372f45 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerWithCoroutinesTest.kt
@@ -17,9 +17,11 @@
 package com.android.keyguard
 
 import android.testing.AndroidTestingRunner
+import android.view.View
 import androidx.test.filters.SmallTest
 import com.android.keyguard.LockIconView.ICON_LOCK
 import com.android.systemui.doze.util.getBurnInOffset
+import com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED
 import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
 import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
 import com.android.systemui.keyguard.shared.model.TransitionState.FINISHED
@@ -117,6 +119,33 @@
             verify(mLockIconView).setTranslationX(0f)
         }
 
+    @Test
+    fun testHideLockIconView_onLockscreenHostedDreamStateChanged() =
+        runBlocking(IMMEDIATE) {
+            // GIVEN starting state for the lock icon (keyguard) and wallpaper dream enabled
+            mFeatureFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, true)
+            setupShowLockIcon()
+            init(/* useMigrationFlag= */ true)
+            reset(mLockIconView)
+
+            // WHEN dream starts
+            mUnderTest.mIsActiveDreamLockscreenHostedCallback.accept(
+                true /* isActiveDreamLockscreenHosted */
+            )
+
+            // THEN the lock icon is hidden
+            verify(mLockIconView).visibility = View.INVISIBLE
+            reset(mLockIconView)
+
+            // WHEN the device is no longer dreaming
+            mUnderTest.mIsActiveDreamLockscreenHostedCallback.accept(
+                false /* isActiveDreamLockscreenHosted */
+            )
+
+            // THEN lock icon is visible
+            verify(mLockIconView).visibility = View.VISIBLE
+        }
+
     companion object {
         private val IMMEDIATE = Dispatchers.Main.immediate
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java
index caf230d..67d6aa8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java
@@ -198,6 +198,7 @@
         assertTrue(mWindowMagnification.mUsersScales.contains(testUserId));
         assertEquals(mWindowMagnification.mUsersScales.get(testUserId).get(TEST_DISPLAY),
                 (Float) testScale);
+        verify(mMagnificationSettingsController).setMagnificationScale(eq(testScale));
     }
 
     private class FakeControllerSupplier extends
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationSettingsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationSettingsControllerTest.java
index 62a176c9..9eead6a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationSettingsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationSettingsControllerTest.java
@@ -86,6 +86,14 @@
     }
 
     @Test
+    public void testSetMagnificationScale() {
+        final float scale = 3.0f;
+        mMagnificationSettingsController.setMagnificationScale(scale);
+
+        verify(mWindowMagnificationSettings).setMagnificationScale(eq(scale));
+    }
+
+    @Test
     public void testOnConfigurationChanged_notifySettingsPanel() {
         mMagnificationSettingsController.onConfigurationChanged(ActivityInfo.CONFIG_DENSITY);
 
@@ -145,10 +153,11 @@
     @Test
     public void testPanelOnMagnifierScale_delegateToCallback() {
         final float scale = 3.0f;
+        final boolean updatePersistence = true;
         mMagnificationSettingsController.mWindowMagnificationSettingsCallback
-                .onMagnifierScale(scale);
+                .onMagnifierScale(scale, updatePersistence);
 
         verify(mMagnificationSettingControllerCallback).onMagnifierScale(
-                eq(mContext.getDisplayId()), eq(scale));
+                eq(mContext.getDisplayId()), eq(scale), eq(updatePersistence));
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
index 31c09b8..56f8160 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
@@ -645,10 +645,12 @@
         assertTrue(
                 mirrorView.performAccessibilityAction(R.id.accessibility_action_zoom_out, null));
         // Minimum scale is 1.0.
-        verify(mWindowMagnifierCallback).onPerformScaleAction(eq(displayId), eq(1.0f));
+        verify(mWindowMagnifierCallback).onPerformScaleAction(
+                eq(displayId), /* scale= */ eq(1.0f), /* updatePersistence= */ eq(true));
 
         assertTrue(mirrorView.performAccessibilityAction(R.id.accessibility_action_zoom_in, null));
-        verify(mWindowMagnifierCallback).onPerformScaleAction(eq(displayId), eq(2.5f));
+        verify(mWindowMagnifierCallback).onPerformScaleAction(
+                eq(displayId), /* scale= */ eq(2.5f), /* updatePersistence= */ eq(true));
 
         // TODO: Verify the final state when the mirror surface is visible.
         assertTrue(mirrorView.performAccessibilityAction(R.id.accessibility_action_move_up, null));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java
index 275723b..eddb8d1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java
@@ -16,7 +16,6 @@
 
 package com.android.systemui.accessibility;
 
-import static android.provider.Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE;
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY;
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL;
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
@@ -28,10 +27,12 @@
 import static junit.framework.Assert.assertNotNull;
 
 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.eq;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -55,10 +56,11 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 
-import com.android.internal.accessibility.common.MagnificationConstants;
 import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView;
+import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView.OnSeekBarWithIconButtonsChangeListener;
 import com.android.systemui.util.settings.SecureSettings;
 
 import org.junit.After;
@@ -79,6 +81,7 @@
     private static final int MAGNIFICATION_SIZE_LARGE = 3;
 
     private ViewGroup mSettingView;
+    private SeekBarWithIconButtonsView mZoomSeekbar;
     @Mock
     private AccessibilityManager mAccessibilityManager;
     @Mock
@@ -111,6 +114,7 @@
                 mSecureSettings);
 
         mSettingView = mWindowMagnificationSettings.getSettingView();
+        mZoomSeekbar = mSettingView.findViewById(R.id.magnifier_zoom_slider);
         mSecureSettingsScaleCaptor = ArgumentCaptor.forClass(Float.class);
         mSecureSettingsNameCaptor = ArgumentCaptor.forClass(String.class);
         mSecureSettingsUserHandleCaptor = ArgumentCaptor.forClass(Integer.class);
@@ -337,20 +341,6 @@
     }
 
     @Test
-    public void showSettingsPanel_observerForMagnificationScaleRegistered() {
-        setupMagnificationCapabilityAndMode(
-                /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_ALL,
-                /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
-
-        mWindowMagnificationSettings.showSettingPanel();
-
-        verify(mSecureSettings).registerContentObserverForUser(
-                eq(ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE),
-                any(ContentObserver.class),
-                eq(UserHandle.USER_CURRENT));
-    }
-
-    @Test
     public void hideSettingsPanel_observerUnregistered() {
         setupMagnificationCapabilityAndMode(
                 /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_ALL,
@@ -359,19 +349,25 @@
         mWindowMagnificationSettings.showSettingPanel();
         mWindowMagnificationSettings.hideSettingPanel();
 
-        verify(mSecureSettings, times(2)).unregisterContentObserver(any(ContentObserver.class));
+        verify(mSecureSettings).unregisterContentObserver(any(ContentObserver.class));
     }
 
     @Test
     public void seekbarProgress_justInflated_maxValueAndProgressSetCorrectly() {
-        setupScaleInSecureSettings(0f);
-        assertThat(mWindowMagnificationSettings.mZoomSeekbar.getProgress()).isEqualTo(0);
-        assertThat(mWindowMagnificationSettings.mZoomSeekbar.getMax()).isEqualTo(70);
+        mWindowMagnificationSettings.setMagnificationScale(2f);
+        mWindowMagnificationSettings.inflateView();
+
+        // inflateView() would create new settingsView in WindowMagnificationSettings so we
+        // need to retrieve the new mZoomSeekbar
+        mSettingView = mWindowMagnificationSettings.getSettingView();
+        mZoomSeekbar = mSettingView.findViewById(R.id.magnifier_zoom_slider);
+        assertThat(mZoomSeekbar.getProgress()).isEqualTo(10);
+        assertThat(mZoomSeekbar.getMax()).isEqualTo(70);
     }
 
     @Test
     public void seekbarProgress_minMagnification_seekbarProgressIsCorrect() {
-        setupScaleInSecureSettings(0f);
+        mWindowMagnificationSettings.setMagnificationScale(1f);
         setupMagnificationCapabilityAndMode(
                 /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
                 /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
@@ -379,24 +375,24 @@
         mWindowMagnificationSettings.showSettingPanel();
 
         // Seekbar index from 0 to 70. 1.0f scale (A11Y_SCALE_MIN_VALUE) would correspond to 0.
-        assertThat(mWindowMagnificationSettings.mZoomSeekbar.getProgress()).isEqualTo(0);
+        assertThat(mZoomSeekbar.getProgress()).isEqualTo(0);
     }
 
     @Test
     public void seekbarProgress_belowMinMagnification_seekbarProgressIsZero() {
-        setupScaleInSecureSettings(0f);
+        mWindowMagnificationSettings.setMagnificationScale(0f);
         setupMagnificationCapabilityAndMode(
                 /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
                 /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
 
         mWindowMagnificationSettings.showSettingPanel();
 
-        assertThat(mWindowMagnificationSettings.mZoomSeekbar.getProgress()).isEqualTo(0);
+        assertThat(mZoomSeekbar.getProgress()).isEqualTo(0);
     }
 
     @Test
     public void seekbarProgress_magnificationBefore_seekbarProgressIsHalf() {
-        setupScaleInSecureSettings(4f);
+        mWindowMagnificationSettings.setMagnificationScale(4f);
         setupMagnificationCapabilityAndMode(
                 /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
                 /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
@@ -405,12 +401,12 @@
 
         // float scale : from 1.0f to 8.0f, seekbar index from 0 to 70.
         // 4.0f would correspond to 30.
-        assertThat(mWindowMagnificationSettings.mZoomSeekbar.getProgress()).isEqualTo(30);
+        assertThat(mZoomSeekbar.getProgress()).isEqualTo(30);
     }
 
     @Test
     public void seekbarProgress_maxMagnificationBefore_seekbarProgressIsMax() {
-        setupScaleInSecureSettings(8f);
+        mWindowMagnificationSettings.setMagnificationScale(8f);
         setupMagnificationCapabilityAndMode(
                 /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
                 /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
@@ -419,12 +415,12 @@
 
         // 8.0f is max magnification {@link MagnificationScaleProvider#MAX_SCALE}.
         // Max zoom seek bar is 70.
-        assertThat(mWindowMagnificationSettings.mZoomSeekbar.getProgress()).isEqualTo(70);
+        assertThat(mZoomSeekbar.getProgress()).isEqualTo(70);
     }
 
     @Test
     public void seekbarProgress_aboveMaxMagnificationBefore_seekbarProgressIsMax() {
-        setupScaleInSecureSettings(9f);
+        mWindowMagnificationSettings.setMagnificationScale(9f);
         setupMagnificationCapabilityAndMode(
                 /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
                 /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
@@ -432,88 +428,81 @@
         mWindowMagnificationSettings.showSettingPanel();
 
         // Max zoom seek bar is 70.
-        assertThat(mWindowMagnificationSettings.mZoomSeekbar.getProgress()).isEqualTo(70);
+        assertThat(mZoomSeekbar.getProgress()).isEqualTo(70);
     }
 
     @Test
-    public void seekbarProgress_progressChangedRoughlyHalf_scaleAndCallbackUpdated() {
-        setupMagnificationCapabilityAndMode(
-                /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
-                /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
-        mWindowMagnificationSettings.showSettingPanel();
+    public void onSeekBarProgressChanged_fromUserFalse_callbackNotTriggered() {
+        OnSeekBarWithIconButtonsChangeListener onChangeListener =
+                mZoomSeekbar.getOnSeekBarWithIconButtonsChangeListener();
+        onChangeListener.onProgressChanged(
+                mZoomSeekbar.getSeekbar(), /* progress= */ 30, /* fromUser= */ false);
 
-        mWindowMagnificationSettings.mZoomSeekbar.setProgress(30);
+        verify(mWindowMagnificationSettingsCallback, never())
+                .onMagnifierScale(/* scale= */ anyFloat(), /* updatePersistence= */ eq(false));
+    }
 
-        verifyScaleUpdatedInSecureSettings(4f);
+    @Test
+    public void onSeekBarProgressChangedToRoughlyHalf_fromUserTrue_callbackUpdated() {
+        OnSeekBarWithIconButtonsChangeListener onChangeListener =
+                mZoomSeekbar.getOnSeekBarWithIconButtonsChangeListener();
+        onChangeListener.onProgressChanged(
+                mZoomSeekbar.getSeekbar(), /* progress= */ 30, /* fromUser= */ true);
+
         verifyCallbackOnMagnifierScale(4f);
     }
 
     @Test
-    public void seekbarProgress_minProgress_callbackUpdated() {
-        setupMagnificationCapabilityAndMode(
-                /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
-                /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
-        mWindowMagnificationSettings.showSettingPanel();
-        // Set progress to non-zero first so onProgressChanged can be triggered upon setting to 0.
-        mWindowMagnificationSettings.mZoomSeekbar.setProgress(30);
+    public void onSeekBarProgressChangedToMin_fromUserTrue_callbackUpdated() {
+        OnSeekBarWithIconButtonsChangeListener onChangeListener =
+                mZoomSeekbar.getOnSeekBarWithIconButtonsChangeListener();
+        onChangeListener.onProgressChanged(
+                mZoomSeekbar.getSeekbar(), /* progress= */ 0, /* fromUser= */ true);
 
-        mWindowMagnificationSettings.mZoomSeekbar.setProgress(0);
-
-        // For now, secure settings will not be updated for values < 1.3f. Follow up on this later.
-        verify(mWindowMagnificationSettingsCallback, times(2))
-                .onMagnifierScale(mCallbackMagnifierScaleCaptor.capture());
-        var capturedArgs = mCallbackMagnifierScaleCaptor.getAllValues();
-        assertThat(capturedArgs).hasSize(2);
-        assertThat(capturedArgs.get(1)).isWithin(0.01f).of(1f);
+        verifyCallbackOnMagnifierScale(1f);
     }
 
     @Test
-    public void seekbarProgress_maxProgress_scaleAndCallbackUpdated() {
-        setupMagnificationCapabilityAndMode(
-                /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
-                /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
-        mWindowMagnificationSettings.showSettingPanel();
+    public void onSeekBarProgressChangedToMax_fromUserTrue_callbackUpdated() {
+        OnSeekBarWithIconButtonsChangeListener onChangeListener =
+                mZoomSeekbar.getOnSeekBarWithIconButtonsChangeListener();
+        onChangeListener.onProgressChanged(
+                mZoomSeekbar.getSeekbar(), /* progress= */ 70, /* fromUser= */ true);
 
-        mWindowMagnificationSettings.mZoomSeekbar.setProgress(70);
-
-        verifyScaleUpdatedInSecureSettings(8f);
         verifyCallbackOnMagnifierScale(8f);
     }
 
     @Test
+    public void onSeekbarUserInteractionFinalized_persistedScaleUpdated() {
+        OnSeekBarWithIconButtonsChangeListener onChangeListener =
+                mZoomSeekbar.getOnSeekBarWithIconButtonsChangeListener();
+
+        mZoomSeekbar.setProgress(30);
+        onChangeListener.onUserInteractionFinalized(
+                mZoomSeekbar.getSeekbar(),
+                OnSeekBarWithIconButtonsChangeListener.ControlUnitType.SLIDER);
+
+        // should trigger callback to update magnifier scale and persist the scale
+        verify(mWindowMagnificationSettingsCallback)
+                .onMagnifierScale(/* scale= */ eq(4f), /* updatePersistence= */ eq(true));
+    }
+
+    @Test
     public void seekbarProgress_scaleUpdatedAfterSettingPanelOpened_progressAlsoUpdated() {
         setupMagnificationCapabilityAndMode(
                 /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_ALL,
                 /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
-        var contentObserverCaptor = ArgumentCaptor.forClass(ContentObserver.class);
         mWindowMagnificationSettings.showSettingPanel();
-        verify(mSecureSettings).registerContentObserverForUser(
-                eq(ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE),
-                contentObserverCaptor.capture(),
-                eq(UserHandle.USER_CURRENT));
 
         // Simulate outside changes.
-        setupScaleInSecureSettings(4f);
-        // Simulate callback due to outside change.
-        contentObserverCaptor.getValue().onChange(/* selfChange= */ false);
+        mWindowMagnificationSettings.setMagnificationScale(4f);
 
-        assertThat(mWindowMagnificationSettings.mZoomSeekbar.getProgress()).isEqualTo(30);
-    }
-
-    private void verifyScaleUpdatedInSecureSettings(float scale) {
-        verify(mSecureSettings).putFloatForUser(
-                mSecureSettingsNameCaptor.capture(),
-                mSecureSettingsScaleCaptor.capture(),
-                mSecureSettingsUserHandleCaptor.capture());
-        assertThat(mSecureSettingsScaleCaptor.getValue()).isWithin(0.01f).of(scale);
-        assertThat(mSecureSettingsNameCaptor.getValue())
-                .isEqualTo(Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE);
-        assertThat(mSecureSettingsUserHandleCaptor.getValue()).isEqualTo(UserHandle.USER_CURRENT);
+        assertThat(mZoomSeekbar.getProgress()).isEqualTo(30);
     }
 
     private void verifyCallbackOnMagnifierScale(float scale) {
         verify(mWindowMagnificationSettingsCallback)
-                .onMagnifierScale(mCallbackMagnifierScaleCaptor.capture());
+                .onMagnifierScale(mCallbackMagnifierScaleCaptor.capture(), anyBoolean());
         assertThat(mCallbackMagnifierScaleCaptor.getValue()).isWithin(0.01f).of(scale);
     }
 
@@ -533,11 +522,4 @@
                 anyInt(),
                 eq(UserHandle.USER_CURRENT))).thenReturn(mode);
     }
-
-    private void setupScaleInSecureSettings(float scale) {
-        when(mSecureSettings.getFloatForUser(
-                ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
-                MagnificationConstants.SCALE_MIN_VALUE,
-                UserHandle.USER_CURRENT)).thenReturn(scale);
-    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java
index db58074..d75781a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java
@@ -163,13 +163,15 @@
     @Test
     public void onPerformScaleAction_enabled_notifyCallback() throws RemoteException {
         final float newScale = 4.0f;
+        final boolean updatePersistence = true;
         mCommandQueue.requestWindowMagnificationConnection(true);
         waitForIdleSync();
 
         mWindowMagnification.mWindowMagnifierCallback
-                .onPerformScaleAction(TEST_DISPLAY, newScale);
+                .onPerformScaleAction(TEST_DISPLAY, newScale, updatePersistence);
 
-        verify(mConnectionCallback).onPerformScaleAction(TEST_DISPLAY, newScale);
+        verify(mConnectionCallback).onPerformScaleAction(
+                eq(TEST_DISPLAY), eq(newScale), eq(updatePersistence));
     }
 
     @Test
@@ -249,10 +251,12 @@
         mCommandQueue.requestWindowMagnificationConnection(true);
         waitForIdleSync();
         final float scale = 3.0f;
+        final boolean updatePersistence = false;
         mWindowMagnification.mMagnificationSettingsControllerCallback.onMagnifierScale(
-                TEST_DISPLAY, scale);
+                TEST_DISPLAY, scale, updatePersistence);
 
-        verify(mConnectionCallback).onPerformScaleAction(eq(TEST_DISPLAY), eq(scale));
+        verify(mConnectionCallback).onPerformScaleAction(
+                eq(TEST_DISPLAY), eq(scale), eq(updatePersistence));
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
index ea3289c..c0c6908 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
@@ -20,11 +20,16 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.authentication.data.repository.AuthenticationRepository
+import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.authentication.shared.model.AuthenticationThrottlingModel
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.scene.SceneTestUtils
 import com.google.common.truth.Truth.assertThat
+import kotlin.time.Duration.Companion.milliseconds
+import kotlin.time.Duration.Companion.seconds
 import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
@@ -47,25 +52,57 @@
     @Test
     fun getAuthenticationMethod() =
         testScope.runTest {
-            assertThat(underTest.getAuthenticationMethod())
-                .isEqualTo(AuthenticationMethodModel.Pin(1234))
+            assertThat(underTest.getAuthenticationMethod()).isEqualTo(AuthenticationMethodModel.Pin)
 
             utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Password("password")
+                AuthenticationMethodModel.Password
             )
+
             assertThat(underTest.getAuthenticationMethod())
-                .isEqualTo(AuthenticationMethodModel.Password("password"))
+                .isEqualTo(AuthenticationMethodModel.Password)
         }
 
     @Test
-    fun isUnlocked_whenAuthMethodIsNone_isTrue() =
+    fun getAuthenticationMethod_noneTreatedAsSwipe_whenLockscreenEnabled() =
         testScope.runTest {
             utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.None)
+            utils.authenticationRepository.setLockscreenEnabled(true)
+
+            assertThat(underTest.getAuthenticationMethod())
+                .isEqualTo(AuthenticationMethodModel.Swipe)
+        }
+
+    @Test
+    fun getAuthenticationMethod_none_whenLockscreenDisabled() =
+        testScope.runTest {
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.None)
+            utils.authenticationRepository.setLockscreenEnabled(false)
+
+            assertThat(underTest.getAuthenticationMethod())
+                .isEqualTo(AuthenticationMethodModel.None)
+        }
+
+    @Test
+    fun isUnlocked_whenAuthMethodIsNoneAndLockscreenDisabled_isTrue() =
+        testScope.runTest {
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.None)
+            utils.authenticationRepository.setLockscreenEnabled(false)
+
             val isUnlocked by collectLastValue(underTest.isUnlocked)
             assertThat(isUnlocked).isTrue()
         }
 
     @Test
+    fun isUnlocked_whenAuthMethodIsNoneAndLockscreenEnabled_isFalse() =
+        testScope.runTest {
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.None)
+            utils.authenticationRepository.setLockscreenEnabled(true)
+
+            val isUnlocked by collectLastValue(underTest.isUnlocked)
+            assertThat(isUnlocked).isFalse()
+        }
+
+    @Test
     fun toggleBypassEnabled() =
         testScope.runTest {
             val isBypassEnabled by collectLastValue(underTest.isBypassEnabled)
@@ -84,7 +121,7 @@
             utils.authenticationRepository.setUnlocked(false)
             runCurrent()
             utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Password("password")
+                AuthenticationMethodModel.Password
             )
 
             assertThat(underTest.isAuthenticationRequired()).isTrue()
@@ -106,7 +143,7 @@
             utils.authenticationRepository.setUnlocked(true)
             runCurrent()
             utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Password("password")
+                AuthenticationMethodModel.Password
             )
 
             assertThat(underTest.isAuthenticationRequired()).isFalse()
@@ -125,49 +162,33 @@
     @Test
     fun authenticate_withCorrectPin_returnsTrue() =
         testScope.runTest {
-            val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
-
+            val isThrottled by collectLastValue(underTest.isThrottled)
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             assertThat(underTest.authenticate(listOf(1, 2, 3, 4))).isTrue()
-            assertThat(failedAttemptCount).isEqualTo(0)
+            assertThat(isThrottled).isFalse()
         }
 
     @Test
     fun authenticate_withIncorrectPin_returnsFalse() =
         testScope.runTest {
-            val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
-
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             assertThat(underTest.authenticate(listOf(9, 8, 7))).isFalse()
-            assertThat(failedAttemptCount).isEqualTo(1)
         }
 
-    @Test
-    fun authenticate_withEmptyPin_returnsFalse() =
+    @Test(expected = IllegalArgumentException::class)
+    fun authenticate_withEmptyPin_throwsException() =
         testScope.runTest {
-            val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
-
-            assertThat(underTest.authenticate(listOf())).isFalse()
-            assertThat(failedAttemptCount).isEqualTo(1)
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+            underTest.authenticate(listOf())
         }
 
     @Test
     fun authenticate_withCorrectMaxLengthPin_returnsTrue() =
         testScope.runTest {
-            val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(9999999999999999)
-            )
-
-            assertThat(underTest.authenticate(List(16) { 9 })).isTrue()
-            assertThat(failedAttemptCount).isEqualTo(0)
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+            val pin = List(16) { 9 }
+            utils.authenticationRepository.overrideCredential(pin)
+            assertThat(underTest.authenticate(pin)).isTrue()
         }
 
     @Test
@@ -179,105 +200,47 @@
             // If the policy changes, there is work to do in SysUI.
             assertThat(DevicePolicyManager.MAX_PASSWORD_LENGTH).isLessThan(17)
 
-            val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(99999999999999999)
-            )
-
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             assertThat(underTest.authenticate(List(17) { 9 })).isFalse()
-            assertThat(failedAttemptCount).isEqualTo(1)
         }
 
     @Test
     fun authenticate_withCorrectPassword_returnsTrue() =
         testScope.runTest {
-            val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
+            val isThrottled by collectLastValue(underTest.isThrottled)
             utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Password("password")
+                AuthenticationMethodModel.Password
             )
 
             assertThat(underTest.authenticate("password".toList())).isTrue()
-            assertThat(failedAttemptCount).isEqualTo(0)
+            assertThat(isThrottled).isFalse()
         }
 
     @Test
     fun authenticate_withIncorrectPassword_returnsFalse() =
         testScope.runTest {
-            val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
             utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Password("password")
+                AuthenticationMethodModel.Password
             )
 
             assertThat(underTest.authenticate("alohomora".toList())).isFalse()
-            assertThat(failedAttemptCount).isEqualTo(1)
         }
 
     @Test
     fun authenticate_withCorrectPattern_returnsTrue() =
         testScope.runTest {
-            val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
             utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pattern(
-                    listOf(
-                        AuthenticationMethodModel.Pattern.PatternCoordinate(
-                            x = 0,
-                            y = 0,
-                        ),
-                        AuthenticationMethodModel.Pattern.PatternCoordinate(
-                            x = 0,
-                            y = 1,
-                        ),
-                        AuthenticationMethodModel.Pattern.PatternCoordinate(
-                            x = 0,
-                            y = 2,
-                        ),
-                    )
-                )
+                AuthenticationMethodModel.Pattern
             )
 
-            assertThat(
-                    underTest.authenticate(
-                        listOf(
-                            AuthenticationMethodModel.Pattern.PatternCoordinate(
-                                x = 0,
-                                y = 0,
-                            ),
-                            AuthenticationMethodModel.Pattern.PatternCoordinate(
-                                x = 0,
-                                y = 1,
-                            ),
-                            AuthenticationMethodModel.Pattern.PatternCoordinate(
-                                x = 0,
-                                y = 2,
-                            ),
-                        )
-                    )
-                )
-                .isTrue()
-            assertThat(failedAttemptCount).isEqualTo(0)
+            assertThat(underTest.authenticate(FakeAuthenticationRepository.PATTERN)).isTrue()
         }
 
     @Test
     fun authenticate_withIncorrectPattern_returnsFalse() =
         testScope.runTest {
-            val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
             utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pattern(
-                    listOf(
-                        AuthenticationMethodModel.Pattern.PatternCoordinate(
-                            x = 0,
-                            y = 0,
-                        ),
-                        AuthenticationMethodModel.Pattern.PatternCoordinate(
-                            x = 0,
-                            y = 1,
-                        ),
-                        AuthenticationMethodModel.Pattern.PatternCoordinate(
-                            x = 0,
-                            y = 2,
-                        ),
-                    )
-                )
+                AuthenticationMethodModel.Pattern
             )
 
             assertThat(
@@ -299,91 +262,159 @@
                     )
                 )
                 .isFalse()
-            assertThat(failedAttemptCount).isEqualTo(1)
-        }
-
-    @Test
-    fun tryAutoConfirm_withAutoConfirmPinAndEmptyInput_returnsNull() =
-        testScope.runTest {
-            val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234, autoConfirm = true)
-            )
-
-            assertThat(underTest.authenticate(listOf(), tryAutoConfirm = true)).isNull()
-            assertThat(failedAttemptCount).isEqualTo(0)
         }
 
     @Test
     fun tryAutoConfirm_withAutoConfirmPinAndShorterPin_returnsNullAndHasNoEffect() =
         testScope.runTest {
-            val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234, autoConfirm = true)
-            )
-
+            val isThrottled by collectLastValue(underTest.isThrottled)
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+            utils.authenticationRepository.setAutoConfirmEnabled(true)
             assertThat(underTest.authenticate(listOf(1, 2, 3), tryAutoConfirm = true)).isNull()
-            assertThat(failedAttemptCount).isEqualTo(0)
+            assertThat(isThrottled).isFalse()
         }
 
     @Test
     fun tryAutoConfirm_withAutoConfirmWrongPinCorrectLength_returnsFalseAndDoesNotUnlockDevice() =
         testScope.runTest {
-            val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234, autoConfirm = true)
-            )
-
+            val isUnlocked by collectLastValue(underTest.isUnlocked)
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+            utils.authenticationRepository.setAutoConfirmEnabled(true)
             assertThat(underTest.authenticate(listOf(1, 2, 4, 4), tryAutoConfirm = true)).isFalse()
-            assertThat(failedAttemptCount).isEqualTo(1)
+            assertThat(isUnlocked).isFalse()
         }
 
     @Test
     fun tryAutoConfirm_withAutoConfirmLongerPin_returnsFalseAndDoesNotUnlockDevice() =
         testScope.runTest {
-            val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234, autoConfirm = true)
-            )
-
+            val isUnlocked by collectLastValue(underTest.isUnlocked)
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+            utils.authenticationRepository.setAutoConfirmEnabled(true)
             assertThat(underTest.authenticate(listOf(1, 2, 3, 4, 5), tryAutoConfirm = true))
                 .isFalse()
-            assertThat(failedAttemptCount).isEqualTo(1)
+            assertThat(isUnlocked).isFalse()
         }
 
     @Test
     fun tryAutoConfirm_withAutoConfirmCorrectPin_returnsTrueAndUnlocksDevice() =
         testScope.runTest {
-            val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234, autoConfirm = true)
-            )
-
-            assertThat(underTest.authenticate(listOf(1, 2, 4, 4), tryAutoConfirm = true)).isFalse()
-            assertThat(failedAttemptCount).isEqualTo(1)
+            val isUnlocked by collectLastValue(underTest.isUnlocked)
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+            utils.authenticationRepository.setAutoConfirmEnabled(true)
+            assertThat(underTest.authenticate(listOf(1, 2, 3, 4), tryAutoConfirm = true)).isTrue()
+            assertThat(isUnlocked).isTrue()
         }
 
     @Test
     fun tryAutoConfirm_withoutAutoConfirmButCorrectPin_returnsNullAndHasNoEffects() =
         testScope.runTest {
-            val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234, autoConfirm = false)
-            )
-
+            val isUnlocked by collectLastValue(underTest.isUnlocked)
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+            utils.authenticationRepository.setAutoConfirmEnabled(false)
             assertThat(underTest.authenticate(listOf(1, 2, 3, 4), tryAutoConfirm = true)).isNull()
-            assertThat(failedAttemptCount).isEqualTo(0)
+            assertThat(isUnlocked).isFalse()
         }
 
     @Test
     fun tryAutoConfirm_withoutCorrectPassword_returnsNullAndHasNoEffects() =
         testScope.runTest {
-            val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
+            val isUnlocked by collectLastValue(underTest.isUnlocked)
             utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Password("password")
+                AuthenticationMethodModel.Password
             )
 
             assertThat(underTest.authenticate("password".toList(), tryAutoConfirm = true)).isNull()
-            assertThat(failedAttemptCount).isEqualTo(0)
+            assertThat(isUnlocked).isFalse()
+        }
+
+    @Test
+    fun throttling() =
+        testScope.runTest {
+            val isUnlocked by collectLastValue(underTest.isUnlocked)
+            val throttling by collectLastValue(underTest.throttling)
+            val isThrottled by collectLastValue(underTest.isThrottled)
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+            underTest.authenticate(listOf(1, 2, 3, 4))
+            assertThat(isUnlocked).isTrue()
+            assertThat(isThrottled).isFalse()
+            assertThat(throttling).isEqualTo(AuthenticationThrottlingModel())
+
+            utils.authenticationRepository.setUnlocked(false)
+            assertThat(isUnlocked).isFalse()
+            assertThat(isThrottled).isFalse()
+            assertThat(throttling).isEqualTo(AuthenticationThrottlingModel())
+
+            // Make many wrong attempts, but just shy of what's needed to get throttled:
+            repeat(FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING - 1) {
+                underTest.authenticate(listOf(5, 6, 7)) // Wrong PIN
+                assertThat(isUnlocked).isFalse()
+                assertThat(isThrottled).isFalse()
+                assertThat(throttling).isEqualTo(AuthenticationThrottlingModel())
+            }
+
+            // Make one more wrong attempt, leading to throttling:
+            underTest.authenticate(listOf(5, 6, 7)) // Wrong PIN
+            assertThat(isUnlocked).isFalse()
+            assertThat(isThrottled).isTrue()
+            assertThat(throttling)
+                .isEqualTo(
+                    AuthenticationThrottlingModel(
+                        failedAttemptCount =
+                            FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING,
+                        remainingMs = FakeAuthenticationRepository.THROTTLE_DURATION_MS,
+                    )
+                )
+
+            // Correct PIN, but throttled, so doesn't attempt it:
+            assertThat(underTest.authenticate(listOf(1, 2, 3, 4))).isNull()
+            assertThat(isUnlocked).isFalse()
+            assertThat(isThrottled).isTrue()
+            assertThat(throttling)
+                .isEqualTo(
+                    AuthenticationThrottlingModel(
+                        failedAttemptCount =
+                            FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING,
+                        remainingMs = FakeAuthenticationRepository.THROTTLE_DURATION_MS,
+                    )
+                )
+
+            // Move the clock forward to ALMOST skip the throttling, leaving one second to go:
+            val throttleTimeoutSec =
+                FakeAuthenticationRepository.THROTTLE_DURATION_MS.milliseconds.inWholeSeconds
+                    .toInt()
+            repeat(throttleTimeoutSec - 1) { time ->
+                advanceTimeBy(1000)
+                assertThat(isThrottled).isTrue()
+                assertThat(throttling)
+                    .isEqualTo(
+                        AuthenticationThrottlingModel(
+                            failedAttemptCount =
+                                FakeAuthenticationRepository
+                                    .MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING,
+                            remainingMs =
+                                ((throttleTimeoutSec - (time + 1)).seconds.inWholeMilliseconds)
+                                    .toInt(),
+                        )
+                    )
+            }
+
+            // Move the clock forward one more second, to completely finish the throttling period:
+            advanceTimeBy(1000)
+            assertThat(isUnlocked).isFalse()
+            assertThat(isThrottled).isFalse()
+            assertThat(throttling)
+                .isEqualTo(
+                    AuthenticationThrottlingModel(
+                        failedAttemptCount =
+                            FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING,
+                        remainingMs = 0,
+                    )
+                )
+
+            // Correct PIN and no longer throttled so unlocks successfully:
+            assertThat(underTest.authenticate(listOf(1, 2, 3, 4))).isTrue()
+            assertThat(isUnlocked).isTrue()
+            assertThat(isThrottled).isFalse()
+            assertThat(throttling).isEqualTo(AuthenticationThrottlingModel())
         }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
index d31a86a..e3e6130 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
@@ -51,6 +51,7 @@
 import com.android.systemui.flags.FakeFeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.WakefulnessLifecycle
+import com.android.systemui.statusbar.VibratorHelper
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
@@ -99,6 +100,8 @@
     lateinit var windowToken: IBinder
     @Mock
     lateinit var interactionJankMonitor: InteractionJankMonitor
+    @Mock
+    lateinit var vibrator: VibratorHelper
 
     // TODO(b/278622168): remove with flag
     open val useNewBiometricPrompt = false
@@ -325,7 +328,7 @@
             authenticators = BiometricManager.Authenticators.BIOMETRIC_WEAK or
                     BiometricManager.Authenticators.DEVICE_CREDENTIAL
         )
-        container.animateToCredentialUI()
+        container.animateToCredentialUI(false)
         waitForIdleSync()
 
         assertThat(container.hasCredentialView()).isTrue()
@@ -514,7 +517,7 @@
         { authBiometricFingerprintViewModel },
         { promptSelectorInteractor },
         { bpCredentialInteractor },
-        PromptViewModel(promptSelectorInteractor),
+        PromptViewModel(promptSelectorInteractor, vibrator),
         { credentialViewModel },
         Handler(TestableLooper.get(this).looper),
         fakeExecutor
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 5cae23c..3d4171f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -191,6 +191,10 @@
     private ArgumentCaptor<IFaceAuthenticatorsRegisteredCallback> mFaceAuthenticatorsRegisteredCaptor;
     @Captor
     private ArgumentCaptor<BiometricStateListener> mBiometricStateCaptor;
+    @Captor
+    private ArgumentCaptor<Integer> mModalityCaptor;
+    @Captor
+    private ArgumentCaptor<String> mMessageCaptor;
     @Mock
     private Resources mResources;
 
@@ -202,9 +206,6 @@
     private TestableAuthController mAuthController;
     private FakeFeatureFlags mFeatureFlags = new FakeFeatureFlags();
 
-    @Mock
-    private VibratorHelper mVibratorHelper;
-
     @Before
     public void setup() throws RemoteException {
         // TODO(b/278622168): remove with flag
@@ -267,7 +268,6 @@
                         true /* supportsSelfIllumination */,
                         true /* resetLockoutRequireHardwareAuthToken */));
         when(mFaceManager.getSensorPropertiesInternal()).thenReturn(faceProps);
-        when(mVibratorHelper.hasVibrator()).thenReturn(true);
 
         mAuthController = new TestableAuthController(mContextSpy);
 
@@ -482,17 +482,26 @@
                 BiometricConstants.BIOMETRIC_PAUSED_REJECTED,
                 0 /* vendorCode */);
 
-        ArgumentCaptor<Integer> modalityCaptor = ArgumentCaptor.forClass(Integer.class);
-        ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
-        verify(mDialog1).onAuthenticationFailed(modalityCaptor.capture(), messageCaptor.capture());
+        verify(mDialog1).onAuthenticationFailed(mModalityCaptor.capture(), mMessageCaptor.capture());
 
-        assertEquals(modalityCaptor.getValue().intValue(), modality);
-        assertEquals(messageCaptor.getValue(),
+        assertEquals(mModalityCaptor.getValue().intValue(), modality);
+        assertEquals(mMessageCaptor.getValue(),
                 mContext.getString(R.string.biometric_not_recognized));
     }
 
     @Test
-    public void testOnAuthenticationFailedInvoked_whenFaceAuthRejected() throws RemoteException {
+    public void testOnAuthenticationFailedInvoked_coex_whenFaceAuthRejected_withPaused() {
+        testOnAuthenticationFailedInvoked_coex_whenFaceAuthRejected(
+                BiometricConstants.BIOMETRIC_PAUSED_REJECTED);
+    }
+
+    @Test
+    public void testOnAuthenticationFailedInvoked_coex_whenFaceAuthRejected_withTimeout() {
+        testOnAuthenticationFailedInvoked_coex_whenFaceAuthRejected(
+                BiometricConstants.BIOMETRIC_ERROR_TIMEOUT);
+    }
+
+    private void testOnAuthenticationFailedInvoked_coex_whenFaceAuthRejected(int error) {
         final int modality = BiometricAuthenticator.TYPE_FACE;
         final int userId = 0;
 
@@ -500,16 +509,12 @@
 
         showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
 
-        mAuthController.onBiometricError(modality,
-                BiometricConstants.BIOMETRIC_PAUSED_REJECTED,
-                0 /* vendorCode */);
+        mAuthController.onBiometricError(modality, error, 0 /* vendorCode */);
 
-        ArgumentCaptor<Integer> modalityCaptor = ArgumentCaptor.forClass(Integer.class);
-        ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
-        verify(mDialog1).onAuthenticationFailed(modalityCaptor.capture(), messageCaptor.capture());
+        verify(mDialog1).onAuthenticationFailed(mModalityCaptor.capture(), mMessageCaptor.capture());
 
-        assertEquals(modalityCaptor.getValue().intValue(), modality);
-        assertEquals(messageCaptor.getValue(),
+        assertThat(mModalityCaptor.getValue().intValue()).isEqualTo(modality);
+        assertThat(mMessageCaptor.getValue()).isEqualTo(
                 mContext.getString(R.string.biometric_face_not_recognized));
     }
 
@@ -526,12 +531,10 @@
                 BiometricConstants.BIOMETRIC_PAUSED_REJECTED,
                 0 /* vendorCode */);
 
-        ArgumentCaptor<Integer> modalityCaptor = ArgumentCaptor.forClass(Integer.class);
-        ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
-        verify(mDialog1).onAuthenticationFailed(modalityCaptor.capture(), messageCaptor.capture());
+        verify(mDialog1).onAuthenticationFailed(mModalityCaptor.capture(), mMessageCaptor.capture());
 
-        assertEquals(modalityCaptor.getValue().intValue(), modality);
-        assertEquals(messageCaptor.getValue(),
+        assertThat(mModalityCaptor.getValue().intValue()).isEqualTo(modality);
+        assertThat(mMessageCaptor.getValue()).isEqualTo(
                 mContext.getString(R.string.fingerprint_error_not_match));
     }
 
@@ -543,13 +546,11 @@
         final int vendorCode = 0;
         mAuthController.onBiometricError(modality, error, vendorCode);
 
-        ArgumentCaptor<Integer> modalityCaptor = ArgumentCaptor.forClass(Integer.class);
-        ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
-        verify(mDialog1).onAuthenticationFailed(modalityCaptor.capture(), messageCaptor.capture());
+        verify(mDialog1).onAuthenticationFailed(mModalityCaptor.capture(), mMessageCaptor.capture());
 
-        assertEquals(modalityCaptor.getValue().intValue(), modality);
-        assertEquals(messageCaptor.getValue(),
-                FaceManager.getErrorString(mContext, error, vendorCode));
+        assertThat(mModalityCaptor.getValue().intValue()).isEqualTo(modality);
+        assertThat(mMessageCaptor.getValue()).isEqualTo(
+                mContext.getString(R.string.biometric_not_recognized));
     }
 
     @Test
@@ -559,12 +560,10 @@
         final String helpMessage = "help";
         mAuthController.onBiometricHelp(modality, helpMessage);
 
-        ArgumentCaptor<Integer> modalityCaptor = ArgumentCaptor.forClass(Integer.class);
-        ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
-        verify(mDialog1).onHelp(modalityCaptor.capture(), messageCaptor.capture());
+        verify(mDialog1).onHelp(mModalityCaptor.capture(), mMessageCaptor.capture());
 
-        assertEquals(modalityCaptor.getValue().intValue(), modality);
-        assertEquals(messageCaptor.getValue(), helpMessage);
+        assertThat(mModalityCaptor.getValue().intValue()).isEqualTo(modality);
+        assertThat(mMessageCaptor.getValue()).isEqualTo(helpMessage);
     }
 
     @Test
@@ -575,12 +574,10 @@
         final int vendorCode = 0;
         mAuthController.onBiometricError(modality, error, vendorCode);
 
-        ArgumentCaptor<Integer> modalityCaptor = ArgumentCaptor.forClass(Integer.class);
-        ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
-        verify(mDialog1).onError(modalityCaptor.capture(), messageCaptor.capture());
+        verify(mDialog1).onError(mModalityCaptor.capture(), mMessageCaptor.capture());
 
-        assertEquals(modalityCaptor.getValue().intValue(), modality);
-        assertEquals(messageCaptor.getValue(),
+        assertThat(mModalityCaptor.getValue().intValue()).isEqualTo(modality);
+        assertThat(mMessageCaptor.getValue()).isEqualTo(
                 FaceManager.getErrorString(mContext, error, vendorCode));
     }
 
@@ -594,7 +591,7 @@
 
         mAuthController.onBiometricError(BiometricAuthenticator.TYPE_FACE, error, vendorCode);
         verify(mDialog1, never()).onError(anyInt(), anyString());
-        verify(mDialog1).animateToCredentialUI();
+        verify(mDialog1).animateToCredentialUI(eq(true));
     }
 
     @Test
@@ -607,7 +604,7 @@
 
         mAuthController.onBiometricError(BiometricAuthenticator.TYPE_FACE, error, vendorCode);
         verify(mDialog1, never()).onError(anyInt(), anyString());
-        verify(mDialog1).animateToCredentialUI();
+        verify(mDialog1).animateToCredentialUI(eq(true));
     }
 
     @Test
@@ -622,7 +619,7 @@
         mAuthController.onBiometricError(modality, error, vendorCode);
         verify(mDialog1).onError(
                 eq(modality), eq(FaceManager.getErrorString(mContext, error, vendorCode)));
-        verify(mDialog1, never()).animateToCredentialUI();
+        verify(mDialog1, never()).animateToCredentialUI(eq(true));
     }
 
     @Test
@@ -637,7 +634,7 @@
         mAuthController.onBiometricError(modality, error, vendorCode);
         verify(mDialog1).onError(
                 eq(modality), eq(FaceManager.getErrorString(mContext, error, vendorCode)));
-        verify(mDialog1, never()).animateToCredentialUI();
+        verify(mDialog1, never()).animateToCredentialUI(eq(true));
     }
 
     @Test
@@ -1100,7 +1097,7 @@
                     () -> mBiometricPromptCredentialInteractor, () -> mPromptSelectionInteractor,
                     () -> mCredentialViewModel, () -> mPromptViewModel,
                     mInteractionJankMonitor, mHandler,
-                    mBackgroundExecutor, mVibratorHelper, mUdfpsUtils);
+                    mBackgroundExecutor, mUdfpsUtils);
         }
 
         @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractorImplTest.kt
index 97d3e68..5eda2b2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractorImplTest.kt
@@ -11,8 +11,8 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.domain.model.BiometricOperationInfo
 import com.android.systemui.biometrics.domain.model.BiometricPromptRequest
-import com.android.systemui.biometrics.domain.model.BiometricUserInfo
 import com.android.systemui.biometrics.promptInfo
+import com.android.systemui.biometrics.shared.model.BiometricUserInfo
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.whenever
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractorTest.kt
index 720a35c9..dcefea2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractorTest.kt
@@ -7,8 +7,8 @@
 import com.android.systemui.biometrics.data.repository.FakePromptRepository
 import com.android.systemui.biometrics.domain.model.BiometricOperationInfo
 import com.android.systemui.biometrics.domain.model.BiometricPromptRequest
-import com.android.systemui.biometrics.domain.model.BiometricUserInfo
 import com.android.systemui.biometrics.promptInfo
+import com.android.systemui.biometrics.shared.model.BiometricUserInfo
 import com.android.systemui.coroutines.collectLastValue
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequestTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequestTest.kt
index e352905..be0276a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequestTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequestTest.kt
@@ -4,6 +4,7 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.fingerprintSensorPropertiesInternal
 import com.android.systemui.biometrics.promptInfo
+import com.android.systemui.biometrics.shared.model.BiometricUserInfo
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptAuthStateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptAuthStateTest.kt
index fff1b81..278a43e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptAuthStateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptAuthStateTest.kt
@@ -18,7 +18,7 @@
 
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.biometrics.domain.model.BiometricModality
+import com.android.systemui.biometrics.shared.model.BiometricModality
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
index 5b3edab..91140a9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
@@ -27,11 +27,14 @@
 import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor
 import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractorImpl
 import com.android.systemui.biometrics.domain.model.BiometricModalities
-import com.android.systemui.biometrics.domain.model.BiometricModality
 import com.android.systemui.biometrics.extractAuthenticatorTypes
 import com.android.systemui.biometrics.faceSensorPropertiesInternal
 import com.android.systemui.biometrics.fingerprintSensorPropertiesInternal
+import com.android.systemui.biometrics.shared.model.BiometricModality
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.coroutines.collectValues
+import com.android.systemui.statusbar.VibratorHelper
+import com.android.systemui.util.mockito.any
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.first
@@ -45,6 +48,9 @@
 import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
 import org.mockito.Mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
 import org.mockito.junit.MockitoJUnit
 
 private const val USER_ID = 4
@@ -58,6 +64,7 @@
     @JvmField @Rule var mockitoRule = MockitoJUnit.rule()
 
     @Mock private lateinit var lockPatternUtils: LockPatternUtils
+    @Mock private lateinit var vibrator: VibratorHelper
 
     private val testScope = TestScope()
     private val promptRepository = FakePromptRepository()
@@ -70,11 +77,11 @@
         selector = PromptSelectorInteractorImpl(promptRepository, lockPatternUtils)
         selector.resetPrompt()
 
-        viewModel = PromptViewModel(selector)
+        viewModel = PromptViewModel(selector, vibrator)
     }
 
     @Test
-    fun `start idle and show authenticating`() =
+    fun start_idle_and_show_authenticating() =
         runGenericTest(doNotStart = true) {
             val expectedSize =
                 if (testCase.shouldStartAsImplicitFlow) PromptSize.SMALL else PromptSize.MEDIUM
@@ -107,7 +114,7 @@
         }
 
     @Test
-    fun `shows authenticated - no errors`() = runGenericTest {
+    fun shows_authenticated_with_no_errors() = runGenericTest {
         // this case can't happen until fingerprint is started
         // trigger it now since no error has occurred in this test
         val forceError = testCase.isCoex && testCase.authenticatedByFingerprint
@@ -124,6 +131,24 @@
         )
     }
 
+    @Test
+    fun play_haptic_on_confirm_when_confirmation_required_otherwise_on_authenticated() =
+        runGenericTest {
+            val expectConfirmation = testCase.expectConfirmation(atLeastOneFailure = false)
+
+            viewModel.showAuthenticated(testCase.authenticatedModality, 1_000L)
+
+            verify(vibrator, if (expectConfirmation) never() else times(1))
+                .vibrateAuthSuccess(any())
+
+            if (expectConfirmation) {
+                viewModel.confirmAuthenticated()
+            }
+
+            verify(vibrator).vibrateAuthSuccess(any())
+            verify(vibrator, never()).vibrateAuthError(any())
+        }
+
     private suspend fun TestScope.showAuthenticated(
         authenticatedModality: BiometricModality,
         expectConfirmation: Boolean,
@@ -172,7 +197,7 @@
     }
 
     @Test
-    fun `shows temporary errors`() = runGenericTest {
+    fun shows_temporary_errors() = runGenericTest {
         val checkAtEnd = suspend { assertButtonsVisible(negative = true) }
 
         showTemporaryErrors(restart = false) { checkAtEnd() }
@@ -180,6 +205,32 @@
         showTemporaryErrors(restart = true) { checkAtEnd() }
     }
 
+    @Test
+    fun plays_haptic_on_errors() = runGenericTest {
+        viewModel.showTemporaryError(
+            "so sad",
+            messageAfterError = "",
+            authenticateAfterError = false,
+            hapticFeedback = true,
+        )
+
+        verify(vibrator).vibrateAuthError(any())
+        verify(vibrator, never()).vibrateAuthSuccess(any())
+    }
+
+    @Test
+    fun plays_haptic_on_errors_unless_skipped() = runGenericTest {
+        viewModel.showTemporaryError(
+            "still sad",
+            messageAfterError = "",
+            authenticateAfterError = false,
+            hapticFeedback = false,
+        )
+
+        verify(vibrator, never()).vibrateAuthError(any())
+        verify(vibrator, never()).vibrateAuthSuccess(any())
+    }
+
     private suspend fun TestScope.showTemporaryErrors(
         restart: Boolean,
         helpAfterError: String = "",
@@ -233,7 +284,7 @@
     }
 
     @Test
-    fun `no errors or temporary help after authenticated`() = runGenericTest {
+    fun no_errors_or_temporary_help_after_authenticated() = runGenericTest {
         val authenticating by collectLastValue(viewModel.isAuthenticating)
         val authenticated by collectLastValue(viewModel.isAuthenticated)
         val message by collectLastValue(viewModel.message)
@@ -249,7 +300,13 @@
             assertThat(canTryAgain).isFalse()
         }
 
-        val errorJob = launch { viewModel.showTemporaryError("error") }
+        val errorJob = launch {
+            viewModel.showTemporaryError(
+                "error",
+                messageAfterError = "",
+                authenticateAfterError = false,
+            )
+        }
         verifyNoError()
         errorJob.join()
         verifyNoError()
@@ -268,16 +325,70 @@
         assertThat(messageIsShowing).isTrue()
     }
 
-    //    @Test
-    fun `suppress errors`() = runGenericTest {
-        val errorMessage = "woot"
-        val message by collectLastValue(viewModel.message)
+    @Test
+    fun suppress_temporary_error() = runGenericTest {
+        val messages by collectValues(viewModel.message)
 
-        val errorJob = launch { viewModel.showTemporaryError(errorMessage) }
+        for (error in listOf("never", "see", "me")) {
+            launch {
+                viewModel.showTemporaryError(
+                    error,
+                    messageAfterError = "or me",
+                    authenticateAfterError = false,
+                    suppressIf = { _ -> true },
+                )
+            }
+        }
+
+        testScheduler.advanceUntilIdle()
+        assertThat(messages).containsExactly(PromptMessage.Empty)
     }
 
     @Test
-    fun `authenticated at most once`() = runGenericTest {
+    fun suppress_temporary_error_when_already_showing_when_requested() =
+        suppress_temporary_error_when_already_showing(suppress = true)
+
+    @Test
+    fun do_not_suppress_temporary_error_when_already_showing_when_not_requested() =
+        suppress_temporary_error_when_already_showing(suppress = false)
+
+    private fun suppress_temporary_error_when_already_showing(suppress: Boolean) = runGenericTest {
+        val errors = listOf("woot", "oh yeah", "nope")
+        val afterSuffix = "(after)"
+        val expectedErrorMessage = if (suppress) errors.first() else errors.last()
+        val messages by collectValues(viewModel.message)
+
+        for (error in errors) {
+            launch {
+                viewModel.showTemporaryError(
+                    error,
+                    messageAfterError = "$error $afterSuffix",
+                    authenticateAfterError = false,
+                    suppressIf = { currentMessage -> suppress && currentMessage.isError },
+                )
+            }
+        }
+
+        testScheduler.runCurrent()
+        assertThat(messages)
+            .containsExactly(
+                PromptMessage.Empty,
+                PromptMessage.Error(expectedErrorMessage),
+            )
+            .inOrder()
+
+        testScheduler.advanceUntilIdle()
+        assertThat(messages)
+            .containsExactly(
+                PromptMessage.Empty,
+                PromptMessage.Error(expectedErrorMessage),
+                PromptMessage.Help("$expectedErrorMessage $afterSuffix"),
+            )
+            .inOrder()
+    }
+
+    @Test
+    fun authenticated_at_most_once() = runGenericTest {
         val authenticating by collectLastValue(viewModel.isAuthenticating)
         val authenticated by collectLastValue(viewModel.isAuthenticated)
 
@@ -293,7 +404,7 @@
     }
 
     @Test
-    fun `authenticating cannot restart after authenticated`() = runGenericTest {
+    fun authenticating_cannot_restart_after_authenticated() = runGenericTest {
         val authenticating by collectLastValue(viewModel.isAuthenticating)
         val authenticated by collectLastValue(viewModel.isAuthenticated)
 
@@ -309,7 +420,7 @@
     }
 
     @Test
-    fun `confirm authentication`() = runGenericTest {
+    fun confirm_authentication() = runGenericTest {
         val expectConfirmation = testCase.expectConfirmation(atLeastOneFailure = false)
 
         viewModel.showAuthenticated(testCase.authenticatedModality, 0)
@@ -341,7 +452,7 @@
     }
 
     @Test
-    fun `cannot confirm unless authenticated`() = runGenericTest {
+    fun cannot_confirm_unless_authenticated() = runGenericTest {
         val authenticating by collectLastValue(viewModel.isAuthenticating)
         val authenticated by collectLastValue(viewModel.isAuthenticated)
 
@@ -360,7 +471,7 @@
     }
 
     @Test
-    fun `shows help - before authenticated`() = runGenericTest {
+    fun shows_help_before_authenticated() = runGenericTest {
         val helpMessage = "please help yourself to some cookies"
         val message by collectLastValue(viewModel.message)
         val messageVisible by collectLastValue(viewModel.isIndicatorMessageVisible)
@@ -379,7 +490,7 @@
     }
 
     @Test
-    fun `shows help - after authenticated`() = runGenericTest {
+    fun shows_help_after_authenticated() = runGenericTest {
         val expectConfirmation = testCase.expectConfirmation(atLeastOneFailure = false)
         val helpMessage = "more cookies please"
         val authenticating by collectLastValue(viewModel.isAuthenticating)
@@ -409,7 +520,7 @@
     }
 
     @Test
-    fun `retries after failure`() = runGenericTest {
+    fun retries_after_failure() = runGenericTest {
         val errorMessage = "bad"
         val helpMessage = "again?"
         val expectTryAgainButton = testCase.isFaceOnly
@@ -455,7 +566,7 @@
     }
 
     @Test
-    fun `switch to credential fallback`() = runGenericTest {
+    fun switch_to_credential_fallback() = runGenericTest {
         val size by collectLastValue(viewModel.size)
 
         // TODO(b/251476085): remove Spaghetti, migrate logic, and update this test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
index d09353b..481f36e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
@@ -19,12 +19,16 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.authentication.shared.model.AuthenticationThrottlingModel
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.scene.SceneTestUtils
 import com.android.systemui.scene.shared.model.SceneKey
 import com.android.systemui.scene.shared.model.SceneModel
 import com.google.common.truth.Truth.assertThat
+import kotlin.math.ceil
+import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runCurrent
@@ -65,14 +69,13 @@
     @Test
     fun pinAuthMethod() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             val message by collectLastValue(underTest.message)
 
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             utils.authenticationRepository.setUnlocked(false)
-            underTest.showOrUnlockDevice("container1")
+            underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1)
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
             assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PIN)
 
@@ -98,14 +101,14 @@
     @Test
     fun pinAuthMethod_tryAutoConfirm_withAutoConfirmPin() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             val message by collectLastValue(underTest.message)
 
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234, autoConfirm = true)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+            utils.authenticationRepository.setAutoConfirmEnabled(true)
             utils.authenticationRepository.setUnlocked(false)
-            underTest.showOrUnlockDevice("container1")
+            underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1)
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
             assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PIN)
             underTest.clearMessage()
@@ -128,14 +131,13 @@
     @Test
     fun pinAuthMethod_tryAutoConfirm_withoutAutoConfirmPin() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             val message by collectLastValue(underTest.message)
 
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234, autoConfirm = false)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             utils.authenticationRepository.setUnlocked(false)
-            underTest.showOrUnlockDevice("container1")
+            underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1)
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
             underTest.clearMessage()
 
@@ -153,13 +155,14 @@
     @Test
     fun passwordAuthMethod() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             val message by collectLastValue(underTest.message)
             utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Password("password")
+                AuthenticationMethodModel.Password
             )
             utils.authenticationRepository.setUnlocked(false)
-            underTest.showOrUnlockDevice("container1")
+            underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1)
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
             assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PASSWORD)
 
@@ -185,13 +188,14 @@
     @Test
     fun patternAuthMethod() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             val message by collectLastValue(underTest.message)
             utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pattern(emptyList())
+                AuthenticationMethodModel.Pattern
             )
             utils.authenticationRepository.setUnlocked(false)
-            underTest.showOrUnlockDevice("container1")
+            underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1)
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
             assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PATTERN)
 
@@ -204,7 +208,7 @@
             // Wrong input.
             assertThat(
                     underTest.authenticate(
-                        listOf(AuthenticationMethodModel.Pattern.PatternCoordinate(3, 4))
+                        listOf(AuthenticationMethodModel.Pattern.PatternCoordinate(1, 2))
                     )
                 )
                 .isFalse()
@@ -215,21 +219,20 @@
             assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PATTERN)
 
             // Correct input.
-            assertThat(underTest.authenticate(emptyList())).isTrue()
+            assertThat(underTest.authenticate(FakeAuthenticationRepository.PATTERN)).isTrue()
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
         }
 
     @Test
     fun showOrUnlockDevice_notLocked_switchesToGoneScene() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             utils.authenticationRepository.setUnlocked(true)
             runCurrent()
 
-            underTest.showOrUnlockDevice("container1")
+            underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1)
 
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
         }
@@ -237,11 +240,12 @@
     @Test
     fun showOrUnlockDevice_authMethodNotSecure_switchesToGoneScene() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
             utils.authenticationRepository.setUnlocked(false)
 
-            underTest.showOrUnlockDevice("container1")
+            underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1)
 
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
         }
@@ -249,15 +253,16 @@
     @Test
     fun showOrUnlockDevice_customMessageShown() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             val message by collectLastValue(underTest.message)
             utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Password("password")
+                AuthenticationMethodModel.Password
             )
             utils.authenticationRepository.setUnlocked(false)
 
             val customMessage = "Hello there!"
-            underTest.showOrUnlockDevice("container1", customMessage)
+            underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1, customMessage)
 
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
             assertThat(message).isEqualTo(customMessage)
@@ -266,67 +271,78 @@
     @Test
     fun throttling() =
         testScope.runTest {
+            val isThrottled by collectLastValue(underTest.isThrottled)
             val throttling by collectLastValue(underTest.throttling)
             val message by collectLastValue(underTest.message)
             val currentScene by
                 collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             runCurrent()
             underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1)
             runCurrent()
             assertThat(currentScene?.key).isEqualTo(SceneKey.Bouncer)
-            assertThat(throttling).isNull()
+            assertThat(isThrottled).isFalse()
+            assertThat(throttling).isEqualTo(AuthenticationThrottlingModel())
             assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PIN)
-            repeat(BouncerInteractor.THROTTLE_EVERY) { times ->
+            repeat(FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING) { times ->
                 // Wrong PIN.
                 assertThat(underTest.authenticate(listOf(6, 7, 8, 9))).isFalse()
-                if (times < BouncerInteractor.THROTTLE_EVERY - 1) {
+                if (
+                    times < FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING - 1
+                ) {
                     assertThat(message).isEqualTo(MESSAGE_WRONG_PIN)
                 }
             }
-            assertThat(throttling).isNotNull()
-            assertTryAgainMessage(message, BouncerInteractor.THROTTLE_DURATION_SEC)
+            assertThat(isThrottled).isTrue()
+            assertThat(throttling)
+                .isEqualTo(
+                    AuthenticationThrottlingModel(
+                        failedAttemptCount =
+                            FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING,
+                        remainingMs = FakeAuthenticationRepository.THROTTLE_DURATION_MS,
+                    )
+                )
+            assertTryAgainMessage(
+                message,
+                FakeAuthenticationRepository.THROTTLE_DURATION_MS.milliseconds.inWholeSeconds
+                    .toInt()
+            )
 
             // Correct PIN, but throttled, so doesn't change away from the bouncer scene:
-            assertThat(underTest.authenticate(listOf(1, 2, 3, 4))).isFalse()
+            assertThat(underTest.authenticate(listOf(1, 2, 3, 4))).isNull()
             assertThat(currentScene?.key).isEqualTo(SceneKey.Bouncer)
-            assertTryAgainMessage(message, BouncerInteractor.THROTTLE_DURATION_SEC)
+            assertTryAgainMessage(
+                message,
+                FakeAuthenticationRepository.THROTTLE_DURATION_MS.milliseconds.inWholeSeconds
+                    .toInt()
+            )
 
-            throttling?.totalDurationSec?.let { seconds ->
+            throttling?.remainingMs?.let { remainingMs ->
+                val seconds = ceil(remainingMs / 1000f).toInt()
                 repeat(seconds) { time ->
                     advanceTimeBy(1000)
-                    val remainingTime = seconds - time - 1
-                    if (remainingTime > 0) {
-                        assertTryAgainMessage(message, remainingTime)
+                    val remainingTimeSec = seconds - time - 1
+                    if (remainingTimeSec > 0) {
+                        assertTryAgainMessage(message, remainingTimeSec)
                     }
                 }
             }
             assertThat(message).isEqualTo("")
-            assertThat(throttling).isNull()
+            assertThat(isThrottled).isFalse()
+            assertThat(throttling)
+                .isEqualTo(
+                    AuthenticationThrottlingModel(
+                        failedAttemptCount =
+                            FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING,
+                    )
+                )
             assertThat(currentScene?.key).isEqualTo(SceneKey.Bouncer)
 
             // Correct PIN and no longer throttled so changes to the Gone scene:
             assertThat(underTest.authenticate(listOf(1, 2, 3, 4))).isTrue()
             assertThat(currentScene?.key).isEqualTo(SceneKey.Gone)
-        }
-
-    @Test
-    fun switchesToGone_whenUnlocked() =
-        testScope.runTest {
-            utils.authenticationRepository.setUnlocked(false)
-            sceneInteractor.setCurrentScene(
-                SceneTestUtils.CONTAINER_1,
-                SceneModel(SceneKey.Bouncer)
-            )
-            val currentScene by
-                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
-            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
-
-            utils.authenticationRepository.setUnlocked(true)
-
-            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
+            assertThat(isThrottled).isFalse()
+            assertThat(throttling).isEqualTo(AuthenticationThrottlingModel())
         }
 
     private fun assertTryAgainMessage(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
index f811ce0..0867558 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
@@ -55,10 +55,8 @@
     @Test
     fun animateFailure() =
         testScope.runTest {
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
             val animateFailure by collectLastValue(underTest.animateFailure)
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             assertThat(animateFailure).isFalse()
 
             // Wrong PIN:
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
index 5ffc471..0df0a17 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
@@ -18,8 +18,8 @@
 
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
-import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.scene.SceneTestUtils
 import com.google.common.truth.Truth.assertThat
@@ -52,7 +52,10 @@
             authenticationInteractor = authenticationInteractor,
             sceneInteractor = utils.sceneInteractor(),
         )
-    private val underTest = utils.bouncerViewModel(bouncerInteractor)
+    private val underTest =
+        utils.bouncerViewModel(
+            bouncerInteractor = bouncerInteractor,
+        )
 
     @Test
     fun authMethod_nonNullForSecureMethods_nullForNotSecureMethods() =
@@ -110,18 +113,16 @@
         testScope.runTest {
             val message by collectLastValue(underTest.message)
             val throttling by collectLastValue(bouncerInteractor.throttling)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             assertThat(message?.isUpdateAnimated).isTrue()
 
-            repeat(BouncerInteractor.THROTTLE_EVERY) {
+            repeat(FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING) {
                 // Wrong PIN.
                 bouncerInteractor.authenticate(listOf(3, 4, 5, 6))
             }
             assertThat(message?.isUpdateAnimated).isFalse()
 
-            throttling?.totalDurationSec?.let { seconds -> advanceTimeBy(seconds * 1000L) }
+            throttling?.remainingMs?.let { remainingMs -> advanceTimeBy(remainingMs.toLong()) }
             assertThat(message?.isUpdateAnimated).isTrue()
         }
 
@@ -135,18 +136,16 @@
                     }
                 )
             val throttling by collectLastValue(bouncerInteractor.throttling)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             assertThat(isInputEnabled).isTrue()
 
-            repeat(BouncerInteractor.THROTTLE_EVERY) {
+            repeat(FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING) {
                 // Wrong PIN.
                 bouncerInteractor.authenticate(listOf(3, 4, 5, 6))
             }
             assertThat(isInputEnabled).isFalse()
 
-            throttling?.totalDurationSec?.let { seconds -> advanceTimeBy(seconds * 1000L) }
+            throttling?.remainingMs?.let { milliseconds -> advanceTimeBy(milliseconds.toLong()) }
             assertThat(isInputEnabled).isTrue()
         }
 
@@ -154,11 +153,9 @@
     fun throttlingDialogMessage() =
         testScope.runTest {
             val throttlingDialogMessage by collectLastValue(underTest.throttlingDialogMessage)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
 
-            repeat(BouncerInteractor.THROTTLE_EVERY) {
+            repeat(FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING) {
                 // Wrong PIN.
                 assertThat(throttlingDialogMessage).isNull()
                 bouncerInteractor.authenticate(listOf(3, 4, 5, 6))
@@ -173,11 +170,9 @@
         return listOf(
             AuthenticationMethodModel.None,
             AuthenticationMethodModel.Swipe,
-            AuthenticationMethodModel.Pin(1234),
-            AuthenticationMethodModel.Password("password"),
-            AuthenticationMethodModel.Pattern(
-                listOf(AuthenticationMethodModel.Pattern.PatternCoordinate(1, 1))
-            ),
+            AuthenticationMethodModel.Pin,
+            AuthenticationMethodModel.Password,
+            AuthenticationMethodModel.Pattern,
         )
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
index 699571b..b1533fe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
@@ -72,14 +72,18 @@
     @Test
     fun onShown() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             val message by collectLastValue(bouncerViewModel.message)
             val password by collectLastValue(underTest.password)
             utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Password("password")
+                AuthenticationMethodModel.Password
             )
             utils.authenticationRepository.setUnlocked(false)
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Bouncer)
+            )
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
 
             underTest.onShown()
@@ -92,14 +96,18 @@
     @Test
     fun onPasswordInputChanged() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             val message by collectLastValue(bouncerViewModel.message)
             val password by collectLastValue(underTest.password)
             utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Password("password")
+                AuthenticationMethodModel.Password
             )
             utils.authenticationRepository.setUnlocked(false)
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Bouncer)
+            )
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
             underTest.onShown()
             runCurrent()
@@ -114,12 +122,16 @@
     @Test
     fun onAuthenticateKeyPressed_whenCorrect() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Password("password")
+                AuthenticationMethodModel.Password
             )
             utils.authenticationRepository.setUnlocked(false)
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Bouncer)
+            )
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
             underTest.onShown()
             underTest.onPasswordInputChanged("password")
@@ -132,14 +144,18 @@
     @Test
     fun onAuthenticateKeyPressed_whenWrong() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             val message by collectLastValue(bouncerViewModel.message)
             val password by collectLastValue(underTest.password)
             utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Password("password")
+                AuthenticationMethodModel.Password
             )
             utils.authenticationRepository.setUnlocked(false)
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Bouncer)
+            )
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
             underTest.onShown()
             underTest.onPasswordInputChanged("wrong")
@@ -154,14 +170,18 @@
     @Test
     fun onAuthenticateKeyPressed_correctAfterWrong() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             val message by collectLastValue(bouncerViewModel.message)
             val password by collectLastValue(underTest.password)
             utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Password("password")
+                AuthenticationMethodModel.Password
             )
             utils.authenticationRepository.setUnlocked(false)
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Bouncer)
+            )
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
             underTest.onShown()
             underTest.onPasswordInputChanged("wrong")
@@ -180,7 +200,6 @@
         }
 
     companion object {
-        private const val CONTAINER_NAME = "container1"
         private const val ENTER_YOUR_PASSWORD = "Enter your password"
         private const val WRONG_PASSWORD = "Wrong password"
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
index 9a1f584..f69cbb8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
@@ -19,6 +19,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.scene.SceneTestUtils
@@ -74,15 +75,19 @@
     @Test
     fun onShown() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             val message by collectLastValue(bouncerViewModel.message)
             val selectedDots by collectLastValue(underTest.selectedDots)
             val currentDot by collectLastValue(underTest.currentDot)
             utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pattern(CORRECT_PATTERN)
+                AuthenticationMethodModel.Pattern
             )
             utils.authenticationRepository.setUnlocked(false)
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Bouncer)
+            )
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
 
             underTest.onShown()
@@ -96,15 +101,19 @@
     @Test
     fun onDragStart() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             val message by collectLastValue(bouncerViewModel.message)
             val selectedDots by collectLastValue(underTest.selectedDots)
             val currentDot by collectLastValue(underTest.currentDot)
             utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pattern(CORRECT_PATTERN)
+                AuthenticationMethodModel.Pattern
             )
             utils.authenticationRepository.setUnlocked(false)
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Bouncer)
+            )
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
             underTest.onShown()
             runCurrent()
@@ -120,14 +129,18 @@
     @Test
     fun onDragEnd_whenCorrect() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             val selectedDots by collectLastValue(underTest.selectedDots)
             val currentDot by collectLastValue(underTest.currentDot)
             utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pattern(CORRECT_PATTERN)
+                AuthenticationMethodModel.Pattern
             )
             utils.authenticationRepository.setUnlocked(false)
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Bouncer)
+            )
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
             underTest.onShown()
             underTest.onDragStart()
@@ -167,15 +180,19 @@
     @Test
     fun onDragEnd_whenWrong() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             val message by collectLastValue(bouncerViewModel.message)
             val selectedDots by collectLastValue(underTest.selectedDots)
             val currentDot by collectLastValue(underTest.currentDot)
             utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pattern(CORRECT_PATTERN)
+                AuthenticationMethodModel.Pattern
             )
             utils.authenticationRepository.setUnlocked(false)
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Bouncer)
+            )
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
             underTest.onShown()
             underTest.onDragStart()
@@ -199,15 +216,19 @@
     @Test
     fun onDragEnd_correctAfterWrong() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             val message by collectLastValue(bouncerViewModel.message)
             val selectedDots by collectLastValue(underTest.selectedDots)
             val currentDot by collectLastValue(underTest.currentDot)
             utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pattern(CORRECT_PATTERN)
+                AuthenticationMethodModel.Pattern
             )
             utils.authenticationRepository.setUnlocked(false)
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Bouncer)
+            )
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
             underTest.onShown()
             underTest.onDragStart()
@@ -241,20 +262,8 @@
         }
 
     companion object {
-        private const val CONTAINER_NAME = "container1"
         private const val ENTER_YOUR_PATTERN = "Enter your pattern"
         private const val WRONG_PATTERN = "Wrong pattern"
-        private val CORRECT_PATTERN =
-            listOf(
-                AuthenticationMethodModel.Pattern.PatternCoordinate(x = 1, y = 1),
-                AuthenticationMethodModel.Pattern.PatternCoordinate(x = 0, y = 1),
-                AuthenticationMethodModel.Pattern.PatternCoordinate(x = 0, y = 0),
-                AuthenticationMethodModel.Pattern.PatternCoordinate(x = 1, y = 0),
-                AuthenticationMethodModel.Pattern.PatternCoordinate(x = 2, y = 0),
-                AuthenticationMethodModel.Pattern.PatternCoordinate(x = 2, y = 1),
-                AuthenticationMethodModel.Pattern.PatternCoordinate(x = 2, y = 2),
-                AuthenticationMethodModel.Pattern.PatternCoordinate(x = 1, y = 2),
-                AuthenticationMethodModel.Pattern.PatternCoordinate(x = 0, y = 2),
-            )
+        private val CORRECT_PATTERN = FakeAuthenticationRepository.PATTERN
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
index 608a187..5c6d4c6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
@@ -20,7 +20,6 @@
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
-import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.scene.SceneTestUtils
 import com.android.systemui.scene.shared.model.SceneKey
@@ -54,16 +53,8 @@
             sceneInteractor = sceneInteractor,
         )
     private val bouncerViewModel =
-        BouncerViewModel(
-            applicationContext = context,
-            applicationScope = testScope.backgroundScope,
-            interactorFactory =
-                object : BouncerInteractor.Factory {
-                    override fun create(containerName: String): BouncerInteractor {
-                        return bouncerInteractor
-                    }
-                },
-            containerName = CONTAINER_NAME,
+        utils.bouncerViewModel(
+            bouncerInteractor = bouncerInteractor,
         )
     private val underTest =
         PinBouncerViewModel(
@@ -82,11 +73,15 @@
     @Test
     fun onShown() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             val message by collectLastValue(bouncerViewModel.message)
             val entries by collectLastValue(underTest.pinEntries)
             utils.authenticationRepository.setUnlocked(false)
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Bouncer)
+            )
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
 
             underTest.onShown()
@@ -99,14 +94,16 @@
     @Test
     fun onPinButtonClicked() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             val message by collectLastValue(bouncerViewModel.message)
             val entries by collectLastValue(underTest.pinEntries)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             utils.authenticationRepository.setUnlocked(false)
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Bouncer)
+            )
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
             underTest.onShown()
             runCurrent()
@@ -122,14 +119,16 @@
     @Test
     fun onBackspaceButtonClicked() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             val message by collectLastValue(bouncerViewModel.message)
             val entries by collectLastValue(underTest.pinEntries)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             utils.authenticationRepository.setUnlocked(false)
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Bouncer)
+            )
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
             underTest.onShown()
             runCurrent()
@@ -146,13 +145,15 @@
     @Test
     fun onPinEdit() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             val entries by collectLastValue(underTest.pinEntries)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             utils.authenticationRepository.setUnlocked(false)
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Bouncer)
+            )
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
             underTest.onShown()
 
@@ -172,14 +173,16 @@
     @Test
     fun onBackspaceButtonLongPressed() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             val message by collectLastValue(bouncerViewModel.message)
             val entries by collectLastValue(underTest.pinEntries)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             utils.authenticationRepository.setUnlocked(false)
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Bouncer)
+            )
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
             underTest.onShown()
             runCurrent()
@@ -198,12 +201,14 @@
     @Test
     fun onAuthenticateButtonClicked_whenCorrect() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             utils.authenticationRepository.setUnlocked(false)
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Bouncer)
+            )
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
             underTest.onShown()
             underTest.onPinButtonClicked(1)
@@ -219,14 +224,16 @@
     @Test
     fun onAuthenticateButtonClicked_whenWrong() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             val message by collectLastValue(bouncerViewModel.message)
             val entries by collectLastValue(underTest.pinEntries)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             utils.authenticationRepository.setUnlocked(false)
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Bouncer)
+            )
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
             underTest.onShown()
             underTest.onPinButtonClicked(1)
@@ -245,14 +252,16 @@
     @Test
     fun onAuthenticateButtonClicked_correctAfterWrong() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             val message by collectLastValue(bouncerViewModel.message)
             val entries by collectLastValue(underTest.pinEntries)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             utils.authenticationRepository.setUnlocked(false)
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Bouncer)
+            )
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
             underTest.onShown()
             underTest.onPinButtonClicked(1)
@@ -280,12 +289,15 @@
     @Test
     fun onAutoConfirm_whenCorrect() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234, autoConfirm = true)
-            )
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             utils.authenticationRepository.setUnlocked(false)
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            utils.authenticationRepository.setAutoConfirmEnabled(true)
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Bouncer)
+            )
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
             underTest.onShown()
             underTest.onPinButtonClicked(1)
@@ -299,14 +311,17 @@
     @Test
     fun onAutoConfirm_whenWrong() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
             val message by collectLastValue(bouncerViewModel.message)
             val entries by collectLastValue(underTest.pinEntries)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234, autoConfirm = true)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             utils.authenticationRepository.setUnlocked(false)
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            utils.authenticationRepository.setAutoConfirmEnabled(true)
+            sceneInteractor.setCurrentScene(
+                SceneTestUtils.CONTAINER_1,
+                SceneModel(SceneKey.Bouncer)
+            )
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
             underTest.onShown()
             underTest.onPinButtonClicked(1)
@@ -324,9 +339,7 @@
         testScope.runTest {
             val backspaceButtonAppearance by collectLastValue(underTest.backspaceButtonAppearance)
 
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234, autoConfirm = false)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
 
             assertThat(backspaceButtonAppearance).isEqualTo(ActionButtonAppearance.Shown)
         }
@@ -335,9 +348,8 @@
     fun backspaceButtonAppearance_withAutoConfirmButNoInput_isHidden() =
         testScope.runTest {
             val backspaceButtonAppearance by collectLastValue(underTest.backspaceButtonAppearance)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234, autoConfirm = true)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+            utils.authenticationRepository.setAutoConfirmEnabled(true)
 
             assertThat(backspaceButtonAppearance).isEqualTo(ActionButtonAppearance.Hidden)
         }
@@ -346,9 +358,8 @@
     fun backspaceButtonAppearance_withAutoConfirmAndInput_isShownQuiet() =
         testScope.runTest {
             val backspaceButtonAppearance by collectLastValue(underTest.backspaceButtonAppearance)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234, autoConfirm = true)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+            utils.authenticationRepository.setAutoConfirmEnabled(true)
 
             underTest.onPinButtonClicked(1)
 
@@ -360,9 +371,7 @@
         testScope.runTest {
             val confirmButtonAppearance by collectLastValue(underTest.confirmButtonAppearance)
 
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234, autoConfirm = false)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
 
             assertThat(confirmButtonAppearance).isEqualTo(ActionButtonAppearance.Shown)
         }
@@ -371,9 +380,8 @@
     fun confirmButtonAppearance_withAutoConfirm_isHidden() =
         testScope.runTest {
             val confirmButtonAppearance by collectLastValue(underTest.confirmButtonAppearance)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234, autoConfirm = true)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+            utils.authenticationRepository.setAutoConfirmEnabled(true)
 
             assertThat(confirmButtonAppearance).isEqualTo(ActionButtonAppearance.Hidden)
         }
@@ -382,9 +390,8 @@
     fun hintedPinLength_withoutAutoConfirm_isNull() =
         testScope.runTest {
             val hintedPinLength by collectLastValue(underTest.hintedPinLength)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234, autoConfirm = false)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+            utils.authenticationRepository.setAutoConfirmEnabled(false)
 
             assertThat(hintedPinLength).isNull()
         }
@@ -393,9 +400,8 @@
     fun hintedPinLength_withAutoConfirmPinLessThanSixDigits_isNull() =
         testScope.runTest {
             val hintedPinLength by collectLastValue(underTest.hintedPinLength)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(12345, autoConfirm = true)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+            utils.authenticationRepository.setAutoConfirmEnabled(true)
 
             assertThat(hintedPinLength).isNull()
         }
@@ -404,9 +410,9 @@
     fun hintedPinLength_withAutoConfirmPinExactlySixDigits_isSix() =
         testScope.runTest {
             val hintedPinLength by collectLastValue(underTest.hintedPinLength)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(123456, autoConfirm = true)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+            utils.authenticationRepository.setAutoConfirmEnabled(true)
+            utils.authenticationRepository.overrideCredential(listOf(1, 2, 3, 4, 5, 6))
 
             assertThat(hintedPinLength).isEqualTo(6)
         }
@@ -415,15 +421,13 @@
     fun hintedPinLength_withAutoConfirmPinMoreThanSixDigits_isNull() =
         testScope.runTest {
             val hintedPinLength by collectLastValue(underTest.hintedPinLength)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234567, autoConfirm = true)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+            utils.authenticationRepository.setAutoConfirmEnabled(true)
 
             assertThat(hintedPinLength).isNull()
         }
 
     companion object {
-        private const val CONTAINER_NAME = "container1"
         private const val ENTER_YOUR_PIN = "Enter your pin"
         private const val WRONG_PIN = "Wrong pin"
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsEditingActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsEditingActivityTest.kt
index 4210675..71d2ec1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsEditingActivityTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsEditingActivityTest.kt
@@ -11,9 +11,9 @@
 import android.window.OnBackInvokedDispatcher
 import androidx.test.filters.SmallTest
 import androidx.test.rule.ActivityTestRule
-import androidx.test.runner.intercepting.SingleActivityFactory
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.activity.SingleActivityFactory
 import com.android.systemui.controls.CustomIconCache
 import com.android.systemui.controls.controller.ControlsControllerImpl
 import com.android.systemui.flags.FakeFeatureFlags
@@ -63,24 +63,19 @@
     @JvmField
     var activityRule =
         ActivityTestRule(
-            object :
-                SingleActivityFactory<TestableControlsEditingActivity>(
-                    TestableControlsEditingActivity::class.java
-                ) {
-                override fun create(intent: Intent?): TestableControlsEditingActivity {
-                    return TestableControlsEditingActivity(
-                        featureFlags,
-                        uiExecutor,
-                        controller,
-                        userTracker,
-                        customIconCache,
-                        mockDispatcher,
-                        latch
-                    )
-                }
+            /* activityFactory= */ SingleActivityFactory {
+                TestableControlsEditingActivity(
+                    featureFlags,
+                    uiExecutor,
+                    controller,
+                    userTracker,
+                    customIconCache,
+                    mockDispatcher,
+                    latch
+                )
             },
-            false,
-            false
+            /* initialTouchMode= */ false,
+            /* launchActivity= */ false,
         )
 
     @Before
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsFavoritingActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsFavoritingActivityTest.kt
index f4cc8bc..f11c296 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsFavoritingActivityTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsFavoritingActivityTest.kt
@@ -13,9 +13,9 @@
 import androidx.test.filters.FlakyTest
 import androidx.test.filters.SmallTest
 import androidx.test.rule.ActivityTestRule
-import androidx.test.runner.intercepting.SingleActivityFactory
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.activity.SingleActivityFactory
 import com.android.systemui.controls.ControlStatus
 import com.android.systemui.controls.ControlsServiceInfo
 import com.android.systemui.controls.controller.ControlsController
@@ -91,24 +91,19 @@
     @JvmField
     var activityRule =
         ActivityTestRule(
-            object :
-                SingleActivityFactory<TestableControlsFavoritingActivity>(
-                    TestableControlsFavoritingActivity::class.java
-                ) {
-                override fun create(intent: Intent?): TestableControlsFavoritingActivity {
-                    return TestableControlsFavoritingActivity(
-                        featureFlags,
-                        executor,
-                        controller,
-                        listingController,
-                        userTracker,
-                        mockDispatcher,
-                        latch
-                    )
-                }
+            /* activityFactory= */ SingleActivityFactory {
+                TestableControlsFavoritingActivity(
+                    featureFlags,
+                    executor,
+                    controller,
+                    listingController,
+                    userTracker,
+                    mockDispatcher,
+                    latch
+                )
             },
-            false,
-            false
+            /* initialTouchMode= */ false,
+            /* launchActivity= */ false,
         )
 
     @Before
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsProviderSelectorActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsProviderSelectorActivityTest.kt
index 4ba6718..d17495f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsProviderSelectorActivityTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsProviderSelectorActivityTest.kt
@@ -29,8 +29,8 @@
 import android.window.OnBackInvokedDispatcher
 import androidx.test.filters.SmallTest
 import androidx.test.rule.ActivityTestRule
-import androidx.test.runner.intercepting.SingleActivityFactory
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.activity.SingleActivityFactory
 import com.android.systemui.controls.ControlsServiceInfo
 import com.android.systemui.controls.controller.ControlsController
 import com.android.systemui.controls.panels.AuthorizedPanelsRepository
@@ -91,26 +91,21 @@
     @JvmField
     var activityRule =
         ActivityTestRule(
-            object :
-                SingleActivityFactory<TestableControlsProviderSelectorActivity>(
-                    TestableControlsProviderSelectorActivity::class.java
-                ) {
-                override fun create(intent: Intent?): TestableControlsProviderSelectorActivity {
-                    return TestableControlsProviderSelectorActivity(
-                        executor,
-                        backExecutor,
-                        listingController,
-                        controlsController,
-                        userTracker,
-                        authorizedPanelsRepository,
-                        dialogFactory,
-                        mockDispatcher,
-                        latch
-                    )
-                }
+            /* activityFactory= */ SingleActivityFactory {
+                TestableControlsProviderSelectorActivity(
+                    executor,
+                    backExecutor,
+                    listingController,
+                    controlsController,
+                    userTracker,
+                    authorizedPanelsRepository,
+                    dialogFactory,
+                    mockDispatcher,
+                    latch
+                )
             },
-            false,
-            false
+            /* initialTouchMode= */ false,
+            /* launchActivity= */ false,
         )
 
     @Before
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestDialogTest.kt
index 314b176..ca970bb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestDialogTest.kt
@@ -30,8 +30,8 @@
 import androidx.lifecycle.Lifecycle
 import androidx.test.filters.MediumTest
 import androidx.test.rule.ActivityTestRule
-import androidx.test.runner.intercepting.SingleActivityFactory
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.activity.SingleActivityFactory
 import com.android.systemui.controls.controller.ControlInfo
 import com.android.systemui.controls.controller.ControlsController
 import com.android.systemui.settings.UserTracker
@@ -81,19 +81,18 @@
 
     @Rule
     @JvmField
-    var activityRule = ActivityTestRule<TestControlsRequestDialog>(
-            object : SingleActivityFactory<TestControlsRequestDialog>(
-                    TestControlsRequestDialog::class.java
-            ) {
-                    override fun create(intent: Intent?): TestControlsRequestDialog {
-                        return TestControlsRequestDialog(
-                                mainExecutor,
-                                controller,
-                                userTracker,
-                                listingController
-                        )
-                    }
-            }, false, false)
+    var activityRule = ActivityTestRule(
+        /* activityFactory= */ SingleActivityFactory {
+            TestControlsRequestDialog(
+                    mainExecutor,
+                    controller,
+                    userTracker,
+                    listingController
+            )
+        },
+        /* initialTouchMode= */ false,
+        /* launchActivity= */ false,
+    )
 
     private lateinit var control: Control
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsActivityTest.kt
index 2d3e10e..e279d28 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsActivityTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsActivityTest.kt
@@ -23,8 +23,8 @@
 import android.testing.TestableLooper
 import androidx.test.filters.SmallTest
 import androidx.test.rule.ActivityTestRule
-import androidx.test.runner.intercepting.SingleActivityFactory
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.activity.SingleActivityFactory
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.controls.settings.ControlsSettingsDialogManager
 import com.android.systemui.flags.FeatureFlags
@@ -53,23 +53,18 @@
     @JvmField
     var activityRule =
         ActivityTestRule(
-            object :
-                SingleActivityFactory<TestableControlsActivity>(
-                    TestableControlsActivity::class.java
-                ) {
-                override fun create(intent: Intent?): TestableControlsActivity {
-                    return TestableControlsActivity(
-                        uiController,
-                        broadcastDispatcher,
-                        dreamManager,
-                        featureFlags,
-                        controlsSettingsDialogManager,
-                        keyguardStateController,
-                    )
-                }
+            /* activityFactory= */ SingleActivityFactory {
+                TestableControlsActivity(
+                    uiController,
+                    broadcastDispatcher,
+                    dreamManager,
+                    featureFlags,
+                    controlsSettingsDialogManager,
+                    keyguardStateController,
+                )
             },
-            false,
-            false
+            /* initialTouchMode= */ false,
+            /* launchActivity= */ false,
         )
 
     @Before
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt
index 7840525..021facc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt
@@ -146,17 +146,8 @@
     }
 
     @Test
-    fun testTaskViewReleasedOnDismiss() {
-        underTest.dismiss()
-        verify(taskView).release()
-    }
-
-    @Test
-    fun testTaskViewReleasedOnBackOnRoot() {
-        underTest.launchTaskView()
-        verify(taskView).setListener(any(), capture(listenerCaptor))
-
-        listenerCaptor.value.onBackPressedOnTaskRoot(0)
+    fun testTaskViewReleasedOnRelease() {
+        underTest.release()
         verify(taskView).release()
     }
 
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 3383516..e73d580 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
@@ -175,7 +175,6 @@
             )
         val featureFlags =
             FakeFeatureFlags().apply {
-                set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, true)
                 set(Flags.LOCKSCREEN_CUSTOM_CLOCKS, true)
                 set(Flags.REVAMPED_WALLPAPER_UI, true)
                 set(Flags.WALLPAPER_FULLSCREEN_PREVIEW, true)
@@ -191,7 +190,6 @@
                         bouncerRepository = FakeKeyguardBouncerRepository(),
                         configurationRepository = FakeConfigurationRepository(),
                     ),
-                registry = mock(),
                 lockPatternUtils = lockPatternUtils,
                 keyguardStateController = keyguardStateController,
                 userTracker = userTracker,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
index 729a1cc..ce8028c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
@@ -19,6 +19,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
@@ -31,6 +32,7 @@
 import android.media.MediaMetadata;
 import android.media.session.PlaybackState;
 import android.net.Uri;
+import android.os.Handler;
 import android.provider.Settings;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -166,6 +168,7 @@
 
     @Test
     public void updatesClock() {
+        clearInvocations(mContentResolver);
         mProvider.mKeyguardUpdateMonitorCallback.onTimeChanged();
         TestableLooper.get(this).processAllMessages();
         verify(mContentResolver).notifyChange(eq(mProvider.getUri()), eq(null));
@@ -217,11 +220,13 @@
         reset(mContentResolver);
         mProvider.onPrimaryMetadataOrStateChanged(mock(MediaMetadata.class),
                 PlaybackState.STATE_PLAYING);
+        TestableLooper.get(this).processAllMessages();
         verify(mContentResolver).notifyChange(eq(mProvider.getUri()), eq(null));
 
         // Hides after waking up
         reset(mContentResolver);
         mProvider.onDozingChanged(false);
+        TestableLooper.get(this).processAllMessages();
         verify(mContentResolver).notifyChange(eq(mProvider.getUri()), eq(null));
     }
 
@@ -231,6 +236,7 @@
         mProvider.onPrimaryMetadataOrStateChanged(mock(MediaMetadata.class),
                 PlaybackState.STATE_PLAYING);
         reset(mContentResolver);
+        TestableLooper.get(this).processAllMessages();
         // Show media when dozing
         mProvider.onDozingChanged(true);
         verify(mContentResolver).notifyChange(eq(mProvider.getUri()), eq(null));
@@ -272,6 +278,8 @@
             mMediaManager = KeyguardSliceProviderTest.this.mNotificationMediaManager;
             mKeyguardUpdateMonitor = KeyguardSliceProviderTest.this.mKeyguardUpdateMonitor;
             mUserTracker = KeyguardSliceProviderTest.this.mUserTracker;
+            mBgHandler =
+                    new Handler(TestableLooper.get(KeyguardSliceProviderTest.this).getLooper());
         }
 
         @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartableTest.kt
index f243d7b..df1833e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartableTest.kt
@@ -24,8 +24,6 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
 import com.android.systemui.settings.UserFileManager
 import com.android.systemui.settings.UserTracker
@@ -59,8 +57,6 @@
 class MuteQuickAffordanceCoreStartableTest : SysuiTestCase() {
 
     @Mock
-    private lateinit var featureFlags: FeatureFlags
-    @Mock
     private lateinit var userTracker: UserTracker
     @Mock
     private lateinit var ringerModeTracker: RingerModeTracker
@@ -78,8 +74,6 @@
     fun setUp() {
         MockitoAnnotations.initMocks(this)
 
-        whenever(featureFlags.isEnabled(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES)).thenReturn(true)
-
         val config: KeyguardQuickAffordanceConfig = mock()
         whenever(config.key).thenReturn(BuiltInKeyguardQuickAffordanceKeys.MUTE)
 
@@ -90,7 +84,6 @@
         testScope = TestScope(testDispatcher)
 
         underTest = MuteQuickAffordanceCoreStartable(
-            featureFlags,
             userTracker,
             ringerModeTracker,
             userFileManager,
@@ -101,20 +94,7 @@
     }
 
     @Test
-    fun featureFlagIsOFF_doNothingWithKeyguardQuickAffordanceRepository() = testScope.runTest {
-        //given
-        whenever(featureFlags.isEnabled(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES)).thenReturn(false)
-
-        //when
-        underTest.start()
-
-        //then
-        verifyZeroInteractions(keyguardQuickAffordanceRepository)
-        coroutineContext.cancelChildren()
-    }
-
-    @Test
-    fun featureFlagIsON_callToKeyguardQuickAffordanceRepository() = testScope.runTest {
+    fun callToKeyguardQuickAffordanceRepository() = testScope.runTest {
         //given
         val ringerModeInternal = mock<MutableLiveData<Int>>()
         whenever(ringerModeTracker.ringerModeInternal).thenReturn(ringerModeInternal)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
index d62db5d..020c0b2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
@@ -228,6 +228,7 @@
             bypassControllerOverride,
             testScope.backgroundScope,
             testDispatcher,
+            testDispatcher,
             sessionTracker,
             uiEventLogger,
             FaceAuthenticationLogger(logcatLogBuffer("DeviceEntryFaceAuthRepositoryLog")),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
index 25573de..e9f0d56 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
@@ -299,6 +299,16 @@
         }
 
     @Test
+    fun isActiveDreamLockscreenHosted() =
+        testScope.runTest {
+            underTest.setIsActiveDreamLockscreenHosted(true)
+            assertThat(underTest.isActiveDreamLockscreenHosted.value).isEqualTo(true)
+
+            underTest.setIsActiveDreamLockscreenHosted(false)
+            assertThat(underTest.isActiveDreamLockscreenHosted.value).isEqualTo(false)
+        }
+
+    @Test
     fun wakefulness() =
         testScope.runTest {
             val values = mutableListOf<WakefulnessModel>()
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 8540bf7..3858cfd 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
@@ -40,7 +40,6 @@
 import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager
 import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
 import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
-import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceRegistry
 import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
 import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancesMetricsLogger
 import com.android.systemui.plugins.ActivityStarter
@@ -300,7 +299,6 @@
             )
         val featureFlags =
             FakeFeatureFlags().apply {
-                set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, false)
                 set(Flags.FACE_AUTH_REFACTOR, true)
             }
         val testDispatcher = StandardTestDispatcher()
@@ -312,20 +310,6 @@
                             featureFlags = featureFlags,
                         )
                         .keyguardInteractor,
-                registry =
-                    FakeKeyguardQuickAffordanceRegistry(
-                        mapOf(
-                            KeyguardQuickAffordancePosition.BOTTOM_START to
-                                listOf(
-                                    homeControls,
-                                ),
-                            KeyguardQuickAffordancePosition.BOTTOM_END to
-                                listOf(
-                                    quickAccessWallet,
-                                    qrCodeScanner,
-                                ),
-                        ),
-                    ),
                 lockPatternUtils = lockPatternUtils,
                 keyguardStateController = keyguardStateController,
                 userTracker = userTracker,
@@ -345,6 +329,7 @@
     @Test
     fun onQuickAffordanceTriggered() =
         testScope.runTest {
+            val key = BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS
             setUpMocks(
                 needStrongAuthAfterBoot = needStrongAuthAfterBoot,
                 keyguardIsUnlocked = keyguardIsUnlocked,
@@ -367,7 +352,7 @@
                 }
 
             underTest.onQuickAffordanceTriggered(
-                configKey = BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS,
+                configKey = "${KeyguardQuickAffordancePosition.BOTTOM_START.toSlotId()}::${key}",
                 expandable = expandable,
                 slotId = "",
             )
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 a0c5a75..07caf59 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
@@ -44,7 +44,6 @@
 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
 import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
 import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel
-import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceRegistry
 import com.android.systemui.keyguard.shared.model.KeyguardQuickAffordancePickerRepresentation
 import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
 import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
@@ -102,6 +101,15 @@
         MockitoAnnotations.initMocks(this)
 
         overrideResource(R.bool.custom_lockscreen_shortcuts_enabled, true)
+        overrideResource(
+            R.array.config_keyguardQuickAffordanceDefaults,
+            arrayOf(
+                KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START + ":" +
+                    BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS,
+                KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END + ":" +
+                    BuiltInKeyguardQuickAffordanceKeys.QUICK_ACCESS_WALLET
+            )
+        )
 
         repository = FakeKeyguardRepository()
         repository.setKeyguardShowing(true)
@@ -164,7 +172,6 @@
             )
         featureFlags =
             FakeFeatureFlags().apply {
-                set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, false)
                 set(Flags.FACE_AUTH_REFACTOR, true)
             }
 
@@ -176,20 +183,6 @@
         underTest =
             KeyguardQuickAffordanceInteractor(
                 keyguardInteractor = withDeps.keyguardInteractor,
-                registry =
-                    FakeKeyguardQuickAffordanceRegistry(
-                        mapOf(
-                            KeyguardQuickAffordancePosition.BOTTOM_START to
-                                listOf(
-                                    homeControls,
-                                ),
-                            KeyguardQuickAffordancePosition.BOTTOM_END to
-                                listOf(
-                                    quickAccessWallet,
-                                    qrCodeScanner,
-                                ),
-                        ),
-                    ),
                 lockPatternUtils = lockPatternUtils,
                 keyguardStateController = keyguardStateController,
                 userTracker = userTracker,
@@ -225,7 +218,9 @@
             assertThat(collectedValue())
                 .isInstanceOf(KeyguardQuickAffordanceModel.Visible::class.java)
             val visibleModel = collectedValue() as KeyguardQuickAffordanceModel.Visible
-            assertThat(visibleModel.configKey).isEqualTo(configKey)
+            assertThat(visibleModel.configKey).isEqualTo(
+                "${KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START}::${configKey}"
+            )
             assertThat(visibleModel.icon).isEqualTo(ICON)
             assertThat(visibleModel.icon.contentDescription)
                 .isEqualTo(ContentDescription.Resource(res = CONTENT_DESCRIPTION_RESOURCE_ID))
@@ -250,7 +245,9 @@
             assertThat(collectedValue())
                 .isInstanceOf(KeyguardQuickAffordanceModel.Visible::class.java)
             val visibleModel = collectedValue() as KeyguardQuickAffordanceModel.Visible
-            assertThat(visibleModel.configKey).isEqualTo(configKey)
+            assertThat(visibleModel.configKey).isEqualTo(
+                "${KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END}::${configKey}"
+            )
             assertThat(visibleModel.icon).isEqualTo(ICON)
             assertThat(visibleModel.icon.contentDescription)
                 .isEqualTo(ContentDescription.Resource(res = CONTENT_DESCRIPTION_RESOURCE_ID))
@@ -387,7 +384,9 @@
             assertThat(collectedValue())
                 .isInstanceOf(KeyguardQuickAffordanceModel.Visible::class.java)
             val visibleModel = collectedValue() as KeyguardQuickAffordanceModel.Visible
-            assertThat(visibleModel.configKey).isEqualTo(configKey)
+            assertThat(visibleModel.configKey).isEqualTo(
+                "${KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START}::${configKey}"
+            )
             assertThat(visibleModel.icon).isEqualTo(ICON)
             assertThat(visibleModel.icon.contentDescription)
                 .isEqualTo(ContentDescription.Resource(res = CONTENT_DESCRIPTION_RESOURCE_ID))
@@ -401,8 +400,6 @@
                 R.array.config_keyguardQuickAffordanceDefaults,
                 arrayOf<String>(),
             )
-
-            featureFlags.set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, true)
             homeControls.setState(
                 KeyguardQuickAffordanceConfig.LockScreenState.Visible(icon = ICON)
             )
@@ -543,7 +540,6 @@
     @Test
     fun unselect_one() =
         testScope.runTest {
-            featureFlags.set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, true)
             homeControls.setState(
                 KeyguardQuickAffordanceConfig.LockScreenState.Visible(icon = ICON)
             )
@@ -620,7 +616,6 @@
     @Test
     fun useLongPress_whenDocked_isFalse() =
         testScope.runTest {
-            featureFlags.set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, true)
             dockManager.setIsDocked(true)
 
             val useLongPress by collectLastValue(underTest.useLongPress())
@@ -631,7 +626,6 @@
     @Test
     fun useLongPress_whenNotDocked_isTrue() =
         testScope.runTest {
-            featureFlags.set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, true)
             dockManager.setIsDocked(false)
 
             val useLongPress by collectLastValue(underTest.useLongPress())
@@ -642,7 +636,6 @@
     @Test
     fun useLongPress_whenNotDocked_isTrue_changedTo_whenDocked_isFalse() =
         testScope.runTest {
-            featureFlags.set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, true)
             dockManager.setIsDocked(false)
             val firstUseLongPress by collectLastValue(underTest.useLongPress())
             runCurrent()
@@ -660,7 +653,6 @@
     @Test
     fun unselect_all() =
         testScope.runTest {
-            featureFlags.set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, true)
             homeControls.setState(
                 KeyguardQuickAffordanceConfig.LockScreenState.Visible(icon = ICON)
             )
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractorTest.kt
index abbdc3d..ca6a5b6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractorTest.kt
@@ -47,7 +47,6 @@
     private val underTest =
         utils.lockScreenSceneInteractor(
             authenticationInteractor = authenticationInteractor,
-            sceneInteractor = sceneInteractor,
             bouncerInteractor =
                 utils.bouncerInteractor(
                     authenticationInteractor = authenticationInteractor,
@@ -94,9 +93,7 @@
         testScope.runTest {
             val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
             utils.authenticationRepository.setUnlocked(false)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
 
             underTest.dismissLockscreen()
@@ -109,9 +106,7 @@
         testScope.runTest {
             val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
             utils.authenticationRepository.setUnlocked(true)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
 
             underTest.dismissLockscreen()
@@ -133,29 +128,11 @@
         }
 
     @Test
-    fun deviceLockedInNonLockScreenScene_switchesToLockScreenScene() =
-        testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
-            runCurrent()
-            sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Gone))
-            runCurrent()
-            utils.authenticationRepository.setUnlocked(true)
-            runCurrent()
-            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
-
-            utils.authenticationRepository.setUnlocked(false)
-
-            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
-        }
-
-    @Test
     fun switchFromLockScreenToGone_authMethodNotSwipe_doesNotUnlockDevice() =
         testScope.runTest {
             val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
             sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Lockscreen))
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             assertThat(isUnlocked).isFalse()
 
             sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Gone))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/quickaffordance/FakeKeyguardQuickAffordanceRegistry.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/quickaffordance/FakeKeyguardQuickAffordanceRegistry.kt
deleted file mode 100644
index 13e2768..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/quickaffordance/FakeKeyguardQuickAffordanceRegistry.kt
+++ /dev/null
@@ -1,40 +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.keyguard.domain.quickaffordance
-
-import com.android.systemui.keyguard.data.quickaffordance.FakeKeyguardQuickAffordanceConfig
-import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
-
-/** Fake implementation of [FakeKeyguardQuickAffordanceRegistry], for tests. */
-class FakeKeyguardQuickAffordanceRegistry(
-    private val configsByPosition:
-        Map<KeyguardQuickAffordancePosition, List<FakeKeyguardQuickAffordanceConfig>>,
-) : KeyguardQuickAffordanceRegistry<FakeKeyguardQuickAffordanceConfig> {
-
-    override fun getAll(
-        position: KeyguardQuickAffordancePosition
-    ): List<FakeKeyguardQuickAffordanceConfig> {
-        return configsByPosition.getValue(position)
-    }
-
-    override fun get(
-        key: String,
-    ): FakeKeyguardQuickAffordanceConfig {
-        return configsByPosition.values.flatten().associateBy { config -> config.key }.getValue(key)
-    }
-}
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 d02b3fc..06bf7f0 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
@@ -22,6 +22,7 @@
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.testing.UiEventLoggerFake
 import com.android.internal.widget.LockPatternUtils
+import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.DialogLaunchAnimator
 import com.android.systemui.animation.Expandable
@@ -47,7 +48,6 @@
 import com.android.systemui.keyguard.domain.interactor.KeyguardLongPressInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory
-import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceRegistry
 import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
 import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
 import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancesMetricsLogger
@@ -102,7 +102,6 @@
 
     private lateinit var testScope: TestScope
     private lateinit var repository: FakeKeyguardRepository
-    private lateinit var registry: FakeKeyguardQuickAffordanceRegistry
     private lateinit var homeControlsQuickAffordanceConfig: FakeKeyguardQuickAffordanceConfig
     private lateinit var quickAccessWalletAffordanceConfig: FakeKeyguardQuickAffordanceConfig
     private lateinit var qrCodeScannerAffordanceConfig: FakeKeyguardQuickAffordanceConfig
@@ -112,6 +111,18 @@
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
+
+        overrideResource(R.bool.custom_lockscreen_shortcuts_enabled, true)
+        overrideResource(
+            R.array.config_keyguardQuickAffordanceDefaults,
+            arrayOf(
+                KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START + ":" +
+                    BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS,
+                KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END + ":" +
+                    BuiltInKeyguardQuickAffordanceKeys.QUICK_ACCESS_WALLET
+            )
+        )
+
         whenever(burnInHelperWrapper.burnInOffset(anyInt(), any()))
             .thenReturn(RETURNED_BURN_IN_OFFSET)
 
@@ -125,23 +136,8 @@
             FakeKeyguardQuickAffordanceConfig(BuiltInKeyguardQuickAffordanceKeys.QR_CODE_SCANNER)
         dockManager = DockManagerFake()
         biometricSettingsRepository = FakeBiometricSettingsRepository()
-        registry =
-            FakeKeyguardQuickAffordanceRegistry(
-                mapOf(
-                    KeyguardQuickAffordancePosition.BOTTOM_START to
-                        listOf(
-                            homeControlsQuickAffordanceConfig,
-                        ),
-                    KeyguardQuickAffordancePosition.BOTTOM_END to
-                        listOf(
-                            quickAccessWalletAffordanceConfig,
-                            qrCodeScannerAffordanceConfig,
-                        ),
-                ),
-            )
         val featureFlags =
             FakeFeatureFlags().apply {
-                set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, false)
                 set(Flags.FACE_AUTH_REFACTOR, true)
                 set(Flags.LOCK_SCREEN_LONG_PRESS_ENABLED, false)
                 set(Flags.LOCK_SCREEN_LONG_PRESS_DIRECT_TO_WPP, false)
@@ -152,7 +148,6 @@
         repository = withDeps.repository
 
         whenever(userTracker.userHandle).thenReturn(mock())
-        whenever(userTracker.userId).thenReturn(10)
         whenever(lockPatternUtils.getStrongAuthForUser(anyInt()))
             .thenReturn(LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED)
         val testDispatcher = StandardTestDispatcher()
@@ -225,7 +220,6 @@
                 quickAffordanceInteractor =
                     KeyguardQuickAffordanceInteractor(
                         keyguardInteractor = keyguardInteractor,
-                        registry = registry,
                         lockPatternUtils = lockPatternUtils,
                         keyguardStateController = keyguardStateController,
                         userTracker = userTracker,
@@ -700,7 +694,8 @@
                 KeyguardQuickAffordanceConfig.LockScreenState.Hidden
             }
         config.setState(lockScreenState)
-        return config.key
+
+        return "${position.toSlotId()}::${config.key}"
     }
 
     private fun assertQuickAffordanceViewModel(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
index ff4ec4b..ba8e0f2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
@@ -56,7 +56,6 @@
                     override fun create(containerName: String): LockscreenSceneInteractor {
                         return utils.lockScreenSceneInteractor(
                             authenticationInteractor = authenticationInteractor,
-                            sceneInteractor = sceneInteractor,
                             bouncerInteractor =
                                 utils.bouncerInteractor(
                                     authenticationInteractor = authenticationInteractor,
@@ -73,7 +72,7 @@
         testScope.runTest {
             val lockButtonIcon by collectLastValue(underTest.lockButtonIcon)
             utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Password("password")
+                AuthenticationMethodModel.Password
             )
             utils.authenticationRepository.setUnlocked(false)
 
@@ -86,7 +85,7 @@
         testScope.runTest {
             val lockButtonIcon by collectLastValue(underTest.lockButtonIcon)
             utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Password("password")
+                AuthenticationMethodModel.Password
             )
             utils.authenticationRepository.setUnlocked(true)
 
@@ -108,9 +107,7 @@
     fun upTransitionSceneKey_swipeToUnlockedNotEnabled_bouncer() =
         testScope.runTest {
             val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             utils.authenticationRepository.setUnlocked(false)
 
             assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Bouncer)
@@ -120,9 +117,7 @@
     fun onLockButtonClicked_deviceLockedSecurely_switchesToBouncer() =
         testScope.runTest {
             val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             utils.authenticationRepository.setUnlocked(false)
             runCurrent()
 
@@ -135,9 +130,7 @@
     fun onContentClicked_deviceUnlocked_switchesToGone() =
         testScope.runTest {
             val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             utils.authenticationRepository.setUnlocked(true)
             runCurrent()
 
@@ -150,9 +143,7 @@
     fun onContentClicked_deviceLockedSecurely_switchesToBouncer() =
         testScope.runTest {
             val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             utils.authenticationRepository.setUnlocked(false)
             runCurrent()
 
@@ -165,9 +156,7 @@
     fun onLockButtonClicked_deviceUnlocked_switchesToGone() =
         testScope.runTest {
             val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             utils.authenticationRepository.setUnlocked(true)
             runCurrent()
 
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 56698e0..d1299d4 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
@@ -261,7 +261,6 @@
         whenever(mediaSmartspaceTarget.creationTimeMillis).thenReturn(SMARTSPACE_CREATION_TIME)
         whenever(mediaSmartspaceTarget.expiryTimeMillis).thenReturn(SMARTSPACE_EXPIRY_TIME)
         whenever(mediaFlags.areMediaSessionActionsEnabled(any(), any())).thenReturn(false)
-        whenever(mediaFlags.isExplicitIndicatorEnabled()).thenReturn(true)
         whenever(mediaFlags.isRetainingPlayersEnabled()).thenReturn(false)
         whenever(mediaFlags.isPersistentSsCardEnabled()).thenReturn(false)
         whenever(mediaFlags.isRemoteResumeAllowed()).thenReturn(false)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
index f902be3..b4b3073 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
@@ -233,7 +233,6 @@
         FakeFeatureFlags().apply {
             this.set(Flags.UMO_SURFACE_RIPPLE, false)
             this.set(Flags.UMO_TURBULENCE_NOISE, false)
-            this.set(Flags.MEDIA_EXPLICIT_INDICATOR, true)
             this.set(Flags.MEDIA_RECOMMENDATION_CARD_UPDATE, false)
         }
     @Mock private lateinit var globalSettings: GlobalSettings
@@ -1793,7 +1792,7 @@
         // THEN it sends the PendingIntent without dismissing keyguard first,
         // and does not use the Intent directly (see b/271845008)
         captor.value.onClick(viewHolder.player)
-        verify(pendingIntent).send()
+        verify(pendingIntent).send(any(Bundle::class.java))
         verify(pendingIntent, never()).getIntent()
         verify(activityStarter, never()).postStartActivityDismissingKeyguard(eq(clickIntent), any())
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinatorTest.kt
new file mode 100644
index 0000000..cfbbf76
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinatorTest.kt
@@ -0,0 +1,128 @@
+/*
+ * 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.mediaprojection.taskswitcher.ui
+
+import android.app.Notification
+import android.app.NotificationManager
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.mediaprojection.taskswitcher.data.repository.ActivityTaskManagerTasksRepository
+import com.android.systemui.mediaprojection.taskswitcher.data.repository.FakeActivityTaskManager
+import com.android.systemui.mediaprojection.taskswitcher.data.repository.FakeMediaProjectionRepository
+import com.android.systemui.mediaprojection.taskswitcher.domain.interactor.TaskSwitchInteractor
+import com.android.systemui.mediaprojection.taskswitcher.ui.viewmodel.TaskSwitcherNotificationViewModel
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.mock
+import com.google.common.truth.Truth.assertThat
+import junit.framework.Assert.assertEquals
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Mockito.verify
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class TaskSwitcherNotificationCoordinatorTest : SysuiTestCase() {
+
+    private val notificationManager: NotificationManager = mock()
+
+    private val dispatcher = UnconfinedTestDispatcher()
+    private val testScope = TestScope(dispatcher)
+    private val fakeActivityTaskManager = FakeActivityTaskManager()
+    private val mediaRepo = FakeMediaProjectionRepository()
+    private val tasksRepo =
+        ActivityTaskManagerTasksRepository(
+            activityTaskManager = fakeActivityTaskManager.activityTaskManager,
+            applicationScope = testScope.backgroundScope,
+            backgroundDispatcher = dispatcher
+        )
+    private val interactor = TaskSwitchInteractor(mediaRepo, tasksRepo)
+    private val viewModel = TaskSwitcherNotificationViewModel(interactor)
+
+    private val coordinator =
+        TaskSwitcherNotificationCoordinator(
+            context,
+            notificationManager,
+            testScope.backgroundScope,
+            dispatcher,
+            viewModel
+        )
+
+    @Before
+    fun setup() {
+        coordinator.start()
+    }
+
+    @Test
+    fun showNotification() {
+        testScope.runTest {
+            switchTask()
+
+            val notification = ArgumentCaptor.forClass(Notification::class.java)
+            verify(notificationManager).notify(any(), any(), notification.capture())
+            assertNotification(notification)
+        }
+    }
+
+    @Test
+    fun hideNotification() {
+        testScope.runTest {
+            mediaRepo.stopProjecting()
+
+            verify(notificationManager).cancel(any())
+        }
+    }
+
+    @Test
+    fun notificationIdIsConsistent() {
+        testScope.runTest {
+            mediaRepo.stopProjecting()
+            val idCancel = argumentCaptor<Int>()
+            verify(notificationManager).cancel(idCancel.capture())
+
+            switchTask()
+            val idNotify = argumentCaptor<Int>()
+            verify(notificationManager).notify(any(), idNotify.capture(), any())
+
+            assertEquals(idCancel.value, idNotify.value)
+        }
+    }
+
+    private fun switchTask() {
+        val projectedTask = FakeActivityTaskManager.createTask(taskId = 1)
+        val foregroundTask = FakeActivityTaskManager.createTask(taskId = 2)
+        mediaRepo.switchProjectedTask(projectedTask)
+        fakeActivityTaskManager.moveTaskToForeground(foregroundTask)
+    }
+
+    private fun assertNotification(notification: ArgumentCaptor<Notification>) {
+        val text = notification.value.extras.getCharSequence(Notification.EXTRA_TEXT)
+        assertEquals(context.getString(R.string.media_projection_task_switcher_text), text)
+
+        val actions = notification.value.actions
+        assertThat(actions).hasLength(2)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/LaunchNotesRoleSettingsTrampolineActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/LaunchNotesRoleSettingsTrampolineActivityTest.kt
index 36b913f..bdb095a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/LaunchNotesRoleSettingsTrampolineActivityTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/LaunchNotesRoleSettingsTrampolineActivityTest.kt
@@ -22,9 +22,9 @@
 import android.testing.TestableLooper
 import androidx.test.filters.SmallTest
 import androidx.test.rule.ActivityTestRule
-import androidx.test.runner.intercepting.SingleActivityFactory
 import com.android.dx.mockito.inline.extended.ExtendedMockito.verify
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.activity.SingleActivityFactory
 import com.android.systemui.notetask.LaunchNotesRoleSettingsTrampolineActivity.Companion.ACTION_MANAGE_NOTES_ROLE_FROM_QUICK_AFFORDANCE
 import com.android.systemui.notetask.NoteTaskEntryPoint.QUICK_AFFORDANCE
 import com.android.systemui.util.mockito.any
@@ -47,13 +47,9 @@
     @Rule
     @JvmField
     val activityRule =
-        ActivityTestRule<LaunchNotesRoleSettingsTrampolineActivity>(
-            /* activityFactory= */ object :
-                SingleActivityFactory<LaunchNotesRoleSettingsTrampolineActivity>(
-                    LaunchNotesRoleSettingsTrampolineActivity::class.java
-                ) {
-                override fun create(intent: Intent?) =
-                    LaunchNotesRoleSettingsTrampolineActivity(noteTaskController)
+        ActivityTestRule(
+            /* activityFactory= */ SingleActivityFactory {
+                LaunchNotesRoleSettingsTrampolineActivity(noteTaskController)
             },
             /* initialTouchMode= */ false,
             /* launchActivity= */ false,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivityTest.kt
index 627c4a8..1f0f0d7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivityTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivityTest.kt
@@ -16,14 +16,13 @@
 
 package com.android.systemui.notetask.shortcut
 
-import android.content.Intent
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import androidx.test.filters.SmallTest
 import androidx.test.rule.ActivityTestRule
-import androidx.test.runner.intercepting.SingleActivityFactory
 import com.android.dx.mockito.inline.extended.ExtendedMockito.verify
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.activity.SingleActivityFactory
 import com.android.systemui.notetask.NoteTaskController
 import com.android.systemui.notetask.NoteTaskEntryPoint
 import com.android.systemui.util.mockito.any
@@ -47,12 +46,8 @@
     @JvmField
     val activityRule =
         ActivityTestRule<LaunchNoteTaskActivity>(
-            /* activityFactory= */ object :
-                SingleActivityFactory<LaunchNoteTaskActivity>(LaunchNoteTaskActivity::class.java) {
-                override fun create(intent: Intent?) =
-                    LaunchNoteTaskActivity(
-                        controller = noteTaskController,
-                    )
+            /* activityFactory= */ SingleActivityFactory {
+                LaunchNoteTaskActivity(controller = noteTaskController)
             },
             /* initialTouchMode= */ false,
             /* launchActivity= */ false,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
index c85c8ba..ed7a59e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
@@ -53,7 +53,6 @@
                     override fun create(containerName: String): LockscreenSceneInteractor {
                         return utils.lockScreenSceneInteractor(
                             authenticationInteractor = authenticationInteractor,
-                            sceneInteractor = sceneInteractor,
                             bouncerInteractor =
                                 utils.bouncerInteractor(
                                     authenticationInteractor = authenticationInteractor,
@@ -69,9 +68,7 @@
     fun onContentClicked_deviceUnlocked_switchesToGone() =
         testScope.runTest {
             val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             utils.authenticationRepository.setUnlocked(true)
             runCurrent()
 
@@ -84,9 +81,7 @@
     fun onContentClicked_deviceLockedSecurely_switchesToBouncer() =
         testScope.runTest {
             val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             utils.authenticationRepository.setUnlocked(false)
             runCurrent()
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
index de15c77..9ce378d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
@@ -24,6 +24,7 @@
 import com.android.systemui.scene.SceneTestUtils
 import com.android.systemui.scene.shared.model.SceneKey
 import com.android.systemui.scene.shared.model.SceneModel
+import com.android.systemui.scene.shared.model.SceneTransitionModel
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runTest
@@ -40,7 +41,7 @@
     @Test
     fun allSceneKeys() {
         val underTest = utils.fakeSceneContainerRepository()
-        assertThat(underTest.allSceneKeys("container1"))
+        assertThat(underTest.allSceneKeys(SceneTestUtils.CONTAINER_1))
             .isEqualTo(
                 listOf(
                     SceneKey.QuickSettings,
@@ -61,10 +62,10 @@
     @Test
     fun currentScene() = runTest {
         val underTest = utils.fakeSceneContainerRepository()
-        val currentScene by collectLastValue(underTest.currentScene("container1"))
+        val currentScene by collectLastValue(underTest.currentScene(SceneTestUtils.CONTAINER_1))
         assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
 
-        underTest.setCurrentScene("container1", SceneModel(SceneKey.Shade))
+        underTest.setCurrentScene(SceneTestUtils.CONTAINER_1, SceneModel(SceneKey.Shade))
         assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Shade))
     }
 
@@ -85,26 +86,26 @@
         val underTest =
             utils.fakeSceneContainerRepository(
                 setOf(
-                    utils.fakeSceneContainerConfig("container1"),
+                    utils.fakeSceneContainerConfig(SceneTestUtils.CONTAINER_1),
                     utils.fakeSceneContainerConfig(
-                        "container2",
+                        SceneTestUtils.CONTAINER_2,
                         listOf(SceneKey.QuickSettings, SceneKey.Lockscreen)
                     ),
                 )
             )
-        underTest.setCurrentScene("container2", SceneModel(SceneKey.Shade))
+        underTest.setCurrentScene(SceneTestUtils.CONTAINER_2, SceneModel(SceneKey.Shade))
     }
 
     @Test
     fun isVisible() = runTest {
         val underTest = utils.fakeSceneContainerRepository()
-        val isVisible by collectLastValue(underTest.isVisible("container1"))
+        val isVisible by collectLastValue(underTest.isVisible(SceneTestUtils.CONTAINER_1))
         assertThat(isVisible).isTrue()
 
-        underTest.setVisible("container1", false)
+        underTest.setVisible(SceneTestUtils.CONTAINER_1, false)
         assertThat(isVisible).isFalse()
 
-        underTest.setVisible("container1", true)
+        underTest.setVisible(SceneTestUtils.CONTAINER_1, true)
         assertThat(isVisible).isTrue()
     }
 
@@ -124,13 +125,13 @@
     fun sceneTransitionProgress() = runTest {
         val underTest = utils.fakeSceneContainerRepository()
         val sceneTransitionProgress by
-            collectLastValue(underTest.sceneTransitionProgress("container1"))
+            collectLastValue(underTest.sceneTransitionProgress(SceneTestUtils.CONTAINER_1))
         assertThat(sceneTransitionProgress).isEqualTo(1f)
 
-        underTest.setSceneTransitionProgress("container1", 0.1f)
+        underTest.setSceneTransitionProgress(SceneTestUtils.CONTAINER_1, 0.1f)
         assertThat(sceneTransitionProgress).isEqualTo(0.1f)
 
-        underTest.setSceneTransitionProgress("container1", 0.9f)
+        underTest.setSceneTransitionProgress(SceneTestUtils.CONTAINER_1, 0.9f)
         assertThat(sceneTransitionProgress).isEqualTo(0.9f)
     }
 
@@ -139,4 +140,75 @@
         val underTest = utils.fakeSceneContainerRepository()
         underTest.sceneTransitionProgress("nonExistingContainer")
     }
+
+    @Test
+    fun setSceneTransition() = runTest {
+        val underTest =
+            utils.fakeSceneContainerRepository(
+                setOf(
+                    utils.fakeSceneContainerConfig(SceneTestUtils.CONTAINER_1),
+                    utils.fakeSceneContainerConfig(
+                        SceneTestUtils.CONTAINER_2,
+                        listOf(SceneKey.QuickSettings, SceneKey.Lockscreen)
+                    ),
+                )
+            )
+        val sceneTransition by
+            collectLastValue(underTest.sceneTransitions(SceneTestUtils.CONTAINER_2))
+        assertThat(sceneTransition).isNull()
+
+        underTest.setSceneTransition(
+            SceneTestUtils.CONTAINER_2,
+            SceneKey.Lockscreen,
+            SceneKey.QuickSettings
+        )
+        assertThat(sceneTransition)
+            .isEqualTo(
+                SceneTransitionModel(from = SceneKey.Lockscreen, to = SceneKey.QuickSettings)
+            )
+    }
+
+    @Test(expected = IllegalStateException::class)
+    fun setSceneTransition_noSuchContainer_throws() {
+        val underTest = utils.fakeSceneContainerRepository()
+        underTest.setSceneTransition("nonExistingContainer", SceneKey.Lockscreen, SceneKey.Shade)
+    }
+
+    @Test(expected = IllegalStateException::class)
+    fun setSceneTransition_noFromSceneInContainer_throws() {
+        val underTest =
+            utils.fakeSceneContainerRepository(
+                setOf(
+                    utils.fakeSceneContainerConfig(SceneTestUtils.CONTAINER_1),
+                    utils.fakeSceneContainerConfig(
+                        SceneTestUtils.CONTAINER_2,
+                        listOf(SceneKey.QuickSettings, SceneKey.Lockscreen)
+                    ),
+                )
+            )
+        underTest.setSceneTransition(
+            SceneTestUtils.CONTAINER_2,
+            SceneKey.Shade,
+            SceneKey.Lockscreen
+        )
+    }
+
+    @Test(expected = IllegalStateException::class)
+    fun setSceneTransition_noToSceneInContainer_throws() {
+        val underTest =
+            utils.fakeSceneContainerRepository(
+                setOf(
+                    utils.fakeSceneContainerConfig(SceneTestUtils.CONTAINER_1),
+                    utils.fakeSceneContainerConfig(
+                        SceneTestUtils.CONTAINER_2,
+                        listOf(SceneKey.QuickSettings, SceneKey.Lockscreen)
+                    ),
+                )
+            )
+        underTest.setSceneTransition(
+            SceneTestUtils.CONTAINER_2,
+            SceneKey.Shade,
+            SceneKey.Lockscreen
+        )
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
index ee4f6c2..3050c4e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
@@ -24,6 +24,7 @@
 import com.android.systemui.scene.SceneTestUtils
 import com.android.systemui.scene.shared.model.SceneKey
 import com.android.systemui.scene.shared.model.SceneModel
+import com.android.systemui.scene.shared.model.SceneTransitionModel
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runTest
@@ -40,36 +41,63 @@
 
     @Test
     fun allSceneKeys() {
-        assertThat(underTest.allSceneKeys("container1")).isEqualTo(utils.fakeSceneKeys())
+        assertThat(underTest.allSceneKeys(SceneTestUtils.CONTAINER_1))
+            .isEqualTo(utils.fakeSceneKeys())
     }
 
     @Test
-    fun sceneTransitions() = runTest {
-        val currentScene by collectLastValue(underTest.currentScene("container1"))
+    fun currentScene() = runTest {
+        val currentScene by collectLastValue(underTest.currentScene(SceneTestUtils.CONTAINER_1))
         assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
 
-        underTest.setCurrentScene("container1", SceneModel(SceneKey.Shade))
+        underTest.setCurrentScene(SceneTestUtils.CONTAINER_1, SceneModel(SceneKey.Shade))
         assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Shade))
     }
 
     @Test
     fun sceneTransitionProgress() = runTest {
-        val progress by collectLastValue(underTest.sceneTransitionProgress("container1"))
+        val progress by
+            collectLastValue(underTest.sceneTransitionProgress(SceneTestUtils.CONTAINER_1))
         assertThat(progress).isEqualTo(1f)
 
-        underTest.setSceneTransitionProgress("container1", 0.55f)
+        underTest.setSceneTransitionProgress(SceneTestUtils.CONTAINER_1, 0.55f)
         assertThat(progress).isEqualTo(0.55f)
     }
 
     @Test
     fun isVisible() = runTest {
-        val isVisible by collectLastValue(underTest.isVisible("container1"))
+        val isVisible by collectLastValue(underTest.isVisible(SceneTestUtils.CONTAINER_1))
         assertThat(isVisible).isTrue()
 
-        underTest.setVisible("container1", false)
+        underTest.setVisible(SceneTestUtils.CONTAINER_1, false)
         assertThat(isVisible).isFalse()
 
-        underTest.setVisible("container1", true)
+        underTest.setVisible(SceneTestUtils.CONTAINER_1, true)
         assertThat(isVisible).isTrue()
     }
+
+    @Test
+    fun sceneTransitions() = runTest {
+        val transitions by collectLastValue(underTest.sceneTransitions(SceneTestUtils.CONTAINER_1))
+        assertThat(transitions).isNull()
+
+        val initialSceneKey = underTest.currentScene(SceneTestUtils.CONTAINER_1).value.key
+        underTest.setCurrentScene(SceneTestUtils.CONTAINER_1, SceneModel(SceneKey.Shade))
+        assertThat(transitions)
+            .isEqualTo(
+                SceneTransitionModel(
+                    from = initialSceneKey,
+                    to = SceneKey.Shade,
+                )
+            )
+
+        underTest.setCurrentScene(SceneTestUtils.CONTAINER_1, SceneModel(SceneKey.QuickSettings))
+        assertThat(transitions)
+            .isEqualTo(
+                SceneTransitionModel(
+                    from = SceneKey.Shade,
+                    to = SceneKey.QuickSettings,
+                )
+            )
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SystemUiDefaultSceneContainerStartableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SystemUiDefaultSceneContainerStartableTest.kt
new file mode 100644
index 0000000..3e9ddcb
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SystemUiDefaultSceneContainerStartableTest.kt
@@ -0,0 +1,402 @@
+/*
+ * 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.
+ */
+
+package com.android.systemui.scene.domain.startable
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.shared.model.WakeSleepReason
+import com.android.systemui.keyguard.shared.model.WakefulnessModel
+import com.android.systemui.keyguard.shared.model.WakefulnessState
+import com.android.systemui.scene.SceneTestUtils
+import com.android.systemui.scene.shared.model.SceneContainerNames
+import com.android.systemui.scene.shared.model.SceneKey
+import com.android.systemui.scene.shared.model.SceneModel
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
+
+    private val utils = SceneTestUtils(this)
+    private val testScope = utils.testScope
+    private val sceneInteractor = utils.sceneInteractor()
+    private val featureFlags = utils.featureFlags
+    private val authenticationRepository = utils.authenticationRepository()
+    private val authenticationInteractor =
+        utils.authenticationInteractor(
+            repository = authenticationRepository,
+        )
+    private val keyguardRepository = utils.keyguardRepository()
+    private val keyguardInteractor =
+        utils.keyguardInteractor(
+            repository = keyguardRepository,
+        )
+
+    private val underTest =
+        SystemUiDefaultSceneContainerStartable(
+            applicationScope = testScope.backgroundScope,
+            sceneInteractor = sceneInteractor,
+            authenticationInteractor = authenticationInteractor,
+            keyguardInteractor = keyguardInteractor,
+            featureFlags = featureFlags,
+        )
+
+    @Before
+    fun setUp() {
+        prepareState()
+    }
+
+    @Test
+    fun hydrateVisibility_featureEnabled() =
+        testScope.runTest {
+            val currentSceneKey by
+                collectLastValue(
+                    sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
+                        it.key
+                    }
+                )
+            val isVisible by
+                collectLastValue(sceneInteractor.isVisible(SceneContainerNames.SYSTEM_UI_DEFAULT))
+            prepareState(
+                isFeatureEnabled = true,
+                isDeviceUnlocked = true,
+                initialSceneKey = SceneKey.Gone,
+            )
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Gone)
+            assertThat(isVisible).isTrue()
+
+            underTest.start()
+
+            assertThat(isVisible).isFalse()
+
+            sceneInteractor.setCurrentScene(
+                SceneContainerNames.SYSTEM_UI_DEFAULT,
+                SceneModel(SceneKey.Shade)
+            )
+            assertThat(isVisible).isTrue()
+        }
+
+    @Test
+    fun hydrateVisibility_featureDisabled() =
+        testScope.runTest {
+            val currentSceneKey by
+                collectLastValue(
+                    sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
+                        it.key
+                    }
+                )
+            val isVisible by
+                collectLastValue(sceneInteractor.isVisible(SceneContainerNames.SYSTEM_UI_DEFAULT))
+            prepareState(
+                isFeatureEnabled = false,
+                isDeviceUnlocked = true,
+                initialSceneKey = SceneKey.Lockscreen,
+            )
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Lockscreen)
+            assertThat(isVisible).isTrue()
+
+            underTest.start()
+            assertThat(isVisible).isTrue()
+
+            sceneInteractor.setCurrentScene(
+                SceneContainerNames.SYSTEM_UI_DEFAULT,
+                SceneModel(SceneKey.Gone)
+            )
+            assertThat(isVisible).isTrue()
+
+            sceneInteractor.setCurrentScene(
+                SceneContainerNames.SYSTEM_UI_DEFAULT,
+                SceneModel(SceneKey.Shade)
+            )
+            assertThat(isVisible).isTrue()
+        }
+
+    @Test
+    fun switchToLockscreenWhenDeviceLocks_featureEnabled() =
+        testScope.runTest {
+            val currentSceneKey by
+                collectLastValue(
+                    sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
+                        it.key
+                    }
+                )
+            prepareState(
+                isFeatureEnabled = true,
+                isDeviceUnlocked = true,
+                initialSceneKey = SceneKey.Gone,
+            )
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Gone)
+            underTest.start()
+
+            authenticationRepository.setUnlocked(false)
+
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Lockscreen)
+        }
+
+    @Test
+    fun switchToLockscreenWhenDeviceLocks_featureDisabled() =
+        testScope.runTest {
+            val currentSceneKey by
+                collectLastValue(
+                    sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
+                        it.key
+                    }
+                )
+            prepareState(
+                isFeatureEnabled = false,
+                isDeviceUnlocked = false,
+                initialSceneKey = SceneKey.Gone,
+            )
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Gone)
+            underTest.start()
+
+            authenticationRepository.setUnlocked(false)
+
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Gone)
+        }
+
+    @Test
+    fun switchFromBouncerToGoneWhenDeviceUnlocked_featureEnabled() =
+        testScope.runTest {
+            val currentSceneKey by
+                collectLastValue(
+                    sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
+                        it.key
+                    }
+                )
+            prepareState(
+                isFeatureEnabled = true,
+                isDeviceUnlocked = false,
+                initialSceneKey = SceneKey.Bouncer,
+            )
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Bouncer)
+            underTest.start()
+
+            authenticationRepository.setUnlocked(true)
+
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Gone)
+        }
+
+    @Test
+    fun switchFromBouncerToGoneWhenDeviceUnlocked_featureDisabled() =
+        testScope.runTest {
+            val currentSceneKey by
+                collectLastValue(
+                    sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
+                        it.key
+                    }
+                )
+            prepareState(
+                isFeatureEnabled = false,
+                isDeviceUnlocked = false,
+                initialSceneKey = SceneKey.Bouncer,
+            )
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Bouncer)
+            underTest.start()
+
+            authenticationRepository.setUnlocked(true)
+
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Bouncer)
+        }
+
+    @Test
+    fun switchFromLockscreenToGoneWhenDeviceUnlocksWithBypassOn_featureOn_bypassOn() =
+        testScope.runTest {
+            val currentSceneKey by
+                collectLastValue(
+                    sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
+                        it.key
+                    }
+                )
+            prepareState(
+                isFeatureEnabled = true,
+                isBypassEnabled = true,
+                initialSceneKey = SceneKey.Lockscreen,
+            )
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Lockscreen)
+            underTest.start()
+
+            authenticationRepository.setUnlocked(true)
+
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Gone)
+        }
+
+    @Test
+    fun switchFromLockscreenToGoneWhenDeviceUnlocksWithBypassOn_featureOn_bypassOff() =
+        testScope.runTest {
+            val currentSceneKey by
+                collectLastValue(
+                    sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
+                        it.key
+                    }
+                )
+            prepareState(
+                isFeatureEnabled = true,
+                isBypassEnabled = false,
+                initialSceneKey = SceneKey.Lockscreen,
+            )
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Lockscreen)
+            underTest.start()
+
+            authenticationRepository.setUnlocked(true)
+
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Lockscreen)
+        }
+
+    @Test
+    fun switchFromLockscreenToGoneWhenDeviceUnlocksWithBypassOn_featureOff_bypassOn() =
+        testScope.runTest {
+            val currentSceneKey by
+                collectLastValue(
+                    sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
+                        it.key
+                    }
+                )
+            prepareState(
+                isFeatureEnabled = false,
+                isBypassEnabled = true,
+                initialSceneKey = SceneKey.Lockscreen,
+            )
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Lockscreen)
+            underTest.start()
+
+            authenticationRepository.setUnlocked(true)
+
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Lockscreen)
+        }
+
+    @Test
+    fun switchToGoneWhenDeviceSleepsUnlocked_featureEnabled() =
+        testScope.runTest {
+            val currentSceneKey by
+                collectLastValue(
+                    sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
+                        it.key
+                    }
+                )
+            prepareState(
+                isFeatureEnabled = true,
+                isDeviceUnlocked = true,
+                initialSceneKey = SceneKey.Shade,
+            )
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Shade)
+            underTest.start()
+
+            keyguardRepository.setWakefulnessModel(ASLEEP)
+
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Gone)
+        }
+
+    @Test
+    fun switchToGoneWhenDeviceSleepsUnlocked_featureDisabled() =
+        testScope.runTest {
+            val currentSceneKey by
+                collectLastValue(
+                    sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
+                        it.key
+                    }
+                )
+            prepareState(
+                isFeatureEnabled = false,
+                isDeviceUnlocked = true,
+                initialSceneKey = SceneKey.Shade,
+            )
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Shade)
+            underTest.start()
+
+            keyguardRepository.setWakefulnessModel(ASLEEP)
+
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Shade)
+        }
+
+    @Test
+    fun switchToLockscreenWhenDeviceSleepsLocked_featureEnabled() =
+        testScope.runTest {
+            val currentSceneKey by
+                collectLastValue(
+                    sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
+                        it.key
+                    }
+                )
+            prepareState(
+                isFeatureEnabled = true,
+                isDeviceUnlocked = false,
+                initialSceneKey = SceneKey.Shade,
+            )
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Shade)
+            underTest.start()
+
+            keyguardRepository.setWakefulnessModel(ASLEEP)
+
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Lockscreen)
+        }
+
+    @Test
+    fun switchToLockscreenWhenDeviceSleepsLocked_featureDisabled() =
+        testScope.runTest {
+            val currentSceneKey by
+                collectLastValue(
+                    sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
+                        it.key
+                    }
+                )
+            prepareState(
+                isFeatureEnabled = false,
+                isDeviceUnlocked = false,
+                initialSceneKey = SceneKey.Shade,
+            )
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Shade)
+            underTest.start()
+
+            keyguardRepository.setWakefulnessModel(ASLEEP)
+
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Shade)
+        }
+
+    private fun prepareState(
+        isFeatureEnabled: Boolean = true,
+        isDeviceUnlocked: Boolean = false,
+        isBypassEnabled: Boolean = false,
+        initialSceneKey: SceneKey? = null,
+    ) {
+        featureFlags.set(Flags.SCENE_CONTAINER, isFeatureEnabled)
+        authenticationRepository.setUnlocked(isDeviceUnlocked)
+        authenticationRepository.setBypassEnabled(isBypassEnabled)
+        initialSceneKey?.let {
+            sceneInteractor.setCurrentScene(SceneContainerNames.SYSTEM_UI_DEFAULT, SceneModel(it))
+        }
+    }
+
+    companion object {
+        private val ASLEEP =
+            WakefulnessModel(
+                state = WakefulnessState.ASLEEP,
+                lastWakeReason = WakeSleepReason.POWER_BUTTON,
+                lastSleepReason = WakeSleepReason.POWER_BUTTON
+            )
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
index cd2f5af..6882be7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
@@ -40,7 +40,7 @@
     private val underTest =
         SceneContainerViewModel(
             interactor = interactor,
-            containerName = "container1",
+            containerName = SceneTestUtils.CONTAINER_1,
         )
 
     @Test
@@ -48,10 +48,10 @@
         val isVisible by collectLastValue(underTest.isVisible)
         assertThat(isVisible).isTrue()
 
-        interactor.setVisible("container1", false)
+        interactor.setVisible(SceneTestUtils.CONTAINER_1, false)
         assertThat(isVisible).isFalse()
 
-        interactor.setVisible("container1", true)
+        interactor.setVisible(SceneTestUtils.CONTAINER_1, true)
         assertThat(isVisible).isTrue()
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt
index 7646193..5c35913 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt
@@ -23,22 +23,28 @@
 import android.testing.TestableLooper
 import android.view.View
 import android.view.ViewGroup
+import android.view.WindowManagerPolicyConstants.EXTRA_FROM_BRIGHTNESS_KEY
 import androidx.test.filters.SmallTest
 import androidx.test.rule.ActivityTestRule
-import androidx.test.runner.intercepting.SingleActivityFactory
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.activity.SingleActivityFactory
 import com.android.systemui.settings.FakeDisplayTracker
 import com.android.systemui.settings.UserTracker
+import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
+import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
+import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
-import java.util.concurrent.Executor
 import org.junit.After
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
+import org.mockito.Mockito.anyInt
+import org.mockito.Mockito.eq
 import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
 
@@ -49,9 +55,12 @@
 
     @Mock private lateinit var userTracker: UserTracker
     @Mock private lateinit var brightnessSliderControllerFactory: BrightnessSliderController.Factory
-    @Mock private lateinit var mainExecutor: Executor
     @Mock private lateinit var backgroundHandler: Handler
     @Mock private lateinit var brightnessSliderController: BrightnessSliderController
+    @Mock private lateinit var accessibilityMgr: AccessibilityManagerWrapper
+
+    private val clock = FakeSystemClock()
+    private val mainExecutor = FakeExecutor(clock)
 
     private var displayTracker = FakeDisplayTracker(mContext)
 
@@ -59,19 +68,18 @@
     @JvmField
     var activityRule =
         ActivityTestRule(
-            object : SingleActivityFactory<TestDialog>(TestDialog::class.java) {
-                override fun create(intent: Intent?): TestDialog {
-                    return TestDialog(
-                        userTracker,
-                        displayTracker,
-                        brightnessSliderControllerFactory,
-                        mainExecutor,
-                        backgroundHandler
-                    )
-                }
+            /* activityFactory= */ SingleActivityFactory {
+                TestDialog(
+                    userTracker,
+                    displayTracker,
+                    brightnessSliderControllerFactory,
+                    mainExecutor,
+                    backgroundHandler,
+                    accessibilityMgr
+                )
             },
-            false,
-            false
+            /* initialTouchMode= */ false,
+            /* launchActivity= */ false,
         )
 
     @Before
@@ -80,8 +88,6 @@
         `when`(brightnessSliderControllerFactory.create(any(), any()))
             .thenReturn(brightnessSliderController)
         `when`(brightnessSliderController.rootView).thenReturn(View(context))
-
-        activityRule.launchActivity(null)
     }
 
     @After
@@ -91,6 +97,7 @@
 
     @Test
     fun testGestureExclusion() {
+        activityRule.launchActivity(Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG))
         val frame = activityRule.activity.requireViewById<View>(R.id.brightness_mirror_container)
 
         val lp = frame.layoutParams as ViewGroup.MarginLayoutParams
@@ -107,18 +114,83 @@
             .isEqualTo(Rect(-horizontalMargin, 0, frame.width + horizontalMargin, frame.height))
     }
 
+    @Test
+    fun testTimeout() {
+        `when`(
+                accessibilityMgr.getRecommendedTimeoutMillis(
+                    eq(BrightnessDialog.DIALOG_TIMEOUT_MILLIS),
+                    anyInt()
+                )
+            )
+            .thenReturn(BrightnessDialog.DIALOG_TIMEOUT_MILLIS)
+        val intent = Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG)
+        intent.putExtra(EXTRA_FROM_BRIGHTNESS_KEY, true)
+        activityRule.launchActivity(intent)
+
+        assertThat(activityRule.activity.isFinishing()).isFalse()
+
+        clock.advanceTime(BrightnessDialog.DIALOG_TIMEOUT_MILLIS.toLong())
+        assertThat(activityRule.activity.isFinishing()).isTrue()
+    }
+
+    @Test
+    fun testRestartTimeout() {
+        `when`(
+                accessibilityMgr.getRecommendedTimeoutMillis(
+                    eq(BrightnessDialog.DIALOG_TIMEOUT_MILLIS),
+                    anyInt()
+                )
+            )
+            .thenReturn(BrightnessDialog.DIALOG_TIMEOUT_MILLIS)
+        val intent = Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG)
+        intent.putExtra(EXTRA_FROM_BRIGHTNESS_KEY, true)
+        activityRule.launchActivity(intent)
+
+        assertThat(activityRule.activity.isFinishing()).isFalse()
+
+        clock.advanceTime(BrightnessDialog.DIALOG_TIMEOUT_MILLIS.toLong() / 2)
+        // Restart the timeout
+        activityRule.activity.onResume()
+
+        clock.advanceTime(BrightnessDialog.DIALOG_TIMEOUT_MILLIS.toLong() / 2)
+        // The dialog should not have disappeared yet
+        assertThat(activityRule.activity.isFinishing()).isFalse()
+
+        clock.advanceTime(BrightnessDialog.DIALOG_TIMEOUT_MILLIS.toLong() / 2)
+        assertThat(activityRule.activity.isFinishing()).isTrue()
+    }
+
+    @Test
+    fun testNoTimeoutIfNotStartedByBrightnessKey() {
+        `when`(
+                accessibilityMgr.getRecommendedTimeoutMillis(
+                    eq(BrightnessDialog.DIALOG_TIMEOUT_MILLIS),
+                    anyInt()
+                )
+            )
+            .thenReturn(BrightnessDialog.DIALOG_TIMEOUT_MILLIS)
+        activityRule.launchActivity(Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG))
+
+        assertThat(activityRule.activity.isFinishing()).isFalse()
+
+        clock.advanceTime(BrightnessDialog.DIALOG_TIMEOUT_MILLIS.toLong())
+        assertThat(activityRule.activity.isFinishing()).isFalse()
+    }
+
     class TestDialog(
         userTracker: UserTracker,
         displayTracker: FakeDisplayTracker,
         brightnessSliderControllerFactory: BrightnessSliderController.Factory,
-        mainExecutor: Executor,
-        backgroundHandler: Handler
+        mainExecutor: DelayableExecutor,
+        backgroundHandler: Handler,
+        accessibilityMgr: AccessibilityManagerWrapper
     ) :
         BrightnessDialog(
             userTracker,
             displayTracker,
             brightnessSliderControllerFactory,
             mainExecutor,
-            backgroundHandler
+            backgroundHandler,
+            accessibilityMgr
         )
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt
index 3ea8f54..cdcd1a2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt
@@ -20,6 +20,7 @@
 import android.app.StatusBarManager.DISABLE2_NONE
 import android.app.StatusBarManager.DISABLE2_NOTIFICATION_SHADE
 import android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS
+import android.content.pm.UserInfo
 import android.os.UserManager
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.UiEventLogger
@@ -47,6 +48,7 @@
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
@@ -92,6 +94,23 @@
                 mainDispatcher = testDispatcher,
                 repository = userRepository,
             )
+
+        runBlocking {
+            val userInfos =
+                listOf(
+                    UserInfo(
+                        /* id= */ 0,
+                        /* name= */ "zero",
+                        /* iconPath= */ "",
+                        /* flags= */ UserInfo.FLAG_PRIMARY or
+                            UserInfo.FLAG_ADMIN or
+                            UserInfo.FLAG_FULL,
+                        UserManager.USER_TYPE_FULL_SYSTEM,
+                    ),
+                )
+            userRepository.setUserInfos(userInfos)
+            userRepository.setSelectedUserInfo(userInfos[0])
+        }
         userInteractor =
             UserInteractor(
                 applicationContext = context,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
index 5d2d192..6e9fba6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
@@ -22,7 +22,6 @@
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
 import com.android.systemui.scene.SceneTestUtils
-import com.android.systemui.scene.SceneTestUtils.Companion.CONTAINER_1
 import com.android.systemui.scene.shared.model.SceneKey
 import com.android.systemui.scene.shared.model.SceneModel
 import com.google.common.truth.Truth.assertThat
@@ -54,7 +53,6 @@
                     override fun create(containerName: String): LockscreenSceneInteractor {
                         return utils.lockScreenSceneInteractor(
                             authenticationInteractor = authenticationInteractor,
-                            sceneInteractor = sceneInteractor,
                             bouncerInteractor =
                                 utils.bouncerInteractor(
                                     authenticationInteractor = authenticationInteractor,
@@ -70,9 +68,7 @@
     fun upTransitionSceneKey_deviceLocked_lockScreen() =
         testScope.runTest {
             val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             utils.authenticationRepository.setUnlocked(false)
 
             assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Lockscreen)
@@ -82,9 +78,7 @@
     fun upTransitionSceneKey_deviceUnlocked_gone() =
         testScope.runTest {
             val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey)
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             utils.authenticationRepository.setUnlocked(true)
 
             assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Gone)
@@ -93,10 +87,9 @@
     @Test
     fun onContentClicked_deviceUnlocked_switchesToGone() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             utils.authenticationRepository.setUnlocked(true)
             runCurrent()
 
@@ -108,10 +101,9 @@
     @Test
     fun onContentClicked_deviceLockedSecurely_switchesToBouncer() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
-            utils.authenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin(1234)
-            )
+            val currentScene by
+                collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
             utils.authenticationRepository.setUnlocked(false)
             runCurrent()
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java
new file mode 100644
index 0000000..d44846e
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java
@@ -0,0 +1,295 @@
+/*
+ * 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 static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_DEFAULT;
+
+import static com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR;
+import static com.android.systemui.flags.Flags.KEYGUARD_TALKBACK_FIX;
+import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED;
+import static com.android.systemui.keyguard.ScreenLifecycle.SCREEN_ON;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.AlarmManager;
+import android.app.Instrumentation;
+import android.app.admin.DevicePolicyManager;
+import android.app.admin.DevicePolicyResourcesManager;
+import android.app.trust.TrustManager;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.hardware.fingerprint.FingerprintManager;
+import android.os.Looper;
+import android.os.UserManager;
+import android.provider.DeviceConfig;
+import android.testing.TestableLooper;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityManager;
+
+import androidx.test.InstrumentationRegistry;
+
+import com.android.internal.app.IBatteryStats;
+import com.android.internal.widget.LockPatternUtils;
+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.SysuiTestCase;
+import com.android.systemui.biometrics.AuthController;
+import com.android.systemui.biometrics.FaceHelpMessageDeferral;
+import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
+import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.dock.DockManager;
+import com.android.systemui.flags.FakeFeatureFlags;
+import com.android.systemui.keyguard.KeyguardIndication;
+import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController;
+import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory;
+import com.android.systemui.keyguard.util.IndicationHelper;
+import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.settings.UserTracker;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
+import com.android.systemui.util.wakelock.WakeLockFake;
+
+import org.junit.After;
+import org.junit.Before;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class KeyguardIndicationControllerBaseTest extends SysuiTestCase {
+
+    protected static final String ORGANIZATION_NAME = "organization";
+
+    protected static final ComponentName DEVICE_OWNER_COMPONENT = new ComponentName(
+            "com.android.foo",
+            "bar");
+
+    protected static final int TEST_STRING_RES = R.string.keyguard_indication_trust_unlocked;
+
+    protected String mDisclosureWithOrganization;
+    protected String mDisclosureGeneric;
+    protected String mFinancedDisclosureWithOrganization;
+
+    @Mock
+    protected DevicePolicyManager mDevicePolicyManager;
+    @Mock
+    protected DevicePolicyResourcesManager mDevicePolicyResourcesManager;
+    @Mock
+    protected ViewGroup mIndicationArea;
+    @Mock
+    protected KeyguardStateController mKeyguardStateController;
+    @Mock
+    protected KeyguardIndicationTextView mIndicationAreaBottom;
+    @Mock
+    protected BroadcastDispatcher mBroadcastDispatcher;
+    @Mock
+    protected StatusBarStateController mStatusBarStateController;
+    @Mock
+    protected KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+    @Mock
+    protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+    @Mock
+    protected UserManager mUserManager;
+    @Mock
+    protected IBatteryStats mIBatteryStats;
+    @Mock
+    protected DockManager mDockManager;
+    @Mock
+    protected KeyguardIndicationRotateTextViewController mRotateTextViewController;
+    @Mock
+    protected FalsingManager mFalsingManager;
+    @Mock
+    protected LockPatternUtils mLockPatternUtils;
+    @Mock
+    protected KeyguardBypassController mKeyguardBypassController;
+    @Mock
+    protected AccessibilityManager mAccessibilityManager;
+    @Mock
+    protected FaceHelpMessageDeferral mFaceHelpMessageDeferral;
+    @Mock
+    protected AlternateBouncerInteractor mAlternateBouncerInteractor;
+    @Mock
+    protected ScreenLifecycle mScreenLifecycle;
+    @Mock
+    protected AuthController mAuthController;
+    @Mock
+    protected AlarmManager mAlarmManager;
+    @Mock
+    protected UserTracker mUserTracker;
+    @Captor
+    protected ArgumentCaptor<DockManager.AlignmentStateListener> mAlignmentListener;
+    @Captor
+    protected ArgumentCaptor<StatusBarStateController.StateListener> mStatusBarStateListenerCaptor;
+    @Captor
+    protected ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor;
+    @Captor
+    protected ArgumentCaptor<KeyguardIndication> mKeyguardIndicationCaptor;
+    @Captor
+    protected ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallbackCaptor;
+    @Captor
+    protected ArgumentCaptor<KeyguardStateController.Callback>
+            mKeyguardStateControllerCallbackCaptor;
+    @Captor
+    protected ArgumentCaptor<ScreenLifecycle.Observer> mScreenObserverCaptor;
+    protected KeyguardStateController.Callback mKeyguardStateControllerCallback;
+    protected KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback;
+    protected StatusBarStateController.StateListener mStatusBarStateListener;
+    protected ScreenLifecycle.Observer mScreenObserver;
+    protected BroadcastReceiver mBroadcastReceiver;
+    protected IndicationHelper mIndicationHelper;
+    protected FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
+    protected TestableLooper mTestableLooper;
+    protected final int mCurrentUserId = 1;
+
+    protected KeyguardIndicationTextView mTextView; // AOD text
+
+    protected KeyguardIndicationController mController;
+    protected WakeLockFake.Builder mWakeLockBuilder;
+    protected WakeLockFake mWakeLock;
+    protected Instrumentation mInstrumentation;
+    protected FakeFeatureFlags mFlags;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+        mTestableLooper = TestableLooper.get(this);
+        mTextView = new KeyguardIndicationTextView(mContext);
+        mTextView.setAnimationsEnabled(false);
+
+        // TODO(b/259908270): remove
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER,
+                DevicePolicyManager.ADD_ISFINANCED_DEVICE_FLAG, "true",
+                /* makeDefault= */ false);
+        mContext.addMockSystemService(Context.DEVICE_POLICY_SERVICE, mDevicePolicyManager);
+        mContext.addMockSystemService(UserManager.class, mUserManager);
+        mContext.addMockSystemService(Context.TRUST_SERVICE, mock(TrustManager.class));
+        mContext.addMockSystemService(Context.FINGERPRINT_SERVICE, mock(FingerprintManager.class));
+        mDisclosureWithOrganization = mContext.getString(R.string.do_disclosure_with_name,
+                ORGANIZATION_NAME);
+        mDisclosureGeneric = mContext.getString(R.string.do_disclosure_generic);
+        mFinancedDisclosureWithOrganization = mContext.getString(
+                R.string.do_financed_disclosure_with_name, ORGANIZATION_NAME);
+
+        when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
+        when(mScreenLifecycle.getScreenState()).thenReturn(SCREEN_ON);
+        when(mKeyguardUpdateMonitor.isUserUnlocked(anyInt())).thenReturn(true);
+
+        when(mIndicationArea.findViewById(R.id.keyguard_indication_text_bottom))
+                .thenReturn(mIndicationAreaBottom);
+        when(mIndicationArea.findViewById(R.id.keyguard_indication_text)).thenReturn(mTextView);
+
+        when(mDevicePolicyManager.getResources()).thenReturn(mDevicePolicyResourcesManager);
+        when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser())
+                .thenReturn(DEVICE_OWNER_COMPONENT);
+        when(mDevicePolicyManager.isFinancedDevice()).thenReturn(false);
+        // TODO(b/259908270): remove
+        when(mDevicePolicyManager.getDeviceOwnerType(DEVICE_OWNER_COMPONENT))
+                .thenReturn(DEVICE_OWNER_TYPE_DEFAULT);
+
+        when(mDevicePolicyResourcesManager.getString(anyString(), any()))
+                .thenReturn(mDisclosureGeneric);
+        when(mDevicePolicyResourcesManager.getString(anyString(), any(), anyString()))
+                .thenReturn(mDisclosureWithOrganization);
+        when(mUserTracker.getUserId()).thenReturn(mCurrentUserId);
+
+        mIndicationHelper = new IndicationHelper(mKeyguardUpdateMonitor);
+
+        mWakeLock = new WakeLockFake();
+        mWakeLockBuilder = new WakeLockFake.Builder(mContext);
+        mWakeLockBuilder.setWakeLock(mWakeLock);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mTextView.setAnimationsEnabled(true);
+        if (mController != null) {
+            mController.destroy();
+            mController = null;
+        }
+    }
+
+    protected void createController() {
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+
+        mFlags = new FakeFeatureFlags();
+        mFlags.set(KEYGUARD_TALKBACK_FIX, true);
+        mFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false);
+        mFlags.set(FACE_AUTH_REFACTOR, false);
+        mController = new KeyguardIndicationController(
+                mContext,
+                mTestableLooper.getLooper(),
+                mWakeLockBuilder,
+                mKeyguardStateController, mStatusBarStateController, mKeyguardUpdateMonitor,
+                mDockManager, mBroadcastDispatcher, mDevicePolicyManager, mIBatteryStats,
+                mUserManager, mExecutor, mExecutor, mFalsingManager,
+                mAuthController, mLockPatternUtils, mScreenLifecycle,
+                mKeyguardBypassController, mAccessibilityManager,
+                mFaceHelpMessageDeferral, mock(KeyguardLogger.class),
+                mAlternateBouncerInteractor,
+                mAlarmManager,
+                mUserTracker,
+                mock(BouncerMessageInteractor.class),
+                mFlags,
+                mIndicationHelper,
+                KeyguardInteractorFactory.create(mFlags).getKeyguardInteractor()
+        );
+        mController.init();
+        mController.setIndicationArea(mIndicationArea);
+        verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture());
+        mStatusBarStateListener = mStatusBarStateListenerCaptor.getValue();
+        verify(mBroadcastDispatcher).registerReceiver(mBroadcastReceiverCaptor.capture(), any());
+        mBroadcastReceiver = mBroadcastReceiverCaptor.getValue();
+        mController.mRotateTextViewController = mRotateTextViewController;
+        mController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
+        clearInvocations(mIBatteryStats);
+
+        verify(mKeyguardStateController).addCallback(
+                mKeyguardStateControllerCallbackCaptor.capture());
+        mKeyguardStateControllerCallback = mKeyguardStateControllerCallbackCaptor.getValue();
+
+        verify(mKeyguardUpdateMonitor).registerCallback(
+                mKeyguardUpdateMonitorCallbackCaptor.capture());
+        mKeyguardUpdateMonitorCallback = mKeyguardUpdateMonitorCallbackCaptor.getValue();
+
+        verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture());
+        mScreenObserver = mScreenObserverCaptor.getValue();
+
+        mExecutor.runAllReady();
+        reset(mRotateTextViewController);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index b1f5dde..8cf005dc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -11,12 +11,11 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
  */
 
 package com.android.systemui.statusbar;
 
-import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_DEFAULT;
 import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED;
 import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE;
 import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_DARK;
@@ -26,7 +25,6 @@
 import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_AVAILABLE;
 import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
 import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED;
-import static com.android.systemui.flags.Flags.KEYGUARD_TALKBACK_FIX;
 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_ALIGNMENT;
 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BATTERY;
 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BIOMETRIC_MESSAGE;
@@ -38,7 +36,6 @@
 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_TRANSIENT;
 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_TRUST;
 import static com.android.systemui.keyguard.ScreenLifecycle.SCREEN_OFF;
-import static com.android.systemui.keyguard.ScreenLifecycle.SCREEN_ON;
 import static com.android.systemui.keyguard.ScreenLifecycle.SCREEN_TURNING_ON;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -60,73 +57,28 @@
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
-import android.app.AlarmManager;
-import android.app.Instrumentation;
-import android.app.admin.DevicePolicyManager;
-import android.app.admin.DevicePolicyResourcesManager;
-import android.app.trust.TrustManager;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
 import android.content.Intent;
 import android.content.pm.UserInfo;
 import android.graphics.Color;
 import android.hardware.biometrics.BiometricFaceConstants;
 import android.hardware.biometrics.BiometricFingerprintConstants;
 import android.hardware.biometrics.BiometricSourceType;
-import android.hardware.fingerprint.FingerprintManager;
 import android.os.BatteryManager;
-import android.os.Looper;
 import android.os.RemoteException;
-import android.os.UserManager;
-import android.provider.DeviceConfig;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
-import android.view.ViewGroup;
-import android.view.accessibility.AccessibilityManager;
 
-import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 
-import com.android.internal.app.IBatteryStats;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.keyguard.TrustGrantFlags;
-import com.android.keyguard.logging.KeyguardLogger;
 import com.android.settingslib.fuelgauge.BatteryStatus;
 import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.biometrics.AuthController;
-import com.android.systemui.biometrics.FaceHelpMessageDeferral;
-import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
-import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor;
-import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dock.DockManager;
-import com.android.systemui.flags.FakeFeatureFlags;
 import com.android.systemui.keyguard.KeyguardIndication;
 import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController;
-import com.android.systemui.keyguard.ScreenLifecycle;
-import com.android.systemui.keyguard.util.IndicationHelper;
-import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.settings.UserTracker;
-import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.util.concurrency.FakeExecutor;
-import com.android.systemui.util.time.FakeSystemClock;
-import com.android.systemui.util.wakelock.WakeLockFake;
 
-import org.junit.After;
-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;
 
 import java.text.NumberFormat;
 import java.util.Collections;
@@ -137,205 +89,7 @@
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
-public class KeyguardIndicationControllerTest extends SysuiTestCase {
-
-    private static final String ORGANIZATION_NAME = "organization";
-
-    private static final ComponentName DEVICE_OWNER_COMPONENT = new ComponentName("com.android.foo",
-            "bar");
-
-    private static final int TEST_STRING_RES = R.string.keyguard_indication_trust_unlocked;
-
-    private String mDisclosureWithOrganization;
-    private String mDisclosureGeneric;
-    private String mFinancedDisclosureWithOrganization;
-
-    @Mock
-    private DevicePolicyManager mDevicePolicyManager;
-    @Mock
-    private DevicePolicyResourcesManager mDevicePolicyResourcesManager;
-    @Mock
-    private ViewGroup mIndicationArea;
-    @Mock
-    private KeyguardStateController mKeyguardStateController;
-    @Mock
-    private KeyguardIndicationTextView mIndicationAreaBottom;
-    @Mock
-    private BroadcastDispatcher mBroadcastDispatcher;
-    @Mock
-    private StatusBarStateController mStatusBarStateController;
-    @Mock
-    private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
-    @Mock
-    private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
-    @Mock
-    private UserManager mUserManager;
-    @Mock
-    private IBatteryStats mIBatteryStats;
-    @Mock
-    private DockManager mDockManager;
-    @Mock
-    private KeyguardIndicationRotateTextViewController mRotateTextViewController;
-    @Mock
-    private FalsingManager mFalsingManager;
-    @Mock
-    private LockPatternUtils mLockPatternUtils;
-    @Mock
-    private KeyguardBypassController mKeyguardBypassController;
-    @Mock
-    private AccessibilityManager mAccessibilityManager;
-    @Mock
-    private FaceHelpMessageDeferral mFaceHelpMessageDeferral;
-    @Mock
-    private AlternateBouncerInteractor mAlternateBouncerInteractor;
-    @Mock
-    private ScreenLifecycle mScreenLifecycle;
-    @Mock
-    private AuthController mAuthController;
-    @Mock
-    private AlarmManager mAlarmManager;
-    @Mock
-    private UserTracker mUserTracker;
-    @Captor
-    private ArgumentCaptor<DockManager.AlignmentStateListener> mAlignmentListener;
-    @Captor
-    private ArgumentCaptor<StatusBarStateController.StateListener> mStatusBarStateListenerCaptor;
-    @Captor
-    private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor;
-    @Captor
-    private ArgumentCaptor<KeyguardIndication> mKeyguardIndicationCaptor;
-    @Captor
-    private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallbackCaptor;
-    @Captor
-    private ArgumentCaptor<KeyguardStateController.Callback> mKeyguardStateControllerCallbackCaptor;
-    @Captor
-    private ArgumentCaptor<ScreenLifecycle.Observer> mScreenObserverCaptor;
-    private KeyguardStateController.Callback mKeyguardStateControllerCallback;
-    private KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback;
-    private StatusBarStateController.StateListener mStatusBarStateListener;
-    private ScreenLifecycle.Observer mScreenObserver;
-    private BroadcastReceiver mBroadcastReceiver;
-    private IndicationHelper mIndicationHelper;
-    private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
-    private TestableLooper mTestableLooper;
-    private final int mCurrentUserId = 1;
-
-    private KeyguardIndicationTextView mTextView; // AOD text
-
-    private KeyguardIndicationController mController;
-    private WakeLockFake.Builder mWakeLockBuilder;
-    private WakeLockFake mWakeLock;
-    private Instrumentation mInstrumentation;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        mInstrumentation = InstrumentationRegistry.getInstrumentation();
-        mTestableLooper = TestableLooper.get(this);
-        mTextView = new KeyguardIndicationTextView(mContext);
-        mTextView.setAnimationsEnabled(false);
-
-        // TODO(b/259908270): remove
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER,
-                DevicePolicyManager.ADD_ISFINANCED_DEVICE_FLAG, "true",
-                /* makeDefault= */ false);
-        mContext.addMockSystemService(Context.DEVICE_POLICY_SERVICE, mDevicePolicyManager);
-        mContext.addMockSystemService(UserManager.class, mUserManager);
-        mContext.addMockSystemService(Context.TRUST_SERVICE, mock(TrustManager.class));
-        mContext.addMockSystemService(Context.FINGERPRINT_SERVICE, mock(FingerprintManager.class));
-        mDisclosureWithOrganization = mContext.getString(R.string.do_disclosure_with_name,
-                ORGANIZATION_NAME);
-        mDisclosureGeneric = mContext.getString(R.string.do_disclosure_generic);
-        mFinancedDisclosureWithOrganization = mContext.getString(
-                R.string.do_financed_disclosure_with_name, ORGANIZATION_NAME);
-
-        when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
-        when(mScreenLifecycle.getScreenState()).thenReturn(SCREEN_ON);
-        when(mKeyguardUpdateMonitor.isUserUnlocked(anyInt())).thenReturn(true);
-
-        when(mIndicationArea.findViewById(R.id.keyguard_indication_text_bottom))
-                .thenReturn(mIndicationAreaBottom);
-        when(mIndicationArea.findViewById(R.id.keyguard_indication_text)).thenReturn(mTextView);
-
-        when(mDevicePolicyManager.getResources()).thenReturn(mDevicePolicyResourcesManager);
-        when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser())
-                .thenReturn(DEVICE_OWNER_COMPONENT);
-        when(mDevicePolicyManager.isFinancedDevice()).thenReturn(false);
-        // TODO(b/259908270): remove
-        when(mDevicePolicyManager.getDeviceOwnerType(DEVICE_OWNER_COMPONENT))
-                .thenReturn(DEVICE_OWNER_TYPE_DEFAULT);
-
-        when(mDevicePolicyResourcesManager.getString(anyString(), any()))
-                .thenReturn(mDisclosureGeneric);
-        when(mDevicePolicyResourcesManager.getString(anyString(), any(), anyString()))
-                .thenReturn(mDisclosureWithOrganization);
-        when(mUserTracker.getUserId()).thenReturn(mCurrentUserId);
-
-        mIndicationHelper = new IndicationHelper(mKeyguardUpdateMonitor);
-
-        mWakeLock = new WakeLockFake();
-        mWakeLockBuilder = new WakeLockFake.Builder(mContext);
-        mWakeLockBuilder.setWakeLock(mWakeLock);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mTextView.setAnimationsEnabled(true);
-        if (mController != null) {
-            mController.destroy();
-            mController = null;
-        }
-    }
-
-    private void createController() {
-        if (Looper.myLooper() == null) {
-            Looper.prepare();
-        }
-
-        FakeFeatureFlags flags = new FakeFeatureFlags();
-        flags.set(KEYGUARD_TALKBACK_FIX, true);
-        mController = new KeyguardIndicationController(
-                mContext,
-                mTestableLooper.getLooper(),
-                mWakeLockBuilder,
-                mKeyguardStateController, mStatusBarStateController, mKeyguardUpdateMonitor,
-                mDockManager, mBroadcastDispatcher, mDevicePolicyManager, mIBatteryStats,
-                mUserManager, mExecutor, mExecutor, mFalsingManager,
-                mAuthController, mLockPatternUtils, mScreenLifecycle,
-                mKeyguardBypassController, mAccessibilityManager,
-                mFaceHelpMessageDeferral, mock(KeyguardLogger.class),
-                mAlternateBouncerInteractor,
-                mAlarmManager,
-                mUserTracker,
-                mock(BouncerMessageInteractor.class),
-                flags,
-                mIndicationHelper
-        );
-        mController.init();
-        mController.setIndicationArea(mIndicationArea);
-        verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture());
-        mStatusBarStateListener = mStatusBarStateListenerCaptor.getValue();
-        verify(mBroadcastDispatcher).registerReceiver(mBroadcastReceiverCaptor.capture(), any());
-        mBroadcastReceiver = mBroadcastReceiverCaptor.getValue();
-        mController.mRotateTextViewController = mRotateTextViewController;
-        mController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
-        clearInvocations(mIBatteryStats);
-
-        verify(mKeyguardStateController).addCallback(
-                mKeyguardStateControllerCallbackCaptor.capture());
-        mKeyguardStateControllerCallback = mKeyguardStateControllerCallbackCaptor.getValue();
-
-        verify(mKeyguardUpdateMonitor).registerCallback(
-                mKeyguardUpdateMonitorCallbackCaptor.capture());
-        mKeyguardUpdateMonitorCallback = mKeyguardUpdateMonitorCallbackCaptor.getValue();
-
-        verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture());
-        mScreenObserver = mScreenObserverCaptor.getValue();
-
-        mExecutor.runAllReady();
-        reset(mRotateTextViewController);
-    }
-
+public class KeyguardIndicationControllerTest extends KeyguardIndicationControllerBaseTest {
     @Test
     public void createController_setIndicationAreaAgain_destroysPreviousRotateTextViewController() {
         // GIVEN a controller with a mocked rotate text view controlller
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerWithCoroutinesTest.kt
new file mode 100644
index 0000000..cdc7520
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerWithCoroutinesTest.kt
@@ -0,0 +1,68 @@
+/*
+ * 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.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.View
+import androidx.test.filters.SmallTest
+import com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.runBlocking
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class KeyguardIndicationControllerWithCoroutinesTest : KeyguardIndicationControllerBaseTest() {
+    @Test
+    fun testIndicationAreaVisibility_onLockscreenHostedDreamStateChanged() =
+        runBlocking(IMMEDIATE) {
+            // GIVEN starting state for keyguard indication and wallpaper dream enabled
+            createController()
+            mFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, true)
+            mController.setVisible(true)
+
+            // THEN indication area is visible
+            verify(mIndicationArea, times(2)).visibility = View.VISIBLE
+
+            // WHEN the device is dreaming with lockscreen hosted dream
+            mController.mIsActiveDreamLockscreenHostedCallback.accept(
+                true /* isActiveDreamLockscreenHosted */
+            )
+            mExecutor.runAllReady()
+
+            // THEN the indication area is hidden
+            verify(mIndicationArea).visibility = View.GONE
+
+            // WHEN the device stops dreaming with lockscreen hosted dream
+            mController.mIsActiveDreamLockscreenHostedCallback.accept(
+                false /* isActiveDreamLockscreenHosted */
+            )
+            mExecutor.runAllReady()
+
+            // THEN indication area is set visible
+            verify(mIndicationArea, times(3)).visibility = View.VISIBLE
+        }
+
+    companion object {
+        private val IMMEDIATE = Dispatchers.Main.immediate
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
index 1b1f4e4..8d016e3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
@@ -45,6 +45,7 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
+import android.view.ViewGroup;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -65,6 +66,8 @@
 @RunWith(AndroidJUnit4.class)
 public class StatusBarIconViewTest extends SysuiTestCase {
 
+    private static final int TEST_STATUS_BAR_HEIGHT = 150;
+
     @Rule
     public ExpectedException mThrown = ExpectedException.none();
 
@@ -184,4 +187,218 @@
 
         // no crash, good
     }
+
+    @Test
+    public void testUpdateIconScale_constrainedDrawableSizeLessThanDpIconSize() {
+        int dpIconSize = 60;
+        int dpDrawingSize = 30;
+        // the icon view layout size would be 60x150
+        //   (the height is always 150 due to TEST_STATUS_BAR_HEIGHT)
+        setUpIconView(dpIconSize, dpDrawingSize, dpIconSize);
+        mIconView.setNotification(mock(StatusBarNotification.class));
+        // the raw drawable size is 50x50. When put the drawable into iconView whose
+        // layout size is 60x150, the drawable size would not be constrained and thus keep 50x50
+        setIconDrawableWithSize(/* width= */ 50, /* height= */ 50);
+        mIconView.maybeUpdateIconScaleDimens();
+
+        // WHEN both the constrained drawable width/height are less than dpIconSize,
+        // THEN the icon is scaled down from dpIconSize to fit the dpDrawingSize
+        float scaleToFitDrawingSize = (float) dpDrawingSize / dpIconSize;
+        assertEquals(scaleToFitDrawingSize, mIconView.getIconScale(), 0.01f);
+    }
+
+    @Test
+    public void testUpdateIconScale_constrainedDrawableHeightLargerThanDpIconSize() {
+        int dpIconSize = 60;
+        int dpDrawingSize = 30;
+        // the icon view layout size would be 60x150
+        //   (the height is always 150 due to TEST_STATUS_BAR_HEIGHT)
+        setUpIconView(dpIconSize, dpDrawingSize, dpIconSize);
+        mIconView.setNotification(mock(StatusBarNotification.class));
+        // the raw drawable size is 50x100. When put the drawable into iconView whose
+        // layout size is 60x150, the drawable size would not be constrained and thus keep 50x100
+        setIconDrawableWithSize(/* width= */ 50, /* height= */ 100);
+        mIconView.maybeUpdateIconScaleDimens();
+
+        // WHEN constrained drawable larger side length 100 >= dpIconSize
+        // THEN the icon is scaled down from larger side length 100 to ensure both side
+        //      length fit in dpDrawingSize.
+        float scaleToFitDrawingSize = (float) dpDrawingSize / 100;
+        assertEquals(scaleToFitDrawingSize, mIconView.getIconScale(), 0.01f);
+    }
+
+    @Test
+    public void testUpdateIconScale_constrainedDrawableWidthLargerThanDpIconSize() {
+        int dpIconSize = 60;
+        int dpDrawingSize = 30;
+        // the icon view layout size would be 60x150
+        //   (the height is always 150 due to TEST_STATUS_BAR_HEIGHT)
+        setUpIconView(dpIconSize, dpDrawingSize, dpIconSize);
+        mIconView.setNotification(mock(StatusBarNotification.class));
+        // the raw drawable size is 100x50. When put the drawable into iconView whose
+        // layout size is 60x150, the drawable size would be constrained to 60x30
+        setIconDrawableWithSize(/* width= */ 100, /* height= */ 50);
+        mIconView.maybeUpdateIconScaleDimens();
+
+        // WHEN constrained drawable larger side length 60 >= dpIconSize
+        // THEN the icon is scaled down from larger side length 60 to ensure both side
+        //      length fit in dpDrawingSize.
+        float scaleToFitDrawingSize = (float) dpDrawingSize / 60;
+        assertEquals(scaleToFitDrawingSize, mIconView.getIconScale(), 0.01f);
+    }
+
+    @Test
+    public void testUpdateIconScale_smallerFontAndConstrainedDrawableSizeLessThanDpIconSize() {
+        int dpIconSize = 60;
+        int dpDrawingSize = 30;
+        // smaller font scaling causes the spIconSize < dpIconSize
+        int spIconSize = 40;
+        // the icon view layout size would be 40x150
+        //   (the height is always 150 due to TEST_STATUS_BAR_HEIGHT)
+        setUpIconView(dpIconSize, dpDrawingSize, spIconSize);
+        mIconView.setNotification(mock(StatusBarNotification.class));
+        // the raw drawable size is 50x50. When put the drawable into iconView whose
+        // layout size is 40x150, the drawable size would be constrained to 40x40
+        setIconDrawableWithSize(/* width= */ 50, /* height= */ 50);
+        mIconView.maybeUpdateIconScaleDimens();
+
+        // WHEN both the constrained drawable width/height are less than dpIconSize,
+        // THEN the icon is scaled down from dpIconSize to fit the dpDrawingSize
+        float scaleToFitDrawingSize = (float) dpDrawingSize / dpIconSize;
+        // THEN the scaled icon should be scaled down further to fit spIconSize
+        float scaleToFitSpIconSize = (float) spIconSize / dpIconSize;
+        assertEquals(scaleToFitDrawingSize * scaleToFitSpIconSize, mIconView.getIconScale(), 0.01f);
+    }
+
+    @Test
+    public void testUpdateIconScale_smallerFontAndConstrainedDrawableHeightLargerThanDpIconSize() {
+        int dpIconSize = 60;
+        int dpDrawingSize = 30;
+        // smaller font scaling causes the spIconSize < dpIconSize
+        int spIconSize = 40;
+        // the icon view layout size would be 40x150
+        //   (the height is always 150 due to TEST_STATUS_BAR_HEIGHT)
+        setUpIconView(dpIconSize, dpDrawingSize, spIconSize);
+        mIconView.setNotification(mock(StatusBarNotification.class));
+        // the raw drawable size is 50x100. When put the drawable into iconView whose
+        // layout size is 40x150, the drawable size would be constrained to 40x80
+        setIconDrawableWithSize(/* width= */ 50, /* height= */ 100);
+        mIconView.maybeUpdateIconScaleDimens();
+
+        // WHEN constrained drawable larger side length 80 >= dpIconSize
+        // THEN the icon is scaled down from larger side length 80 to ensure both side
+        //      length fit in dpDrawingSize.
+        float scaleToFitDrawingSize = (float) dpDrawingSize / 80;
+        // THEN the scaled icon should be scaled down further to fit spIconSize
+        float scaleToFitSpIconSize = (float) spIconSize / dpIconSize;
+        assertEquals(scaleToFitDrawingSize * scaleToFitSpIconSize, mIconView.getIconScale(), 0.01f);
+    }
+
+    @Test
+    public void testUpdateIconScale_largerFontAndConstrainedDrawableSizeLessThanDpIconSize() {
+        int dpIconSize = 60;
+        int dpDrawingSize = 30;
+        // larger font scaling causes the spIconSize > dpIconSize
+        int spIconSize = 80;
+        // the icon view layout size would be 80x150
+        //   (the height is always 150 due to TEST_STATUS_BAR_HEIGHT)
+        setUpIconView(dpIconSize, dpDrawingSize, spIconSize);
+        mIconView.setNotification(mock(StatusBarNotification.class));
+        // the raw drawable size is 50x50. When put the drawable into iconView whose
+        // layout size is 80x150, the drawable size would not be constrained and thus keep 50x50
+        setIconDrawableWithSize(/* width= */ 50, /* height= */ 50);
+        mIconView.maybeUpdateIconScaleDimens();
+
+        // WHEN both the constrained drawable width/height are less than dpIconSize,
+        // THEN the icon is scaled down from dpIconSize to fit the dpDrawingSize
+        float scaleToFitDrawingSize = (float) dpDrawingSize / dpIconSize;
+        // THEN the scaled icon should be scaled up to fit spIconSize
+        float scaleToFitSpIconSize = (float) spIconSize / dpIconSize;
+        assertEquals(scaleToFitDrawingSize * scaleToFitSpIconSize, mIconView.getIconScale(), 0.01f);
+    }
+
+    @Test
+    public void testUpdateIconScale_largerFontAndConstrainedDrawableHeightLargerThanDpIconSize() {
+        int dpIconSize = 60;
+        int dpDrawingSize = 30;
+        // larger font scaling causes the spIconSize > dpIconSize
+        int spIconSize = 80;
+        // the icon view layout size would be 80x150
+        //   (the height is always 150 due to TEST_STATUS_BAR_HEIGHT)
+        setUpIconView(dpIconSize, dpDrawingSize, spIconSize);
+        mIconView.setNotification(mock(StatusBarNotification.class));
+        // the raw drawable size is 50x100. When put the drawable into iconView whose
+        // layout size is 80x150, the drawable size would not be constrained and thus keep 50x100
+        setIconDrawableWithSize(/* width= */ 50, /* height= */ 100);
+        mIconView.maybeUpdateIconScaleDimens();
+
+        // WHEN constrained drawable larger side length 100 >= dpIconSize
+        // THEN the icon is scaled down from larger side length 100 to ensure both side
+        //      length fit in dpDrawingSize.
+        float scaleToFitDrawingSize = (float) dpDrawingSize / 100;
+        // THEN the scaled icon should be scaled up to fit spIconSize
+        float scaleToFitSpIconSize = (float) spIconSize / dpIconSize;
+        assertEquals(scaleToFitDrawingSize * scaleToFitSpIconSize, mIconView.getIconScale(), 0.01f);
+    }
+
+    @Test
+    public void testUpdateIconScale_largerFontAndConstrainedDrawableWidthLargerThanDpIconSize() {
+        int dpIconSize = 60;
+        int dpDrawingSize = 30;
+        // larger font scaling causes the spIconSize > dpIconSize
+        int spIconSize = 80;
+        // the icon view layout size would be 80x150
+        //   (the height is always 150 due to TEST_STATUS_BAR_HEIGHT)
+        setUpIconView(dpIconSize, dpDrawingSize, spIconSize);
+        mIconView.setNotification(mock(StatusBarNotification.class));
+        // the raw drawable size is 100x50. When put the drawable into iconView whose
+        // layout size is 80x150, the drawable size would not be constrained and thus keep 80x40
+        setIconDrawableWithSize(/* width= */ 100, /* height= */ 50);
+        mIconView.maybeUpdateIconScaleDimens();
+
+        // WHEN constrained drawable larger side length 80 >= dpIconSize
+        // THEN the icon is scaled down from larger side length 80 to ensure both side
+        //      length fit in dpDrawingSize.
+        float scaleToFitDrawingSize = (float) dpDrawingSize / 80;
+        // THEN the scaled icon should be scaled up to fit spIconSize
+        float scaleToFitSpIconSize = (float) spIconSize / dpIconSize;
+        assertEquals(scaleToFitDrawingSize * scaleToFitSpIconSize,
+                mIconView.getIconScale(), 0.01f);
+    }
+
+    /**
+     * Setup iconView dimens for testing. The result icon view layout width would
+     * be spIconSize and height would be 150.
+     *
+     * @param dpIconSize corresponding to status_bar_icon_size
+     * @param dpDrawingSize corresponding to status_bar_icon_drawing_size
+     * @param spIconSize corresponding to status_bar_icon_size_sp under different font scaling
+     */
+    private void setUpIconView(int dpIconSize, int dpDrawingSize, int spIconSize) {
+        mIconView.setIncreasedSize(false);
+        mIconView.mOriginalStatusBarIconSize = dpIconSize;
+        mIconView.mStatusBarIconDrawingSize = dpDrawingSize;
+
+        mIconView.mNewStatusBarIconSize = spIconSize;
+        mIconView.mScaleToFitNewIconSize = (float) spIconSize / dpIconSize;
+
+        // the layout width would be spIconSize + 2 * iconPadding, and we assume iconPadding
+        // is 0 here.
+        ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(spIconSize, TEST_STATUS_BAR_HEIGHT);
+        mIconView.setLayoutParams(lp);
+    }
+
+    private void setIconDrawableWithSize(int width, int height) {
+        Bitmap bitmap = Bitmap.createBitmap(
+                width, height, Bitmap.Config.ARGB_8888);
+        Icon icon = Icon.createWithBitmap(bitmap);
+        mStatusBarIcon = new StatusBarIcon(UserHandle.ALL, "mockPackage",
+                icon, 0, 0, "");
+        // Since we only want to verify icon scale logic here, we directly use
+        // {@link StatusBarIconView#setImageDrawable(Drawable)} to set the image drawable
+        // to iconView instead of call {@link StatusBarIconView#set(StatusBarIcon)}. It's to prevent
+        // the icon drawable size being scaled down when internally calling
+        // {@link StatusBarIconView#getIcon(Context,Context,StatusBarIcon)}.
+        mIconView.setImageDrawable(icon.loadDrawable(mContext));
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventChipAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventChipAnimationControllerTest.kt
new file mode 100644
index 0000000..55b6be9
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventChipAnimationControllerTest.kt
@@ -0,0 +1,189 @@
+/*
+ * 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.content.Context
+import android.graphics.Rect
+import android.util.Pair
+import android.view.Gravity
+import android.view.View
+import android.widget.FrameLayout
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.statusbar.phone.StatusBarContentInsetsChangedListener
+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.argumentCaptor
+import com.android.systemui.util.mockito.capture
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+class SystemEventChipAnimationControllerTest : SysuiTestCase() {
+    private lateinit var controller: SystemEventChipAnimationController
+
+    @Mock private lateinit var sbWindowController: StatusBarWindowController
+    @Mock private lateinit var insetsProvider: StatusBarContentInsetsProvider
+
+    private var testView = TestView(mContext)
+    private var viewCreator: ViewCreator = { testView }
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+
+        // StatusBarWindowController is mocked. The addViewToWindow function needs to be mocked to
+        // ensure that the chip view is added to a parent view
+        whenever(sbWindowController.addViewToWindow(any(), any())).then {
+            val statusbarFake = FrameLayout(mContext)
+            statusbarFake.layout(
+                portraitArea.left,
+                portraitArea.top,
+                portraitArea.right,
+                portraitArea.bottom,
+            )
+            statusbarFake.addView(
+                it.arguments[0] as View,
+                it.arguments[1] as FrameLayout.LayoutParams
+            )
+        }
+
+        whenever(insetsProvider.getStatusBarContentInsetsForCurrentRotation())
+            .thenReturn(Pair(insets, insets))
+        whenever(insetsProvider.getStatusBarContentAreaForCurrentRotation())
+            .thenReturn(portraitArea)
+
+        controller =
+            SystemEventChipAnimationController(
+                context = mContext,
+                statusBarWindowController = sbWindowController,
+                contentInsetsProvider = insetsProvider,
+                featureFlags = FakeFeatureFlags(),
+            )
+    }
+
+    @Test
+    fun prepareChipAnimation_lazyInitializes() {
+        // Until Dagger can do our initialization, make sure that the first chip animation calls
+        // init()
+        assertFalse(controller.initialized)
+        controller.prepareChipAnimation(viewCreator)
+        assertTrue(controller.initialized)
+    }
+
+    @Test
+    fun prepareChipAnimation_positionsChip() {
+        controller.prepareChipAnimation(viewCreator)
+        val chipRect = controller.chipBounds
+
+        // SB area = 10, 0, 990, 100
+        // chip size = 0, 0, 100, 50
+        assertThat(chipRect).isEqualTo(Rect(890, 25, 990, 75))
+    }
+
+    @Test
+    fun prepareChipAnimation_rotation_repositionsChip() {
+        controller.prepareChipAnimation(viewCreator)
+
+        // Chip has been prepared, and is located at (890, 25, 990, 75)
+        // Rotation should put it into its landscape location:
+        // SB area = 10, 0, 1990, 80
+        // chip size = 0, 0, 100, 50
+
+        whenever(insetsProvider.getStatusBarContentAreaForCurrentRotation())
+            .thenReturn(landscapeArea)
+        getInsetsListener().onStatusBarContentInsetsChanged()
+
+        val chipRect = controller.chipBounds
+        assertThat(chipRect).isEqualTo(Rect(1890, 15, 1990, 65))
+    }
+
+    /** regression test for (b/289378932) */
+    @Test
+    fun fullScreenStatusBar_positionsChipAtTop_withTopGravity() {
+        // In the case of a fullscreen status bar window, the content insets area is still correct
+        // (because it uses the dimens), but the window can be full screen. This seems to happen
+        // when launching an app from the ongoing call chip.
+
+        // GIVEN layout the status bar window fullscreen portrait
+        whenever(sbWindowController.addViewToWindow(any(), any())).then {
+            val statusbarFake = FrameLayout(mContext)
+            statusbarFake.layout(
+                fullScreenSb.left,
+                fullScreenSb.top,
+                fullScreenSb.right,
+                fullScreenSb.bottom,
+            )
+
+            val lp = it.arguments[1] as FrameLayout.LayoutParams
+            assertThat(lp.gravity and Gravity.VERTICAL_GRAVITY_MASK).isEqualTo(Gravity.TOP)
+
+            statusbarFake.addView(
+                it.arguments[0] as View,
+                lp,
+            )
+        }
+
+        // GIVEN insets provider gives the correct content area
+        whenever(insetsProvider.getStatusBarContentAreaForCurrentRotation())
+            .thenReturn(portraitArea)
+
+        // WHEN the controller lays out the chip in a fullscreen window
+        controller.prepareChipAnimation(viewCreator)
+
+        // THEN it still aligns the chip to the content area provided by the insets provider
+        val chipRect = controller.chipBounds
+        assertThat(chipRect).isEqualTo(Rect(890, 25, 990, 75))
+    }
+
+    class TestView(context: Context) : View(context), BackgroundAnimatableView {
+        override val view: View
+            get() = this
+
+        override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+            setMeasuredDimension(100, 50)
+        }
+
+        override fun setBoundsForAnimation(l: Int, t: Int, r: Int, b: Int) {
+            setLeftTopRightBottom(l, t, r, b)
+        }
+    }
+
+    private fun getInsetsListener(): StatusBarContentInsetsChangedListener {
+        val callbackCaptor = argumentCaptor<StatusBarContentInsetsChangedListener>()
+        verify(insetsProvider).addCallback(capture(callbackCaptor))
+        return callbackCaptor.value!!
+    }
+
+    companion object {
+        private val portraitArea = Rect(10, 0, 990, 100)
+        private val landscapeArea = Rect(10, 0, 1990, 80)
+        private val fullScreenSb = Rect(10, 0, 990, 2000)
+
+        // 10px insets on both sides
+        private const val insets = 10
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventCoordinatorTest.kt
new file mode 100644
index 0000000..786856b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventCoordinatorTest.kt
@@ -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.systemui.statusbar.events
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor
+import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor.State.CONNECTED
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.privacy.PrivacyItemController
+import com.android.systemui.statusbar.policy.BatteryController
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.time.FakeSystemClock
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@SmallTest
+@OptIn(ExperimentalCoroutinesApi::class)
+class SystemEventCoordinatorTest : SysuiTestCase() {
+
+    private val fakeSystemClock = FakeSystemClock()
+    private val featureFlags = FakeFeatureFlags()
+    private val testScope = TestScope(UnconfinedTestDispatcher())
+    private val connectedDisplayInteractor = FakeConnectedDisplayInteractor()
+
+    @Mock lateinit var batteryController: BatteryController
+    @Mock lateinit var privacyController: PrivacyItemController
+    @Mock lateinit var scheduler: SystemStatusAnimationScheduler
+
+    private lateinit var systemEventCoordinator: SystemEventCoordinator
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+        systemEventCoordinator =
+            SystemEventCoordinator(
+                    fakeSystemClock,
+                    batteryController,
+                    privacyController,
+                    context,
+                    featureFlags,
+                    TestScope(UnconfinedTestDispatcher()),
+                    connectedDisplayInteractor
+                )
+                .apply { attachScheduler(scheduler) }
+    }
+
+    @Test
+    fun startObserving_propagatesConnectedDisplayStatusEvents() =
+        testScope.runTest {
+            systemEventCoordinator.startObserving()
+
+            connectedDisplayInteractor.emit(CONNECTED)
+            connectedDisplayInteractor.emit(CONNECTED)
+
+            verify(scheduler, times(2)).onStatusEvent(any<ConnectedDisplayEvent>())
+        }
+
+    @Test
+    fun stopObserving_doesNotPropagateConnectedDisplayStatusEvents() =
+        testScope.runTest {
+            systemEventCoordinator.startObserving()
+
+            connectedDisplayInteractor.emit(CONNECTED)
+
+            verify(scheduler).onStatusEvent(any<ConnectedDisplayEvent>())
+
+            systemEventCoordinator.stopObserving()
+
+            connectedDisplayInteractor.emit(CONNECTED)
+
+            verifyNoMoreInteractions(scheduler)
+        }
+
+    class FakeConnectedDisplayInteractor : ConnectedDisplayInteractor {
+        private val flow = MutableSharedFlow<ConnectedDisplayInteractor.State>()
+        suspend fun emit(value: ConnectedDisplayInteractor.State) = flow.emit(value)
+        override val connectedDisplayState: Flow<ConnectedDisplayInteractor.State>
+            get() = flow
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
index 2fbe871..ea70e9e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
@@ -32,7 +32,6 @@
 import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.statusbar.StatusBarState
-import com.android.systemui.statusbar.notification.NotifPipelineFlags
 import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder
 import com.android.systemui.statusbar.notification.collection.NotifPipeline
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
@@ -46,11 +45,14 @@
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.policy.HeadsUpManager
 import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
+import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.withArgCaptor
 import com.android.systemui.util.settings.FakeSettings
 import com.google.common.truth.Truth.assertThat
+import java.util.function.Consumer
+import kotlin.time.Duration.Companion.seconds
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestCoroutineScheduler
@@ -62,9 +64,8 @@
 import org.mockito.ArgumentMatchers.same
 import org.mockito.Mockito.anyString
 import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
-import java.util.function.Consumer
-import kotlin.time.Duration.Companion.seconds
 import org.mockito.Mockito.`when` as whenever
 
 @SmallTest
@@ -75,7 +76,6 @@
     private val keyguardNotifVisibilityProvider: KeyguardNotificationVisibilityProvider = mock()
     private val keyguardRepository = FakeKeyguardRepository()
     private val keyguardTransitionRepository = FakeKeyguardTransitionRepository()
-    private val notifPipelineFlags: NotifPipelineFlags = mock()
     private val notifPipeline: NotifPipeline = mock()
     private val sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider = mock()
     private val statusBarStateController: StatusBarStateController = mock()
@@ -136,13 +136,8 @@
             )
             testScheduler.runCurrent()
 
-            // WHEN: The shade is expanded
-            whenever(statusBarStateController.isExpanded).thenReturn(true)
-            statusBarStateListener.onExpandedChanged(true)
-            testScheduler.runCurrent()
-
-            // THEN: The notification is still treated as "unseen" and is not filtered out.
-            assertThat(unseenFilter.shouldFilterOut(fakeEntry, 0L)).isFalse()
+            // THEN: We are no longer listening for shade expansions
+            verify(statusBarStateController, never()).addCallback(any())
         }
     }
 
@@ -152,6 +147,10 @@
         keyguardRepository.setKeyguardShowing(false)
         whenever(statusBarStateController.isExpanded).thenReturn(false)
         runKeyguardCoordinatorTest {
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE)
+            )
+
             // WHEN: A notification is posted
             val fakeEntry = NotificationEntryBuilder().build()
             collectionListener.onEntryAdded(fakeEntry)
@@ -162,6 +161,9 @@
 
             // WHEN: The keyguard is now showing
             keyguardRepository.setKeyguardShowing(true)
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(from = KeyguardState.GONE, to = KeyguardState.AOD)
+            )
             testScheduler.runCurrent()
 
             // THEN: The notification is recognized as "seen" and is filtered out.
@@ -169,6 +171,9 @@
 
             // WHEN: The keyguard goes away
             keyguardRepository.setKeyguardShowing(false)
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(from = KeyguardState.AOD, to = KeyguardState.GONE)
+            )
             testScheduler.runCurrent()
 
             // THEN: The notification is shown regardless
@@ -182,9 +187,10 @@
         keyguardRepository.setKeyguardShowing(false)
         whenever(statusBarStateController.isExpanded).thenReturn(true)
         runKeyguardCoordinatorTest {
-            val fakeEntry = NotificationEntryBuilder()
+            val fakeEntry =
+                NotificationEntryBuilder()
                     .setNotification(Notification.Builder(mContext, "id").setOngoing(true).build())
-                .build()
+                    .build()
             collectionListener.onEntryAdded(fakeEntry)
 
             // WHEN: The keyguard is now showing
@@ -202,11 +208,13 @@
         keyguardRepository.setKeyguardShowing(false)
         whenever(statusBarStateController.isExpanded).thenReturn(true)
         runKeyguardCoordinatorTest {
-            val fakeEntry = NotificationEntryBuilder().build().apply {
-                row = mock<ExpandableNotificationRow>().apply {
-                    whenever(isMediaRow).thenReturn(true)
+            val fakeEntry =
+                NotificationEntryBuilder().build().apply {
+                    row =
+                        mock<ExpandableNotificationRow>().apply {
+                            whenever(isMediaRow).thenReturn(true)
+                        }
                 }
-            }
             collectionListener.onEntryAdded(fakeEntry)
 
             // WHEN: The keyguard is now showing
@@ -299,14 +307,12 @@
         runKeyguardCoordinatorTest {
             // WHEN: A new notification is posted
             val fakeSummary = NotificationEntryBuilder().build()
-            val fakeChild = NotificationEntryBuilder()
+            val fakeChild =
+                NotificationEntryBuilder()
                     .setGroup(context, "group")
                     .setGroupSummary(context, false)
                     .build()
-            GroupEntryBuilder()
-                    .setSummary(fakeSummary)
-                    .addChild(fakeChild)
-                    .build()
+            GroupEntryBuilder().setSummary(fakeSummary).addChild(fakeChild).build()
 
             collectionListener.onEntryAdded(fakeSummary)
             collectionListener.onEntryAdded(fakeChild)
@@ -331,6 +337,10 @@
         runKeyguardCoordinatorTest {
             val fakeEntry = NotificationEntryBuilder().build()
             collectionListener.onEntryAdded(fakeEntry)
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(from = KeyguardState.AOD, to = KeyguardState.LOCKSCREEN)
+            )
+            testScheduler.runCurrent()
 
             // WHEN: five seconds have passed
             testScheduler.advanceTimeBy(5.seconds)
@@ -338,10 +348,16 @@
 
             // WHEN: Keyguard is no longer showing
             keyguardRepository.setKeyguardShowing(false)
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE)
+            )
             testScheduler.runCurrent()
 
             // WHEN: Keyguard is shown again
             keyguardRepository.setKeyguardShowing(true)
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(from = KeyguardState.GONE, to = KeyguardState.AOD)
+            )
             testScheduler.runCurrent()
 
             // THEN: The notification is now recognized as "seen" and is filtered out.
@@ -354,11 +370,17 @@
         // GIVEN: Keyguard is showing, unseen notification is present
         keyguardRepository.setKeyguardShowing(true)
         runKeyguardCoordinatorTest {
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(from = KeyguardState.GONE, to = KeyguardState.LOCKSCREEN)
+            )
             val fakeEntry = NotificationEntryBuilder().build()
             collectionListener.onEntryAdded(fakeEntry)
 
             // WHEN: Keyguard is no longer showing
             keyguardRepository.setKeyguardShowing(false)
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE)
+            )
 
             // WHEN: Keyguard is shown again
             keyguardRepository.setKeyguardShowing(true)
@@ -369,14 +391,212 @@
         }
     }
 
+    @Test
+    fun unseenNotificationIsNotMarkedAsSeenIfNotOnKeyguardLongEnough() {
+        // GIVEN: Keyguard is showing, not dozing, unseen notification is present
+        keyguardRepository.setKeyguardShowing(true)
+        keyguardRepository.setIsDozing(false)
+        runKeyguardCoordinatorTest {
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(from = KeyguardState.GONE, to = KeyguardState.LOCKSCREEN)
+            )
+            val firstEntry = NotificationEntryBuilder().setId(1).build()
+            collectionListener.onEntryAdded(firstEntry)
+            testScheduler.runCurrent()
+
+            // WHEN: one second has passed
+            testScheduler.advanceTimeBy(1.seconds)
+            testScheduler.runCurrent()
+
+            // WHEN: another unseen notification is posted
+            val secondEntry = NotificationEntryBuilder().setId(2).build()
+            collectionListener.onEntryAdded(secondEntry)
+            testScheduler.runCurrent()
+
+            // WHEN: four more seconds have passed
+            testScheduler.advanceTimeBy(4.seconds)
+            testScheduler.runCurrent()
+
+            // WHEN: the keyguard is no longer showing
+            keyguardRepository.setKeyguardShowing(false)
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE)
+            )
+            testScheduler.runCurrent()
+
+            // WHEN: Keyguard is shown again
+            keyguardRepository.setKeyguardShowing(true)
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(from = KeyguardState.GONE, to = KeyguardState.LOCKSCREEN)
+            )
+            testScheduler.runCurrent()
+
+            // THEN: The first notification is considered seen and is filtered out.
+            assertThat(unseenFilter.shouldFilterOut(firstEntry, 0L)).isTrue()
+
+            // THEN: The second notification is still considered unseen and is not filtered out
+            assertThat(unseenFilter.shouldFilterOut(secondEntry, 0L)).isFalse()
+        }
+    }
+
+    @Test
+    fun unseenNotificationOnKeyguardNotMarkedAsSeenIfRemovedAfterThreshold() {
+        // GIVEN: Keyguard is showing, not dozing
+        keyguardRepository.setKeyguardShowing(true)
+        keyguardRepository.setIsDozing(false)
+        runKeyguardCoordinatorTest {
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(from = KeyguardState.GONE, to = KeyguardState.LOCKSCREEN)
+            )
+            testScheduler.runCurrent()
+
+            // WHEN: a new notification is posted
+            val entry = NotificationEntryBuilder().setId(1).build()
+            collectionListener.onEntryAdded(entry)
+            testScheduler.runCurrent()
+
+            // WHEN: five more seconds have passed
+            testScheduler.advanceTimeBy(5.seconds)
+            testScheduler.runCurrent()
+
+            // WHEN: the notification is removed
+            collectionListener.onEntryRemoved(entry, 0)
+            testScheduler.runCurrent()
+
+            // WHEN: the notification is re-posted
+            collectionListener.onEntryAdded(entry)
+            testScheduler.runCurrent()
+
+            // WHEN: one more second has passed
+            testScheduler.advanceTimeBy(1.seconds)
+            testScheduler.runCurrent()
+
+            // WHEN: the keyguard is no longer showing
+            keyguardRepository.setKeyguardShowing(false)
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE)
+            )
+            testScheduler.runCurrent()
+
+            // WHEN: Keyguard is shown again
+            keyguardRepository.setKeyguardShowing(true)
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(from = KeyguardState.GONE, to = KeyguardState.LOCKSCREEN)
+            )
+            testScheduler.runCurrent()
+
+            // THEN: The notification is considered unseen and is not filtered out.
+            assertThat(unseenFilter.shouldFilterOut(entry, 0L)).isFalse()
+        }
+    }
+
+    @Test
+    fun unseenNotificationOnKeyguardNotMarkedAsSeenIfRemovedBeforeThreshold() {
+        // GIVEN: Keyguard is showing, not dozing
+        keyguardRepository.setKeyguardShowing(true)
+        keyguardRepository.setIsDozing(false)
+        runKeyguardCoordinatorTest {
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(from = KeyguardState.GONE, to = KeyguardState.LOCKSCREEN)
+            )
+            testScheduler.runCurrent()
+
+            // WHEN: a new notification is posted
+            val entry = NotificationEntryBuilder().setId(1).build()
+            collectionListener.onEntryAdded(entry)
+            testScheduler.runCurrent()
+
+            // WHEN: one second has passed
+            testScheduler.advanceTimeBy(1.seconds)
+            testScheduler.runCurrent()
+
+            // WHEN: the notification is removed
+            collectionListener.onEntryRemoved(entry, 0)
+            testScheduler.runCurrent()
+
+            // WHEN: the notification is re-posted
+            collectionListener.onEntryAdded(entry)
+            testScheduler.runCurrent()
+
+            // WHEN: one more second has passed
+            testScheduler.advanceTimeBy(1.seconds)
+            testScheduler.runCurrent()
+
+            // WHEN: the keyguard is no longer showing
+            keyguardRepository.setKeyguardShowing(false)
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE)
+            )
+            testScheduler.runCurrent()
+
+            // WHEN: Keyguard is shown again
+            keyguardRepository.setKeyguardShowing(true)
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(from = KeyguardState.GONE, to = KeyguardState.LOCKSCREEN)
+            )
+            testScheduler.runCurrent()
+
+            // THEN: The notification is considered unseen and is not filtered out.
+            assertThat(unseenFilter.shouldFilterOut(entry, 0L)).isFalse()
+        }
+    }
+
+    @Test
+    fun unseenNotificationOnKeyguardNotMarkedAsSeenIfUpdatedBeforeThreshold() {
+        // GIVEN: Keyguard is showing, not dozing
+        keyguardRepository.setKeyguardShowing(true)
+        keyguardRepository.setIsDozing(false)
+        runKeyguardCoordinatorTest {
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(from = KeyguardState.GONE, to = KeyguardState.LOCKSCREEN)
+            )
+            testScheduler.runCurrent()
+
+            // WHEN: a new notification is posted
+            val entry = NotificationEntryBuilder().setId(1).build()
+            collectionListener.onEntryAdded(entry)
+            testScheduler.runCurrent()
+
+            // WHEN: one second has passed
+            testScheduler.advanceTimeBy(1.seconds)
+            testScheduler.runCurrent()
+
+            // WHEN: the notification is updated
+            collectionListener.onEntryUpdated(entry)
+            testScheduler.runCurrent()
+
+            // WHEN: four more seconds have passed
+            testScheduler.advanceTimeBy(4.seconds)
+            testScheduler.runCurrent()
+
+            // WHEN: the keyguard is no longer showing
+            keyguardRepository.setKeyguardShowing(false)
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE)
+            )
+            testScheduler.runCurrent()
+
+            // WHEN: Keyguard is shown again
+            keyguardRepository.setKeyguardShowing(true)
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(from = KeyguardState.GONE, to = KeyguardState.LOCKSCREEN)
+            )
+            testScheduler.runCurrent()
+
+            // THEN: The notification is considered unseen and is not filtered out.
+            assertThat(unseenFilter.shouldFilterOut(entry, 0L)).isFalse()
+        }
+    }
+
     private fun runKeyguardCoordinatorTest(
         testBlock: suspend KeyguardCoordinatorTestScope.() -> Unit
     ) {
         val testDispatcher = UnconfinedTestDispatcher()
         val testScope = TestScope(testDispatcher)
-        val fakeSettings = FakeSettings().apply {
-            putInt(Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS, 1)
-        }
+        val fakeSettings =
+            FakeSettings().apply {
+                putInt(Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS, 1)
+            }
         val seenNotificationsProvider = SeenNotificationsProviderImpl()
         val keyguardCoordinator =
             KeyguardCoordinator(
@@ -387,7 +607,6 @@
                 keyguardRepository,
                 keyguardTransitionRepository,
                 mock<KeyguardCoordinatorLogger>(),
-                notifPipelineFlags,
                 testScope.backgroundScope,
                 sectionHeaderVisibilityProvider,
                 fakeSettings,
@@ -397,11 +616,12 @@
         keyguardCoordinator.attach(notifPipeline)
         testScope.runTest(dispatchTimeoutMs = 1.seconds.inWholeMilliseconds) {
             KeyguardCoordinatorTestScope(
-                keyguardCoordinator,
-                testScope,
-                seenNotificationsProvider,
-                fakeSettings,
-            ).testBlock()
+                    keyguardCoordinator,
+                    testScope,
+                    seenNotificationsProvider,
+                    fakeSettings,
+                )
+                .testBlock()
         }
     }
 
@@ -414,10 +634,9 @@
         val testScheduler: TestCoroutineScheduler
             get() = scope.testScheduler
 
-        val onStateChangeListener: Consumer<String> =
-            withArgCaptor {
-                verify(keyguardNotifVisibilityProvider).addOnStateChangedListener(capture())
-            }
+        val onStateChangeListener: Consumer<String> = withArgCaptor {
+            verify(keyguardNotifVisibilityProvider).addOnStateChangedListener(capture())
+        }
 
         val unseenFilter: NotifFilter
             get() = keyguardCoordinator.unseenNotifFilter
@@ -426,11 +645,11 @@
             verify(notifPipeline).addCollectionListener(capture())
         }
 
-        val onHeadsUpChangedListener: OnHeadsUpChangedListener get() =
-            withArgCaptor { verify(headsUpManager).addListener(capture()) }
+        val onHeadsUpChangedListener: OnHeadsUpChangedListener
+            get() = withArgCaptor { verify(headsUpManager).addListener(capture()) }
 
-        val statusBarStateListener: StatusBarStateController.StateListener get() =
-            withArgCaptor { verify(statusBarStateController).addCallback(capture()) }
+        val statusBarStateListener: StatusBarStateController.StateListener
+            get() = withArgCaptor { verify(statusBarStateController).addCallback(capture()) }
 
         var showOnlyUnseenNotifsOnKeyguardSetting: Boolean
             get() =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifLayoutInflaterFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifLayoutInflaterFactoryTest.kt
new file mode 100644
index 0000000..d5612e8
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifLayoutInflaterFactoryTest.kt
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.systemui.statusbar.notification.row
+
+import android.content.Context
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import android.util.AttributeSet
+import android.view.View
+import android.widget.FrameLayout
+import android.widget.LinearLayout
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import junit.framework.Assert.assertEquals
+import junit.framework.Assert.assertNotNull
+import junit.framework.Assert.assertNull
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+
+/** Tests for [NotifLayoutInflaterFactory] */
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper
+class NotifLayoutInflaterFactoryTest : SysuiTestCase() {
+
+    @Mock private lateinit var attrs: AttributeSet
+
+    @Before
+    fun before() {
+        MockitoAnnotations.initMocks(this)
+    }
+
+    @Test
+    fun onCreateView_notMatchingViews_returnNull() {
+        // GIVEN
+        val layoutInflaterFactory =
+            createNotifLayoutInflaterFactoryImpl(
+                setOf(
+                    createReplacementViewFactory("TextView") { context, attrs ->
+                        FrameLayout(context)
+                    }
+                )
+            )
+
+        // WHEN
+        val createView = layoutInflaterFactory.onCreateView("ImageView", mContext, attrs)
+
+        // THEN
+        assertNull(createView)
+    }
+
+    @Test
+    fun onCreateView_matchingViews_returnReplacementView() {
+        // GIVEN
+        val layoutInflaterFactory =
+            createNotifLayoutInflaterFactoryImpl(
+                setOf(
+                    createReplacementViewFactory("TextView") { context, attrs ->
+                        FrameLayout(context)
+                    }
+                )
+            )
+
+        // WHEN
+        val createView = layoutInflaterFactory.onCreateView("TextView", mContext, attrs)
+
+        // THEN
+        assertNotNull(createView)
+        assertEquals(requireNotNull(createView)::class.java, FrameLayout::class.java)
+    }
+
+    @Test(expected = IllegalStateException::class)
+    fun onCreateView_multipleFactory_throwIllegalStateException() {
+        // GIVEN
+        val layoutInflaterFactory =
+            createNotifLayoutInflaterFactoryImpl(
+                setOf(
+                    createReplacementViewFactory("TextView") { context, attrs ->
+                        FrameLayout(context)
+                    },
+                    createReplacementViewFactory("TextView") { context, attrs ->
+                        LinearLayout(context)
+                    }
+                )
+            )
+
+        // WHEN
+        layoutInflaterFactory.onCreateView("TextView", mContext, attrs)
+    }
+
+    private fun createNotifLayoutInflaterFactoryImpl(
+        replacementViewFactories: Set<@JvmSuppressWildcards NotifRemoteViewsFactory>
+    ) = NotifLayoutInflaterFactory(DumpManager(), replacementViewFactories)
+
+    private fun createReplacementViewFactory(
+        replacementName: String,
+        createView: (context: Context, attrs: AttributeSet) -> View
+    ) =
+        object : NotifRemoteViewsFactory {
+            override fun instantiate(
+                parent: View?,
+                name: String,
+                context: Context,
+                attrs: AttributeSet
+            ): View? =
+                if (replacementName == name) {
+                    createView(context, attrs)
+                } else {
+                    null
+                }
+        }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
index 3face35..f55b0a8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
@@ -92,6 +92,7 @@
     @Mock private ConversationNotificationProcessor mConversationNotificationProcessor;
     @Mock private InflatedSmartReplyState mInflatedSmartReplyState;
     @Mock private InflatedSmartReplyViewHolder mInflatedSmartReplies;
+    @Mock private NotifLayoutInflaterFactory mNotifLayoutInflaterFactory;
 
     private final SmartReplyStateInflater mSmartReplyStateInflater =
             new SmartReplyStateInflater() {
@@ -130,7 +131,8 @@
                 mConversationNotificationProcessor,
                 mock(MediaFeatureFlag.class),
                 mock(Executor.class),
-                mSmartReplyStateInflater);
+                mSmartReplyStateInflater,
+                mNotifLayoutInflaterFactory);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index df47071..1a644d3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -158,7 +158,8 @@
                 mock(ConversationNotificationProcessor.class),
                 mock(MediaFeatureFlag.class),
                 mock(Executor.class),
-                new MockSmartReplyInflater());
+                new MockSmartReplyInflater(),
+                mock(NotifLayoutInflaterFactory.class));
         contentBinder.setInflateSynchronously(true);
         mBindStage = new RowContentBindStage(contentBinder,
                 mock(NotifInflationErrorManager.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt
index b80b825..c282c1e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt
@@ -21,6 +21,8 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.StatusBarIconView
+import com.android.systemui.statusbar.StatusBarIconView.STATE_DOT
+import com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN
 import junit.framework.Assert.assertEquals
 import junit.framework.Assert.assertFalse
 import junit.framework.Assert.assertTrue
@@ -49,7 +51,7 @@
     fun calculateWidthFor_oneIcon_widthForOneIcon() {
         iconContainer.setActualPaddingStart(10f)
         iconContainer.setActualPaddingEnd(10f)
-        iconContainer.setIconSize(10);
+        iconContainer.setIconSize(10)
 
         assertEquals(/* expected= */ iconContainer.calculateWidthFor(/* numIcons= */ 1f),
                 /* actual= */ 30f)
@@ -59,7 +61,7 @@
     fun calculateWidthFor_fourIcons_widthForFourIcons() {
         iconContainer.setActualPaddingStart(10f)
         iconContainer.setActualPaddingEnd(10f)
-        iconContainer.setIconSize(10);
+        iconContainer.setIconSize(10)
 
         assertEquals(/* expected= */ iconContainer.calculateWidthFor(/* numIcons= */ 4f),
                 /* actual= */ 60f)
@@ -69,7 +71,7 @@
     fun calculateWidthFor_fiveIcons_widthForFourIcons() {
         iconContainer.setActualPaddingStart(10f)
         iconContainer.setActualPaddingEnd(10f)
-        iconContainer.setIconSize(10);
+        iconContainer.setIconSize(10)
         assertEquals(/* expected= */ iconContainer.calculateWidthFor(/* numIcons= */ 5f),
                 /* actual= */ 60f)
     }
@@ -78,7 +80,7 @@
     fun calculateIconXTranslations_shortShelfOneIcon_atCorrectXWithoutOverflowDot() {
         iconContainer.setActualPaddingStart(10f)
         iconContainer.setActualPaddingEnd(10f)
-        iconContainer.setIconSize(10);
+        iconContainer.setIconSize(10)
 
         val icon = mockStatusBarIcon()
         iconContainer.addView(icon)
@@ -99,7 +101,7 @@
     fun calculateIconXTranslations_shortShelfFourIcons_atCorrectXWithoutOverflowDot() {
         iconContainer.setActualPaddingStart(10f)
         iconContainer.setActualPaddingEnd(10f)
-        iconContainer.setIconSize(10);
+        iconContainer.setIconSize(10)
 
         val iconOne = mockStatusBarIcon()
         val iconTwo = mockStatusBarIcon()
@@ -128,7 +130,7 @@
     fun calculateIconXTranslations_shortShelfFiveIcons_atCorrectXWithOverflowDot() {
         iconContainer.setActualPaddingStart(10f)
         iconContainer.setActualPaddingEnd(10f)
-        iconContainer.setIconSize(10);
+        iconContainer.setIconSize(10)
 
         val iconOne = mockStatusBarIcon()
         val iconTwo = mockStatusBarIcon()
@@ -154,6 +156,55 @@
     }
 
     @Test
+    fun calculateIconXTranslations_givenWidthEnoughForThreeIcons_atCorrectXWithoutOverflowDot() {
+        iconContainer.setActualPaddingStart(0f)
+        iconContainer.setActualPaddingEnd(0f)
+        iconContainer.setActualLayoutWidth(30)
+        iconContainer.setIconSize(10)
+
+        val iconOne = mockStatusBarIcon()
+        val iconTwo = mockStatusBarIcon()
+        val iconThree = mockStatusBarIcon()
+
+        iconContainer.addView(iconOne)
+        iconContainer.addView(iconTwo)
+        iconContainer.addView(iconThree)
+        assertEquals(3, iconContainer.childCount)
+
+        iconContainer.calculateIconXTranslations()
+        assertEquals(0f, iconContainer.getIconState(iconOne).xTranslation)
+        assertEquals(10f, iconContainer.getIconState(iconTwo).xTranslation)
+        assertEquals(20f, iconContainer.getIconState(iconThree).xTranslation)
+        assertFalse(iconContainer.areIconsOverflowing())
+    }
+
+    @Test
+    fun calculateIconXTranslations_givenWidthNotEnoughForFourIcons_atCorrectXWithOverflowDot() {
+        iconContainer.setActualPaddingStart(0f)
+        iconContainer.setActualPaddingEnd(0f)
+        iconContainer.setActualLayoutWidth(35)
+        iconContainer.setIconSize(10)
+
+        val iconOne = mockStatusBarIcon()
+        val iconTwo = mockStatusBarIcon()
+        val iconThree = mockStatusBarIcon()
+        val iconFour = mockStatusBarIcon()
+
+        iconContainer.addView(iconOne)
+        iconContainer.addView(iconTwo)
+        iconContainer.addView(iconThree)
+        iconContainer.addView(iconFour)
+        assertEquals(4, iconContainer.childCount)
+
+        iconContainer.calculateIconXTranslations()
+        assertEquals(0f, iconContainer.getIconState(iconOne).xTranslation)
+        assertEquals(10f, iconContainer.getIconState(iconTwo).xTranslation)
+        assertEquals(STATE_DOT, iconContainer.getIconState(iconThree).visibleState)
+        assertEquals(STATE_HIDDEN, iconContainer.getIconState(iconFour).visibleState)
+        assertTrue(iconContainer.areIconsOverflowing())
+    }
+
+    @Test
     fun shouldForceOverflow_appearingAboveSpeedBump_true() {
         val forceOverflow = iconContainer.shouldForceOverflow(
                 /* i= */ 1,
@@ -161,7 +212,7 @@
                 /* iconAppearAmount= */ 1f,
                 /* maxVisibleIcons= */ 5
         )
-        assertTrue(forceOverflow);
+        assertTrue(forceOverflow)
     }
 
     @Test
@@ -172,7 +223,7 @@
                 /* iconAppearAmount= */ 0f,
                 /* maxVisibleIcons= */ 5
         )
-        assertTrue(forceOverflow);
+        assertTrue(forceOverflow)
     }
 
     @Test
@@ -183,7 +234,7 @@
                 /* iconAppearAmount= */ 0f,
                 /* maxVisibleIcons= */ 5
         )
-        assertFalse(forceOverflow);
+        assertFalse(forceOverflow)
     }
 
     @Test
@@ -210,6 +261,17 @@
     }
 
     @Test
+    fun isOverflowing_lastChildXGreaterThanDotX_true() {
+        val isOverflowing = iconContainer.isOverflowing(
+                /* isLastChild= */ true,
+                /* translationX= */ 9f,
+                /* layoutEnd= */ 10f,
+                /* iconSize= */ 2f,
+        )
+        assertTrue(isOverflowing)
+    }
+
+    @Test
     fun isOverflowing_lastChildXGreaterThanLayoutEnd_true() {
         val isOverflowing = iconContainer.isOverflowing(
                 /* isLastChild= */ true,
@@ -253,7 +315,7 @@
         assertTrue(isOverflowing)
     }
 
-    private fun mockStatusBarIcon() : StatusBarIconView {
+    private fun mockStatusBarIcon(): StatusBarIconView {
         val iconView = mock(StatusBarIconView::class.java)
         whenever(iconView.width).thenReturn(10)
 
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 ab80158..bbc75c9 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
@@ -44,6 +44,9 @@
 
 import android.animation.Animator;
 import android.app.AlarmManager;
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.TypedArray;
 import android.graphics.Color;
 import android.os.Handler;
 import android.testing.AndroidTestingRunner;
@@ -59,11 +62,11 @@
 import com.android.systemui.DejankUtils;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.ShadeInterpolation;
+import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
-import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants;
 import com.android.systemui.keyguard.shared.model.KeyguardState;
 import com.android.systemui.keyguard.shared.model.TransitionState;
 import com.android.systemui.keyguard.shared.model.TransitionStep;
@@ -120,6 +123,7 @@
     private int mScrimVisibility;
     private boolean mAlwaysOnEnabled;
     private TestableLooper mLooper;
+    private Context mContext;
     @Mock private AlarmManager mAlarmManager;
     @Mock private DozeParameters mDozeParameters;
     @Mock private LightBarController mLightBarController;
@@ -133,6 +137,7 @@
     @Mock private PrimaryBouncerToGoneTransitionViewModel mPrimaryBouncerToGoneTransitionViewModel;
     @Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
     @Mock private CoroutineDispatcher mMainDispatcher;
+    @Mock private TypedArray mMockTypedArray;
 
     // TODO(b/204991468): Use a real PanelExpansionStateManager object once this bug is fixed. (The
     //   event-dispatch-on-registration pattern caused some of these unit tests to fail.)
@@ -181,10 +186,11 @@
             mNumEnds = 0;
             mNumCancels = 0;
         }
-    };
+    }
 
     private AnimatorListener mAnimatorListener = new AnimatorListener();
 
+    private int mSurfaceColor = 0x112233;
 
     private void finishAnimationsImmediately() {
         // Execute code that will trigger animations.
@@ -213,10 +219,17 @@
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
+        mContext = spy(getContext());
+        when(mContext.obtainStyledAttributes(
+                new int[]{com.android.internal.R.attr.materialColorSurface}))
+                .thenReturn(mMockTypedArray);
 
-        mScrimBehind = spy(new ScrimView(getContext()));
-        mScrimInFront = new ScrimView(getContext());
-        mNotificationsScrim = new ScrimView(getContext());
+        when(mMockTypedArray.getColorStateList(anyInt()))
+                .thenAnswer((invocation) -> ColorStateList.valueOf(mSurfaceColor));
+
+        mScrimBehind = spy(new ScrimView(mContext));
+        mScrimInFront = new ScrimView(mContext);
+        mNotificationsScrim = new ScrimView(mContext);
         mAlwaysOnEnabled = true;
         mLooper = TestableLooper.get(this);
         DejankUtils.setImmediate(true);
@@ -576,7 +589,7 @@
         mScrimController.transitionTo(BOUNCER);
         finishAnimationsImmediately();
         // Front scrim should be transparent
-        // Back scrim should be visible without tint
+        // Back scrim should be visible and tinted to the surface color
         assertScrimAlpha(Map.of(
                 mScrimInFront, TRANSPARENT,
                 mNotificationsScrim, TRANSPARENT,
@@ -584,9 +597,31 @@
 
         assertScrimTinted(Map.of(
                 mScrimInFront, false,
-                mScrimBehind, false,
+                mScrimBehind, true,
                 mNotificationsScrim, false
         ));
+
+        assertScrimTint(mScrimBehind, mSurfaceColor);
+    }
+
+    @Test
+    public void onThemeChange_bouncerBehindTint_isUpdatedToSurfaceColor() {
+        assertEquals(BOUNCER.getBehindTint(), 0x112233);
+        mSurfaceColor = 0x223344;
+        mConfigurationController.notifyThemeChanged();
+        assertEquals(BOUNCER.getBehindTint(), 0x223344);
+    }
+
+    @Test
+    public void onThemeChangeWhileClipQsScrim_bouncerBehindTint_remainsBlack() {
+        mScrimController.setClipsQsScrim(true);
+        mScrimController.transitionTo(BOUNCER);
+        finishAnimationsImmediately();
+
+        assertEquals(BOUNCER.getBehindTint(), Color.BLACK);
+        mSurfaceColor = 0x223344;
+        mConfigurationController.notifyThemeChanged();
+        assertEquals(BOUNCER.getBehindTint(), Color.BLACK);
     }
 
     @Test
@@ -618,16 +653,17 @@
 
         finishAnimationsImmediately();
         // Front scrim should be transparent
-        // Back scrim should be visible without tint
+        // Back scrim should be visible and has a tint of surfaceColor
         assertScrimAlpha(Map.of(
                 mScrimInFront, TRANSPARENT,
                 mNotificationsScrim, TRANSPARENT,
                 mScrimBehind, OPAQUE));
         assertScrimTinted(Map.of(
                 mScrimInFront, false,
-                mScrimBehind, false,
+                mScrimBehind, true,
                 mNotificationsScrim, false
         ));
+        assertScrimTint(mScrimBehind, mSurfaceColor);
     }
 
     @Test
@@ -1764,6 +1800,13 @@
         assertEquals(message, hasTint, scrim.getTint() != Color.TRANSPARENT);
     }
 
+    private void assertScrimTint(ScrimView scrim, int expectedTint) {
+        String message = "Tint test failed with expected scrim tint: "
+                + Integer.toHexString(expectedTint) + " and actual tint: "
+                + Integer.toHexString(scrim.getTint()) + " for scrim: " + getScrimName(scrim);
+        assertEquals(message, expectedTint, scrim.getTint(), 0.1);
+    }
+
     private String getScrimName(ScrimView scrim) {
         if (scrim == mScrimInFront) {
             return "front";
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 c7143de..ed9cf3f 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
@@ -35,6 +35,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.service.trust.TrustAgentService;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.view.MotionEvent;
@@ -57,6 +58,8 @@
 import com.android.keyguard.KeyguardMessageAreaController;
 import com.android.keyguard.KeyguardSecurityModel;
 import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.keyguard.TrustGrantFlags;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor;
@@ -84,7 +87,6 @@
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.unfold.SysUIUnfoldComponent;
 
 import com.google.common.truth.Truth;
@@ -154,7 +156,7 @@
     @Captor
     private ArgumentCaptor<OnBackInvokedCallback> mBackCallbackCaptor;
     @Captor
-    private ArgumentCaptor<KeyguardStateController.Callback> mKeyguardStateControllerCallback;
+    private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallback;
 
 
     @Before
@@ -936,18 +938,24 @@
     }
 
     @Test
-    public void onDeviceUnlocked_hideAlternateBouncerAndClearMessageArea() {
+    public void onTrustChanged_hideAlternateBouncerAndClearMessageArea() {
+        // GIVEN keyguard update monitor callback is registered
+        verify(mKeyguardUpdateMonitor).registerCallback(mKeyguardUpdateMonitorCallback.capture());
+
         reset(mKeyguardUpdateMonitor);
         reset(mKeyguardMessageAreaController);
 
-        // GIVEN keyguard state controller callback is registered
-        verify(mKeyguardStateController).addCallback(mKeyguardStateControllerCallback.capture());
-
         // GIVEN alternate bouncer state = not visible
         when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(false);
 
-        // WHEN the device is unlocked
-        mKeyguardStateControllerCallback.getValue().onUnlockedChanged();
+        // WHEN the device is trusted by active unlock
+        mKeyguardUpdateMonitorCallback.getValue().onTrustGrantedForCurrentUser(
+                true,
+                true,
+                new TrustGrantFlags(TrustAgentService.FLAG_GRANT_TRUST_DISMISS_KEYGUARD
+                        | TrustAgentService.FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE),
+                null
+        );
 
         // THEN the false visibility state is propagated to the keyguardUpdateMonitor
         verify(mKeyguardUpdateMonitor).setAlternateBouncerShowing(eq(false));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
index 862eb00..c8b6f13d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
@@ -159,6 +159,7 @@
                 mock(),
                 mock(),
                 FakeExecutor(FakeSystemClock()),
+                dispatcher,
                 testScope.backgroundScope,
                 mock(),
             )
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt
index 30b95ef..5bc98e0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt
@@ -83,6 +83,7 @@
                 logger,
                 tableLogger,
                 mainExecutor,
+                testDispatcher,
                 testScope.backgroundScope,
                 wifiManager,
             )
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
index 5ed3a5c..7007345 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
@@ -76,7 +76,8 @@
     private lateinit var executor: Executor
     private lateinit var connectivityRepository: ConnectivityRepository
 
-    private val testScope = TestScope(UnconfinedTestDispatcher())
+    private val dispatcher = UnconfinedTestDispatcher()
+    private val testScope = TestScope(dispatcher)
 
     @Before
     fun setUp() {
@@ -1301,6 +1302,7 @@
             logger,
             tableLogger,
             executor,
+            dispatcher,
             testScope.backgroundScope,
             wifiManager,
         )
diff --git a/packages/SystemUI/tests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt
index b30c20d..b04eb01 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt
@@ -25,8 +25,8 @@
 import android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS
 import androidx.test.filters.SmallTest
 import androidx.test.rule.ActivityTestRule
-import androidx.test.runner.intercepting.SingleActivityFactory
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.activity.SingleActivityFactory
 import com.google.common.truth.Truth.assertThat
 
 import javax.inject.Inject
@@ -49,19 +49,17 @@
 
     open class UsbPermissionActivityTestable @Inject constructor (
         val message: UsbAudioWarningDialogMessage
-    )
-        : UsbPermissionActivity(UsbAudioWarningDialogMessage())
+    ) : UsbPermissionActivity(UsbAudioWarningDialogMessage())
 
     @Rule
     @JvmField
-    var activityRule = ActivityTestRule<UsbPermissionActivityTestable>(
-            object : SingleActivityFactory<UsbPermissionActivityTestable>(
-                    UsbPermissionActivityTestable::class.java
-            ) {
-                    override fun create(intent: Intent?): UsbPermissionActivityTestable {
-                        return UsbPermissionActivityTestable(mMessage)
-                    }
-            }, false, false)
+    var activityRule = ActivityTestRule(
+            /* activityFactory= */ SingleActivityFactory {
+                UsbPermissionActivityTestable(mMessage)
+            },
+            /* initialTouchMode= */ false,
+            /* launchActivity= */ false,
+    )
 
     private val activityIntent = Intent(mContext, UsbPermissionActivityTestable::class.java)
             .apply {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
index 89dce61..5b418ed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
@@ -19,10 +19,12 @@
 
 import android.app.ActivityManager
 import android.app.admin.DevicePolicyManager
+import android.content.Context
 import android.content.Intent
 import android.content.pm.UserInfo
 import android.graphics.Bitmap
 import android.graphics.drawable.Drawable
+import android.os.Process
 import android.os.UserHandle
 import android.os.UserManager
 import android.provider.Settings
@@ -62,7 +64,9 @@
 import junit.framework.Assert.assertNotNull
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestDispatcher
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -76,6 +80,7 @@
 import org.mockito.Mock
 import org.mockito.Mockito.atLeastOnce
 import org.mockito.Mockito.never
+import org.mockito.Mockito.spy
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
@@ -99,11 +104,15 @@
 
     private lateinit var underTest: UserInteractor
 
+    private lateinit var spyContext: Context
     private lateinit var testScope: TestScope
     private lateinit var userRepository: FakeUserRepository
+    private lateinit var keyguardReply: KeyguardInteractorFactory.WithDependencies
     private lateinit var keyguardRepository: FakeKeyguardRepository
     private lateinit var telephonyRepository: FakeTelephonyRepository
+    private lateinit var testDispatcher: TestDispatcher
     private lateinit var featureFlags: FakeFeatureFlags
+    private lateinit var refreshUsersScheduler: RefreshUsersScheduler
 
     @Before
     fun setUp() {
@@ -123,58 +132,36 @@
                 set(Flags.FULL_SCREEN_USER_SWITCHER, false)
                 set(Flags.FACE_AUTH_REFACTOR, true)
             }
-        val reply = KeyguardInteractorFactory.create(featureFlags = featureFlags)
-        keyguardRepository = reply.repository
+        spyContext = spy(context)
+        keyguardReply = KeyguardInteractorFactory.create(featureFlags = featureFlags)
+        keyguardRepository = keyguardReply.repository
         userRepository = FakeUserRepository()
         telephonyRepository = FakeTelephonyRepository()
-        val testDispatcher = StandardTestDispatcher()
+        testDispatcher = StandardTestDispatcher()
         testScope = TestScope(testDispatcher)
-        val refreshUsersScheduler =
+        refreshUsersScheduler =
             RefreshUsersScheduler(
                 applicationScope = testScope.backgroundScope,
                 mainDispatcher = testDispatcher,
                 repository = userRepository,
             )
-        underTest =
-            UserInteractor(
-                applicationContext = context,
-                repository = userRepository,
-                activityStarter = activityStarter,
-                keyguardInteractor = reply.keyguardInteractor,
-                manager = manager,
-                headlessSystemUserMode = headlessSystemUserMode,
-                applicationScope = testScope.backgroundScope,
-                telephonyInteractor =
-                    TelephonyInteractor(
-                        repository = telephonyRepository,
-                    ),
-                broadcastDispatcher = fakeBroadcastDispatcher,
-                keyguardUpdateMonitor = keyguardUpdateMonitor,
-                backgroundDispatcher = testDispatcher,
-                activityManager = activityManager,
-                refreshUsersScheduler = refreshUsersScheduler,
-                guestUserInteractor =
-                    GuestUserInteractor(
-                        applicationContext = context,
-                        applicationScope = testScope.backgroundScope,
-                        mainDispatcher = testDispatcher,
-                        backgroundDispatcher = testDispatcher,
-                        manager = manager,
-                        repository = userRepository,
-                        deviceProvisionedController = deviceProvisionedController,
-                        devicePolicyManager = devicePolicyManager,
-                        refreshUsersScheduler = refreshUsersScheduler,
-                        uiEventLogger = uiEventLogger,
-                        resumeSessionReceiver = resumeSessionReceiver,
-                        resetOrExitSessionReceiver = resetOrExitSessionReceiver,
-                    ),
-                uiEventLogger = uiEventLogger,
-                featureFlags = featureFlags,
-            )
     }
 
     @Test
-    fun testKeyguardUpdateMonitor_onKeyguardGoingAway() =
+    fun createUserInteractor_processUser_noSecondaryService() {
+        createUserInteractor()
+        verify(spyContext, never()).startServiceAsUser(any(), any())
+    }
+
+    @Test
+    fun createUserInteractor_nonProcessUser_startsSecondaryService() {
+        createUserInteractor(false /* startAsProcessUser */)
+        verify(spyContext).startServiceAsUser(any(), any())
+    }
+
+    @Test
+    fun testKeyguardUpdateMonitor_onKeyguardGoingAway() {
+        createUserInteractor()
         testScope.runTest {
             val argumentCaptor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
             verify(keyguardUpdateMonitor).registerCallback(argumentCaptor.capture())
@@ -184,9 +171,11 @@
             val lastValue = collectLastValue(underTest.dialogDismissRequests)
             assertNotNull(lastValue)
         }
+    }
 
     @Test
-    fun onRecordSelected_user() =
+    fun onRecordSelected_user() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 3, includeGuest = false)
             userRepository.setUserInfos(userInfos)
@@ -201,9 +190,11 @@
             verify(activityManager).switchUser(userInfos[1].id)
             Unit
         }
+    }
 
     @Test
-    fun onRecordSelected_switchToGuestUser() =
+    fun onRecordSelected_switchToGuestUser() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 3, includeGuest = true)
             userRepository.setUserInfos(userInfos)
@@ -217,9 +208,11 @@
             verify(activityManager).switchUser(userInfos.last().id)
             Unit
         }
+    }
 
     @Test
-    fun onRecordSelected_switchToRestrictedUser() =
+    fun onRecordSelected_switchToRestrictedUser() {
+        createUserInteractor()
         testScope.runTest {
             var userInfos = createUserInfos(count = 2, includeGuest = false).toMutableList()
             userInfos.add(
@@ -242,9 +235,11 @@
             verify(activityManager).switchUser(userInfos.last().id)
             Unit
         }
+    }
 
     @Test
-    fun onRecordSelected_enterGuestMode() =
+    fun onRecordSelected_enterGuestMode() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 3, includeGuest = false)
             userRepository.setUserInfos(userInfos)
@@ -262,9 +257,11 @@
             verify(manager).createGuest(any())
             Unit
         }
+    }
 
     @Test
-    fun onRecordSelected_action() =
+    fun onRecordSelected_action() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 3, includeGuest = true)
             userRepository.setUserInfos(userInfos)
@@ -278,9 +275,11 @@
             verify(dialogShower, never()).dismiss()
             verify(activityStarter).startActivity(any(), anyBoolean())
         }
+    }
 
     @Test
-    fun users_switcherEnabled() =
+    fun users_switcherEnabled() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 3, includeGuest = true)
             userRepository.setUserInfos(userInfos)
@@ -291,9 +290,11 @@
 
             assertUsers(models = value(), count = 3, includeGuest = true)
         }
+    }
 
     @Test
-    fun users_switchesToSecondUser() =
+    fun users_switchesToSecondUser() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
@@ -305,9 +306,11 @@
 
             assertUsers(models = value(), count = 2, selectedIndex = 1)
         }
+    }
 
     @Test
-    fun users_switcherNotEnabled() =
+    fun users_switcherNotEnabled() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
@@ -317,9 +320,11 @@
             val value = collectLastValue(underTest.users)
             assertUsers(models = value(), count = 1)
         }
+    }
 
     @Test
-    fun selectedUser() =
+    fun selectedUser() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
@@ -332,9 +337,11 @@
             userRepository.setSelectedUserInfo(userInfos[1])
             assertUser(value(), id = 1, isSelected = true)
         }
+    }
 
     @Test
-    fun actions_deviceUnlocked() =
+    fun actions_deviceUnlocked() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
 
@@ -356,9 +363,11 @@
                     )
                 )
         }
+    }
 
     @Test
-    fun actions_deviceUnlocked_fullScreen() =
+    fun actions_deviceUnlocked_fullScreen() {
+        createUserInteractor()
         testScope.runTest {
             featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, true)
             val userInfos = createUserInfos(count = 2, includeGuest = false)
@@ -379,9 +388,11 @@
                     )
                 )
         }
+    }
 
     @Test
-    fun actions_deviceUnlockedUserNotPrimary_emptyList() =
+    fun actions_deviceUnlockedUserNotPrimary_emptyList() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
@@ -392,9 +403,11 @@
 
             assertThat(value()).isEqualTo(emptyList<UserActionModel>())
         }
+    }
 
     @Test
-    fun actions_deviceUnlockedUserIsGuest_emptyList() =
+    fun actions_deviceUnlockedUserIsGuest_emptyList() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = true)
             assertThat(userInfos[1].isGuest).isTrue()
@@ -406,9 +419,11 @@
 
             assertThat(value()).isEqualTo(emptyList<UserActionModel>())
         }
+    }
 
     @Test
-    fun actions_deviceLockedAddFromLockscreenSet_fullList() =
+    fun actions_deviceLockedAddFromLockscreenSet_fullList() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
@@ -432,9 +447,11 @@
                     )
                 )
         }
+    }
 
     @Test
-    fun actions_deviceLockedAddFromLockscreenSet_fullList_fullScreen() =
+    fun actions_deviceLockedAddFromLockscreenSet_fullList_fullScreen() {
+        createUserInteractor()
         testScope.runTest {
             featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, true)
             val userInfos = createUserInfos(count = 2, includeGuest = false)
@@ -459,9 +476,11 @@
                     )
                 )
         }
+    }
 
     @Test
-    fun actions_deviceLocked_onlymanageUserIsShown() =
+    fun actions_deviceLocked_onlymanageUserIsShown() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
@@ -472,9 +491,11 @@
 
             assertThat(value()).isEqualTo(listOf(UserActionModel.NAVIGATE_TO_USER_MANAGEMENT))
         }
+    }
 
     @Test
-    fun executeAction_addUser_dismissesDialogAndStartsActivity() =
+    fun executeAction_addUser_dismissesDialogAndStartsActivity() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
@@ -486,9 +507,11 @@
                 .log(MultiUserActionsEvent.CREATE_USER_FROM_USER_SWITCHER)
             underTest.onDialogShown()
         }
+    }
 
     @Test
-    fun executeAction_addSupervisedUser_dismissesDialogAndStartsActivity() =
+    fun executeAction_addSupervisedUser_dismissesDialogAndStartsActivity() {
+        createUserInteractor()
         testScope.runTest {
             underTest.executeAction(UserActionModel.ADD_SUPERVISED_USER)
 
@@ -500,9 +523,11 @@
                 .isEqualTo(UserManager.ACTION_CREATE_SUPERVISED_USER)
             assertThat(intentCaptor.value.`package`).isEqualTo(SUPERVISED_USER_CREATION_APP_PACKAGE)
         }
+    }
 
     @Test
-    fun executeAction_navigateToManageUsers() =
+    fun executeAction_navigateToManageUsers() {
+        createUserInteractor()
         testScope.runTest {
             underTest.executeAction(UserActionModel.NAVIGATE_TO_USER_MANAGEMENT)
 
@@ -510,9 +535,11 @@
             verify(activityStarter).startActivity(intentCaptor.capture(), eq(true))
             assertThat(intentCaptor.value.action).isEqualTo(Settings.ACTION_USER_SETTINGS)
         }
+    }
 
     @Test
-    fun executeAction_guestMode() =
+    fun executeAction_guestMode() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
@@ -548,9 +575,11 @@
                 )
             verify(activityManager).switchUser(guestUserInfo.id)
         }
+    }
 
     @Test
-    fun selectUser_alreadySelectedGuestReSelected_exitGuestDialog() =
+    fun selectUser_alreadySelectedGuestReSelected_exitGuestDialog() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = true)
             val guestUserInfo = userInfos[1]
@@ -569,9 +598,11 @@
                 .isInstanceOf(ShowDialogRequestModel.ShowExitGuestDialog::class.java)
             verify(dialogShower, never()).dismiss()
         }
+    }
 
     @Test
-    fun selectUser_currentlyGuestNonGuestSelected_exitGuestDialog() =
+    fun selectUser_currentlyGuestNonGuestSelected_exitGuestDialog() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = true)
             val guestUserInfo = userInfos[1]
@@ -587,9 +618,11 @@
                 .isInstanceOf(ShowDialogRequestModel.ShowExitGuestDialog::class.java)
             verify(dialogShower, never()).dismiss()
         }
+    }
 
     @Test
-    fun selectUser_notCurrentlyGuest_switchesUsers() =
+    fun selectUser_notCurrentlyGuest_switchesUsers() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
@@ -603,9 +636,11 @@
             verify(activityManager).switchUser(userInfos[1].id)
             verify(dialogShower).dismiss()
         }
+    }
 
     @Test
-    fun telephonyCallStateChanges_refreshesUsers() =
+    fun telephonyCallStateChanges_refreshesUsers() {
+        createUserInteractor()
         testScope.runTest {
             runCurrent()
 
@@ -616,9 +651,11 @@
 
             assertThat(userRepository.refreshUsersCallCount).isEqualTo(refreshUsersCallCount + 1)
         }
+    }
 
     @Test
-    fun userSwitchedBroadcast() =
+    fun userSwitchedBroadcast() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
@@ -634,7 +671,7 @@
             userRepository.setSelectedUserInfo(userInfos[1])
             runCurrent()
             fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
-                context,
+                spyContext,
                 Intent(Intent.ACTION_USER_SWITCHED)
                     .putExtra(Intent.EXTRA_USER_HANDLE, userInfos[1].id),
             )
@@ -644,10 +681,13 @@
             verify(callback2, atLeastOnce()).onUserStateChanged()
             assertThat(userRepository.secondaryUserId).isEqualTo(userInfos[1].id)
             assertThat(userRepository.refreshUsersCallCount).isEqualTo(refreshUsersCallCount + 1)
+            verify(spyContext).startServiceAsUser(any(), eq(UserHandle.of(userInfos[1].id)))
         }
+    }
 
     @Test
-    fun userInfoChangedBroadcast() =
+    fun userInfoChangedBroadcast() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
@@ -655,7 +695,7 @@
             val refreshUsersCallCount = userRepository.refreshUsersCallCount
 
             fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
-                context,
+                spyContext,
                 Intent(Intent.ACTION_USER_INFO_CHANGED),
             )
 
@@ -663,9 +703,11 @@
 
             assertThat(userRepository.refreshUsersCallCount).isEqualTo(refreshUsersCallCount + 1)
         }
+    }
 
     @Test
-    fun systemUserUnlockedBroadcast_refreshUsers() =
+    fun systemUserUnlockedBroadcast_refreshUsers() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
@@ -673,7 +715,7 @@
             val refreshUsersCallCount = userRepository.refreshUsersCallCount
 
             fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
-                context,
+                spyContext,
                 Intent(Intent.ACTION_USER_UNLOCKED)
                     .putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_SYSTEM),
             )
@@ -681,9 +723,11 @@
 
             assertThat(userRepository.refreshUsersCallCount).isEqualTo(refreshUsersCallCount + 1)
         }
+    }
 
     @Test
-    fun nonSystemUserUnlockedBroadcast_doNotRefreshUsers() =
+    fun nonSystemUserUnlockedBroadcast_doNotRefreshUsers() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
@@ -691,15 +735,17 @@
             val refreshUsersCallCount = userRepository.refreshUsersCallCount
 
             fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
-                context,
+                spyContext,
                 Intent(Intent.ACTION_USER_UNLOCKED).putExtra(Intent.EXTRA_USER_HANDLE, 1337),
             )
 
             assertThat(userRepository.refreshUsersCallCount).isEqualTo(refreshUsersCallCount)
         }
+    }
 
     @Test
-    fun userRecords() =
+    fun userRecords() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 3, includeGuest = false)
             userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
@@ -723,9 +769,11 @@
                     ),
             )
         }
+    }
 
     @Test
-    fun userRecordsFullScreen() =
+    fun userRecordsFullScreen() {
+        createUserInteractor()
         testScope.runTest {
             featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, true)
             val userInfos = createUserInfos(count = 3, includeGuest = false)
@@ -750,9 +798,11 @@
                     ),
             )
         }
+    }
 
     @Test
-    fun selectedUserRecord() =
+    fun selectedUserRecord() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 3, includeGuest = true)
             userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
@@ -768,9 +818,11 @@
                 isSwitchToEnabled = true,
             )
         }
+    }
 
     @Test
-    fun users_secondaryUser_guestUserCanBeSwitchedTo() =
+    fun users_secondaryUser_guestUserCanBeSwitchedTo() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 3, includeGuest = true)
             userRepository.setUserInfos(userInfos)
@@ -781,9 +833,11 @@
             assertThat(res()?.size == 3).isTrue()
             assertThat(res()?.find { it.isGuest }).isNotNull()
         }
+    }
 
     @Test
-    fun users_secondaryUser_noGuestAction() =
+    fun users_secondaryUser_noGuestAction() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 3, includeGuest = true)
             userRepository.setUserInfos(userInfos)
@@ -793,9 +847,11 @@
             val res = collectLastValue(underTest.actions)
             assertThat(res()?.find { it == UserActionModel.ENTER_GUEST_MODE }).isNull()
         }
+    }
 
     @Test
-    fun users_secondaryUser_noGuestUserRecord() =
+    fun users_secondaryUser_noGuestUserRecord() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 3, includeGuest = true)
             userRepository.setUserInfos(userInfos)
@@ -804,9 +860,11 @@
 
             assertThat(underTest.userRecords.value.find { it.isGuest }).isNull()
         }
+    }
 
     @Test
-    fun showUserSwitcher_fullScreenDisabled_showsDialogSwitcher() =
+    fun showUserSwitcher_fullScreenDisabled_showsDialogSwitcher() {
+        createUserInteractor()
         testScope.runTest {
             val expandable = mock<Expandable>()
             underTest.showUserSwitcher(expandable)
@@ -820,9 +878,11 @@
             underTest.onDialogShown()
             assertThat(dialogRequest()).isNull()
         }
+    }
 
     @Test
-    fun showUserSwitcher_fullScreenEnabled_launchesFullScreenDialog() =
+    fun showUserSwitcher_fullScreenEnabled_launchesFullScreenDialog() {
+        createUserInteractor()
         testScope.runTest {
             featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, true)
 
@@ -838,9 +898,11 @@
             underTest.onDialogShown()
             assertThat(dialogRequest()).isNull()
         }
+    }
 
     @Test
-    fun users_secondaryUser_managedProfileIsNotIncluded() =
+    fun users_secondaryUser_managedProfileIsNotIncluded() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 3, includeGuest = false).toMutableList()
             userInfos.add(
@@ -858,9 +920,11 @@
             val res = collectLastValue(underTest.users)
             assertThat(res()?.size == 3).isTrue()
         }
+    }
 
     @Test
-    fun currentUserIsNotPrimaryAndUserSwitcherIsDisabled() =
+    fun currentUserIsNotPrimaryAndUserSwitcherIsDisabled() {
+        createUserInteractor()
         testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
@@ -869,9 +933,11 @@
             val selectedUser = collectLastValue(underTest.selectedUser)
             assertThat(selectedUser()).isNotNull()
         }
+    }
 
     @Test
-    fun userRecords_isActionAndNoUsersUnlocked_actionIsDisabled() =
+    fun userRecords_isActionAndNoUsersUnlocked_actionIsDisabled() {
+        createUserInteractor()
         testScope.runTest {
             keyguardRepository.setKeyguardShowing(true)
             whenever(manager.getUserSwitchability(any()))
@@ -891,9 +957,11 @@
                 .filter { it.info == null }
                 .forEach { action -> assertThat(action.isSwitchToEnabled).isFalse() }
         }
+    }
 
     @Test
-    fun userRecords_isActionAndNoUsersUnlocked_actionIsDisabled_HeadlessMode() =
+    fun userRecords_isActionAndNoUsersUnlocked_actionIsDisabled_HeadlessMode() {
+        createUserInteractor()
         testScope.runTest {
             keyguardRepository.setKeyguardShowing(true)
             whenever(headlessSystemUserMode.isHeadlessSystemUserMode()).thenReturn(true)
@@ -913,6 +981,7 @@
                 .filter { it.info == null }
                 .forEach { action -> assertThat(action.isSwitchToEnabled).isFalse() }
         }
+    }
 
     private fun assertUsers(
         models: List<UserModel>?,
@@ -1005,6 +1074,53 @@
             .isEqualTo(type == UserActionModel.ADD_SUPERVISED_USER)
     }
 
+    private fun createUserInteractor(startAsProcessUser: Boolean = true) {
+        val processUserId = Process.myUserHandle().identifier
+        val startUserId = if (startAsProcessUser) processUserId else (processUserId + 1)
+        runBlocking {
+            val userInfo =
+                createUserInfo(id = startUserId, name = "user_$startUserId", isPrimary = true)
+            userRepository.setUserInfos(listOf(userInfo))
+            userRepository.setSelectedUserInfo(userInfo)
+        }
+        underTest =
+            UserInteractor(
+                applicationContext = spyContext,
+                repository = userRepository,
+                activityStarter = activityStarter,
+                keyguardInteractor = keyguardReply.keyguardInteractor,
+                manager = manager,
+                headlessSystemUserMode = headlessSystemUserMode,
+                applicationScope = testScope.backgroundScope,
+                telephonyInteractor =
+                    TelephonyInteractor(
+                        repository = telephonyRepository,
+                    ),
+                broadcastDispatcher = fakeBroadcastDispatcher,
+                keyguardUpdateMonitor = keyguardUpdateMonitor,
+                backgroundDispatcher = testDispatcher,
+                activityManager = activityManager,
+                refreshUsersScheduler = refreshUsersScheduler,
+                guestUserInteractor =
+                    GuestUserInteractor(
+                        applicationContext = spyContext,
+                        applicationScope = testScope.backgroundScope,
+                        mainDispatcher = testDispatcher,
+                        backgroundDispatcher = testDispatcher,
+                        manager = manager,
+                        repository = userRepository,
+                        deviceProvisionedController = deviceProvisionedController,
+                        devicePolicyManager = devicePolicyManager,
+                        refreshUsersScheduler = refreshUsersScheduler,
+                        uiEventLogger = uiEventLogger,
+                        resumeSessionReceiver = resumeSessionReceiver,
+                        resetOrExitSessionReceiver = resetOrExitSessionReceiver,
+                    ),
+                uiEventLogger = uiEventLogger,
+                featureFlags = featureFlags,
+            )
+    }
+
     private fun createUserInfos(
         count: Int,
         includeGuest: Boolean,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt
index 9cb26e0..2433e12 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt
@@ -50,6 +50,7 @@
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.toList
 import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.advanceUntilIdle
@@ -237,6 +238,10 @@
                 set(Flags.FULL_SCREEN_USER_SWITCHER, false)
                 set(Flags.FACE_AUTH_REFACTOR, true)
             }
+        runBlocking {
+            userRepository.setUserInfos(listOf(USER_0))
+            userRepository.setSelectedUserInfo(USER_0)
+        }
         return StatusBarUserChipViewModel(
             context = context,
             interactor =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
index e3f9fac..8c88f95 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
@@ -102,6 +102,20 @@
         testScope = TestScope(testDispatcher)
         userRepository = FakeUserRepository()
         runBlocking {
+            val userInfos =
+                listOf(
+                    UserInfo(
+                        /* id= */ 0,
+                        /* name= */ "zero",
+                        /* iconPath= */ "",
+                        /* flags= */ UserInfo.FLAG_PRIMARY or
+                            UserInfo.FLAG_ADMIN or
+                            UserInfo.FLAG_FULL,
+                        UserManager.USER_TYPE_FULL_SYSTEM,
+                    ),
+                )
+            userRepository.setUserInfos(userInfos)
+            userRepository.setSelectedUserInfo(userInfos[0])
             userRepository.setSettings(
                 UserSwitcherSettingsModel(
                     isUserSwitcherEnabled = true,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index a09af00..4839eeb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -39,6 +39,7 @@
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
@@ -153,6 +154,7 @@
 import com.android.wm.shell.sysui.ShellController;
 import com.android.wm.shell.sysui.ShellInit;
 import com.android.wm.shell.taskview.TaskViewTransitions;
+import com.android.wm.shell.transition.Transitions;
 
 import org.junit.After;
 import org.junit.Before;
@@ -282,7 +284,7 @@
     @Mock
     private ScreenOffAnimationController mScreenOffAnimationController;
     @Mock
-    private TaskViewTransitions mTaskViewTransitions;
+    Transitions mTransitions;
     @Mock
     private Optional<OneHandedController> mOneHandedOptional;
     @Mock
@@ -294,6 +296,8 @@
     @Mock
     private Icon mAppBubbleIcon;
 
+    private TaskViewTransitions mTaskViewTransitions;
+
     private TestableBubblePositioner mPositioner;
 
     private BubbleData mBubbleData;
@@ -309,6 +313,12 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
+
+        if (Transitions.ENABLE_SHELL_TRANSITIONS) {
+            doReturn(true).when(mTransitions).isRegistered();
+        }
+        mTaskViewTransitions = new TaskViewTransitions(mTransitions);
+
         mTestableLooper = TestableLooper.get(this);
 
         // For the purposes of this test, just run everything synchronously
@@ -1986,7 +1996,7 @@
 
         FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
         mBubbleController.registerBubbleStateListener(bubbleStateListener);
-        mBubbleController.expandStackAndSelectBubbleFromLauncher(mBubbleEntry.getKey(), true);
+        mBubbleController.expandStackAndSelectBubbleFromLauncher(mBubbleEntry.getKey(), 500, 1000);
 
         assertThat(mBubbleController.getLayerView().isExpanded()).isTrue();
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/activity/SingleActivityFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/activity/SingleActivityFactory.kt
new file mode 100644
index 0000000..5a92fb1
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/activity/SingleActivityFactory.kt
@@ -0,0 +1,35 @@
+/*
+ * 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.activity
+
+import android.app.Activity
+import android.content.Intent
+import androidx.test.runner.intercepting.SingleActivityFactory
+
+/**
+ * Builds a new [SingleActivityFactory] which delegating any call of [SingleActivityFactory.create]
+ * to the [instantiate] parameter.
+ *
+ * For more details, see [SingleActivityFactory].
+ */
+inline fun <reified T : Activity> SingleActivityFactory(
+    crossinline instantiate: (intent: Intent?) -> T,
+): SingleActivityFactory<T> {
+    return object : SingleActivityFactory<T>(T::class.java) {
+        override fun create(intent: Intent?): T = instantiate(intent)
+    }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt
index a718f70..bebdd40 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt
@@ -16,40 +16,154 @@
 
 package com.android.systemui.authentication.data.repository
 
+import com.android.internal.widget.LockPatternUtils
+import com.android.internal.widget.LockPatternView
+import com.android.internal.widget.LockscreenCredential
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.authentication.shared.model.AuthenticationResultModel
+import com.android.systemui.authentication.shared.model.AuthenticationThrottlingModel
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.asStateFlow
 
 class FakeAuthenticationRepository(
-    private val delegate: AuthenticationRepository,
-    private val onSecurityModeChanged: (SecurityMode) -> Unit,
-) : AuthenticationRepository by delegate {
+    private val currentTime: () -> Long,
+) : AuthenticationRepository {
+
+    private val _isBypassEnabled = MutableStateFlow(false)
+    override val isBypassEnabled: StateFlow<Boolean> = _isBypassEnabled
+
+    private val _isAutoConfirmEnabled = MutableStateFlow(false)
+    override val isAutoConfirmEnabled: StateFlow<Boolean> = _isAutoConfirmEnabled.asStateFlow()
 
     private val _isUnlocked = MutableStateFlow(false)
     override val isUnlocked: StateFlow<Boolean> = _isUnlocked.asStateFlow()
 
-    private var authenticationMethod: AuthenticationMethodModel = DEFAULT_AUTHENTICATION_METHOD
+    override val hintedPinLength: Int = 6
+
+    private val _isPatternVisible = MutableStateFlow(true)
+    override val isPatternVisible: StateFlow<Boolean> = _isPatternVisible.asStateFlow()
+
+    private val _throttling = MutableStateFlow(AuthenticationThrottlingModel())
+    override val throttling: StateFlow<AuthenticationThrottlingModel> = _throttling.asStateFlow()
+
+    private val _authenticationMethod =
+        MutableStateFlow<AuthenticationMethodModel>(DEFAULT_AUTHENTICATION_METHOD)
+    val authenticationMethod: StateFlow<AuthenticationMethodModel> =
+        _authenticationMethod.asStateFlow()
+
+    private var isLockscreenEnabled = true
+    private var failedAttemptCount = 0
+    private var throttlingEndTimestamp = 0L
+    private var credentialOverride: List<Any>? = null
+    private var securityMode: SecurityMode = DEFAULT_AUTHENTICATION_METHOD.toSecurityMode()
 
     override suspend fun getAuthenticationMethod(): AuthenticationMethodModel {
-        return authenticationMethod
+        return authenticationMethod.value
     }
 
     fun setAuthenticationMethod(authenticationMethod: AuthenticationMethodModel) {
-        this.authenticationMethod = authenticationMethod
-        onSecurityModeChanged(authenticationMethod.toSecurityMode())
+        _authenticationMethod.value = authenticationMethod
+        securityMode = authenticationMethod.toSecurityMode()
+    }
+
+    fun overrideCredential(pin: List<Int>) {
+        credentialOverride = pin
+    }
+
+    override suspend fun isLockscreenEnabled(): Boolean {
+        return isLockscreenEnabled
+    }
+
+    override suspend fun reportAuthenticationAttempt(isSuccessful: Boolean) {
+        failedAttemptCount = if (isSuccessful) 0 else failedAttemptCount + 1
+        _isUnlocked.value = isSuccessful
+    }
+
+    override suspend fun getPinLength(): Int {
+        return (credentialOverride ?: listOf(1, 2, 3, 4)).size
+    }
+
+    override fun setBypassEnabled(isBypassEnabled: Boolean) {
+        _isBypassEnabled.value = isBypassEnabled
+    }
+
+    override suspend fun getFailedAuthenticationAttemptCount(): Int {
+        return failedAttemptCount
+    }
+
+    override suspend fun getThrottlingEndTimestamp(): Long {
+        return throttlingEndTimestamp
+    }
+
+    override fun setThrottling(throttlingModel: AuthenticationThrottlingModel) {
+        _throttling.value = throttlingModel
     }
 
     fun setUnlocked(isUnlocked: Boolean) {
         _isUnlocked.value = isUnlocked
     }
 
-    companion object {
-        val DEFAULT_AUTHENTICATION_METHOD =
-            AuthenticationMethodModel.Pin(listOf(1, 2, 3, 4), autoConfirm = false)
+    fun setAutoConfirmEnabled(isEnabled: Boolean) {
+        _isAutoConfirmEnabled.value = isEnabled
+    }
 
-        fun AuthenticationMethodModel.toSecurityMode(): SecurityMode {
+    fun setLockscreenEnabled(isLockscreenEnabled: Boolean) {
+        this.isLockscreenEnabled = isLockscreenEnabled
+    }
+
+    override suspend fun setThrottleDuration(durationMs: Int) {
+        throttlingEndTimestamp = if (durationMs > 0) currentTime() + durationMs else 0
+    }
+
+    override suspend fun checkCredential(
+        credential: LockscreenCredential
+    ): AuthenticationResultModel {
+        val expectedCredential = credentialOverride ?: getExpectedCredential(securityMode)
+        val isSuccessful =
+            when {
+                credential.type != getCurrentCredentialType(securityMode) -> false
+                credential.type == LockPatternUtils.CREDENTIAL_TYPE_PIN ->
+                    credential.isPin && credential.matches(expectedCredential)
+                credential.type == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD ->
+                    credential.isPassword && credential.matches(expectedCredential)
+                credential.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN ->
+                    credential.isPattern && credential.matches(expectedCredential)
+                else -> error("Unexpected credential type ${credential.type}!")
+            }
+
+        return if (
+            isSuccessful || failedAttemptCount < MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING - 1
+        ) {
+            AuthenticationResultModel(
+                isSuccessful = isSuccessful,
+                throttleDurationMs = 0,
+            )
+        } else {
+            AuthenticationResultModel(
+                isSuccessful = false,
+                throttleDurationMs = THROTTLE_DURATION_MS,
+            )
+        }
+    }
+
+    companion object {
+        val DEFAULT_AUTHENTICATION_METHOD = AuthenticationMethodModel.Pin
+        val PATTERN =
+            listOf(
+                AuthenticationMethodModel.Pattern.PatternCoordinate(2, 0),
+                AuthenticationMethodModel.Pattern.PatternCoordinate(2, 1),
+                AuthenticationMethodModel.Pattern.PatternCoordinate(2, 2),
+                AuthenticationMethodModel.Pattern.PatternCoordinate(1, 1),
+                AuthenticationMethodModel.Pattern.PatternCoordinate(0, 0),
+                AuthenticationMethodModel.Pattern.PatternCoordinate(0, 1),
+                AuthenticationMethodModel.Pattern.PatternCoordinate(0, 2),
+            )
+        const val MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING = 5
+        const val THROTTLE_DURATION_MS = 30000
+
+        private fun AuthenticationMethodModel.toSecurityMode(): SecurityMode {
             return when (this) {
                 is AuthenticationMethodModel.Pin -> SecurityMode.PIN
                 is AuthenticationMethodModel.Password -> SecurityMode.Password
@@ -58,5 +172,50 @@
                 is AuthenticationMethodModel.None -> SecurityMode.None
             }
         }
+
+        @LockPatternUtils.CredentialType
+        private fun getCurrentCredentialType(
+            securityMode: SecurityMode,
+        ): Int {
+            return when (securityMode) {
+                SecurityMode.PIN,
+                SecurityMode.SimPin,
+                SecurityMode.SimPuk -> LockPatternUtils.CREDENTIAL_TYPE_PIN
+                SecurityMode.Password -> LockPatternUtils.CREDENTIAL_TYPE_PASSWORD
+                SecurityMode.Pattern -> LockPatternUtils.CREDENTIAL_TYPE_PATTERN
+                SecurityMode.None -> LockPatternUtils.CREDENTIAL_TYPE_NONE
+                else -> error("Unsupported SecurityMode $securityMode!")
+            }
+        }
+
+        private fun getExpectedCredential(securityMode: SecurityMode): List<Any> {
+            return when (val credentialType = getCurrentCredentialType(securityMode)) {
+                LockPatternUtils.CREDENTIAL_TYPE_PIN -> listOf(1, 2, 3, 4)
+                LockPatternUtils.CREDENTIAL_TYPE_PASSWORD -> "password".toList()
+                LockPatternUtils.CREDENTIAL_TYPE_PATTERN -> PATTERN.toCells()
+                else -> error("Unsupported credential type $credentialType!")
+            }
+        }
+
+        private fun LockscreenCredential.matches(expectedCredential: List<Any>): Boolean {
+            @Suppress("UNCHECKED_CAST")
+            return when {
+                isPin ->
+                    credential.map { byte -> byte.toInt().toChar() - '0' } == expectedCredential
+                isPassword -> credential.map { byte -> byte.toInt().toChar() } == expectedCredential
+                isPattern ->
+                    credential.contentEquals(
+                        LockPatternUtils.patternToByteArray(
+                            expectedCredential as List<LockPatternView.Cell>
+                        )
+                    )
+                else -> error("Unsupported credential type $type!")
+            }
+        }
+
+        private fun List<AuthenticationMethodModel.Pattern.PatternCoordinate>.toCells():
+            List<LockPatternView.Cell> {
+            return map { coordinate -> LockPatternView.Cell.of(coordinate.y, coordinate.x) }
+        }
     }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
index f6cbb07..6309740 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
@@ -48,7 +48,7 @@
     override val isKeyguardShowing: Flow<Boolean> = _isKeyguardShowing
 
     private val _isKeyguardUnlocked = MutableStateFlow(false)
-    override val isKeyguardUnlocked: Flow<Boolean> = _isKeyguardUnlocked
+    override val isKeyguardUnlocked: StateFlow<Boolean> = _isKeyguardUnlocked.asStateFlow()
 
     private val _isKeyguardOccluded = MutableStateFlow(false)
     override val isKeyguardOccluded: Flow<Boolean> = _isKeyguardOccluded
@@ -68,6 +68,9 @@
     private val _isDreamingWithOverlay = MutableStateFlow(false)
     override val isDreamingWithOverlay: Flow<Boolean> = _isDreamingWithOverlay
 
+    private val _isActiveDreamLockscreenHosted = MutableStateFlow(false)
+    override val isActiveDreamLockscreenHosted: StateFlow<Boolean> = _isActiveDreamLockscreenHosted
+
     private val _dozeAmount = MutableStateFlow(0f)
     override val linearDozeAmount: Flow<Float> = _dozeAmount
 
@@ -155,6 +158,10 @@
         _isDreamingWithOverlay.value = isDreaming
     }
 
+    override fun setIsActiveDreamLockscreenHosted(isLockscreenHosted: Boolean) {
+        _isActiveDreamLockscreenHosted.value = isLockscreenHosted
+    }
+
     fun setDozeAmount(dozeAmount: Float) {
         _dozeAmount.value = dozeAmount
     }
@@ -187,6 +194,10 @@
         _statusBarState.value = state
     }
 
+    fun setKeyguardUnlocked(isUnlocked: Boolean) {
+        _isKeyguardUnlocked.value = isUnlocked
+    }
+
     override fun isUdfpsSupported(): Boolean {
         return _isUdfpsSupported.value
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt
index 0b6e2a2..47e1daf4 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt
@@ -16,29 +16,41 @@
 
 package com.android.systemui.scene
 
-import com.android.keyguard.KeyguardSecurityModel.SecurityMode
+import android.content.pm.UserInfo
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.authentication.data.repository.AuthenticationRepository
-import com.android.systemui.authentication.data.repository.AuthenticationRepositoryImpl
 import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
-import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository.Companion.toSecurityMode
 import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
 import com.android.systemui.bouncer.data.repository.BouncerRepository
+import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
 import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
 import com.android.systemui.bouncer.ui.viewmodel.BouncerViewModel
+import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.data.repository.FakeCommandQueue
 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
+import com.android.systemui.keyguard.data.repository.KeyguardRepository
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
 import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
+import com.android.systemui.keyguard.shared.model.WakeSleepReason
+import com.android.systemui.keyguard.shared.model.WakefulnessModel
+import com.android.systemui.keyguard.shared.model.WakefulnessState
 import com.android.systemui.scene.data.repository.SceneContainerRepository
 import com.android.systemui.scene.domain.interactor.SceneInteractor
 import com.android.systemui.scene.shared.model.SceneContainerConfig
+import com.android.systemui.scene.shared.model.SceneContainerNames
 import com.android.systemui.scene.shared.model.SceneKey
 import com.android.systemui.user.data.repository.FakeUserRepository
+import com.android.systemui.user.data.repository.UserRepository
 import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.test.StandardTestDispatcher
-import kotlinx.coroutines.test.TestDispatcher
 import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.currentTime
 
 /**
  * Utilities for creating scene container framework related repositories, interactors, and
@@ -48,24 +60,37 @@
 class SceneTestUtils(
     test: SysuiTestCase,
 ) {
-    val testDispatcher: TestDispatcher by lazy { StandardTestDispatcher() }
-    val testScope: TestScope by lazy { TestScope(testDispatcher) }
-    private var securityMode: SecurityMode =
-        FakeAuthenticationRepository.DEFAULT_AUTHENTICATION_METHOD.toSecurityMode()
+    val testDispatcher = StandardTestDispatcher()
+    val testScope = TestScope(testDispatcher)
+    val featureFlags =
+        FakeFeatureFlags().apply {
+            set(Flags.SCENE_CONTAINER, true)
+            set(Flags.FACE_AUTH_REFACTOR, false)
+        }
+    private val userRepository: UserRepository by lazy {
+        FakeUserRepository().apply {
+            val users = listOf(UserInfo(/* id=  */ 0, "name", /* flags= */ 0))
+            setUserInfos(users)
+            runBlocking { setSelectedUserInfo(users.first()) }
+        }
+    }
+
     val authenticationRepository: FakeAuthenticationRepository by lazy {
         FakeAuthenticationRepository(
-            delegate =
-                AuthenticationRepositoryImpl(
-                    applicationScope = applicationScope(),
-                    getSecurityMode = { securityMode },
-                    backgroundDispatcher = testDispatcher,
-                    userRepository = FakeUserRepository(),
-                    lockPatternUtils = mock(),
-                    keyguardRepository = FakeKeyguardRepository(),
-                ),
-            onSecurityModeChanged = { securityMode = it },
+            currentTime = { testScope.currentTime },
         )
     }
+    val keyguardRepository: FakeKeyguardRepository by lazy {
+        FakeKeyguardRepository().apply {
+            setWakefulnessModel(
+                WakefulnessModel(
+                    WakefulnessState.AWAKE,
+                    WakeSleepReason.OTHER,
+                    WakeSleepReason.OTHER,
+                )
+            )
+        }
+    }
     private val context = test.context
 
     fun fakeSceneContainerRepository(
@@ -105,7 +130,7 @@
         )
     }
 
-    fun authenticationRepository(): AuthenticationRepository {
+    fun authenticationRepository(): FakeAuthenticationRepository {
         return authenticationRepository
     }
 
@@ -115,6 +140,23 @@
         return AuthenticationInteractor(
             applicationScope = applicationScope(),
             repository = repository,
+            backgroundDispatcher = testDispatcher,
+            userRepository = userRepository,
+            clock = mock { whenever(elapsedRealtime()).thenAnswer { testScope.currentTime } }
+        )
+    }
+
+    fun keyguardRepository(): FakeKeyguardRepository {
+        return keyguardRepository
+    }
+
+    fun keyguardInteractor(repository: KeyguardRepository): KeyguardInteractor {
+        return KeyguardInteractor(
+            repository = repository,
+            commandQueue = FakeCommandQueue(),
+            featureFlags = featureFlags,
+            bouncerRepository = FakeKeyguardBouncerRepository(),
+            configurationRepository = FakeConfigurationRepository()
         )
     }
 
@@ -128,6 +170,7 @@
             repository = BouncerRepository(),
             authenticationInteractor = authenticationInteractor,
             sceneInteractor = sceneInteractor,
+            featureFlags = featureFlags,
             containerName = CONTAINER_1,
         )
     }
@@ -144,13 +187,13 @@
                         return bouncerInteractor
                     }
                 },
+            featureFlags = featureFlags,
             containerName = CONTAINER_1,
         )
     }
 
     fun lockScreenSceneInteractor(
         authenticationInteractor: AuthenticationInteractor,
-        sceneInteractor: SceneInteractor,
         bouncerInteractor: BouncerInteractor,
     ): LockscreenSceneInteractor {
         return LockscreenSceneInteractor(
@@ -162,7 +205,6 @@
                         return bouncerInteractor
                     }
                 },
-            sceneInteractor = sceneInteractor,
             containerName = CONTAINER_1,
         )
     }
@@ -172,7 +214,7 @@
     }
 
     companion object {
-        const val CONTAINER_1 = "container1"
+        const val CONTAINER_1 = SceneContainerNames.SYSTEM_UI_DEFAULT
         const val CONTAINER_2 = "container2"
     }
 }
diff --git a/services/Android.bp b/services/Android.bp
index b0a0e5e..453f572 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -159,6 +159,7 @@
         "services.coverage",
         "services.credentials",
         "services.devicepolicy",
+        "services.flags",
         "services.midi",
         "services.musicsearch",
         "services.net",
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
index f6948e9..effd873 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
@@ -172,14 +172,18 @@
     }
 
     @Override
-    public void onPerformScaleAction(int displayId, float scale) {
+    public void onPerformScaleAction(int displayId, float scale, boolean updatePersistence) {
         if (getFullScreenMagnificationController().isActivated(displayId)) {
             getFullScreenMagnificationController().setScaleAndCenter(displayId, scale,
                     Float.NaN, Float.NaN, false, MAGNIFICATION_GESTURE_HANDLER_ID);
-            getFullScreenMagnificationController().persistScale(displayId);
+            if (updatePersistence) {
+                getFullScreenMagnificationController().persistScale(displayId);
+            }
         } else if (getWindowMagnificationMgr().isWindowMagnifierEnabled(displayId)) {
             getWindowMagnificationMgr().setScale(displayId, scale);
-            getWindowMagnificationMgr().persistScale(displayId);
+            if (updatePersistence) {
+                getWindowMagnificationMgr().persistScale(displayId);
+            }
         }
     }
 
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
index d96682c..816f22f 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
@@ -167,8 +167,9 @@
          *
          * @param displayId The logical display id.
          * @param scale the target scale, or {@link Float#NaN} to leave unchanged
+         * @param updatePersistence whether the scale should be persisted
          */
-        void onPerformScaleAction(int displayId, float scale);
+        void onPerformScaleAction(int displayId, float scale, boolean updatePersistence);
 
         /**
          * Called when the accessibility action is performed.
@@ -977,14 +978,15 @@
         }
 
         @Override
-        public void onPerformScaleAction(int displayId, float scale) {
+        public void onPerformScaleAction(int displayId, float scale, boolean updatePersistence) {
             if (mTrace.isA11yTracingEnabledForTypes(
                     FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK)) {
                 mTrace.logTrace(TAG + "ConnectionCallback.onPerformScaleAction",
                         FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK,
-                        "displayId=" + displayId + ";scale=" + scale);
+                        "displayId=" + displayId + ";scale=" + scale
+                                + ";updatePersistence=" + updatePersistence);
             }
-            mCallback.onPerformScaleAction(displayId, scale);
+            mCallback.onPerformScaleAction(displayId, scale, updatePersistence);
         }
 
         @Override
diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java
index 82af382..7557071 100644
--- a/services/autofill/java/com/android/server/autofill/Helper.java
+++ b/services/autofill/java/com/android/server/autofill/Helper.java
@@ -20,6 +20,8 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.app.ActivityManager;
 import android.app.assist.AssistStructure;
 import android.app.assist.AssistStructure.ViewNode;
 import android.app.assist.AssistStructure.WindowNode;
@@ -40,6 +42,7 @@
 import android.view.WindowManager;
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillValue;
+import android.widget.RemoteViews;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.ArrayUtils;
@@ -50,6 +53,8 @@
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicBoolean;
+
 
 public final class Helper {
 
@@ -83,6 +88,44 @@
         throw new UnsupportedOperationException("contains static members only");
     }
 
+    private static boolean checkRemoteViewUriPermissions(
+            @UserIdInt int userId, @NonNull RemoteViews rView) {
+        final AtomicBoolean permissionsOk = new AtomicBoolean(true);
+
+        rView.visitUris(uri -> {
+            int uriOwnerId = android.content.ContentProvider.getUserIdFromUri(uri);
+            boolean allowed = uriOwnerId == userId;
+            permissionsOk.set(allowed && permissionsOk.get());
+        });
+
+        return permissionsOk.get();
+    }
+
+    /**
+     * Checks the URI permissions of the remote view,
+     * to see if the current userId is able to access it.
+     *
+     * Returns the RemoteView that is passed if user is able, null otherwise.
+     *
+     * TODO: instead of returning a null remoteview when
+     * the current userId cannot access an URI,
+     * return a new RemoteView with the URI removed.
+     */
+    public static @Nullable RemoteViews sanitizeRemoteView(RemoteViews rView) {
+        if (rView == null) return null;
+
+        int userId = ActivityManager.getCurrentUser();
+
+        boolean ok = checkRemoteViewUriPermissions(userId, rView);
+        if (!ok) {
+            Slog.w(TAG,
+                    "sanitizeRemoteView() user: " + userId
+                    + " tried accessing resource that does not belong to them");
+        }
+        return (ok ? rView : null);
+    }
+
+
     @Nullable
     static AutofillId[] toArray(@Nullable ArraySet<AutofillId> set) {
         if (set == null) return null;
diff --git a/services/autofill/java/com/android/server/autofill/ui/DialogFillUi.java b/services/autofill/java/com/android/server/autofill/ui/DialogFillUi.java
index dbeb624..fa414e3 100644
--- a/services/autofill/java/com/android/server/autofill/ui/DialogFillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/DialogFillUi.java
@@ -53,6 +53,7 @@
 
 import com.android.internal.R;
 import com.android.server.autofill.AutofillManagerService;
+import com.android.server.autofill.Helper;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -208,7 +209,8 @@
     }
 
     private void setHeader(View decor, FillResponse response) {
-        final RemoteViews presentation = response.getDialogHeader();
+        final RemoteViews presentation =
+                Helper.sanitizeRemoteView(response.getDialogHeader());
         if (presentation == null) {
             return;
         }
@@ -243,9 +245,10 @@
     }
 
     private void initialAuthenticationLayout(View decor, FillResponse response) {
-        RemoteViews presentation = response.getDialogPresentation();
+        RemoteViews presentation = Helper.sanitizeRemoteView(
+                response.getDialogPresentation());
         if (presentation == null) {
-            presentation = response.getPresentation();
+            presentation = Helper.sanitizeRemoteView(response.getPresentation());
         }
         if (presentation == null) {
             throw new RuntimeException("No presentation for fill dialog authentication");
@@ -289,7 +292,8 @@
             final Dataset dataset = response.getDatasets().get(i);
             final int index = dataset.getFieldIds().indexOf(focusedViewId);
             if (index >= 0) {
-                RemoteViews presentation = dataset.getFieldDialogPresentation(index);
+                RemoteViews presentation = Helper.sanitizeRemoteView(
+                        dataset.getFieldDialogPresentation(index));
                 if (presentation == null) {
                     if (sDebug) {
                         Slog.w(TAG, "not displaying UI on field " + focusedViewId + " because "
diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
index 129ce72..cdfe7bb 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -148,8 +148,9 @@
 
         final LayoutInflater inflater = LayoutInflater.from(mContext);
 
-        final RemoteViews headerPresentation = response.getHeader();
-        final RemoteViews footerPresentation = response.getFooter();
+        final RemoteViews headerPresentation = Helper.sanitizeRemoteView(response.getHeader());
+        final RemoteViews footerPresentation = Helper.sanitizeRemoteView(response.getFooter());
+
         final ViewGroup decor;
         if (mFullScreen) {
             decor = (ViewGroup) inflater.inflate(R.layout.autofill_dataset_picker_fullscreen, null);
@@ -227,6 +228,9 @@
             ViewGroup container = decor.findViewById(R.id.autofill_dataset_picker);
             final View content;
             try {
+                if (Helper.sanitizeRemoteView(response.getPresentation()) == null) {
+                    throw new RuntimeException("Permission error accessing RemoteView");
+                }
                 content = response.getPresentation().applyWithTheme(
                         mContext, decor, interceptionHandler, mThemeId);
                 container.addView(content);
@@ -306,7 +310,8 @@
                 final Dataset dataset = response.getDatasets().get(i);
                 final int index = dataset.getFieldIds().indexOf(focusedViewId);
                 if (index >= 0) {
-                    final RemoteViews presentation = dataset.getFieldPresentation(index);
+                    final RemoteViews presentation = Helper.sanitizeRemoteView(
+                            dataset.getFieldPresentation(index));
                     if (presentation == null) {
                         Slog.w(TAG, "not displaying UI on field " + focusedViewId + " because "
                                 + "service didn't provide a presentation for it on " + dataset);
diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
index f035d07..70382f1 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -384,8 +384,7 @@
             return false;
         }
         writeLog(MetricsEvent.AUTOFILL_SAVE_CUSTOM_DESCRIPTION);
-
-        final RemoteViews template = customDescription.getPresentation();
+        final RemoteViews template = Helper.sanitizeRemoteView(customDescription.getPresentation());
         if (template == null) {
             Slog.w(TAG, "No remote view on custom description");
             return false;
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 578f520..c30b522 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -4984,7 +4984,10 @@
             p.setDataPosition(0);
             Bundle simulateBundle = p.readBundle();
             p.recycle();
-            Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT, Intent.class);
+            Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT);
+            if (intent != null && intent.getClass() != Intent.class) {
+                return false;
+            }
             Intent simulateIntent = simulateBundle.getParcelable(AccountManager.KEY_INTENT,
                     Intent.class);
             if (intent == null) {
diff --git a/services/core/java/com/android/server/am/BroadcastProcessQueue.java b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
index 0fcec6f..fc8175b 100644
--- a/services/core/java/com/android/server/am/BroadcastProcessQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
@@ -1144,9 +1144,6 @@
             } else if (mProcessPersistent) {
                 mRunnableAt = runnableAt + constants.DELAY_PERSISTENT_PROC_MILLIS;
                 mRunnableAtReason = REASON_PERSISTENT;
-            } else if (UserHandle.isCore(uid)) {
-                mRunnableAt = runnableAt;
-                mRunnableAtReason = REASON_CORE_UID;
             } else if (mCountOrdered > 0) {
                 mRunnableAt = runnableAt;
                 mRunnableAtReason = REASON_CONTAINS_ORDERED;
@@ -1193,6 +1190,9 @@
                 // is already cached, they'll be deferred on the line above
                 mRunnableAt = runnableAt;
                 mRunnableAtReason = REASON_CONTAINS_RESULT_TO;
+            } else if (UserHandle.isCore(uid)) {
+                mRunnableAt = runnableAt;
+                mRunnableAtReason = REASON_CORE_UID;
             } else {
                 mRunnableAt = runnableAt + constants.DELAY_NORMAL_MILLIS;
                 mRunnableAtReason = REASON_NORMAL;
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index e51fc0a..a682c85 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -1713,6 +1713,11 @@
         }
     }
 
+    private boolean isScreenOnOrAnimatingLocked(ProcessStateRecord state) {
+        return mService.mWakefulness.get() == PowerManagerInternal.WAKEFULNESS_AWAKE
+                || state.isRunningRemoteAnimation();
+    }
+
     @GuardedBy({"mService", "mProcLock"})
     private boolean computeOomAdjLSP(ProcessRecord app, int cachedAdj,
             ProcessRecord topApp, boolean doingAll, long now, boolean cycleReEval,
@@ -1794,8 +1799,7 @@
                 state.setSystemNoUi(false);
             }
             if (!state.isSystemNoUi()) {
-                if (mService.mWakefulness.get() == PowerManagerInternal.WAKEFULNESS_AWAKE
-                        || state.isRunningRemoteAnimation()) {
+                if (isScreenOnOrAnimatingLocked(state)) {
                     // screen on or animating, promote UI
                     state.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT_UI);
                     state.setCurrentSchedulingGroup(SCHED_GROUP_TOP_APP);
@@ -3281,8 +3285,10 @@
                 } else {
                     setThreadPriority(app.getPid(), THREAD_PRIORITY_TOP_APP_BOOST);
                 }
-                initialSchedGroup = SCHED_GROUP_TOP_APP;
-                initialProcState = PROCESS_STATE_TOP;
+                if (isScreenOnOrAnimatingLocked(state)) {
+                    initialSchedGroup = SCHED_GROUP_TOP_APP;
+                    initialProcState = PROCESS_STATE_TOP;
+                }
                 initialCapability = PROCESS_CAPABILITY_ALL;
                 initialCached = false;
             } catch (Exception e) {
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index c5776d8..acd9771 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -1827,6 +1827,7 @@
 
             if (debuggableFlag) {
                 runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
+                runtimeFlags |= Zygote.DEBUG_ENABLE_PTRACE;
                 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
                 // Also turn on CheckJNI for debuggable apps. It's quite
                 // awkward to turn on otherwise.
diff --git a/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java b/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java
index f84a58c..472c1f5 100644
--- a/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java
+++ b/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java
@@ -22,7 +22,6 @@
 import android.util.IndentingPrintWriter;
 import android.util.Slog;
 import android.util.SparseArray;
-import android.view.Display;
 import android.view.DisplayAddress;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -38,6 +37,7 @@
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.math.BigInteger;
 
 import javax.xml.datatype.DatatypeConfigurationException;
 
@@ -115,13 +115,16 @@
                 Slog.i(TAG, "Display layout config not found: " + configFile);
                 return;
             }
-            int leadDisplayId = Display.DEFAULT_DISPLAY;
             for (com.android.server.display.config.layout.Layout l : layouts.getLayout()) {
                 final int state = l.getState().intValue();
                 final Layout layout = createLayout(state);
                 for (com.android.server.display.config.layout.Display d: l.getDisplay()) {
                     assert layout != null;
                     int position = getPosition(d.getPosition());
+                    BigInteger leadDisplayPhysicalId = d.getLeadDisplayAddress();
+                    DisplayAddress leadDisplayAddress = leadDisplayPhysicalId == null ? null
+                            : DisplayAddress.fromPhysicalDisplayId(
+                                    leadDisplayPhysicalId.longValue());
                     layout.createDisplayLocked(
                             DisplayAddress.fromPhysicalDisplayId(d.getAddress().longValue()),
                             d.isDefaultDisplay(),
@@ -129,11 +132,12 @@
                             d.getDisplayGroup(),
                             mIdProducer,
                             position,
-                            leadDisplayId,
+                            leadDisplayAddress,
                             d.getBrightnessThrottlingMapId(),
                             d.getRefreshRateZoneId(),
                             d.getRefreshRateThermalThrottlingMapId());
                 }
+                layout.postProcessLocked();
             }
         } catch (IOException | DatatypeConfigurationException | XmlPullParserException e) {
             Slog.e(TAG, "Encountered an error while reading/parsing display layout config file: "
diff --git a/services/core/java/com/android/server/display/layout/Layout.java b/services/core/java/com/android/server/display/layout/Layout.java
index b55d7d5..d9ec3de 100644
--- a/services/core/java/com/android/server/display/layout/Layout.java
+++ b/services/core/java/com/android/server/display/layout/Layout.java
@@ -22,6 +22,8 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.text.TextUtils;
+import android.util.ArraySet;
 import android.util.Slog;
 import android.view.DisplayAddress;
 
@@ -77,7 +79,7 @@
             DisplayIdProducer idProducer) {
         createDisplayLocked(address, /* isDefault= */ true, /* isEnabled= */ true,
                 DEFAULT_DISPLAY_GROUP_NAME, idProducer, POSITION_UNKNOWN,
-                NO_LEAD_DISPLAY, /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayAddress= */ null, /* brightnessThrottlingMapId= */ null,
                 /* refreshRateZoneId= */ null, /* refreshRateThermalThrottlingMapId= */ null);
     }
 
@@ -90,19 +92,20 @@
      * @param displayGroupName Name of the display group to which the display is assigned.
      * @param idProducer Produces the logical display id.
      * @param position Indicates the position this display is facing in this layout.
-     * @param leadDisplayId Display that this one follows (-1 if none).
+     * @param leadDisplayAddress Address of a display that this one follows ({@code null} if none).
      * @param brightnessThrottlingMapId Name of which brightness throttling policy should be used.
      * @param refreshRateZoneId Layout limited refresh rate zone name.
      * @param refreshRateThermalThrottlingMapId Name of which refresh rate throttling
      *                                          policy should be used.
-
+     *
      * @exception IllegalArgumentException When a default display owns a display group other than
      *            DEFAULT_DISPLAY_GROUP.
      */
     public void createDisplayLocked(
             @NonNull DisplayAddress address, boolean isDefault, boolean isEnabled,
-            String displayGroupName, DisplayIdProducer idProducer, int position, int leadDisplayId,
-            String brightnessThrottlingMapId, @Nullable String refreshRateZoneId,
+            String displayGroupName, DisplayIdProducer idProducer, int position,
+            @Nullable DisplayAddress leadDisplayAddress, String brightnessThrottlingMapId,
+            @Nullable String refreshRateZoneId,
             @Nullable String refreshRateThermalThrottlingMapId) {
         if (contains(address)) {
             Slog.w(TAG, "Attempting to add second definition for display-device: " + address);
@@ -115,21 +118,27 @@
             return;
         }
 
-        // Assign a logical display ID and create the new display.
-        // Note that the logical display ID is saved into the layout, so when switching between
-        // different layouts, a logical display can be destroyed and later recreated with the
-        // same logical display ID.
         if (displayGroupName == null) {
             displayGroupName = DEFAULT_DISPLAY_GROUP_NAME;
         }
         if (isDefault && !displayGroupName.equals(DEFAULT_DISPLAY_GROUP_NAME)) {
             throw new IllegalArgumentException("Default display should own DEFAULT_DISPLAY_GROUP");
         }
+        if (isDefault && leadDisplayAddress != null) {
+            throw new IllegalArgumentException("Default display cannot have a lead display");
+        }
+        if (address.equals(leadDisplayAddress)) {
+            throw new IllegalArgumentException("Lead display address cannot be the same as display "
+                    + " address");
+        }
+        // Assign a logical display ID and create the new display.
+        // Note that the logical display ID is saved into the layout, so when switching between
+        // different layouts, a logical display can be destroyed and later recreated with the
+        // same logical display ID.
         final int logicalDisplayId = idProducer.getId(isDefault);
-        leadDisplayId = isDefault ? NO_LEAD_DISPLAY : leadDisplayId;
 
         final Display display = new Display(address, logicalDisplayId, isEnabled, displayGroupName,
-                brightnessThrottlingMapId, position, leadDisplayId, refreshRateZoneId,
+                brightnessThrottlingMapId, position, leadDisplayAddress, refreshRateZoneId,
                 refreshRateThermalThrottlingMapId);
 
         mDisplays.add(display);
@@ -146,6 +155,43 @@
     }
 
     /**
+     * Applies post-processing to displays to make sure the information of each display is
+     * up-to-date.
+     *
+     * <p>At creation of a display, lead display is specified by display address. At post
+     * processing, we convert it to logical display ID.
+     */
+    public void postProcessLocked() {
+        for (int i = 0; i < mDisplays.size(); i++) {
+            Display display = mDisplays.get(i);
+            if (display.getLogicalDisplayId() == DEFAULT_DISPLAY) {
+                display.setLeadDisplayId(NO_LEAD_DISPLAY);
+                continue;
+            }
+            DisplayAddress leadDisplayAddress = display.getLeadDisplayAddress();
+            if (leadDisplayAddress == null) {
+                display.setLeadDisplayId(NO_LEAD_DISPLAY);
+                continue;
+            }
+            Display leadDisplay = getByAddress(leadDisplayAddress);
+            if (leadDisplay == null) {
+                throw new IllegalArgumentException("Cannot find a lead display whose address is "
+                        + leadDisplayAddress);
+            }
+            if (!TextUtils.equals(display.getDisplayGroupName(),
+                    leadDisplay.getDisplayGroupName())) {
+                throw new IllegalArgumentException("Lead display(" + leadDisplay + ") should be in "
+                        + "the same display group of the display(" + display + ")");
+            }
+            if (hasCyclicLeadDisplay(display)) {
+                throw new IllegalArgumentException("Display(" + display + ") has a cyclic lead "
+                        + "display");
+            }
+            display.setLeadDisplayId(leadDisplay.getLogicalDisplayId());
+        }
+    }
+
+    /**
      * @param address The address to check.
      *
      * @return True if the specified address is used in this layout.
@@ -208,6 +254,20 @@
         return mDisplays.size();
     }
 
+    private boolean hasCyclicLeadDisplay(Display display) {
+        ArraySet<Display> visited = new ArraySet<>();
+
+        while (display != null) {
+            if (visited.contains(display)) {
+                return true;
+            }
+            visited.add(display);
+            DisplayAddress leadDisplayAddress = display.getLeadDisplayAddress();
+            display = leadDisplayAddress == null ? null : getByAddress(leadDisplayAddress);
+        }
+        return false;
+    }
+
     /**
      * Describes how a {@link LogicalDisplay} is built from {@link DisplayDevice}s.
      */
@@ -240,8 +300,9 @@
         @Nullable
         private final String mThermalBrightnessThrottlingMapId;
 
-        // The ID of the lead display that this display will follow in a layout. -1 means no lead.
-        private final int mLeadDisplayId;
+        // The address of the lead display that is specified in display-layout-configuration.
+        @Nullable
+        private final DisplayAddress mLeadDisplayAddress;
 
         // Refresh rate zone id for specific layout
         @Nullable
@@ -250,9 +311,13 @@
         @Nullable
         private final String mThermalRefreshRateThrottlingMapId;
 
+        // The ID of the lead display that this display will follow in a layout. -1 means no lead.
+        // This is determined using {@code mLeadDisplayAddress}.
+        private int mLeadDisplayId;
+
         private Display(@NonNull DisplayAddress address, int logicalDisplayId, boolean isEnabled,
                 @NonNull String displayGroupName, String brightnessThrottlingMapId, int position,
-                int leadDisplayId, @Nullable String refreshRateZoneId,
+                @Nullable DisplayAddress leadDisplayAddress, @Nullable String refreshRateZoneId,
                 @Nullable String refreshRateThermalThrottlingMapId) {
             mAddress = address;
             mLogicalDisplayId = logicalDisplayId;
@@ -260,9 +325,10 @@
             mDisplayGroupName = displayGroupName;
             mPosition = position;
             mThermalBrightnessThrottlingMapId = brightnessThrottlingMapId;
+            mLeadDisplayAddress = leadDisplayAddress;
             mRefreshRateZoneId = refreshRateZoneId;
             mThermalRefreshRateThrottlingMapId = refreshRateThermalThrottlingMapId;
-            mLeadDisplayId = leadDisplayId;
+            mLeadDisplayId = NO_LEAD_DISPLAY;
         }
 
         @Override
@@ -276,6 +342,7 @@
                     + ", mThermalBrightnessThrottlingMapId: " + mThermalBrightnessThrottlingMapId
                     + ", mRefreshRateZoneId: " + mRefreshRateZoneId
                     + ", mLeadDisplayId: " + mLeadDisplayId
+                    + ", mLeadDisplayAddress: " + mLeadDisplayAddress
                     + ", mThermalRefreshRateThrottlingMapId: " + mThermalRefreshRateThrottlingMapId
                     + "}";
         }
@@ -297,6 +364,7 @@
                     otherDisplay.mThermalBrightnessThrottlingMapId)
                     && Objects.equals(otherDisplay.mRefreshRateZoneId, this.mRefreshRateZoneId)
                     && this.mLeadDisplayId == otherDisplay.mLeadDisplayId
+                    && Objects.equals(mLeadDisplayAddress, otherDisplay.mLeadDisplayAddress)
                     && Objects.equals(mThermalRefreshRateThrottlingMapId,
                     otherDisplay.mThermalRefreshRateThrottlingMapId);
         }
@@ -309,9 +377,10 @@
             result = 31 * result + mLogicalDisplayId;
             result = 31 * result + mDisplayGroupName.hashCode();
             result = 31 * result + mAddress.hashCode();
-            result = 31 * result + mThermalBrightnessThrottlingMapId.hashCode();
+            result = 31 * result + Objects.hashCode(mThermalBrightnessThrottlingMapId);
             result = 31 * result + Objects.hashCode(mRefreshRateZoneId);
             result = 31 * result + mLeadDisplayId;
+            result = 31 * result + Objects.hashCode(mLeadDisplayAddress);
             result = 31 * result + Objects.hashCode(mThermalRefreshRateThrottlingMapId);
             return result;
         }
@@ -360,8 +429,20 @@
             return mLeadDisplayId;
         }
 
+        /**
+         * @return Display address of the display that this one follows.
+         */
+        @Nullable
+        public DisplayAddress getLeadDisplayAddress() {
+            return mLeadDisplayAddress;
+        }
+
         public String getRefreshRateThermalThrottlingMapId() {
             return mThermalRefreshRateThrottlingMapId;
         }
+
+        private void setLeadDisplayId(int id) {
+            mLeadDisplayId = id;
+        }
     }
 }
diff --git a/services/core/java/com/android/server/input/KeyboardLayoutManager.java b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
index 3ac1594..63fded1 100644
--- a/services/core/java/com/android/server/input/KeyboardLayoutManager.java
+++ b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
@@ -28,6 +28,7 @@
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
+import android.app.settings.SettingsEnums;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -1168,6 +1169,8 @@
 
         if (targetDevice != null) {
             intent.putExtra(Settings.EXTRA_INPUT_DEVICE_IDENTIFIER, targetDevice.getIdentifier());
+            intent.putExtra(
+                    Settings.EXTRA_ENTRYPOINT, SettingsEnums.KEYBOARD_CONFIGURED_NOTIFICATION);
         }
 
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
diff --git a/services/core/java/com/android/server/notification/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java
index 030c96e..bfc4f53 100644
--- a/services/core/java/com/android/server/notification/ConditionProviders.java
+++ b/services/core/java/com/android/server/notification/ConditionProviders.java
@@ -251,6 +251,11 @@
     }
 
     @Override
+    protected boolean allowRebindForParentUser() {
+        return true;
+    }
+
+    @Override
     protected String getRequiredPermission() {
         return null;
     }
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 12fc263..5dd958b 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -1371,7 +1371,9 @@
     protected void rebindServices(boolean forceRebind, int userToRebind) {
         if (DEBUG) Slog.d(TAG, "rebindServices " + forceRebind + " " + userToRebind);
         IntArray userIds = mUserProfiles.getCurrentProfileIds();
-        if (userToRebind != USER_ALL) {
+        boolean rebindAllCurrentUsers = mUserProfiles.isProfileUser(userToRebind)
+                && allowRebindForParentUser();
+        if (userToRebind != USER_ALL && !rebindAllCurrentUsers) {
             userIds = new IntArray(1);
             userIds.add(userToRebind);
         }
@@ -1758,6 +1760,13 @@
         return true;
     }
 
+    /**
+     * Returns true if services in the parent user should be rebound
+     *  when rebindServices is called with a profile userId.
+     * Must be false for NotificationAssistants.
+     */
+    protected abstract boolean allowRebindForParentUser();
+
     public class ManagedServiceInfo implements IBinder.DeathRecipient {
         public IInterface service;
         public ComponentName component;
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index e0e6410..3325ddd 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -4443,7 +4443,7 @@
                     // Remove background token before returning notification to untrusted app, this
                     // ensures the app isn't able to perform background operations that are
                     // associated with notification interactions.
-                    notification.setAllowlistToken(null);
+                    notification.clearAllowlistToken();
                     return new StatusBarNotification(
                             sbn.getPackageName(),
                             sbn.getOpPkg(),
@@ -7008,7 +7008,7 @@
      */
     private boolean canBeNonDismissible(ApplicationInfo ai, Notification notification) {
         return notification.isMediaNotification() || isEnterpriseExempted(ai)
-                || isCallNotification(ai.packageName, ai.uid, notification)
+                || notification.isStyle(Notification.CallStyle.class)
                 || isDefaultSearchSelectorPackage(ai.packageName);
     }
 
@@ -10504,6 +10504,11 @@
         }
 
         @Override
+        protected boolean allowRebindForParentUser() {
+            return false;
+        }
+
+        @Override
         protected String getRequiredPermission() {
             // only signature/privileged apps can be bound.
             return android.Manifest.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE;
@@ -11048,6 +11053,11 @@
         }
 
         @Override
+        protected boolean allowRebindForParentUser() {
+            return true;
+        }
+
+        @Override
         public void onPackagesChanged(boolean removingPackage, String[] pkgList, int[] uidList) {
             super.onPackagesChanged(removingPackage, pkgList, uidList);
 
diff --git a/services/core/java/com/android/server/notification/NotificationRecordLogger.java b/services/core/java/com/android/server/notification/NotificationRecordLogger.java
index 5ca882c..b015a72 100644
--- a/services/core/java/com/android/server/notification/NotificationRecordLogger.java
+++ b/services/core/java/com/android/server/notification/NotificationRecordLogger.java
@@ -30,6 +30,7 @@
 import android.os.Bundle;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.NotificationStats;
+import android.util.Log;
 
 import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags;
 import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags;
@@ -48,6 +49,8 @@
  */
 interface NotificationRecordLogger {
 
+    static final String TAG = "NotificationRecordLogger";
+
     // The high-level interface used by clients.
 
     /**
@@ -228,51 +231,40 @@
                 @NotificationStats.DismissalSurface int surface) {
             // Shouldn't be possible to get a non-dismissed notification here.
             if (surface == NotificationStats.DISMISSAL_NOT_DISMISSED) {
-                if (NotificationManagerService.DBG) {
-                    throw new IllegalArgumentException("Unexpected surface " + surface);
-                }
+                Log.wtf(TAG, "Unexpected surface: " + surface + " with reason " + reason);
                 return INVALID;
             }
-            // Most cancel reasons do not have a meaningful surface. Reason codes map directly
-            // to NotificationCancelledEvent codes.
-            if (surface == NotificationStats.DISMISSAL_OTHER) {
+
+            // User cancels have a meaningful surface, which we differentiate by. See b/149038335
+            // for caveats.
+            if (reason == REASON_CANCEL) {
+                switch (surface) {
+                    case NotificationStats.DISMISSAL_PEEK:
+                        return NOTIFICATION_CANCEL_USER_PEEK;
+                    case NotificationStats.DISMISSAL_AOD:
+                        return NOTIFICATION_CANCEL_USER_AOD;
+                    case NotificationStats.DISMISSAL_SHADE:
+                        return NOTIFICATION_CANCEL_USER_SHADE;
+                    case NotificationStats.DISMISSAL_BUBBLE:
+                        return NOTIFICATION_CANCEL_USER_BUBBLE;
+                    case NotificationStats.DISMISSAL_LOCKSCREEN:
+                        return NOTIFICATION_CANCEL_USER_LOCKSCREEN;
+                    case NotificationStats.DISMISSAL_OTHER:
+                        return NOTIFICATION_CANCEL_USER_OTHER;
+                    default:
+                        Log.wtf(TAG, "Unexpected surface: " + surface + " with reason " + reason);
+                        return INVALID;
+                }
+            } else {
                 if ((REASON_CLICK <= reason) && (reason <= REASON_CLEAR_DATA)) {
                     return NotificationCancelledEvent.values()[reason];
                 }
                 if (reason == REASON_ASSISTANT_CANCEL) {
                     return NotificationCancelledEvent.NOTIFICATION_CANCEL_ASSISTANT;
                 }
-                if (NotificationManagerService.DBG) {
-                    throw new IllegalArgumentException("Unexpected cancel reason " + reason);
-                }
+                Log.wtf(TAG, "Unexpected reason: " + reason + " with surface " + surface);
                 return INVALID;
             }
-            // User cancels have a meaningful surface, which we differentiate by. See b/149038335
-            // for caveats.
-            if (reason != REASON_CANCEL) {
-                if (NotificationManagerService.DBG) {
-                    throw new IllegalArgumentException("Unexpected cancel with surface " + reason);
-                }
-                return INVALID;
-            }
-            switch (surface) {
-                case NotificationStats.DISMISSAL_PEEK:
-                    return NOTIFICATION_CANCEL_USER_PEEK;
-                case NotificationStats.DISMISSAL_AOD:
-                    return NOTIFICATION_CANCEL_USER_AOD;
-                case NotificationStats.DISMISSAL_SHADE:
-                    return NOTIFICATION_CANCEL_USER_SHADE;
-                case NotificationStats.DISMISSAL_BUBBLE:
-                    return NOTIFICATION_CANCEL_USER_BUBBLE;
-                case NotificationStats.DISMISSAL_LOCKSCREEN:
-                    return NOTIFICATION_CANCEL_USER_LOCKSCREEN;
-                default:
-                    if (NotificationManagerService.DBG) {
-                        throw new IllegalArgumentException("Unexpected surface for user-dismiss "
-                                + reason);
-                    }
-                    return INVALID;
-            }
         }
     }
 
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 838a0fb..1818d25 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -30,9 +30,9 @@
 import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_CHANNEL_GROUP_PREFERENCES;
 import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES;
 import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES;
-import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__NOT_REQUESTED;
-import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__GRANTED;
 import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__DENIED;
+import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__GRANTED;
+import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__NOT_REQUESTED;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -164,6 +164,9 @@
     static final int DEFAULT_BUBBLE_PREFERENCE = BUBBLE_PREFERENCE_NONE;
     static final boolean DEFAULT_MEDIA_NOTIFICATION_FILTERING = true;
 
+    private static final int NOTIFICATION_UPDATE_LOG_SUBTYPE_FROM_APP = 0;
+    private static final int NOTIFICATION_UPDATE_LOG_SUBTYPE_FROM_USER = 1;
+
     /**
      * Default value for what fields are user locked. See {@link LockableAppFields} for all lockable
      * fields.
@@ -1110,12 +1113,20 @@
             if (!channel.equals(updatedChannel)) {
                 // only log if there are real changes
                 MetricsLogger.action(getChannelLog(updatedChannel, pkg)
-                        .setSubtype(fromUser ? 1 : 0));
+                        .setSubtype(fromUser ? NOTIFICATION_UPDATE_LOG_SUBTYPE_FROM_USER
+                                : NOTIFICATION_UPDATE_LOG_SUBTYPE_FROM_APP));
                 mNotificationChannelLogger.logNotificationChannelModified(updatedChannel, uid, pkg,
                         NotificationChannelLogger.getLoggingImportance(channel), fromUser);
                 changed = true;
             }
 
+            if (fromUser && SystemUiSystemPropertiesFlags.getResolver().isEnabled(
+                    NotificationFlags.PROPAGATE_CHANNEL_UPDATES_TO_CONVERSATIONS)) {
+                updateChildrenConversationChannels(r, channel, updatedChannel);
+                // No need to update changed or needsDndChanged as the child channel(s) cannot be
+                // relevantly affected without the parent channel already having been.
+            }
+
             if (updatedChannel.canBypassDnd() != mAreChannelsBypassingDnd
                     || channel.getImportance() != updatedChannel.getImportance()) {
                 needsDndChange = true;
@@ -1130,6 +1141,101 @@
         }
     }
 
+    /**
+     * Updates conversation channels after user changes to their parent channel. See
+     * {@link #maybeUpdateChildConversationChannel}.
+     */
+    @GuardedBy("mPackagePreferences")
+    private void updateChildrenConversationChannels(@NonNull PackagePreferences packagePreferences,
+            @NonNull NotificationChannel oldParent, @NonNull NotificationChannel updatedParent) {
+        if (oldParent.equals(updatedParent)) {
+            return;
+        }
+        if (oldParent.isConversation()) {
+            return; // Can't have children.
+        }
+        for (NotificationChannel channel : packagePreferences.channels.values()) {
+            // Include deleted -- otherwise they will have old settings if later resurrected.
+            // Include demoted -- still attached to their parents.
+            if (channel.isConversation()
+                    && oldParent.getId().equals(channel.getParentChannelId())) {
+                maybeUpdateChildConversationChannel(packagePreferences.pkg, packagePreferences.uid,
+                        channel, oldParent, updatedParent);
+            }
+        }
+    }
+
+    /**
+     * Apply the diff between {@code oldParent} and {@code updatedParent} to the child
+     * {@code conversation} channel. Only fields that are not locked on the conversation channel
+     * (see {@link NotificationChannel#LOCKABLE_FIELDS }) will be updated (so that we don't override
+     * previous explicit user choices).
+     *
+     * <p>This will also log the change as if it was {@code fromUser=true}.
+     */
+    @GuardedBy("mPackagePreferences")
+    private void maybeUpdateChildConversationChannel(String pkg, int uid,
+            @NonNull NotificationChannel conversation, @NonNull NotificationChannel oldParent,
+            @NonNull NotificationChannel updatedParent) {
+        boolean changed = false;
+        int oldLoggingImportance = NotificationChannelLogger.getLoggingImportance(conversation);
+
+        if ((conversation.getUserLockedFields() & NotificationChannel.USER_LOCKED_PRIORITY) == 0
+                && oldParent.canBypassDnd() != updatedParent.canBypassDnd()) {
+            conversation.setBypassDnd(updatedParent.canBypassDnd());
+            changed = true;
+        }
+        if ((conversation.getUserLockedFields() & NotificationChannel.USER_LOCKED_VISIBILITY) == 0
+                && oldParent.getLockscreenVisibility()
+                != updatedParent.getLockscreenVisibility()) {
+            conversation.setLockscreenVisibility(updatedParent.getLockscreenVisibility());
+            changed = true;
+        }
+        if ((conversation.getUserLockedFields() & NotificationChannel.USER_LOCKED_IMPORTANCE) == 0
+                && oldParent.getImportance() != updatedParent.getImportance()) {
+            conversation.setImportance(updatedParent.getImportance());
+            changed = true;
+        }
+        if ((conversation.getUserLockedFields() & NotificationChannel.USER_LOCKED_LIGHTS) == 0
+                && (oldParent.shouldShowLights() != updatedParent.shouldShowLights()
+                || oldParent.getLightColor() != updatedParent.getLightColor())) {
+            conversation.enableLights(updatedParent.shouldShowLights());
+            conversation.setLightColor(updatedParent.getLightColor());
+            changed = true;
+        }
+        if ((conversation.getUserLockedFields() & NotificationChannel.USER_LOCKED_SOUND) == 0
+                && !Objects.equals(oldParent.getSound(), updatedParent.getSound())) {
+            conversation.setSound(updatedParent.getSound(), updatedParent.getAudioAttributes());
+            changed = true;
+        }
+        if ((conversation.getUserLockedFields() & NotificationChannel.USER_LOCKED_VIBRATION) == 0
+                && (!Arrays.equals(oldParent.getVibrationPattern(),
+                updatedParent.getVibrationPattern())
+                || oldParent.shouldVibrate() != updatedParent.shouldVibrate())) {
+            // enableVibration must be 2nd because setVibrationPattern may toggle it.
+            conversation.setVibrationPattern(updatedParent.getVibrationPattern());
+            conversation.enableVibration(updatedParent.shouldVibrate());
+            changed = true;
+        }
+        if ((conversation.getUserLockedFields() & NotificationChannel.USER_LOCKED_SHOW_BADGE) == 0
+                && oldParent.canShowBadge() != updatedParent.canShowBadge()) {
+            conversation.setShowBadge(updatedParent.canShowBadge());
+            changed = true;
+        }
+        if ((conversation.getUserLockedFields() & NotificationChannel.USER_LOCKED_ALLOW_BUBBLE) == 0
+                && oldParent.getAllowBubbles() != updatedParent.getAllowBubbles()) {
+            conversation.setAllowBubbles(updatedParent.getAllowBubbles());
+            changed = true;
+        }
+
+        if (changed) {
+            MetricsLogger.action(getChannelLog(conversation, pkg).setSubtype(
+                    NOTIFICATION_UPDATE_LOG_SUBTYPE_FROM_USER));
+            mNotificationChannelLogger.logNotificationChannelModified(conversation, uid, pkg,
+                    oldLoggingImportance, /* fromUser= */ true);
+        }
+    }
+
     @Override
     public NotificationChannel getNotificationChannel(String pkg, int uid, String channelId,
             boolean includeDeleted) {
@@ -1838,8 +1944,8 @@
         }
     }
 
-    @VisibleForTesting
-    void lockFieldsForUpdateLocked(NotificationChannel original, NotificationChannel update) {
+    private void lockFieldsForUpdateLocked(NotificationChannel original,
+            NotificationChannel update) {
         if (original.canBypassDnd() != update.canBypassDnd()) {
             update.lockFields(NotificationChannel.USER_LOCKED_PRIORITY);
         }
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 279a480..5cfbcaa 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -3211,8 +3211,10 @@
                             minLinearBrightness, maxLinearBrightness);
                     mDisplayManager.setBrightness(screenDisplayId, adjustedLinearBrightness);
 
-                    startActivityAsUser(new Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG),
-                            UserHandle.CURRENT_OR_SELF);
+                    Intent intent = new Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG);
+                    intent.addFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION);
+                    intent.putExtra(EXTRA_FROM_BRIGHTNESS_KEY, true);
+                    startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
                 }
                 return true;
             case KeyEvent.KEYCODE_KEYBOARD_BACKLIGHT_DOWN:
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
index b216578..188f4d0 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
@@ -280,7 +280,7 @@
         // visible window.
         if (Process.isSdkSandboxUid(realCallingUid)) {
             int realCallingSdkSandboxUidToAppUid =
-                    Process.getAppUidForSdkSandboxUid(UserHandle.getAppId(realCallingUid));
+                    Process.getAppUidForSdkSandboxUid(realCallingUid);
 
             if (mService.hasActiveVisibleWindow(realCallingSdkSandboxUidToAppUid)) {
                 return logStartAllowedAndReturnCode(BAL_ALLOW_SDK_SANDBOX,
diff --git a/services/core/java/com/android/server/wm/ContentRecorder.java b/services/core/java/com/android/server/wm/ContentRecorder.java
index 6a7e764..2ecbf8a 100644
--- a/services/core/java/com/android/server/wm/ContentRecorder.java
+++ b/services/core/java/com/android/server/wm/ContentRecorder.java
@@ -166,7 +166,7 @@
                                     + "%d to new bounds %s and/or orientation %d.",
                             mDisplayContent.getDisplayId(), recordedContentBounds,
                             recordedContentOrientation);
-                    updateMirroredSurface(mDisplayContent.mWmService.mTransactionFactory.get(),
+                    updateMirroredSurface(mRecordedWindowContainer.getSyncTransaction(),
                             recordedContentBounds, surfaceSize);
                 } else {
                     // If the surface removed, do nothing. We will handle this via onDisplayChanged
@@ -325,6 +325,7 @@
                         .reparent(mDisplayContent.getOverlayLayer(), null);
         // Retrieve the size of the DisplayArea to mirror.
         updateMirroredSurface(transaction, mRecordedWindowContainer.getBounds(), surfaceSize);
+        transaction.apply();
 
         // Notify the client about the visibility of the mirrored region, now that we have begun
         // capture.
@@ -481,8 +482,7 @@
                 .setMatrix(mRecordedSurface, scale, 0 /* dtdx */, 0 /* dtdy */, scale)
                 // Position needs to be updated when the mirrored DisplayArea has changed, since
                 // the content will no longer be centered in the output surface.
-                .setPosition(mRecordedSurface, shiftedX /* x */, shiftedY /* y */)
-                .apply();
+                .setPosition(mRecordedSurface, shiftedX /* x */, shiftedY /* y */);
         mLastRecordedBounds = new Rect(recordedContentBounds);
         // Request to notify the client about the resize.
         mMediaProjectionManager.notifyActiveProjectionCapturedContentResized(
diff --git a/services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java b/services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java
index 2b6b62e..4180cd2 100644
--- a/services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java
@@ -39,10 +39,11 @@
             TAG_WITH_CLASS_NAME ? "DesktopModeLaunchParamsModifier" : TAG_ATM;
     private static final boolean DEBUG = false;
 
-    // Desktop mode feature flag.
-    static final boolean DESKTOP_MODE_SUPPORTED = SystemProperties.getBoolean(
-            "persist.wm.debug.desktop_mode", false) || SystemProperties.getBoolean(
-            "persist.wm.debug.desktop_mode_2", false);
+    // Desktop mode feature flags.
+    private static final boolean DESKTOP_MODE_PROTO1_SUPPORTED =
+            SystemProperties.getBoolean("persist.wm.debug.desktop_mode", false);
+    private static final boolean DESKTOP_MODE_PROTO2_SUPPORTED =
+            SystemProperties.getBoolean("persist.wm.debug.desktop_mode_2", false);
     // Override default freeform task width when desktop mode is enabled. In dips.
     private static final int DESKTOP_MODE_DEFAULT_WIDTH_DP = SystemProperties.getInt(
             "persist.wm.debug.desktop_mode.default_width", 840);
@@ -76,22 +77,37 @@
             appendLog("task null, skipping");
             return RESULT_SKIP;
         }
-        if (phase != PHASE_BOUNDS) {
-            appendLog("not in bounds phase, skipping");
-            return RESULT_SKIP;
-        }
         if (!task.isActivityTypeStandardOrUndefined()) {
             appendLog("not standard or undefined activity type, skipping");
             return RESULT_SKIP;
         }
-        if (!currentParams.mBounds.isEmpty()) {
-            appendLog("currentParams has bounds set, not overriding");
+        if (phase < PHASE_WINDOWING_MODE) {
+            appendLog("not in windowing mode or bounds phase, skipping");
             return RESULT_SKIP;
         }
 
         // Copy over any values
         outParams.set(currentParams);
 
+        // In Proto2, trampoline task launches of an existing background task can result in the
+        // previous windowing mode to be restored even if the desktop mode state has changed.
+        // Let task launches inherit the windowing mode from the source task if available, which
+        // should have the desired windowing mode set by WM Shell. See b/286929122.
+        if (DESKTOP_MODE_PROTO2_SUPPORTED && source != null && source.getTask() != null) {
+            final Task sourceTask = source.getTask();
+            outParams.mWindowingMode = sourceTask.getWindowingMode();
+            appendLog("inherit-from-source=" + outParams.mWindowingMode);
+        }
+
+        if (phase == PHASE_WINDOWING_MODE) {
+            return RESULT_DONE;
+        }
+
+        if (!currentParams.mBounds.isEmpty()) {
+            appendLog("currentParams has bounds set, not overriding");
+            return RESULT_SKIP;
+        }
+
         // Update width and height with default desktop mode values
         float density = (float) task.getConfiguration().densityDpi / DENSITY_DEFAULT;
         final int width = (int) (DESKTOP_MODE_DEFAULT_WIDTH_DP * density + 0.5f);
@@ -123,4 +139,9 @@
     private void outputLog() {
         if (DEBUG) Slog.d(TAG, mLogBuilder.toString());
     }
+
+    /** Whether desktop mode is supported. */
+    static boolean isDesktopModeSupported() {
+        return DESKTOP_MODE_PROTO1_SUPPORTED || DESKTOP_MODE_PROTO2_SUPPORTED;
+    }
 }
diff --git a/services/core/java/com/android/server/wm/LaunchParamsController.java b/services/core/java/com/android/server/wm/LaunchParamsController.java
index e74e5787..91bb8d0 100644
--- a/services/core/java/com/android/server/wm/LaunchParamsController.java
+++ b/services/core/java/com/android/server/wm/LaunchParamsController.java
@@ -64,7 +64,7 @@
     void registerDefaultModifiers(ActivityTaskSupervisor supervisor) {
         // {@link TaskLaunchParamsModifier} handles window layout preferences.
         registerModifier(new TaskLaunchParamsModifier(supervisor));
-        if (DesktopModeLaunchParamsModifier.DESKTOP_MODE_SUPPORTED) {
+        if (DesktopModeLaunchParamsModifier.isDesktopModeSupported()) {
             // {@link DesktopModeLaunchParamsModifier} handles default task size changes
             registerModifier(new DesktopModeLaunchParamsModifier());
         }
diff --git a/services/core/java/com/android/server/wm/LaunchParamsPersister.java b/services/core/java/com/android/server/wm/LaunchParamsPersister.java
index bf511adf0..2394da9 100644
--- a/services/core/java/com/android/server/wm/LaunchParamsPersister.java
+++ b/services/core/java/com/android/server/wm/LaunchParamsPersister.java
@@ -433,7 +433,7 @@
             final byte[] data = saveParamsToXml();
 
             final File launchParamFolder = getLaunchParamFolder(mUserId);
-            if (!launchParamFolder.isDirectory() && !launchParamFolder.mkdirs()) {
+            if (!launchParamFolder.isDirectory() && !launchParamFolder.mkdir()) {
                 Slog.w(TAG, "Failed to create folder for " + mUserId);
                 return;
             }
diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
index fda22ca..7a201a7 100644
--- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java
+++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
@@ -85,6 +85,13 @@
     // TODO(b/288142656): Enable user aspect ratio settings by default.
     private static final boolean DEFAULT_VALUE_ENABLE_USER_ASPECT_RATIO_SETTINGS = false;
 
+    // Whether the letterbox wallpaper style is enabled by default
+    private static final String KEY_ENABLE_LETTERBOX_BACKGROUND_WALLPAPER =
+            "enable_letterbox_background_wallpaper";
+
+    // TODO(b/290048978): Enable wallpaper as default letterbox background.
+    private static final boolean DEFAULT_VALUE_ENABLE_LETTERBOX_BACKGROUND_WALLPAPER = false;
+
     /**
      * Override of aspect ratio for fixed orientation letterboxing that is set via ADB with
      * set-fixed-orientation-letterbox-aspect-ratio or via {@link
@@ -101,9 +108,16 @@
 
     /** Enum for Letterbox background type. */
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef({LETTERBOX_BACKGROUND_SOLID_COLOR, LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND,
-            LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING, LETTERBOX_BACKGROUND_WALLPAPER})
+    @IntDef({LETTERBOX_BACKGROUND_OVERRIDE_UNSET,
+            LETTERBOX_BACKGROUND_SOLID_COLOR,
+            LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND,
+            LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING,
+            LETTERBOX_BACKGROUND_WALLPAPER})
     @interface LetterboxBackgroundType {};
+
+    /** No letterbox background style set. Using the one defined by DeviceConfig. */
+    static final int LETTERBOX_BACKGROUND_OVERRIDE_UNSET = -1;
+
     /** Solid background using color specified in R.color.config_letterboxBackgroundColor. */
     static final int LETTERBOX_BACKGROUND_SOLID_COLOR = 0;
 
@@ -183,14 +197,14 @@
     @Nullable private Integer mLetterboxBackgroundColorResourceIdOverride;
 
     @LetterboxBackgroundType
-    private int mLetterboxBackgroundType;
+    private final int mLetterboxBackgroundType;
 
-    // Blur radius for LETTERBOX_BACKGROUND_WALLPAPER option in mLetterboxBackgroundType.
+    // Blur radius for LETTERBOX_BACKGROUND_WALLPAPER option from getLetterboxBackgroundType().
     // Values <= 0 are ignored and 0 is used instead.
-    private int mLetterboxBackgroundWallpaperBlurRadius;
+    private int mLetterboxBackgroundWallpaperBlurRadiusPx;
 
     // Alpha of a black scrim shown over wallpaper letterbox background when
-    // LETTERBOX_BACKGROUND_WALLPAPER option is selected for mLetterboxBackgroundType.
+    // LETTERBOX_BACKGROUND_WALLPAPER option is returned from getLetterboxBackgroundType().
     // Values < 0 or >= 1 are ignored and 0.0 (transparent) is used instead.
     private float mLetterboxBackgroundWallpaperDarkScrimAlpha;
 
@@ -252,6 +266,11 @@
     // Allows to enable user aspect ratio settings ignoring flags.
     private boolean mUserAppAspectRatioSettingsOverrideEnabled;
 
+    // The override for letterbox background type in case it's different from
+    // LETTERBOX_BACKGROUND_OVERRIDE_UNSET
+    @LetterboxBackgroundType
+    private int mLetterboxBackgroundTypeOverride = LETTERBOX_BACKGROUND_OVERRIDE_UNSET;
+
     // Whether we should use split screen aspect ratio for the activity when camera compat treatment
     // is enabled and activity is connected to the camera in fullscreen.
     private final boolean mIsCameraCompatSplitScreenAspectRatioEnabled;
@@ -294,10 +313,10 @@
 
         mFixedOrientationLetterboxAspectRatio = mContext.getResources().getFloat(
                 R.dimen.config_fixedOrientationLetterboxAspectRatio);
+        mLetterboxBackgroundType = readLetterboxBackgroundTypeFromConfig(mContext);
         mLetterboxActivityCornersRadius = mContext.getResources().getInteger(
                 R.integer.config_letterboxActivityCornersRadius);
-        mLetterboxBackgroundType = readLetterboxBackgroundTypeFromConfig(mContext);
-        mLetterboxBackgroundWallpaperBlurRadius = mContext.getResources().getDimensionPixelSize(
+        mLetterboxBackgroundWallpaperBlurRadiusPx = mContext.getResources().getDimensionPixelSize(
                 R.dimen.config_letterboxBackgroundWallpaperBlurRadius);
         mLetterboxBackgroundWallpaperDarkScrimAlpha = mContext.getResources().getFloat(
                 R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha);
@@ -359,6 +378,8 @@
                         DEFAULT_VALUE_ENABLE_USER_ASPECT_RATIO_SETTINGS,
                         mContext.getResources().getBoolean(
                                 R.bool.config_appCompatUserAppAspectRatioSettingsIsEnabled))
+                .addDeviceConfigEntry(KEY_ENABLE_LETTERBOX_BACKGROUND_WALLPAPER,
+                        DEFAULT_VALUE_ENABLE_LETTERBOX_BACKGROUND_WALLPAPER, /* enabled */ true)
                 .build();
     }
 
@@ -497,25 +518,39 @@
     }
 
     /**
-     * Gets {@link LetterboxBackgroundType} specified in {@link
-     * com.android.internal.R.integer.config_letterboxBackgroundType} or over via ADB command.
+     * Gets {@link LetterboxBackgroundType} specified via ADB command or the default one.
      */
     @LetterboxBackgroundType
     int getLetterboxBackgroundType() {
-        return mLetterboxBackgroundType;
+        return mLetterboxBackgroundTypeOverride != LETTERBOX_BACKGROUND_OVERRIDE_UNSET
+                ? mLetterboxBackgroundTypeOverride
+                : getDefaultLetterboxBackgroundType();
     }
 
-    /** Sets letterbox background type. */
-    void setLetterboxBackgroundType(@LetterboxBackgroundType int backgroundType) {
-        mLetterboxBackgroundType = backgroundType;
+    /** Overrides the letterbox background type. */
+    void setLetterboxBackgroundTypeOverride(@LetterboxBackgroundType int backgroundType) {
+        mLetterboxBackgroundTypeOverride = backgroundType;
     }
 
     /**
-     * Resets cletterbox background type to {@link
-     * com.android.internal.R.integer.config_letterboxBackgroundType}.
+     * Resets letterbox background type value depending on the
+     * {@link #KEY_ENABLE_LETTERBOX_BACKGROUND_WALLPAPER} built time and runtime flags.
+     *
+     * <p>If enabled, the letterbox background type value is set toZ
+     * {@link #LETTERBOX_BACKGROUND_WALLPAPER}. When disabled the letterbox background type value
+     * comes from {@link R.integer.config_letterboxBackgroundType}.
      */
     void resetLetterboxBackgroundType() {
-        mLetterboxBackgroundType = readLetterboxBackgroundTypeFromConfig(mContext);
+        mLetterboxBackgroundTypeOverride = LETTERBOX_BACKGROUND_OVERRIDE_UNSET;
+    }
+
+    // Returns KEY_ENABLE_LETTERBOX_BACKGROUND_WALLPAPER if the DeviceConfig flag is enabled
+    // or the value in com.android.internal.R.integer.config_letterboxBackgroundType if the flag
+    // is disabled.
+    @LetterboxBackgroundType
+    private int getDefaultLetterboxBackgroundType() {
+        return mDeviceConfig.getFlagValue(KEY_ENABLE_LETTERBOX_BACKGROUND_WALLPAPER)
+                ? LETTERBOX_BACKGROUND_WALLPAPER : mLetterboxBackgroundType;
     }
 
     /** Returns a string representing the given {@link LetterboxBackgroundType}. */
@@ -548,7 +583,7 @@
 
     /**
      * Overrides alpha of a black scrim shown over wallpaper for {@link
-     * #LETTERBOX_BACKGROUND_WALLPAPER} option in {@link mLetterboxBackgroundType}.
+     * #LETTERBOX_BACKGROUND_WALLPAPER} option returned from {@link getLetterboxBackgroundType()}.
      *
      * <p>If given value is < 0 or >= 1, both it and a value of {@link
      * com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha} are ignored
@@ -575,33 +610,33 @@
     }
 
     /**
-     * Overrides blur radius for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option in
-     * {@link mLetterboxBackgroundType}.
+     * Overrides blur radius for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option from
+     * {@link getLetterboxBackgroundType()}.
      *
      * <p> If given value <= 0, both it and a value of {@link
      * com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius} are ignored
      * and 0 is used instead.
      */
-    void setLetterboxBackgroundWallpaperBlurRadius(int radius) {
-        mLetterboxBackgroundWallpaperBlurRadius = radius;
+    void setLetterboxBackgroundWallpaperBlurRadiusPx(int radius) {
+        mLetterboxBackgroundWallpaperBlurRadiusPx = radius;
     }
 
     /**
-     * Resets blur raidus for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option in {@link
-     * mLetterboxBackgroundType} to {@link
+     * Resets blur raidus for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option returned by {@link
+     * getLetterboxBackgroundType()} to {@link
      * com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius}.
      */
-    void resetLetterboxBackgroundWallpaperBlurRadius() {
-        mLetterboxBackgroundWallpaperBlurRadius = mContext.getResources().getDimensionPixelSize(
+    void resetLetterboxBackgroundWallpaperBlurRadiusPx() {
+        mLetterboxBackgroundWallpaperBlurRadiusPx = mContext.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius);
     }
 
     /**
-     * Gets blur raidus for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option in {@link
-     * mLetterboxBackgroundType}.
+     * Gets blur raidus for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option returned by {@link
+     * getLetterboxBackgroundType()}.
      */
-    int getLetterboxBackgroundWallpaperBlurRadius() {
-        return mLetterboxBackgroundWallpaperBlurRadius;
+    int getLetterboxBackgroundWallpaperBlurRadiusPx() {
+        return mLetterboxBackgroundWallpaperBlurRadiusPx;
     }
 
     /*
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index a816838..39f7570 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -894,7 +894,7 @@
                         this::shouldLetterboxHaveRoundedCorners,
                         this::getLetterboxBackgroundColor,
                         this::hasWallpaperBackgroundForLetterbox,
-                        this::getLetterboxWallpaperBlurRadius,
+                        this::getLetterboxWallpaperBlurRadiusPx,
                         this::getLetterboxWallpaperDarkScrimAlpha,
                         this::handleHorizontalDoubleTap,
                         this::handleVerticalDoubleTap,
@@ -1315,7 +1315,7 @@
             case LETTERBOX_BACKGROUND_WALLPAPER:
                 if (hasWallpaperBackgroundForLetterbox()) {
                     // Color is used for translucent scrim that dims wallpaper.
-                    return Color.valueOf(Color.BLACK);
+                    return mLetterboxConfiguration.getLetterboxBackgroundColor();
                 }
                 Slog.w(TAG, "Wallpaper option is selected for letterbox background but "
                         + "blur is not supported by a device or not supported in the current "
@@ -1472,10 +1472,10 @@
                         // Don't use wallpaper as a background if letterboxed for display cutout.
                         && isLetterboxedNotForDisplayCutout(mainWindow)
                         // Check that dark scrim alpha or blur radius are provided
-                        && (getLetterboxWallpaperBlurRadius() > 0
+                        && (getLetterboxWallpaperBlurRadiusPx() > 0
                                 || getLetterboxWallpaperDarkScrimAlpha() > 0)
                         // Check that blur is supported by a device if blur radius is provided.
-                        && (getLetterboxWallpaperBlurRadius() <= 0
+                        && (getLetterboxWallpaperBlurRadiusPx() <= 0
                                 || isLetterboxWallpaperBlurSupported());
         if (mShowWallpaperForLetterboxBackground != wallpaperShouldBeShown) {
             mShowWallpaperForLetterboxBackground = wallpaperShouldBeShown;
@@ -1483,9 +1483,9 @@
         }
     }
 
-    private int getLetterboxWallpaperBlurRadius() {
-        int blurRadius = mLetterboxConfiguration.getLetterboxBackgroundWallpaperBlurRadius();
-        return blurRadius < 0 ? 0 : blurRadius;
+    private int getLetterboxWallpaperBlurRadiusPx() {
+        int blurRadius = mLetterboxConfiguration.getLetterboxBackgroundWallpaperBlurRadiusPx();
+        return Math.max(blurRadius, 0);
     }
 
     private float getLetterboxWallpaperDarkScrimAlpha() {
@@ -1535,7 +1535,7 @@
             pw.println(prefix + "  letterboxBackgroundWallpaperDarkScrimAlpha="
                     + getLetterboxWallpaperDarkScrimAlpha());
             pw.println(prefix + "  letterboxBackgroundWallpaperBlurRadius="
-                    + getLetterboxWallpaperBlurRadius());
+                    + getLetterboxWallpaperBlurRadiusPx());
         }
 
         pw.println(prefix + "  isHorizontalReachabilityEnabled="
diff --git a/services/core/java/com/android/server/wm/TaskPersister.java b/services/core/java/com/android/server/wm/TaskPersister.java
index 29c192c..f882b9b 100644
--- a/services/core/java/com/android/server/wm/TaskPersister.java
+++ b/services/core/java/com/android/server/wm/TaskPersister.java
@@ -509,7 +509,7 @@
 
     private static boolean createParentDirectory(String filePath) {
         File parentDir = new File(filePath).getParentFile();
-        return parentDir.exists() || parentDir.mkdirs();
+        return parentDir.isDirectory() || parentDir.mkdir();
     }
 
     private static class TaskWriteQueueItem implements PersisterQueue.WriteQueueItem {
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 5b3bbd5..db3b267 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -619,6 +619,12 @@
         if (!isInTransientHide(wc)) {
             mSyncEngine.addToSyncSet(mSyncId, wc);
         }
+        if (wc.asWindowToken() != null && wc.asWindowToken().mRoundedCornerOverlay) {
+            // Only need to sync the transaction (SyncSet) without ChangeInfo because cutout and
+            // rounded corner overlay never need animations. Especially their surfaces may be put
+            // in root (null, see WindowToken#makeSurface()) that cannot reparent.
+            return;
+        }
         ChangeInfo info = mChanges.get(wc);
         if (info == null) {
             info = new ChangeInfo(wc);
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 4bc4c26..457a555 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -81,7 +81,9 @@
 import android.graphics.Rect;
 import android.os.Debug;
 import android.os.IBinder;
+import android.os.RemoteException;
 import android.os.Trace;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Pair;
 import android.util.Pools;
@@ -174,6 +176,9 @@
      */
     protected SparseArray<InsetsSourceProvider> mInsetsSourceProviders = null;
 
+    @Nullable
+    private ArrayMap<IBinder, DeathRecipient> mInsetsOwnerDeathRecipientMap;
+
     // List of children for this window container. List is in z-order as the children appear on
     // screen with the top-most window container at the tail of the list.
     protected final WindowList<E> mChildren = new WindowList<E>();
@@ -419,11 +424,12 @@
      * Adds an {@link InsetsFrameProvider} which describes what insets should be provided to
      * this {@link WindowContainer} and its children.
      *
-     * @param provider describes the insets types and the frames.
+     * @param provider describes the insets type and the frame.
+     * @param owner owns the insets source which only exists when the owner is alive.
      */
-    void addLocalInsetsFrameProvider(InsetsFrameProvider provider) {
-        if (provider == null) {
-            throw new IllegalArgumentException("Insets type not specified.");
+    void addLocalInsetsFrameProvider(InsetsFrameProvider provider, IBinder owner) {
+        if (provider == null || owner == null) {
+            throw new IllegalArgumentException("Insets provider or owner not specified.");
         }
         if (mDisplayContent == null) {
             // This is possible this container is detached when WM shell is responding to a previous
@@ -432,10 +438,26 @@
             Slog.w(TAG, "Can't add insets frame provider when detached. " + this);
             return;
         }
+
+        if (mInsetsOwnerDeathRecipientMap == null) {
+            mInsetsOwnerDeathRecipientMap = new ArrayMap<>();
+        }
+        DeathRecipient deathRecipient = mInsetsOwnerDeathRecipientMap.get(owner);
+        if (deathRecipient == null) {
+            deathRecipient = new DeathRecipient(owner);
+            try {
+                owner.linkToDeath(deathRecipient, 0);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Failed to add source for " + provider + " since the owner has died.");
+                return;
+            }
+            mInsetsOwnerDeathRecipientMap.put(owner, deathRecipient);
+        }
+        final int id = provider.getId();
+        deathRecipient.addSourceId(id);
         if (mLocalInsetsSources == null) {
             mLocalInsetsSources = new SparseArray<>();
         }
-        final int id = provider.getId();
         if (mLocalInsetsSources.get(id) != null) {
             if (DEBUG) {
                 Slog.d(TAG, "The local insets source for this " + provider
@@ -448,27 +470,77 @@
         mDisplayContent.getInsetsStateController().updateAboveInsetsState(true);
     }
 
-    void removeLocalInsetsFrameProvider(InsetsFrameProvider provider) {
-        if (provider == null) {
-            throw new IllegalArgumentException("Insets type not specified.");
-        }
-        if (mLocalInsetsSources == null) {
-            return;
+    private class DeathRecipient implements IBinder.DeathRecipient {
+
+        private final IBinder mOwner;
+        private final ArraySet<Integer> mSourceIds = new ArraySet<>();
+
+        DeathRecipient(IBinder owner) {
+            mOwner = owner;
         }
 
-        final int id = provider.getId();
-        if (mLocalInsetsSources.get(id) == null) {
-            if (DEBUG) {
-                Slog.d(TAG, "Given " + provider + " doesn't have a local insets source.");
+        void addSourceId(int id) {
+            mSourceIds.add(id);
+        }
+
+        void removeSourceId(int id) {
+            mSourceIds.remove(id);
+        }
+
+        boolean hasSource() {
+            return !mSourceIds.isEmpty();
+        }
+
+        @Override
+        public void binderDied() {
+            synchronized (mWmService.mGlobalLock) {
+                boolean changed = false;
+                for (int i = mSourceIds.size() - 1; i >= 0; i--) {
+                    changed |= removeLocalInsetsSource(mSourceIds.valueAt(i));
+                }
+                mSourceIds.clear();
+                mOwner.unlinkToDeath(this, 0);
+                mInsetsOwnerDeathRecipientMap.remove(mOwner);
+                if (changed && mDisplayContent != null) {
+                    mDisplayContent.getInsetsStateController().updateAboveInsetsState(true);
+                }
             }
-            return;
         }
-        mLocalInsetsSources.remove(id);
+    }
 
-        // Update insets if this window is attached.
-        if (mDisplayContent != null) {
+    void removeLocalInsetsFrameProvider(InsetsFrameProvider provider, IBinder owner) {
+        if (provider == null || owner == null) {
+            throw new IllegalArgumentException("Insets provider or owner not specified.");
+        }
+        final int id = provider.getId();
+        if (removeLocalInsetsSource(id) && mDisplayContent != null) {
             mDisplayContent.getInsetsStateController().updateAboveInsetsState(true);
         }
+        if (mInsetsOwnerDeathRecipientMap == null) {
+            return;
+        }
+        final DeathRecipient deathRecipient = mInsetsOwnerDeathRecipientMap.get(owner);
+        if (deathRecipient == null) {
+            return;
+        }
+        deathRecipient.removeSourceId(id);
+        if (!deathRecipient.hasSource()) {
+            owner.unlinkToDeath(deathRecipient, 0);
+            mInsetsOwnerDeathRecipientMap.remove(owner);
+        }
+    }
+
+    private boolean removeLocalInsetsSource(int id) {
+        if (mLocalInsetsSources == null) {
+            return false;
+        }
+        if (mLocalInsetsSources.removeReturnOld(id) == null) {
+            if (DEBUG) {
+                Slog.d(TAG, "Given id " + Integer.toHexString(id) + " doesn't exist.");
+            }
+            return false;
+        }
+        return true;
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index 05e858d..f4781f9 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -41,6 +41,7 @@
 import android.provider.Settings;
 import android.util.DisplayMetrics;
 import android.util.Pair;
+import android.util.TypedValue;
 import android.view.Display;
 import android.view.IWindow;
 import android.view.IWindowManager;
@@ -728,7 +729,7 @@
             return -1;
         }
         synchronized (mInternal.mGlobalLock) {
-            mLetterboxConfiguration.setLetterboxBackgroundType(backgroundType);
+            mLetterboxConfiguration.setLetterboxBackgroundTypeOverride(backgroundType);
         }
         return 0;
     }
@@ -770,10 +771,10 @@
 
     private int runSetLetterboxBackgroundWallpaperBlurRadius(PrintWriter pw)
             throws RemoteException {
-        final int radius;
+        final int radiusDp;
         try {
             String arg = getNextArgRequired();
-            radius = Integer.parseInt(arg);
+            radiusDp = Integer.parseInt(arg);
         } catch (NumberFormatException  e) {
             getErrPrintWriter().println("Error: blur radius format " + e);
             return -1;
@@ -783,7 +784,9 @@
             return -1;
         }
         synchronized (mInternal.mGlobalLock) {
-            mLetterboxConfiguration.setLetterboxBackgroundWallpaperBlurRadius(radius);
+            final int radiusPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                    radiusDp, mInternal.mContext.getResources().getDisplayMetrics());
+            mLetterboxConfiguration.setLetterboxBackgroundWallpaperBlurRadiusPx(radiusPx);
         }
         return 0;
     }
@@ -1050,7 +1053,7 @@
                         mLetterboxConfiguration.resetLetterboxBackgroundColor();
                         break;
                     case "wallpaperBlurRadius":
-                        mLetterboxConfiguration.resetLetterboxBackgroundWallpaperBlurRadius();
+                        mLetterboxConfiguration.resetLetterboxBackgroundWallpaperBlurRadiusPx();
                         break;
                     case "wallpaperDarkScrimAlpha":
                         mLetterboxConfiguration.resetLetterboxBackgroundWallpaperDarkScrimAlpha();
@@ -1188,7 +1191,7 @@
             mLetterboxConfiguration.resetLetterboxActivityCornersRadius();
             mLetterboxConfiguration.resetLetterboxBackgroundType();
             mLetterboxConfiguration.resetLetterboxBackgroundColor();
-            mLetterboxConfiguration.resetLetterboxBackgroundWallpaperBlurRadius();
+            mLetterboxConfiguration.resetLetterboxBackgroundWallpaperBlurRadiusPx();
             mLetterboxConfiguration.resetLetterboxBackgroundWallpaperDarkScrimAlpha();
             mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier();
             mLetterboxConfiguration.resetIsHorizontalReachabilityEnabled();
@@ -1262,7 +1265,7 @@
             pw.println("    Background color: " + Integer.toHexString(
                     mLetterboxConfiguration.getLetterboxBackgroundColor().toArgb()));
             pw.println("    Wallpaper blur radius: "
-                    + mLetterboxConfiguration.getLetterboxBackgroundWallpaperBlurRadius());
+                    + mLetterboxConfiguration.getLetterboxBackgroundWallpaperBlurRadiusPx());
             pw.println("    Wallpaper dark scrim alpha: "
                     + mLetterboxConfiguration.getLetterboxBackgroundWallpaperDarkScrimAlpha());
             pw.println("Is letterboxing for translucent activities enabled: "
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 31918f4..d1b00a3 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -1090,7 +1090,8 @@
                             + container);
                     break;
                 }
-                container.addLocalInsetsFrameProvider(hop.getInsetsFrameProvider());
+                container.addLocalInsetsFrameProvider(
+                        hop.getInsetsFrameProvider(), hop.getInsetsFrameOwner());
                 break;
             }
             case HIERARCHY_OP_TYPE_REMOVE_INSETS_FRAME_PROVIDER: {
@@ -1100,7 +1101,8 @@
                                     + container);
                     break;
                 }
-                container.removeLocalInsetsFrameProvider(hop.getInsetsFrameProvider());
+                container.removeLocalInsetsFrameProvider(
+                        hop.getInsetsFrameProvider(), hop.getInsetsFrameOwner());
                 break;
             }
             case HIERARCHY_OP_TYPE_SET_ALWAYS_ON_TOP: {
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index e76cbe44..c065cb5 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -971,7 +971,7 @@
 void NativeInputManager::notifyDeviceInteraction(int32_t deviceId, nsecs_t timestamp,
                                                  const std::set<gui::Uid>& uids) {
     static const bool ENABLE_INPUT_DEVICE_USAGE_METRICS =
-            sysprop::InputProperties::enable_input_device_usage_metrics().value_or(false);
+            sysprop::InputProperties::enable_input_device_usage_metrics().value_or(true);
     if (!ENABLE_INPUT_DEVICE_USAGE_METRICS) return;
 
     mInputManager->getMetricsCollector().notifyDeviceInteraction(deviceId, timestamp, uids);
diff --git a/services/core/xsd/display-layout-config/display-layout-config.xsd b/services/core/xsd/display-layout-config/display-layout-config.xsd
index ce022e9..57b5d00 100644
--- a/services/core/xsd/display-layout-config/display-layout-config.xsd
+++ b/services/core/xsd/display-layout-config/display-layout-config.xsd
@@ -53,6 +53,7 @@
             <xs:element name="position" type="xs:string" minOccurs="0" maxOccurs="1" />
             <xs:element name="brightnessThrottlingMapId" type="xs:string" minOccurs="0" maxOccurs="1" />
             <xs:element name="refreshRateThermalThrottlingMapId" type="xs:string" minOccurs="0" />
+            <xs:element name="leadDisplayAddress" type="xs:nonNegativeInteger" minOccurs="0" maxOccurs="1" />
         </xs:sequence>
         <xs:attribute name="enabled" type="xs:boolean" use="optional" />
         <xs:attribute name="defaultDisplay" type="xs:boolean" use="optional" />
diff --git a/services/core/xsd/display-layout-config/schema/current.txt b/services/core/xsd/display-layout-config/schema/current.txt
index 42a800d..2d4f7a4 100644
--- a/services/core/xsd/display-layout-config/schema/current.txt
+++ b/services/core/xsd/display-layout-config/schema/current.txt
@@ -6,6 +6,7 @@
     method public java.math.BigInteger getAddress();
     method public String getBrightnessThrottlingMapId();
     method public String getDisplayGroup();
+    method public java.math.BigInteger getLeadDisplayAddress();
     method public String getPosition();
     method public String getRefreshRateThermalThrottlingMapId();
     method public String getRefreshRateZoneId();
@@ -16,6 +17,7 @@
     method public void setDefaultDisplay(boolean);
     method public void setDisplayGroup(String);
     method public void setEnabled(boolean);
+    method public void setLeadDisplayAddress(java.math.BigInteger);
     method public void setPosition(String);
     method public void setRefreshRateThermalThrottlingMapId(String);
     method public void setRefreshRateZoneId(String);
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
index a1199d9..6747cea 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
@@ -91,8 +91,6 @@
         CredentialManagerService, CredentialManagerServiceImpl> {
 
     private static final String TAG = "CredManSysService";
-    private static final String DEVICE_CONFIG_ENABLE_CREDENTIAL_DESC_API =
-            "enable_credential_description_api";
     private static final String PERMISSION_DENIED_ERROR = "permission_denied";
     private static final String PERMISSION_DENIED_WRITE_SECURE_SETTINGS_ERROR =
             "Caller is missing WRITE_SECURE_SETTINGS permission";
@@ -311,14 +309,7 @@
     }
 
     public static boolean isCredentialDescriptionApiEnabled() {
-        final long origId = Binder.clearCallingIdentity();
-        try {
-            return DeviceConfig.getBoolean(
-                    DeviceConfig.NAMESPACE_CREDENTIAL, DEVICE_CONFIG_ENABLE_CREDENTIAL_DESC_API,
-                    false);
-        } finally {
-            Binder.restoreCallingIdentity(origId);
-        }
+        return true;
     }
 
     @SuppressWarnings("GuardedBy") // ErrorProne requires initiateProviderSessionForRequestLocked
diff --git a/services/flags/Android.bp b/services/flags/Android.bp
new file mode 100644
index 0000000..29d2b9c
--- /dev/null
+++ b/services/flags/Android.bp
@@ -0,0 +1,18 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+java_library_static {
+    name: "services.flags",
+    defaults: ["platform_service_defaults"],
+    srcs: [
+        "java/**/*.java",
+        ":feature_flags_aidl",
+    ],
+    libs: ["services.core"],
+}
diff --git a/services/flags/OWNERS b/services/flags/OWNERS
new file mode 100644
index 0000000..3925b5c
--- /dev/null
+++ b/services/flags/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 1306523
+
+mankoff@google.com
+
+pixel@google.com
+dsandler@android.com
diff --git a/services/flags/java/com/android/server/flags/DynamicFlagBinderDelegate.java b/services/flags/java/com/android/server/flags/DynamicFlagBinderDelegate.java
new file mode 100644
index 0000000..0db3287
--- /dev/null
+++ b/services/flags/java/com/android/server/flags/DynamicFlagBinderDelegate.java
@@ -0,0 +1,280 @@
+/*
+ * 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.flags;
+
+import android.annotation.NonNull;
+import android.flags.IFeatureFlagsCallback;
+import android.flags.SyncableFlag;
+import android.os.Build;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.provider.DeviceConfig;
+import android.util.Slog;
+
+import com.android.internal.os.BackgroundThread;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
+
+/**
+ * Handles DynamicFlags for {@link FeatureFlagsBinder}.
+ *
+ * Dynamic flags are simultaneously simpler and more complicated than process stable flags. We can
+ * return whatever value is last known for a flag is, without too much worry about the flags
+ * changing (they are dynamic after all). However, we have to alert all the relevant clients
+ * about those flag changes, and need to be able to restore to a default value if the flag gets
+ * reset/erased during runtime.
+ */
+class DynamicFlagBinderDelegate {
+
+    private final FlagOverrideStore mFlagStore;
+    private final FlagCache<DynamicFlagData> mDynamicFlags = new FlagCache<>();
+    private final Map<Integer, Set<IFeatureFlagsCallback>> mCallbacks = new HashMap<>();
+    private static final Function<Integer, Set<IFeatureFlagsCallback>> NEW_CALLBACK_SET =
+            k -> new HashSet<>();
+
+    private final DeviceConfig.OnPropertiesChangedListener mDeviceConfigListener =
+            new DeviceConfig.OnPropertiesChangedListener() {
+                @Override
+                public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) {
+                    String ns = properties.getNamespace();
+                    for (String name : properties.getKeyset()) {
+                        // Don't alert for flags we don't care about.
+                        // Don't alert for flags that have been overridden locally.
+                        if (!mDynamicFlags.contains(ns, name) || mFlagStore.contains(ns, name)) {
+                            continue;
+                        }
+                        mFlagChangeCallback.onFlagChanged(
+                                ns, name, properties.getString(name, null));
+                    }
+                }
+            };
+
+    private final FlagOverrideStore.FlagChangeCallback mFlagChangeCallback =
+            (namespace, name, value) -> {
+                // Don't bother with callbacks for non-dynamic flags.
+                if (!mDynamicFlags.contains(namespace, name)) {
+                    return;
+                }
+
+                // Don't bother with callbacks if nothing changed.
+                // Handling erasure (null) is special, as we may be restoring back to a value
+                // we were already at.
+                DynamicFlagData data = mDynamicFlags.getOrNull(namespace, name);
+                if (data == null) {
+                    return;  // shouldn't happen, but better safe than sorry.
+                }
+                if (value == null) {
+                    if (data.getValue().equals(data.getDefaultValue())) {
+                        return;
+                    }
+                    value = data.getDefaultValue();
+                } else if (data.getValue().equals(value)) {
+                    return;
+                }
+                data.setValue(value);
+
+                final Set<IFeatureFlagsCallback> cbCopy;
+                synchronized (mCallbacks) {
+                    cbCopy = new HashSet<>();
+
+                    for (Integer pid : mCallbacks.keySet()) {
+                        if (data.containsPid(pid)) {
+                            cbCopy.addAll(mCallbacks.get(pid));
+                        }
+                    }
+                }
+                SyncableFlag sFlag = new SyncableFlag(namespace, name, value, true);
+                cbCopy.forEach(cb -> {
+                    try {
+                        cb.onFlagChange(sFlag);
+                    } catch (RemoteException e) {
+                        Slog.w(
+                                FeatureFlagsService.TAG,
+                                "Failed to communicate flag change to client.");
+                    }
+                });
+            };
+
+    DynamicFlagBinderDelegate(FlagOverrideStore flagStore) {
+        mFlagStore = flagStore;
+        mFlagStore.setChangeCallback(mFlagChangeCallback);
+    }
+
+    SyncableFlag syncDynamicFlag(int pid, SyncableFlag sf) {
+        if (!sf.isDynamic()) {
+            return sf;
+        }
+
+        String ns = sf.getNamespace();
+        String name = sf.getName();
+
+        // Dynamic flags don't need any special threading or synchronization considerations.
+        // We simply give them whatever the current value is.
+        // However, we do need to keep track of dynamic flags, so that we can alert
+        // about changes coming in from adb, DeviceConfig, or other sources.
+        // And also so that we can keep flags relatively consistent across processes.
+
+        DynamicFlagData data = mDynamicFlags.getOrNull(ns, name);
+        String value = getFlagValue(ns, name, sf.getValue());
+        // DeviceConfig listeners are per-namespace.
+        if (!mDynamicFlags.containsNamespace(ns)) {
+            DeviceConfig.addOnPropertiesChangedListener(
+                    ns, BackgroundThread.getExecutor(), mDeviceConfigListener);
+        }
+        data.addClientPid(pid);
+        data.setValue(value);
+        // Store the default value so that if an override gets erased, we can restore
+        // to something.
+        data.setDefaultValue(sf.getValue());
+
+        return new SyncableFlag(sf.getNamespace(), sf.getName(), value, true);
+    }
+
+
+    void registerCallback(int pid, IFeatureFlagsCallback callback) {
+        // Always add callback so that we don't end up with a possible race/leak.
+        // We remove the callback directly if we fail to call #linkToDeath.
+        // If we tried to add the callback after we linked, then we could end up in a
+        // scenario where we link, then the binder dies, firing our BinderGriever which tries
+        // to remove the callback (which has not yet been added), then finally we add the
+        // callback, creating a leak.
+        Set<IFeatureFlagsCallback> callbacks;
+        synchronized (mCallbacks) {
+            callbacks = mCallbacks.computeIfAbsent(pid, NEW_CALLBACK_SET);
+            callbacks.add(callback);
+        }
+        try {
+            callback.asBinder().linkToDeath(new BinderGriever(pid), 0);
+        } catch (RemoteException e) {
+            Slog.e(
+                    FeatureFlagsService.TAG,
+                    "Failed to link to binder death. Callback not registered.");
+            synchronized (mCallbacks) {
+                callbacks.remove(callback);
+            }
+        }
+    }
+
+    void unregisterCallback(int pid, IFeatureFlagsCallback callback) {
+        // No need to unlink, since the BinderGriever will essentially be a no-op.
+        // We would have to track our BinderGriever's in a map otherwise.
+        synchronized (mCallbacks) {
+            Set<IFeatureFlagsCallback> callbacks =
+                    mCallbacks.computeIfAbsent(pid, NEW_CALLBACK_SET);
+            callbacks.remove(callback);
+        }
+    }
+
+    String getFlagValue(String namespace, String name, String defaultValue) {
+        // If we already have a value cached, just use that.
+        String value = null;
+        DynamicFlagData data = mDynamicFlags.getOrNull(namespace, name);
+        if (data != null) {
+            value = data.getValue();
+        } else {
+            // Put the value in the cache for future reference.
+            data = new DynamicFlagData(namespace, name);
+            mDynamicFlags.setIfChanged(namespace, name, data);
+        }
+        // If we're not in a release build, flags can be overridden locally on device.
+        if (!Build.IS_USER && value == null) {
+            value = mFlagStore.get(namespace, name);
+        }
+        // If we still don't have a value, maybe DeviceConfig does?
+        // Fallback to sf.getValue() here as well.
+        if (value == null) {
+            value = DeviceConfig.getString(namespace, name, defaultValue);
+        }
+
+        return value;
+    }
+
+    private static class DynamicFlagData {
+        private final String mNamespace;
+        private final String mName;
+        private final Set<Integer> mPids = new HashSet<>();
+        private String mValue;
+        private String mDefaultValue;
+
+        private DynamicFlagData(String namespace, String name) {
+            mNamespace = namespace;
+            mName = name;
+        }
+
+        String getValue() {
+            return mValue;
+        }
+
+        void setValue(String value) {
+            mValue = value;
+        }
+
+        String getDefaultValue() {
+            return mDefaultValue;
+        }
+
+        void setDefaultValue(String value) {
+            mDefaultValue = value;
+        }
+
+        void addClientPid(int pid) {
+            mPids.add(pid);
+        }
+
+        boolean containsPid(int pid) {
+            return mPids.contains(pid);
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (other == null || !(other instanceof DynamicFlagData)) {
+                return false;
+            }
+
+            DynamicFlagData o = (DynamicFlagData) other;
+
+            return mName.equals(o.mName) && mNamespace.equals(o.mNamespace)
+                    && mValue.equals(o.mValue) && mDefaultValue.equals(o.mDefaultValue);
+        }
+
+        @Override
+        public int hashCode() {
+            return mName.hashCode() + mNamespace.hashCode()
+              + mValue.hashCode() + mDefaultValue.hashCode();
+        }
+    }
+
+
+    private class BinderGriever implements IBinder.DeathRecipient {
+        private final int mPid;
+
+        private BinderGriever(int pid) {
+            mPid = pid;
+        }
+
+        @Override
+        public void binderDied() {
+            synchronized (mCallbacks) {
+                mCallbacks.remove(mPid);
+            }
+        }
+    }
+}
diff --git a/services/flags/java/com/android/server/flags/FeatureFlagsBinder.java b/services/flags/java/com/android/server/flags/FeatureFlagsBinder.java
new file mode 100644
index 0000000..1fa8532
--- /dev/null
+++ b/services/flags/java/com/android/server/flags/FeatureFlagsBinder.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.flags;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.flags.IFeatureFlags;
+import android.flags.IFeatureFlagsCallback;
+import android.flags.SyncableFlag;
+import android.os.Build;
+import android.os.ParcelFileDescriptor;
+
+import com.android.internal.flags.CoreFlags;
+import com.android.server.flags.FeatureFlagsService.PermissionsChecker;
+
+import java.io.FileOutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+class FeatureFlagsBinder extends IFeatureFlags.Stub {
+    private final FlagOverrideStore mFlagStore;
+    private final FlagsShellCommand mShellCommand;
+    private final FlagCache<String> mFlagCache = new FlagCache<>();
+    private final DynamicFlagBinderDelegate mDynamicFlagDelegate;
+    private final PermissionsChecker mPermissionsChecker;
+
+    FeatureFlagsBinder(
+            FlagOverrideStore flagStore,
+            FlagsShellCommand shellCommand,
+            PermissionsChecker permissionsChecker) {
+        mFlagStore = flagStore;
+        mShellCommand = shellCommand;
+        mDynamicFlagDelegate = new DynamicFlagBinderDelegate(flagStore);
+        mPermissionsChecker = permissionsChecker;
+    }
+
+    @Override
+    public void registerCallback(IFeatureFlagsCallback callback) {
+        mDynamicFlagDelegate.registerCallback(getCallingPid(), callback);
+    }
+
+    @Override
+    public void unregisterCallback(IFeatureFlagsCallback callback) {
+        mDynamicFlagDelegate.unregisterCallback(getCallingPid(), callback);
+    }
+
+    // Note: The internals of this method should be kept in sync with queryFlags
+    // as they both should return identical results. The difference is that this method
+    // caches any values it receives and/or reads, whereas queryFlags does not.
+
+    @Override
+    public List<SyncableFlag> syncFlags(List<SyncableFlag> incomingFlags) {
+        int pid = getCallingPid();
+        List<SyncableFlag> outputFlags = new ArrayList<>();
+
+        boolean hasFullSyncPrivileges = false;
+        SecurityException permissionFailureException = null;
+        try {
+            assertSyncPermission();
+            hasFullSyncPrivileges = true;
+        } catch (SecurityException e) {
+            permissionFailureException = e;
+        }
+
+        for (SyncableFlag sf : incomingFlags) {
+            if (!hasFullSyncPrivileges && !CoreFlags.isCoreFlag(sf)) {
+                throw permissionFailureException;
+            }
+
+            String ns = sf.getNamespace();
+            String name = sf.getName();
+            SyncableFlag outFlag;
+            if (sf.isDynamic()) {
+                outFlag = mDynamicFlagDelegate.syncDynamicFlag(pid, sf);
+            } else {
+                synchronized (mFlagCache) {
+                    String value = mFlagCache.getOrNull(ns, name);
+                    if (value == null) {
+                        String overrideValue = Build.IS_USER ? null : mFlagStore.get(ns, name);
+                        value = overrideValue != null ? overrideValue : sf.getValue();
+                        mFlagCache.setIfChanged(ns, name, value);
+                    }
+                    outFlag = new SyncableFlag(sf.getNamespace(), sf.getName(), value, false);
+                }
+            }
+            outputFlags.add(outFlag);
+        }
+        return outputFlags;
+    }
+
+    @Override
+    public void overrideFlag(SyncableFlag flag) {
+        assertWritePermission();
+        mFlagStore.set(flag.getNamespace(), flag.getName(), flag.getValue());
+    }
+
+    @Override
+    public void resetFlag(SyncableFlag flag) {
+        assertWritePermission();
+        mFlagStore.erase(flag.getNamespace(), flag.getName());
+    }
+
+    @Override
+    public List<SyncableFlag> queryFlags(List<SyncableFlag> incomingFlags) {
+        assertSyncPermission();
+        List<SyncableFlag> outputFlags = new ArrayList<>();
+        for (SyncableFlag sf : incomingFlags) {
+            String ns = sf.getNamespace();
+            String name = sf.getName();
+            String value;
+            String storeValue = mFlagStore.get(ns, name);
+            boolean overridden  = storeValue != null;
+
+            if (sf.isDynamic()) {
+                value = mDynamicFlagDelegate.getFlagValue(ns, name, sf.getValue());
+            } else {
+                value = mFlagCache.getOrNull(ns, name);
+                if (value == null) {
+                    value = Build.IS_USER ? null : storeValue;
+                    if (value == null) {
+                        value = sf.getValue();
+                    }
+                }
+            }
+            outputFlags.add(new SyncableFlag(
+                    sf.getNamespace(), sf.getName(), value, sf.isDynamic(), overridden));
+        }
+
+        return outputFlags;
+    }
+
+    private void assertSyncPermission() {
+        mPermissionsChecker.assertSyncPermission();
+        clearCallingIdentity();
+    }
+
+    private void assertWritePermission() {
+        mPermissionsChecker.assertWritePermission();
+        clearCallingIdentity();
+    }
+
+
+    @SystemApi
+    public int handleShellCommand(
+            @NonNull ParcelFileDescriptor in,
+            @NonNull ParcelFileDescriptor out,
+            @NonNull ParcelFileDescriptor err,
+            @NonNull String[] args) {
+        FileOutputStream fout = new FileOutputStream(out.getFileDescriptor());
+        FileOutputStream ferr = new FileOutputStream(err.getFileDescriptor());
+
+        return mShellCommand.process(args, fout, ferr);
+    }
+}
diff --git a/services/flags/java/com/android/server/flags/FeatureFlagsService.java b/services/flags/java/com/android/server/flags/FeatureFlagsService.java
new file mode 100644
index 0000000..93b9e9e
--- /dev/null
+++ b/services/flags/java/com/android/server/flags/FeatureFlagsService.java
@@ -0,0 +1,113 @@
+/*
+ * 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.flags;
+
+import static android.Manifest.permission.SYNC_FLAGS;
+import static android.Manifest.permission.WRITE_FLAGS;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.flags.FeatureFlags;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.SystemService;
+
+/**
+ * A service that manages syncing {@link android.flags.FeatureFlags} across processes.
+ *
+ * This service holds flags stable for at least the lifetime of a process, meaning that if
+ * a process comes online with a flag set to true, any other process that connects here and
+ * tries to read the same flag will also receive the flag as true. The flag will remain stable
+ * until either all of the interested processes have died, or the device restarts.
+ *
+ * TODO(279054964): Add to dumpsys
+ * @hide
+ */
+public class FeatureFlagsService extends SystemService {
+
+    static final String TAG = "FeatureFlagsService";
+    private final FlagOverrideStore mFlagStore;
+    private final FlagsShellCommand mShellCommand;
+
+    /**
+     * Initializes the system service.
+     *
+     * @param context The system server context.
+     */
+    public FeatureFlagsService(Context context) {
+        super(context);
+        mFlagStore = new FlagOverrideStore(
+                new GlobalSettingsProxy(context.getContentResolver()));
+        mShellCommand = new FlagsShellCommand(mFlagStore);
+    }
+
+    @Override
+    public void onStart() {
+        Slog.d(TAG, "Started Feature Flag Service");
+        FeatureFlagsBinder service = new FeatureFlagsBinder(
+                mFlagStore, mShellCommand, new PermissionsChecker(getContext()));
+        publishBinderService(
+                Context.FEATURE_FLAGS_SERVICE, service);
+        publishLocalService(FeatureFlags.class, new FeatureFlags(service));
+    }
+
+    @Override
+    public void onBootPhase(int phase) {
+        super.onBootPhase(phase);
+
+        if (phase == PHASE_SYSTEM_SERVICES_READY) {
+            // Immediately sync our core flags so that they get locked in. We don't want third-party
+            // apps to override them, and syncing immediately is the easiest way to prevent that.
+            FeatureFlags.getInstance().sync();
+        }
+    }
+
+    /**
+     * Delegate for checking flag permissions.
+     */
+    @VisibleForTesting
+    public static class PermissionsChecker {
+        private final Context mContext;
+
+        @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+        public PermissionsChecker(Context context) {
+            mContext = context;
+        }
+
+        /**
+         * Ensures that the caller has {@link SYNC_FLAGS} permission.
+         */
+        @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+        public void assertSyncPermission() {
+            if (mContext.checkCallingOrSelfPermission(SYNC_FLAGS)
+                    != PackageManager.PERMISSION_GRANTED) {
+                throw new SecurityException(
+                        "Non-core flag queried. Requires SYNC_FLAGS permission!");
+            }
+        }
+
+        /**
+         * Ensures that the caller has {@link WRITE_FLAGS} permission.
+         */
+        @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+        public void assertWritePermission() {
+            if (mContext.checkCallingPermission(WRITE_FLAGS) != PackageManager.PERMISSION_GRANTED) {
+                throw new SecurityException("Requires WRITE_FLAGS permission!");
+            }
+        }
+    }
+}
diff --git a/services/flags/java/com/android/server/flags/FlagCache.java b/services/flags/java/com/android/server/flags/FlagCache.java
new file mode 100644
index 0000000..cee1578
--- /dev/null
+++ b/services/flags/java/com/android/server/flags/FlagCache.java
@@ -0,0 +1,103 @@
+/*
+ * 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.flags;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Function;
+
+/**
+ * Threadsafe cache of values that stores the supplied default on cache miss.
+ *
+ * @param <V> The type of value to store.
+ */
+public class FlagCache<V> {
+    private final Function<String, HashMap<String, V>> mNewHashMap = k -> new HashMap<>();
+
+    // Cache is organized first by namespace, then by name. All values are stored as strings.
+    final Map<String, Map<String, V>> mCache = new HashMap<>();
+
+    FlagCache() {
+    }
+
+    /**
+     * Returns true if the namespace exists in the cache already.
+     */
+    boolean containsNamespace(String namespace) {
+        synchronized (mCache) {
+            return mCache.containsKey(namespace);
+        }
+    }
+
+    /**
+     * Returns true if the value is stored in the cache.
+     */
+    boolean contains(String namespace, String name) {
+        synchronized (mCache) {
+            Map<String, V> nsCache = mCache.get(namespace);
+            return nsCache != null && nsCache.containsKey(name);
+        }
+    }
+
+    /**
+     * Sets the value if it is different from what is currently stored.
+     *
+     * If the value is not set, or the current value is null, it will store the value and
+     * return true.
+     *
+     * @return True if the value was set. False if the value is the same.
+     */
+    boolean setIfChanged(String namespace, String name, V value) {
+        synchronized (mCache) {
+            Map<String, V> nsCache = mCache.computeIfAbsent(namespace, mNewHashMap);
+            V curValue = nsCache.get(name);
+            if (curValue == null || !curValue.equals(value)) {
+                nsCache.put(name, value);
+                return true;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Gets the current value from the cache, setting it if it is currently absent.
+     *
+     * @return The value that is now in the cache after the call to the method.
+     */
+    V getOrSet(String namespace, String name, V defaultValue) {
+        synchronized (mCache) {
+            Map<String, V> nsCache = mCache.computeIfAbsent(namespace, mNewHashMap);
+            V value = nsCache.putIfAbsent(name, defaultValue);
+            return value == null ? defaultValue : value;
+        }
+    }
+
+    /**
+     * Gets the current value from the cache, returning null if not present.
+     *
+     * @return The value that is now in the cache if there is one.
+     */
+    V getOrNull(String namespace, String name) {
+        synchronized (mCache) {
+            Map<String, V> nsCache = mCache.get(namespace);
+            if (nsCache == null) {
+                return null;
+            }
+            return nsCache.get(name);
+        }
+    }
+}
diff --git a/services/flags/java/com/android/server/flags/FlagOverrideStore.java b/services/flags/java/com/android/server/flags/FlagOverrideStore.java
new file mode 100644
index 0000000..b1ddc7e6
--- /dev/null
+++ b/services/flags/java/com/android/server/flags/FlagOverrideStore.java
@@ -0,0 +1,122 @@
+/*
+ * 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.flags;
+
+import android.database.Cursor;
+import android.provider.Settings;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Persistent storage for the {@link FeatureFlagsService}.
+ *
+ * The implementation stores data in Settings.<store> (generally {@link Settings.Global}
+ * is expected).
+ */
+@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+public class FlagOverrideStore {
+    private static final String KEYNAME_PREFIX = "flag|";
+    private static final String NAMESPACE_NAME_SEPARATOR = ".";
+
+    private final SettingsProxy mSettingsProxy;
+
+    private FlagChangeCallback mCallback;
+
+    FlagOverrideStore(SettingsProxy settingsProxy) {
+        mSettingsProxy = settingsProxy;
+    }
+
+    void setChangeCallback(FlagChangeCallback callback) {
+        mCallback = callback;
+    }
+
+    /** Returns true if a non-null value is in the store. */
+    boolean contains(String namespace, String name) {
+        return get(namespace, name) != null;
+    }
+
+    /** Put a value in the store. */
+    @VisibleForTesting
+    public void set(String namespace, String name, String value) {
+        mSettingsProxy.putString(getPropName(namespace, name), value);
+        mCallback.onFlagChanged(namespace, name, value);
+    }
+
+    /** Read a value out of the store. */
+    @VisibleForTesting
+    public String get(String namespace, String name) {
+        return mSettingsProxy.getString(getPropName(namespace, name));
+    }
+
+    /** Erase a value from the store. */
+    @VisibleForTesting
+    public void erase(String namespace, String name) {
+        set(namespace, name, null);
+    }
+
+    Map<String, Map<String, String>> getFlags() {
+        return getFlagsForNamespace(null);
+    }
+
+    Map<String, Map<String, String>> getFlagsForNamespace(String namespace) {
+        Cursor c = mSettingsProxy.getContentResolver().query(
+                Settings.Global.CONTENT_URI,
+                new String[]{Settings.NameValueTable.NAME, Settings.NameValueTable.VALUE},
+                null, // Doesn't support a "LIKE" query
+                null,
+                null
+        );
+
+        if (c == null) {
+            return Map.of();
+        }
+        int keynamePrefixLength = KEYNAME_PREFIX.length();
+        Map<String, Map<String, String>> results = new HashMap<>();
+        while (c.moveToNext()) {
+            String key = c.getString(0);
+            if (!key.startsWith(KEYNAME_PREFIX)
+                    || key.indexOf(NAMESPACE_NAME_SEPARATOR, keynamePrefixLength) < 0) {
+                continue;
+            }
+            String value = c.getString(1);
+            if (value == null || value.isEmpty()) {
+                continue;
+            }
+            String ns = key.substring(keynamePrefixLength, key.indexOf(NAMESPACE_NAME_SEPARATOR));
+            if (namespace != null && !namespace.equals(ns)) {
+                continue;
+            }
+            String name = key.substring(key.indexOf(NAMESPACE_NAME_SEPARATOR) + 1);
+            results.putIfAbsent(ns, new HashMap<>());
+            results.get(ns).put(name, value);
+        }
+        c.close();
+        return results;
+    }
+
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    static String getPropName(String namespace, String name) {
+        return KEYNAME_PREFIX + namespace + NAMESPACE_NAME_SEPARATOR + name;
+    }
+
+    interface FlagChangeCallback {
+        void onFlagChanged(String namespace, String name, String value);
+    }
+}
diff --git a/services/flags/java/com/android/server/flags/FlagsShellCommand.java b/services/flags/java/com/android/server/flags/FlagsShellCommand.java
new file mode 100644
index 0000000..b7896ee
--- /dev/null
+++ b/services/flags/java/com/android/server/flags/FlagsShellCommand.java
@@ -0,0 +1,214 @@
+/*
+ * 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.flags;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.FastPrintWriter;
+
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Process command line input for the flags service.
+ */
+@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+public class FlagsShellCommand {
+    private final FlagOverrideStore mFlagStore;
+
+    FlagsShellCommand(FlagOverrideStore flagStore) {
+        mFlagStore = flagStore;
+    }
+
+    /**
+     * Interpret the command supplied in the constructor.
+     *
+     * @return Zero on success or non-zero on error.
+     */
+    public int process(
+            String[] args,
+            OutputStream out,
+            OutputStream err) {
+        PrintWriter outPw = new FastPrintWriter(out);
+        PrintWriter errPw = new FastPrintWriter(err);
+
+        if (args.length == 0) {
+            return printHelp(outPw);
+        }
+        switch (args[0].toLowerCase(Locale.ROOT)) {
+            case "help":
+                return printHelp(outPw);
+            case "list":
+                return listCmd(args, outPw, errPw);
+            case "set":
+                return setCmd(args, outPw, errPw);
+            case "get":
+                return getCmd(args, outPw, errPw);
+            case "erase":
+                return eraseCmd(args, outPw, errPw);
+            default:
+                return unknownCmd(outPw);
+        }
+    }
+
+    private int printHelp(PrintWriter outPw) {
+        outPw.println("Feature Flags command, allowing listing, setting, getting, and erasing of");
+        outPw.println("local flag overrides on a device.");
+        outPw.println();
+        outPw.println("Commands:");
+        outPw.println("  list [namespace]");
+        outPw.println("    List all flag overrides. Namespace is optional.");
+        outPw.println();
+        outPw.println("  get <namespace> <name>");
+        outPw.println("    Return the string value of a specific flag, or <unset>");
+        outPw.println();
+        outPw.println("  set <namespace> <name> <value>");
+        outPw.println("    Set a specific flag");
+        outPw.println();
+        outPw.println("  erase <namespace> <name>");
+        outPw.println("    Unset a specific flag");
+        outPw.flush();
+        return 0;
+    }
+
+    private int listCmd(String[] args, PrintWriter outPw, PrintWriter errPw) {
+        if (!validateNumArguments(args, 0, 1, args[0], errPw)) {
+            errPw.println("Expected `" + args[0] + " [namespace]`");
+            errPw.flush();
+            return -1;
+        }
+        Map<String, Map<String, String>> overrides;
+        if (args.length == 2) {
+            overrides = mFlagStore.getFlagsForNamespace(args[1]);
+        } else {
+            overrides = mFlagStore.getFlags();
+        }
+        if (overrides.isEmpty()) {
+            outPw.println("No overrides set");
+        } else {
+            int longestNamespaceLen = "namespace".length();
+            int longestFlagLen = "flag".length();
+            int longestValLen = "value".length();
+            for (Map.Entry<String, Map<String, String>> namespace : overrides.entrySet()) {
+                longestNamespaceLen = Math.max(longestNamespaceLen, namespace.getKey().length());
+                for (Map.Entry<String, String> flag : namespace.getValue().entrySet()) {
+                    longestFlagLen = Math.max(longestFlagLen, flag.getKey().length());
+                    longestValLen = Math.max(longestValLen, flag.getValue().length());
+                }
+            }
+            outPw.print(String.format("%-" + longestNamespaceLen + "s", "namespace"));
+            outPw.print(' ');
+            outPw.print(String.format("%-" + longestFlagLen + "s", "flag"));
+            outPw.print(' ');
+            outPw.println("value");
+            for (int i = 0; i < longestNamespaceLen; i++) {
+                outPw.print('=');
+            }
+            outPw.print(' ');
+            for (int i = 0; i < longestFlagLen; i++) {
+                outPw.print('=');
+            }
+            outPw.print(' ');
+            for (int i = 0; i < longestValLen; i++) {
+                outPw.print('=');
+            }
+            outPw.println();
+            for (Map.Entry<String, Map<String, String>> namespace : overrides.entrySet()) {
+                for (Map.Entry<String, String> flag : namespace.getValue().entrySet()) {
+                    outPw.print(
+                            String.format("%-" + longestNamespaceLen + "s", namespace.getKey()));
+                    outPw.print(' ');
+                    outPw.print(String.format("%-" + longestFlagLen + "s", flag.getKey()));
+                    outPw.print(' ');
+                    outPw.println(flag.getValue());
+                }
+            }
+        }
+        outPw.flush();
+        return 0;
+    }
+
+    private int setCmd(String[] args, PrintWriter outPw, PrintWriter errPw) {
+        if (!validateNumArguments(args, 3, args[0], errPw)) {
+            errPw.println("Expected `" + args[0] + " <namespace> <name> <value>`");
+            errPw.flush();
+            return -1;
+        }
+        mFlagStore.set(args[1], args[2], args[3]);
+        outPw.println("Flag " + args[1] + "." + args[2] + " is now " + args[3]);
+        outPw.flush();
+        return 0;
+    }
+
+    private int getCmd(String[] args, PrintWriter outPw, PrintWriter errPw) {
+        if (!validateNumArguments(args, 2, args[0], errPw)) {
+            errPw.println("Expected `" + args[0] + " <namespace> <name>`");
+            errPw.flush();
+            return -1;
+        }
+
+        String value = mFlagStore.get(args[1], args[2]);
+        outPw.print(args[1] + "." + args[2] + " is ");
+        if (value == null || value.isEmpty()) {
+            outPw.println("<unset>");
+        } else {
+            outPw.println("\"" + value.translateEscapes() + "\"");
+        }
+        outPw.flush();
+        return 0;
+    }
+
+    private int eraseCmd(String[] args, PrintWriter outPw, PrintWriter errPw) {
+        if (!validateNumArguments(args, 2, args[0], errPw)) {
+            errPw.println("Expected `" + args[0] + " <namespace> <name>`");
+            errPw.flush();
+            return -1;
+        }
+        mFlagStore.erase(args[1], args[2]);
+        outPw.println("Erased " + args[1] + "." + args[2]);
+        return 0;
+    }
+
+    private int unknownCmd(PrintWriter outPw) {
+        outPw.println("This command is unknown.");
+        printHelp(outPw);
+        outPw.flush();
+        return -1;
+    }
+
+    private boolean validateNumArguments(
+            String[] args, int exactly, String cmdName, PrintWriter errPw) {
+        return validateNumArguments(args, exactly, exactly, cmdName, errPw);
+    }
+
+    private boolean validateNumArguments(
+            String[] args, int min, int max, String cmdName, PrintWriter errPw) {
+        int len = args.length - 1; // Discount the command itself.
+        if (len < min) {
+            errPw.println(
+                    "Less than " + min + " arguments provided for \"" + cmdName + "\" command.");
+            return false;
+        } else if (len > max) {
+            errPw.println(
+                    "More than " + max + " arguments provided for \"" + cmdName + "\" command.");
+            return false;
+        }
+
+        return true;
+    }
+}
diff --git a/services/flags/java/com/android/server/flags/GlobalSettingsProxy.java b/services/flags/java/com/android/server/flags/GlobalSettingsProxy.java
new file mode 100644
index 0000000..acb7bb5
--- /dev/null
+++ b/services/flags/java/com/android/server/flags/GlobalSettingsProxy.java
@@ -0,0 +1,68 @@
+/*
+ * 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.flags;
+
+import android.content.ContentResolver;
+import android.net.Uri;
+import android.provider.Settings;
+
+class GlobalSettingsProxy implements SettingsProxy {
+    private final ContentResolver mContentResolver;
+
+    GlobalSettingsProxy(ContentResolver contentResolver) {
+        mContentResolver = contentResolver;
+    }
+
+    @Override
+    public ContentResolver getContentResolver() {
+        return mContentResolver;
+    }
+
+    @Override
+    public Uri getUriFor(String name) {
+        return Settings.Global.getUriFor(name);
+    }
+
+    @Override
+    public String getStringForUser(String name, int userHandle) {
+        return Settings.Global.getStringForUser(mContentResolver, name, userHandle);
+    }
+
+    @Override
+    public boolean putString(String name, String value, boolean overrideableByRestore) {
+        throw new UnsupportedOperationException(
+                "This method only exists publicly for Settings.System and Settings.Secure");
+    }
+
+    @Override
+    public boolean putStringForUser(String name, String value, int userHandle) {
+        return Settings.Global.putStringForUser(mContentResolver, name, value, userHandle);
+    }
+
+    @Override
+    public boolean putStringForUser(String name, String value, String tag, boolean makeDefault,
+            int userHandle, boolean overrideableByRestore) {
+        return Settings.Global.putStringForUser(
+                mContentResolver, name, value, tag, makeDefault, userHandle,
+                overrideableByRestore);
+    }
+
+    @Override
+    public boolean putString(String name, String value, String tag, boolean makeDefault) {
+        return Settings.Global.putString(mContentResolver, name, value, tag, makeDefault);
+    }
+}
diff --git a/services/flags/java/com/android/server/flags/SettingsProxy.java b/services/flags/java/com/android/server/flags/SettingsProxy.java
new file mode 100644
index 0000000..c6e85d5
--- /dev/null
+++ b/services/flags/java/com/android/server/flags/SettingsProxy.java
@@ -0,0 +1,381 @@
+/*
+ * 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.flags;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.content.ContentResolver;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.provider.Settings;
+
+/**
+ * Wrapper class meant to enable hermetic testing of {@link Settings}.
+ *
+ * Implementations of this class are expected to be constructed with a {@link ContentResolver} or,
+ * otherwise have access to an implicit one. All the proxy methods in this class exclude
+ * {@link ContentResolver} from their signature and rely on an internally defined one instead.
+ *
+ * Most methods in the {@link Settings} classes have default implementations defined.
+ * Implementations of this interfac need only concern themselves with getting and putting Strings.
+ * They should also override any methods for a class they are proxying that _are not_ defined, and
+ * throw an appropriate {@link UnsupportedOperationException}. For instance, {@link Settings.Global}
+ * does not define {@link #putString(String, String, boolean)}, so an implementation of this
+ * interface that proxies through to it should throw an exception when that method is called.
+ *
+ * This class adds in the following helpers as well:
+ *  - {@link #getBool(String)}
+ *  - {@link #putBool(String, boolean)}
+ *  - {@link #registerContentObserver(Uri, ContentObserver)}
+ *
+ * ... and similar variations for all of those.
+ */
+public interface SettingsProxy {
+
+    /**
+     * Returns the {@link ContentResolver} this instance uses.
+     */
+    ContentResolver getContentResolver();
+
+    /**
+     * Construct the content URI for a particular name/value pair,
+     * useful for monitoring changes with a ContentObserver.
+     * @param name to look up in the table
+     * @return the corresponding content URI, or null if not present
+     */
+    Uri getUriFor(String name);
+
+    /**See {@link Settings.Secure#getString(ContentResolver, String)} */
+    String getStringForUser(String name, int userHandle);
+
+    /**See {@link Settings.Secure#putString(ContentResolver, String, String, boolean)} */
+    boolean putString(String name, String value, boolean overrideableByRestore);
+
+    /** See {@link Settings.Secure#putStringForUser(ContentResolver, String, String, int)} */
+    boolean putStringForUser(String name, String value, int userHandle);
+
+    /**
+     * See {@link Settings.Secure#putStringForUser(ContentResolver, String, String, String, boolean,
+     * int, boolean)}
+     */
+    boolean putStringForUser(@NonNull String name, @Nullable String value, @Nullable String tag,
+            boolean makeDefault, @UserIdInt int userHandle, boolean overrideableByRestore);
+
+    /** See {@link Settings.Secure#putString(ContentResolver, String, String, String, boolean)} */
+    boolean putString(@NonNull String name, @Nullable String value, @Nullable String tag,
+            boolean makeDefault);
+
+    /**
+     * Returns the user id for the associated {@link ContentResolver}.
+     */
+    default int getUserId() {
+        return getContentResolver().getUserId();
+    }
+
+    /** See {@link Settings.Secure#getString(ContentResolver, String)} */
+    default String getString(String name) {
+        return getStringForUser(name, getUserId());
+    }
+
+    /** See {@link Settings.Secure#putString(ContentResolver, String, String)} */
+    default boolean putString(String name, String value) {
+        return putStringForUser(name, value, getUserId());
+    }
+    /** See {@link Settings.Secure#getIntForUser(ContentResolver, String, int, int)} */
+    default int getIntForUser(String name, int def, int userHandle) {
+        String v = getStringForUser(name, userHandle);
+        try {
+            return v != null ? Integer.parseInt(v) : def;
+        } catch (NumberFormatException e) {
+            return def;
+        }
+    }
+
+    /** See {@link Settings.Secure#getInt(ContentResolver, String)}  */
+    default int getInt(String name) throws Settings.SettingNotFoundException {
+        return getIntForUser(name, getUserId());
+    }
+
+    /** See {@link Settings.Secure#getIntForUser(ContentResolver, String, int)} */
+    default int getIntForUser(String name, int userHandle)
+            throws Settings.SettingNotFoundException {
+        String v = getStringForUser(name, userHandle);
+        try {
+            return Integer.parseInt(v);
+        } catch (NumberFormatException e) {
+            throw new Settings.SettingNotFoundException(name);
+        }
+    }
+
+    /** See {@link Settings.Secure#putInt(ContentResolver, String, int)} */
+    default boolean putInt(String name, int value) {
+        return putIntForUser(name, value, getUserId());
+    }
+
+    /** See {@link Settings.Secure#putIntForUser(ContentResolver, String, int, int)} */
+    default boolean putIntForUser(String name, int value, int userHandle) {
+        return putStringForUser(name, Integer.toString(value), userHandle);
+    }
+
+    /**
+     * Convenience function for retrieving a single settings value
+     * as a boolean.  Note that internally setting values are always
+     * stored as strings; this function converts the string to a boolean
+     * for you. The default value will be returned if the setting is
+     * not defined or not a boolean.
+     *
+     * @param name The name of the setting to retrieve.
+     * @param def Value to return if the setting is not defined.
+     *
+     * @return The setting's current value, or 'def' if it is not defined
+     * or not a valid boolean.
+     */
+    default boolean getBool(String name, boolean def) {
+        return getBoolForUser(name, def, getUserId());
+    }
+
+    /** See {@link #getBool(String, boolean)}. */
+    default boolean getBoolForUser(String name, boolean def, int userHandle) {
+        return getIntForUser(name, def ? 1 : 0, userHandle) != 0;
+    }
+
+    /**
+     * Convenience function for retrieving a single settings value
+     * as a boolean.  Note that internally setting values are always
+     * stored as strings; this function converts the string to a boolean
+     * for you.
+     * <p>
+     * This version does not take a default value.  If the setting has not
+     * been set, or the string value is not a number,
+     * it throws {@link Settings.SettingNotFoundException}.
+     *
+     * @param name The name of the setting to retrieve.
+     *
+     * @throws Settings.SettingNotFoundException Thrown if a setting by the given
+     * name can't be found or the setting value is not a boolean.
+     *
+     * @return The setting's current value.
+     */
+    default boolean getBool(String name) throws Settings.SettingNotFoundException {
+        return getBoolForUser(name, getUserId());
+    }
+
+    /** See {@link #getBool(String)}. */
+    default boolean getBoolForUser(String name, int userHandle)
+            throws Settings.SettingNotFoundException {
+        return getIntForUser(name, userHandle) != 0;
+    }
+
+    /**
+     * Convenience function for updating a single settings value as a
+     * boolean. This will either create a new entry in the table if the
+     * given name does not exist, or modify the value of the existing row
+     * with that name.  Note that internally setting values are always
+     * stored as strings, so this function converts the given value to a
+     * string before storing it.
+     *
+     * @param name The name of the setting to modify.
+     * @param value The new value for the setting.
+     * @return true if the value was set, false on database errors
+     */
+    default boolean putBool(String name, boolean value) {
+        return putBoolForUser(name, value, getUserId());
+    }
+
+    /** See {@link #putBool(String, boolean)}. */
+    default boolean putBoolForUser(String name, boolean value, int userHandle) {
+        return putIntForUser(name, value ? 1 : 0, userHandle);
+    }
+
+    /** See {@link Settings.Secure#getLong(ContentResolver, String, long)}  */
+    default long getLong(String name, long def) {
+        return getLongForUser(name, def, getUserId());
+    }
+
+    /** See {@link Settings.Secure#getLongForUser(ContentResolver, String, long, int)}  */
+    default long getLongForUser(String name, long def, int userHandle) {
+        String valString = getStringForUser(name, userHandle);
+        long value;
+        try {
+            value = valString != null ? Long.parseLong(valString) : def;
+        } catch (NumberFormatException e) {
+            value = def;
+        }
+        return value;
+    }
+
+    /** See {@link Settings.Secure#getLong(ContentResolver, String)}  */
+    default long getLong(String name) throws Settings.SettingNotFoundException {
+        return getLongForUser(name, getUserId());
+    }
+
+    /** See {@link Settings.Secure#getLongForUser(ContentResolver, String, int)}  */
+    default long getLongForUser(String name, int userHandle)
+            throws Settings.SettingNotFoundException {
+        String valString = getStringForUser(name, userHandle);
+        try {
+            return Long.parseLong(valString);
+        } catch (NumberFormatException e) {
+            throw new Settings.SettingNotFoundException(name);
+        }
+    }
+
+    /** See {@link Settings.Secure#putLong(ContentResolver, String, long)} */
+    default boolean putLong(String name, long value) {
+        return putLongForUser(name, value, getUserId());
+    }
+
+    /** See {@link Settings.Secure#putLongForUser(ContentResolver, String, long, int)}  */
+    default boolean putLongForUser(String name, long value, int userHandle) {
+        return putStringForUser(name, Long.toString(value), userHandle);
+    }
+
+    /** See {@link Settings.Secure#getFloat(ContentResolver, String, float)} */
+    default float getFloat(String name, float def) {
+        return getFloatForUser(name, def, getUserId());
+    }
+
+    /** See {@link Settings.Secure#getFloatForUser(ContentResolver, String, int)} */
+    default float getFloatForUser(String name, float def, int userHandle) {
+        String v = getStringForUser(name, userHandle);
+        try {
+            return v != null ? Float.parseFloat(v) : def;
+        } catch (NumberFormatException e) {
+            return def;
+        }
+    }
+
+
+    /** See {@link Settings.Secure#getFloat(ContentResolver, String)}  */
+    default float getFloat(String name) throws Settings.SettingNotFoundException {
+        return getFloatForUser(name, getUserId());
+    }
+
+    /** See {@link Settings.Secure#getFloatForUser(ContentResolver, String, int)}   */
+    default float getFloatForUser(String name, int userHandle)
+            throws Settings.SettingNotFoundException {
+        String v = getStringForUser(name, userHandle);
+        if (v == null) {
+            throw new Settings.SettingNotFoundException(name);
+        }
+        try {
+            return Float.parseFloat(v);
+        } catch (NumberFormatException e) {
+            throw new Settings.SettingNotFoundException(name);
+        }
+    }
+
+    /** See {@link Settings.Secure#putFloat(ContentResolver, String, float)} */
+    default boolean putFloat(String name, float value) {
+        return putFloatForUser(name, value, getUserId());
+    }
+
+    /** See {@link Settings.Secure#putFloatForUser(ContentResolver, String, float, int)} */
+    default boolean putFloatForUser(String name, float value, int userHandle) {
+        return putStringForUser(name, Float.toString(value), userHandle);
+    }
+
+    /**
+     * Convenience wrapper around
+     * {@link ContentResolver#registerContentObserver(Uri, boolean, ContentObserver)}.'
+     *
+     * Implicitly calls {@link #getUriFor(String)} on the passed in name.
+     */
+    default void registerContentObserver(String name, ContentObserver settingsObserver) {
+        registerContentObserver(getUriFor(name), settingsObserver);
+    }
+
+    /**
+     * Convenience wrapper around
+     * {@link ContentResolver#registerContentObserver(Uri, boolean, ContentObserver)}.'
+     */
+    default void registerContentObserver(Uri uri, ContentObserver settingsObserver) {
+        registerContentObserverForUser(uri, settingsObserver, getUserId());
+    }
+
+    /**
+     * Convenience wrapper around
+     * {@link ContentResolver#registerContentObserver(Uri, boolean, ContentObserver)}.
+     *
+     * Implicitly calls {@link #getUriFor(String)} on the passed in name.
+     */
+    default void registerContentObserver(String name, boolean notifyForDescendants,
+            ContentObserver settingsObserver) {
+        registerContentObserver(getUriFor(name), notifyForDescendants, settingsObserver);
+    }
+
+    /**
+     * Convenience wrapper around
+     * {@link ContentResolver#registerContentObserver(Uri, boolean, ContentObserver)}.'
+     */
+    default void registerContentObserver(Uri uri, boolean notifyForDescendants,
+            ContentObserver settingsObserver) {
+        registerContentObserverForUser(uri, notifyForDescendants, settingsObserver, getUserId());
+    }
+
+    /**
+     * Convenience wrapper around
+     * {@link ContentResolver#registerContentObserver(Uri, boolean, ContentObserver, int)}
+     *
+     * Implicitly calls {@link #getUriFor(String)} on the passed in name.
+     */
+    default void registerContentObserverForUser(
+            String name, ContentObserver settingsObserver, int userHandle) {
+        registerContentObserverForUser(
+                getUriFor(name), settingsObserver, userHandle);
+    }
+
+    /**
+     * Convenience wrapper around
+     * {@link ContentResolver#registerContentObserver(Uri, boolean, ContentObserver, int)}
+     */
+    default void registerContentObserverForUser(
+            Uri uri, ContentObserver settingsObserver, int userHandle) {
+        registerContentObserverForUser(
+                uri, false, settingsObserver, userHandle);
+    }
+
+    /**
+     * Convenience wrapper around
+     * {@link ContentResolver#registerContentObserver(Uri, boolean, ContentObserver, int)}
+     *
+     * Implicitly calls {@link #getUriFor(String)} on the passed in name.
+     */
+    default void registerContentObserverForUser(
+            String name, boolean notifyForDescendants, ContentObserver settingsObserver,
+            int userHandle) {
+        registerContentObserverForUser(
+                getUriFor(name), notifyForDescendants, settingsObserver, userHandle);
+    }
+
+    /**
+     * Convenience wrapper around
+     * {@link ContentResolver#registerContentObserver(Uri, boolean, ContentObserver, int)}
+     */
+    default void registerContentObserverForUser(
+            Uri uri, boolean notifyForDescendants, ContentObserver settingsObserver,
+            int userHandle) {
+        getContentResolver().registerContentObserver(
+                uri, notifyForDescendants, settingsObserver, userHandle);
+    }
+
+    /** See {@link ContentResolver#unregisterContentObserver(ContentObserver)}. */
+    default void unregisterContentObserver(ContentObserver settingsObserver) {
+        getContentResolver().unregisterContentObserver(settingsObserver);
+    }
+}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 991248a..7de1279 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -132,6 +132,7 @@
 import com.android.server.display.color.ColorDisplayService;
 import com.android.server.dreams.DreamManagerService;
 import com.android.server.emergency.EmergencyAffordanceService;
+import com.android.server.flags.FeatureFlagsService;
 import com.android.server.gpu.GpuService;
 import com.android.server.grammaticalinflection.GrammaticalInflectionService;
 import com.android.server.graphics.fonts.FontManagerService;
@@ -1111,6 +1112,12 @@
         mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
         t.traceEnd();
 
+        // Starts a service for reading runtime flag overrides, and keeping processes
+        // in sync with one another.
+        t.traceBegin("StartFeatureFlagsService");
+        mSystemServiceManager.startService(FeatureFlagsService.class);
+        t.traceEnd();
+
         // Uri Grants Manager.
         t.traceBegin("UriGrantsManagerService");
         mSystemServiceManager.startService(UriGrantsManagerService.Lifecycle.class);
diff --git a/services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert5_rotated_cert6 b/services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert5_rotated_cert6
index 2da2436..c2418be 100644
--- a/services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert5_rotated_cert6
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert5_rotated_cert6
Binary files differ
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DeviceStateToLayoutMapTest.java b/services/tests/displayservicetests/src/com/android/server/display/DeviceStateToLayoutMapTest.java
index 130e6ad..4b124ca 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DeviceStateToLayoutMapTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DeviceStateToLayoutMapTest.java
@@ -19,8 +19,8 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
 
-import android.view.Display;
 import android.view.DisplayAddress;
 
 import androidx.test.filters.SmallTest;
@@ -65,9 +65,15 @@
 
         Layout testLayout = new Layout();
         createDefaultDisplay(testLayout, 123456L);
-        createNonDefaultDisplay(testLayout, 78910L, /* enabled= */ false, /* group= */ null);
-        createNonDefaultDisplay(testLayout, 98765L, /* enabled= */ true, /* group= */ "group1");
-        createNonDefaultDisplay(testLayout, 786L, /* enabled= */ false, /* group= */ "group2");
+        createNonDefaultDisplay(testLayout, 78910L, /* enabled= */ false, /* group= */ null,
+                /* leadDisplayAddress= */ null);
+        createNonDefaultDisplay(testLayout, 98765L, /* enabled= */ true, /* group= */ "group1",
+                /* leadDisplayAddress= */ null);
+        createNonDefaultDisplay(testLayout, 786L, /* enabled= */ false, /* group= */ "group2",
+                /* leadDisplayAddress= */ null);
+        createNonDefaultDisplay(testLayout, 1092L, /* enabled= */ true, /* group= */ null,
+                DisplayAddress.fromPhysicalDisplayId(78910L));
+        testLayout.postProcessLocked();
 
         assertEquals(testLayout, configLayout);
     }
@@ -78,7 +84,9 @@
 
         Layout testLayout = new Layout();
         createDefaultDisplay(testLayout, 78910L);
-        createNonDefaultDisplay(testLayout, 123456L, /* enabled= */ false, /* group= */ null);
+        createNonDefaultDisplay(testLayout, 123456L, /* enabled= */ false, /* group= */ null,
+                /* leadDisplayAddress= */ null);
+        testLayout.postProcessLocked();
 
         assertEquals(testLayout, configLayout);
     }
@@ -122,20 +130,132 @@
         Layout testLayout = new Layout();
         testLayout.createDisplayLocked(DisplayAddress.fromPhysicalDisplayId(345L),
                 /* isDefault= */ true, /* isEnabled= */ true, /* displayGroupName= */ null,
-                mDisplayIdProducerMock,  Layout.Display.POSITION_FRONT, Display.DEFAULT_DISPLAY,
-                /* brightnessThrottlingMapId= */ "brightness1",
+                mDisplayIdProducerMock,  Layout.Display.POSITION_FRONT,
+                /* leadDisplayAddress= */ null, /* brightnessThrottlingMapId= */ "brightness1",
                 /* refreshRateZoneId= */ "zone1",
                 /* refreshRateThermalThrottlingMapId= */ "rr1");
         testLayout.createDisplayLocked(DisplayAddress.fromPhysicalDisplayId(678L),
                 /* isDefault= */ false, /* isEnabled= */ false, /* displayGroupName= */ "group1",
-                mDisplayIdProducerMock, Layout.Display.POSITION_REAR, Display.DEFAULT_DISPLAY,
-                /* brightnessThrottlingMapId= */ "brightness2",
+                mDisplayIdProducerMock, Layout.Display.POSITION_REAR,
+                /* leadDisplayAddress= */ null, /* brightnessThrottlingMapId= */ "brightness2",
                 /* refreshRateZoneId= */ "zone2",
                 /* refreshRateThermalThrottlingMapId= */ "rr2");
+        testLayout.postProcessLocked();
 
         assertEquals(testLayout, configLayout);
     }
 
+    @Test
+    public void testLeadDisplayAddress() {
+        Layout layout = new Layout();
+        createNonDefaultDisplay(layout, 111L, /* enabled= */ true, /* group= */ null,
+                /* leadDisplayAddress= */ null);
+        createNonDefaultDisplay(layout, 222L, /* enabled= */ true, /* group= */ null,
+                DisplayAddress.fromPhysicalDisplayId(111L));
+
+        layout.postProcessLocked();
+
+        com.android.server.display.layout.Layout.Display display111 =
+                layout.getByAddress(DisplayAddress.fromPhysicalDisplayId(111));
+        com.android.server.display.layout.Layout.Display display222 =
+                layout.getByAddress(DisplayAddress.fromPhysicalDisplayId(222));
+        assertEquals(display111.getLeadDisplayId(), layout.NO_LEAD_DISPLAY);
+        assertEquals(display222.getLeadDisplayId(), display111.getLogicalDisplayId());
+    }
+
+    @Test
+    public void testLeadDisplayAddress_defaultDisplay() {
+        Layout layout = new Layout();
+        createDefaultDisplay(layout, 123456L);
+
+        layout.postProcessLocked();
+
+        com.android.server.display.layout.Layout.Display display =
+                layout.getByAddress(DisplayAddress.fromPhysicalDisplayId(123456));
+        assertEquals(display.getLeadDisplayId(), layout.NO_LEAD_DISPLAY);
+    }
+
+    @Test
+    public void testLeadDisplayAddress_noLeadDisplay() {
+        Layout layout = new Layout();
+        createNonDefaultDisplay(layout, 222L, /* enabled= */ true, /* group= */ null,
+                /* leadDisplayAddress= */ null);
+
+        layout.postProcessLocked();
+
+        com.android.server.display.layout.Layout.Display display =
+                layout.getByAddress(DisplayAddress.fromPhysicalDisplayId(222));
+        assertEquals(display.getLeadDisplayId(), layout.NO_LEAD_DISPLAY);
+    }
+
+    @Test
+    public void testLeadDisplayAddress_selfLeadDisplayForNonDefaultDisplay() {
+        Layout layout = new Layout();
+
+        assertThrows("Expected Layout to throw IllegalArgumentException when the display points out"
+                + " itself as a lead display",
+                IllegalArgumentException.class,
+                () -> layout.createDisplayLocked(DisplayAddress.fromPhysicalDisplayId(123L),
+                    /* isDefault= */ true, /* isEnabled= */ true, /* displayGroupName= */ null,
+                    mDisplayIdProducerMock,  Layout.Display.POSITION_FRONT,
+                    DisplayAddress.fromPhysicalDisplayId(123L),
+                    /* brightnessThrottlingMapId= */ null, /* refreshRateZoneId= */ null,
+                    /* refreshRateThermalThrottlingMapId= */ null));
+    }
+
+    @Test
+    public void testLeadDisplayAddress_wrongLeadDisplayForDefaultDisplay() {
+        Layout layout = new Layout();
+
+        assertThrows("Expected Layout to throw IllegalArgumentException when the default display "
+                + "has a lead display",
+                IllegalArgumentException.class,
+                () -> layout.createDisplayLocked(DisplayAddress.fromPhysicalDisplayId(123L),
+                    /* isDefault= */ true, /* isEnabled= */ true, /* displayGroupName= */ null,
+                    mDisplayIdProducerMock,  Layout.Display.POSITION_FRONT,
+                    DisplayAddress.fromPhysicalDisplayId(987L),
+                    /* brightnessThrottlingMapId= */ null, /* refreshRateZoneId= */ null,
+                    /* refreshRateThermalThrottlingMapId= */ null));
+    }
+
+    @Test
+    public void testLeadDisplayAddress_notExistingLeadDisplayForNonDefaultDisplay() {
+        Layout layout = new Layout();
+        createNonDefaultDisplay(layout, 222L, /* enabled= */ true, /* group= */ null,
+                DisplayAddress.fromPhysicalDisplayId(111L));
+
+        assertThrows("Expected Layout to throw IllegalArgumentException when a lead display doesn't"
+                + " exist", IllegalArgumentException.class, () -> layout.postProcessLocked());
+    }
+
+    @Test
+    public void testLeadDisplayAddress_leadDisplayInDifferentDisplayGroup() {
+        Layout layout = new Layout();
+        createNonDefaultDisplay(layout, 111, /* enabled= */ true, /* group= */ "group1",
+                /* leadDisplayAddress= */ null);
+        createNonDefaultDisplay(layout, 222L, /* enabled= */ true, /* group= */ "group2",
+                DisplayAddress.fromPhysicalDisplayId(111L));
+
+        assertThrows("Expected Layout to throw IllegalArgumentException when pointing to a lead "
+                + "display in the different group",
+                IllegalArgumentException.class, () -> layout.postProcessLocked());
+    }
+
+    @Test
+    public void testLeadDisplayAddress_cyclicLeadDisplay() {
+        Layout layout = new Layout();
+        createNonDefaultDisplay(layout, 111, /* enabled= */ true, /* group= */ null,
+                DisplayAddress.fromPhysicalDisplayId(222L));
+        createNonDefaultDisplay(layout, 222L, /* enabled= */ true, /* group= */ null,
+                DisplayAddress.fromPhysicalDisplayId(333L));
+        createNonDefaultDisplay(layout, 333L, /* enabled= */ true, /* group= */ null,
+                DisplayAddress.fromPhysicalDisplayId(222L));
+
+        assertThrows("Expected Layout to throw IllegalArgumentException when pointing to a lead "
+                + "display in the different group",
+                IllegalArgumentException.class, () -> layout.postProcessLocked());
+    }
+
     ////////////////////
     // Helper Methods //
     ////////////////////
@@ -145,10 +265,11 @@
                 mDisplayIdProducerMock);
     }
 
-    private void createNonDefaultDisplay(Layout layout, long id, boolean enabled, String group) {
+    private void createNonDefaultDisplay(Layout layout, long id, boolean enabled, String group,
+            DisplayAddress leadDisplayAddress) {
         layout.createDisplayLocked(DisplayAddress.fromPhysicalDisplayId(id), /* isDefault= */ false,
                 enabled, group, mDisplayIdProducerMock, Layout.Display.POSITION_UNKNOWN,
-                Display.DEFAULT_DISPLAY, /* brightnessThrottlingMapId= */ null,
+                leadDisplayAddress, /* brightnessThrottlingMapId= */ null,
                 /* refreshRateZoneId= */ null,
                 /* refreshRateThermalThrottlingMapId= */ null);
     }
@@ -177,6 +298,10 @@
                 +      "<display enabled=\"false\" displayGroup=\"group2\">\n"
                 +        "<address>786</address>\n"
                 +      "</display>\n"
+                +      "<display enabled=\"true\">\n"
+                +        "<address>1092</address>\n"
+                +        "<leadDisplayAddress>78910</leadDisplayAddress>\n"
+                +      "</display>\n"
                 +    "</layout>\n"
 
                 +    "<layout>\n"
diff --git a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java
index 1eec70d..3e695c9 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java
@@ -604,13 +604,13 @@
         layout.createDisplayLocked(device1.getDisplayDeviceInfoLocked().address,
                 /* isDefault= */ true, /* isEnabled= */ true, /* displayGroup= */ null,
                 mIdProducer, POSITION_UNKNOWN,
-                /* leadDisplayId= */ Display.DEFAULT_DISPLAY,
+                /* leadDisplayAddress= */ null,
                 /* brightnessThrottlingMapId= */ "concurrent",
                 /* refreshRateZoneId= */ null, /* refreshRateThermalThrottlingMapId= */ null);
         layout.createDisplayLocked(device2.getDisplayDeviceInfoLocked().address,
                 /* isDefault= */ false, /* isEnabled= */ true, /* displayGroup= */ null,
                 mIdProducer, POSITION_UNKNOWN,
-                /* leadDisplayId= */ Display.DEFAULT_DISPLAY,
+                /* leadDisplayAddress= */ null,
                 /* brightnessThrottlingMapId= */ "concurrent",
                 /* refreshRateZoneId= */ null, /* refreshRateThermalThrottlingMapId= */ null);
         when(mDeviceStateToLayoutMapSpy.get(0)).thenReturn(layout);
@@ -646,7 +646,7 @@
         assertFalse(mLogicalDisplayMapper.getDisplayLocked(device2).isInTransitionLocked());
         assertEquals(-1, mLogicalDisplayMapper.getDisplayLocked(device1)
                 .getLeadDisplayIdLocked());
-        assertEquals(0, mLogicalDisplayMapper.getDisplayLocked(device2)
+        assertEquals(-1, mLogicalDisplayMapper.getDisplayLocked(device2)
                 .getLeadDisplayIdLocked());
         assertEquals("concurrent", mLogicalDisplayMapper.getDisplayLocked(device1)
                 .getDisplayInfoLocked().thermalBrightnessThrottlingDataId);
@@ -811,7 +811,7 @@
                 mIdProducer);
         layout.createDisplayLocked(device2.getDisplayDeviceInfoLocked().address,
                 /* isDefault= */ false, /* isEnabled= */ true, /* displayGroupName= */ null,
-                mIdProducer, POSITION_REAR, Display.DEFAULT_DISPLAY,
+                mIdProducer, POSITION_REAR, /* leadDisplayAddress= */ null,
                 /* brightnessThrottlingMapId= */ null, /* refreshRateZoneId= */ null,
                 /* refreshRateThermalThrottlingMapId= */null);
         when(mDeviceStateToLayoutMapSpy.get(0)).thenReturn(layout);
@@ -861,7 +861,7 @@
     private void createNonDefaultDisplay(Layout layout, DisplayAddress address, boolean enabled,
             String group) {
         layout.createDisplayLocked(address, /* isDefault= */ false, enabled, group, mIdProducer,
-                Layout.Display.POSITION_UNKNOWN, Display.DEFAULT_DISPLAY,
+                Layout.Display.POSITION_UNKNOWN, /* leadDisplayAddress= */ null,
                 /* brightnessThrottlingMapId= */ null, /* refreshRateZoneId= */ null,
                 /* refreshRateThermalThrottlingMapId= */ null);
     }
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
index 6bcc14e..a147098 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
@@ -620,6 +620,28 @@
         assertEquals(BroadcastProcessQueue.REASON_CORE_UID, queue.getRunnableAtReason());
     }
 
+    @Test
+    public void testRunnableAt_freezableCoreUid() {
+        final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
+                "com.android.bluetooth", Process.BLUETOOTH_UID);
+
+        // Mark the process as freezable
+        queue.setProcessAndUidState(mProcess, false, true);
+        final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
+        final BroadcastOptions options = BroadcastOptions.makeWithDeferUntilActive(true);
+        final BroadcastRecord timeTickRecord = makeBroadcastRecord(timeTick, options,
+                List.of(makeMockRegisteredReceiver()), false);
+        enqueueOrReplaceBroadcast(queue, timeTickRecord, 0);
+
+        assertEquals(Long.MAX_VALUE, queue.getRunnableAt());
+        assertEquals(BroadcastProcessQueue.REASON_CACHED_INFINITE_DEFER,
+                queue.getRunnableAtReason());
+
+        queue.setProcessAndUidState(mProcess, false, false);
+        assertThat(queue.getRunnableAt()).isEqualTo(timeTickRecord.enqueueTime);
+        assertEquals(BroadcastProcessQueue.REASON_CORE_UID, queue.getRunnableAtReason());
+    }
+
     /**
      * Verify that a cached process that would normally be delayed becomes
      * immediately runnable when the given broadcast is enqueued.
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index ee3a773..0530f89 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -34,6 +34,7 @@
         "services.core",
         "services.credentials",
         "services.devicepolicy",
+        "services.flags",
         "services.net",
         "services.people",
         "services.usage",
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
index 81dd961..d4c6fad 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
@@ -606,9 +606,10 @@
     public void onPerformScaleAction_fullScreenMagnifierEnabled_handleScaleChange()
             throws RemoteException {
         final float newScale = 4.0f;
+        final boolean updatePersistence = true;
         setMagnificationEnabled(MODE_FULLSCREEN);
 
-        mMagnificationController.onPerformScaleAction(TEST_DISPLAY, newScale);
+        mMagnificationController.onPerformScaleAction(TEST_DISPLAY, newScale, updatePersistence);
 
         verify(mScreenMagnificationController).setScaleAndCenter(eq(TEST_DISPLAY), eq(newScale),
                 anyFloat(), anyFloat(), anyBoolean(), anyInt());
@@ -619,12 +620,13 @@
     public void onPerformScaleAction_windowMagnifierEnabled_handleScaleChange()
             throws RemoteException {
         final float newScale = 4.0f;
+        final boolean updatePersistence = false;
         setMagnificationEnabled(MODE_WINDOW);
 
-        mMagnificationController.onPerformScaleAction(TEST_DISPLAY, newScale);
+        mMagnificationController.onPerformScaleAction(TEST_DISPLAY, newScale, updatePersistence);
 
         verify(mWindowMagnificationManager).setScale(eq(TEST_DISPLAY), eq(newScale));
-        verify(mWindowMagnificationManager).persistScale(eq(TEST_DISPLAY));
+        verify(mWindowMagnificationManager, never()).persistScale(eq(TEST_DISPLAY));
     }
 
     @Test
@@ -1310,9 +1312,9 @@
         }
 
         @Override
-        public void onPerformScaleAction(int displayId, float scale) {
+        public void onPerformScaleAction(int displayId, float scale, boolean updatePersistence) {
             if (mCallback != null) {
-                mCallback.onPerformScaleAction(displayId, scale);
+                mCallback.onPerformScaleAction(displayId, scale, updatePersistence);
             }
         }
 
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
index e8b337a..27e6ef1 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
@@ -576,12 +576,15 @@
     @Test
     public void onPerformScaleAction_magnifierEnabled_notifyAction() throws RemoteException {
         final float newScale = 4.0f;
+        final boolean updatePersistence = true;
         mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
         mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
 
-        mMockConnection.getConnectionCallback().onPerformScaleAction(TEST_DISPLAY, newScale);
+        mMockConnection.getConnectionCallback().onPerformScaleAction(
+                TEST_DISPLAY, newScale, updatePersistence);
 
-        verify(mMockCallback).onPerformScaleAction(eq(TEST_DISPLAY), eq(newScale));
+        verify(mMockCallback).onPerformScaleAction(
+                eq(TEST_DISPLAY), eq(newScale), eq(updatePersistence));
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/flags/FeatureFlagsServiceTest.java b/services/tests/servicestests/src/com/android/server/flags/FeatureFlagsServiceTest.java
new file mode 100644
index 0000000..df4731f
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/flags/FeatureFlagsServiceTest.java
@@ -0,0 +1,293 @@
+/*
+ * 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.flags;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.flags.IFeatureFlagsCallback;
+import android.flags.SyncableFlag;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.util.List;
+
+@Presubmit
+@SmallTest
+public class FeatureFlagsServiceTest {
+    private static final String NS = "ns";
+    private static final String NAME = "name";
+    private static final String PROP_NAME = FlagOverrideStore.getPropName(NS, NAME);
+
+    @Rule
+    public final MockitoRule mockito = MockitoJUnit.rule();
+
+    @Mock
+    private FlagOverrideStore mFlagStore;
+    @Mock
+    private FlagsShellCommand mFlagCommand;
+    @Mock
+    private IFeatureFlagsCallback mIFeatureFlagsCallback;
+    @Mock
+    private IBinder mIFeatureFlagsCallbackAsBinder;
+    @Mock
+    private FeatureFlagsService.PermissionsChecker mPermissionsChecker;
+
+    private FeatureFlagsBinder mFeatureFlagsService;
+
+    @Before
+    public void setup() {
+        when(mIFeatureFlagsCallback.asBinder()).thenReturn(mIFeatureFlagsCallbackAsBinder);
+        mFeatureFlagsService = new FeatureFlagsBinder(
+                mFlagStore, mFlagCommand, mPermissionsChecker);
+    }
+
+    @Test
+    public void testRegisterCallback() {
+        mFeatureFlagsService.registerCallback(mIFeatureFlagsCallback);
+        try {
+            verify(mIFeatureFlagsCallbackAsBinder).linkToDeath(any(), eq(0));
+        } catch (RemoteException e) {
+            fail("Our mock threw a Remote Exception?");
+        }
+    }
+
+    @Test
+    public void testOverrideFlag_requiresWritePermission() {
+        SecurityException exc = new SecurityException("not allowed");
+        doThrow(exc).when(mPermissionsChecker).assertWritePermission();
+
+        SyncableFlag f = new SyncableFlag(NS, "a", "false", false);
+
+        try {
+            mFeatureFlagsService.overrideFlag(f);
+            fail("Should have thrown exception");
+        } catch (SecurityException e) {
+            assertThat(exc).isEqualTo(e);
+        } catch (Exception e) {
+            fail("should have thrown a security exception");
+        }
+    }
+
+    @Test
+    public void testResetFlag_requiresWritePermission() {
+        SecurityException exc = new SecurityException("not allowed");
+        doThrow(exc).when(mPermissionsChecker).assertWritePermission();
+
+        SyncableFlag f = new SyncableFlag(NS, "a", "false", false);
+
+        try {
+            mFeatureFlagsService.resetFlag(f);
+            fail("Should have thrown exception");
+        } catch (SecurityException e) {
+            assertThat(exc).isEqualTo(e);
+        } catch (Exception e) {
+            fail("should have thrown a security exception");
+        }
+    }
+
+    @Test
+    public void testSyncFlags_noOverrides() {
+        List<SyncableFlag> inputFlags = List.of(
+                new SyncableFlag(NS, "a", "false", false),
+                new SyncableFlag(NS, "b", "true", false),
+                new SyncableFlag(NS, "c", "false", false)
+        );
+
+        List<SyncableFlag> outputFlags = mFeatureFlagsService.syncFlags(inputFlags);
+
+        assertThat(inputFlags.size()).isEqualTo(outputFlags.size());
+
+        for (SyncableFlag inpF: inputFlags) {
+            boolean found = false;
+            for (SyncableFlag outF : outputFlags) {
+                if (compareSyncableFlagsNames(inpF, outF)) {
+                    found = true;
+                    break;
+                }
+            }
+            assertWithMessage("Failed to find input flag " + inpF + " in the output")
+                    .that(found).isTrue();
+        }
+    }
+
+    @Test
+    public void testSyncFlags_withSomeOverrides() {
+        List<SyncableFlag> inputFlags = List.of(
+                new SyncableFlag(NS, "a", "false", false),
+                new SyncableFlag(NS, "b", "true", false),
+                new SyncableFlag(NS, "c", "false", false)
+        );
+
+        assertThat(mFlagStore).isNotNull();
+        when(mFlagStore.get(NS, "c")).thenReturn("true");
+        List<SyncableFlag> outputFlags = mFeatureFlagsService.syncFlags(inputFlags);
+
+        assertThat(inputFlags.size()).isEqualTo(outputFlags.size());
+
+        for (SyncableFlag inpF: inputFlags) {
+            boolean found = false;
+            for (SyncableFlag outF : outputFlags) {
+                if (compareSyncableFlagsNames(inpF, outF)) {
+                    found = true;
+
+                    // Once we've found "c", do an extra check
+                    if (outF.getName().equals("c")) {
+                        assertWithMessage("Flag " + outF + "was not returned with an override")
+                                .that(outF.getValue()).isEqualTo("true");
+                    }
+                    break;
+                }
+            }
+            assertWithMessage("Failed to find input flag " + inpF + " in the output")
+                    .that(found).isTrue();
+        }
+    }
+
+    @Test
+    public void testSyncFlags_twoCallsWithDifferentDefaults() {
+        List<SyncableFlag> inputFlagsFirst = List.of(
+                new SyncableFlag(NS, "a", "false", false)
+        );
+        List<SyncableFlag> inputFlagsSecond = List.of(
+                new SyncableFlag(NS, "a", "true", false),
+                new SyncableFlag(NS, "b", "false", false)
+        );
+
+        List<SyncableFlag> outputFlagsFirst = mFeatureFlagsService.syncFlags(inputFlagsFirst);
+        List<SyncableFlag> outputFlagsSecond = mFeatureFlagsService.syncFlags(inputFlagsSecond);
+
+        assertThat(inputFlagsFirst.size()).isEqualTo(outputFlagsFirst.size());
+        assertThat(inputFlagsSecond.size()).isEqualTo(outputFlagsSecond.size());
+
+        // This test only cares that the "a" flag passed in the second time came out with the
+        // same value that was passed in the first time.
+
+        boolean found = false;
+        for (SyncableFlag second : outputFlagsSecond) {
+            if (compareSyncableFlagsNames(second, inputFlagsFirst.get(0))) {
+                found = true;
+                assertThat(second.getValue()).isEqualTo(inputFlagsFirst.get(0).getValue());
+                break;
+            }
+        }
+
+        assertWithMessage(
+                "Failed to find flag " + inputFlagsFirst.get(0) + " in the second calls output")
+                .that(found).isTrue();
+    }
+
+    @Test
+    public void testQueryFlags_onlyOnce() {
+        List<SyncableFlag> inputFlags = List.of(
+                new SyncableFlag(NS, "a", "false", false),
+                new SyncableFlag(NS, "b", "true", false),
+                new SyncableFlag(NS, "c", "false", false)
+        );
+
+        List<SyncableFlag> outputFlags = mFeatureFlagsService.queryFlags(inputFlags);
+
+        assertThat(inputFlags.size()).isEqualTo(outputFlags.size());
+
+        for (SyncableFlag inpF: inputFlags) {
+            boolean found = false;
+            for (SyncableFlag outF : outputFlags) {
+                if (compareSyncableFlagsNames(inpF, outF)) {
+                    found = true;
+                    break;
+                }
+            }
+            assertWithMessage("Failed to find input flag " + inpF + " in the output")
+                    .that(found).isTrue();
+        }
+    }
+
+    @Test
+    public void testQueryFlags_twoCallsWithDifferentDefaults() {
+        List<SyncableFlag> inputFlagsFirst = List.of(
+                new SyncableFlag(NS, "a", "false", false)
+        );
+        List<SyncableFlag> inputFlagsSecond = List.of(
+                new SyncableFlag(NS, "a", "true", false),
+                new SyncableFlag(NS, "b", "false", false)
+        );
+
+        List<SyncableFlag> outputFlagsFirst = mFeatureFlagsService.queryFlags(inputFlagsFirst);
+        List<SyncableFlag> outputFlagsSecond = mFeatureFlagsService.queryFlags(inputFlagsSecond);
+
+        assertThat(inputFlagsFirst.size()).isEqualTo(outputFlagsFirst.size());
+        assertThat(inputFlagsSecond.size()).isEqualTo(outputFlagsSecond.size());
+
+        // This test only cares that the "a" flag passed in the second time came out with the
+        // same value that was passed in (i.e. it wasn't cached).
+
+        boolean found = false;
+        for (SyncableFlag second : outputFlagsSecond) {
+            if (compareSyncableFlagsNames(second, inputFlagsSecond.get(0))) {
+                found = true;
+                assertThat(second.getValue()).isEqualTo(inputFlagsSecond.get(0).getValue());
+                break;
+            }
+        }
+
+        assertWithMessage(
+                "Failed to find flag " + inputFlagsSecond.get(0) + " in the second calls output")
+                .that(found).isTrue();
+    }
+
+    @Test
+    public void testOverrideFlag() {
+        SyncableFlag f = new SyncableFlag(NS, "a", "false", false);
+
+        mFeatureFlagsService.overrideFlag(f);
+
+        verify(mFlagStore).set(f.getNamespace(), f.getName(), f.getValue());
+    }
+
+    @Test
+    public void testResetFlag() {
+        SyncableFlag f = new SyncableFlag(NS, "a", "false", false);
+
+        mFeatureFlagsService.resetFlag(f);
+
+        verify(mFlagStore).erase(f.getNamespace(), f.getName());
+    }
+
+
+    private static boolean compareSyncableFlagsNames(SyncableFlag a, SyncableFlag b) {
+        return a.getNamespace().equals(b.getNamespace())
+                && a.getName().equals(b.getName())
+                && a.isDynamic() == b.isDynamic();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/flags/FlagCacheTest.java b/services/tests/servicestests/src/com/android/server/flags/FlagCacheTest.java
new file mode 100644
index 0000000..c2cf540
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/flags/FlagCacheTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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.flags;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class FlagCacheTest {
+    private static final String NS = "ns";
+    private static final String NAME = "name";
+
+    FlagCache mFlagCache = new FlagCache();
+
+    @Test
+    public void testGetOrNull_unset() {
+        assertThat(mFlagCache.getOrNull(NS, NAME)).isNull();
+    }
+
+    @Test
+    public void testGetOrSet_unset() {
+        assertThat(mFlagCache.getOrSet(NS, NAME, "value")).isEqualTo("value");
+    }
+
+    @Test
+    public void testGetOrSet_alreadySet() {
+        mFlagCache.setIfChanged(NS, NAME, "value");
+        assertThat(mFlagCache.getOrSet(NS, NAME, "newvalue")).isEqualTo("value");
+    }
+
+    @Test
+    public void testSetIfChanged_unset() {
+        assertThat(mFlagCache.setIfChanged(NS, NAME, "value")).isTrue();
+    }
+
+    @Test
+    public void testSetIfChanged_noChange() {
+        mFlagCache.setIfChanged(NS, NAME, "value");
+        assertThat(mFlagCache.setIfChanged(NS, NAME, "value")).isFalse();
+    }
+
+    @Test
+    public void testSetIfChanged_changing() {
+        mFlagCache.setIfChanged(NS, NAME, "value");
+        assertThat(mFlagCache.setIfChanged(NS, NAME, "newvalue")).isTrue();
+    }
+
+    @Test
+    public void testContainsNamespace_unset() {
+        assertThat(mFlagCache.containsNamespace(NS)).isFalse();
+    }
+
+    @Test
+    public void testContainsNamespace_set() {
+        mFlagCache.setIfChanged(NS, NAME, "value");
+        assertThat(mFlagCache.containsNamespace(NS)).isTrue();
+    }
+
+    @Test
+    public void testContains_unset() {
+        assertThat(mFlagCache.contains(NS, NAME)).isFalse();
+    }
+
+    @Test
+    public void testContains_set() {
+        mFlagCache.setIfChanged(NS, NAME, "value");
+        assertThat(mFlagCache.contains(NS, NAME)).isTrue();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/flags/FlagOverrideStoreTest.java b/services/tests/servicestests/src/com/android/server/flags/FlagOverrideStoreTest.java
new file mode 100644
index 0000000..6cc3acf
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/flags/FlagOverrideStoreTest.java
@@ -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.server.flags;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+@Presubmit
+@SmallTest
+public class FlagOverrideStoreTest {
+    private static final String NS = "ns";
+    private static final String NAME = "name";
+    private static final String PROP_NAME = FlagOverrideStore.getPropName(NS, NAME);
+
+    @Rule
+    public final MockitoRule mockito = MockitoJUnit.rule();
+
+    @Mock
+    private SettingsProxy mSettingsProxy;
+    @Mock
+    private FlagOverrideStore.FlagChangeCallback mCallback;
+
+    private FlagOverrideStore mFlagStore;
+
+    @Before
+    public void setup() {
+        mFlagStore = new FlagOverrideStore(mSettingsProxy);
+        mFlagStore.setChangeCallback(mCallback);
+    }
+
+    @Test
+    public void testSet_unset() {
+        mFlagStore.set(NS, NAME, "value");
+        verify(mSettingsProxy).putString(PROP_NAME, "value");
+    }
+
+    @Test
+    public void testSet_setTwice() {
+        mFlagStore.set(NS, NAME, "value");
+        mFlagStore.set(NS, NAME, "newvalue");
+        verify(mSettingsProxy).putString(PROP_NAME, "value");
+        verify(mSettingsProxy).putString(PROP_NAME, "newvalue");
+    }
+
+    @Test
+    public void testGet_unset() {
+        assertThat(mFlagStore.get(NS, NAME)).isNull();
+    }
+
+    @Test
+    public void testGet_set() {
+        when(mSettingsProxy.getString(PROP_NAME)).thenReturn("value");
+        assertThat(mFlagStore.get(NS, NAME)).isEqualTo("value");
+    }
+
+    @Test
+    public void testErase() {
+        mFlagStore.erase(NS, NAME);
+        verify(mSettingsProxy).putString(PROP_NAME, null);
+    }
+
+    @Test
+    public void testContains_unset() {
+        assertThat(mFlagStore.contains(NS, NAME)).isFalse();
+    }
+
+    @Test
+    public void testContains_set() {
+        when(mSettingsProxy.getString(PROP_NAME)).thenReturn("value");
+        assertThat(mFlagStore.contains(NS, NAME)).isTrue();
+    }
+
+    @Test
+    public void testCallback_onSet() {
+        mFlagStore.set(NS, NAME, "value");
+        verify(mCallback).onFlagChanged(NS, NAME, "value");
+    }
+
+    @Test
+    public void testCallback_onErase() {
+        mFlagStore.erase(NS, NAME);
+        verify(mCallback).onFlagChanged(NS, NAME, null);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/flags/OWNERS b/services/tests/servicestests/src/com/android/server/flags/OWNERS
new file mode 100644
index 0000000..7ed369e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/flags/OWNERS
@@ -0,0 +1 @@
+include /services/flags/OWNERS
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
index 541739d..2136811 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
@@ -1933,6 +1933,36 @@
         }, 20, 30);
     }
 
+    @Test
+    public void isComponentEnabledForCurrentProfiles_profileUserId() {
+        final int profileUserId = 10;
+        when(mUserProfiles.isProfileUser(profileUserId)).thenReturn(true);
+        // Only approve for parent user (0)
+        mService.addApprovedList("pkg1/cmp1:pkg2/cmp2:pkg3/cmp3", 0, true);
+
+        // Test that the component is enabled after calling rebindServices with profile userId (10)
+        mService.rebindServices(false, profileUserId);
+        assertThat(mService.isComponentEnabledForCurrentProfiles(
+                new ComponentName("pkg1", "cmp1"))).isTrue();
+    }
+
+    @Test
+    public void isComponentEnabledForCurrentProfiles_profileUserId_NAS() {
+        final int profileUserId = 10;
+        when(mUserProfiles.isProfileUser(profileUserId)).thenReturn(true);
+        // Do not rebind for parent users (NAS use-case)
+        ManagedServices service = spy(mService);
+        when(service.allowRebindForParentUser()).thenReturn(false);
+
+        // Only approve for parent user (0)
+        service.addApprovedList("pkg1/cmp1:pkg2/cmp2:pkg3/cmp3", 0, true);
+
+        // Test that the component is disabled after calling rebindServices with profile userId (10)
+        service.rebindServices(false, profileUserId);
+        assertThat(service.isComponentEnabledForCurrentProfiles(
+                new ComponentName("pkg1", "cmp1"))).isFalse();
+    }
+
     private void mockServiceInfoWithMetaData(List<ComponentName> componentNames,
             ManagedServices service, ArrayMap<ComponentName, Bundle> metaDatas)
             throws RemoteException {
@@ -2276,6 +2306,11 @@
         protected String getRequiredPermission() {
             return null;
         }
+
+        @Override
+        protected boolean allowRebindForParentUser() {
+            return true;
+        }
     }
 
     class TestManagedServicesSettings extends TestManagedServices {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelLoggerFake.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelLoggerFake.java
index 6f7bace..082b675 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelLoggerFake.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelLoggerFake.java
@@ -16,24 +16,44 @@
 
 package com.android.server.notification;
 
+import android.annotation.Nullable;
 import android.app.NotificationChannel;
 import android.app.NotificationChannelGroup;
 
+import com.google.common.base.MoreObjects;
+
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 
 public class NotificationChannelLoggerFake implements NotificationChannelLogger {
     static class CallRecord {
-        public NotificationChannelEvent event;
-        CallRecord(NotificationChannelEvent event) {
+        public final NotificationChannelEvent event;
+        @Nullable public final String channelId;
+
+        CallRecord(NotificationChannelEvent event, @Nullable String channelId) {
             this.event = event;
+            this.channelId = channelId;
         }
 
         @Override
         public String toString() {
-            return "CallRecord{" +
-                    "event=" + event +
-                    '}';
+            return MoreObjects.toStringHelper(this)
+                    .add("event", event)
+                    .add(channelId, channelId)
+                    .toString();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            return (obj instanceof CallRecord other)
+                    && Objects.equals(this.event, other.event)
+                    && Objects.equals(this.channelId, other.channelId);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(event, channelId);
         }
     }
 
@@ -47,20 +67,24 @@
         return mCalls.get(index);
     }
 
+    void clear() {
+        mCalls.clear();
+    }
+
     @Override
     public void logNotificationChannel(NotificationChannelEvent event, NotificationChannel channel,
             int uid, String pkg, int oldImportance, int newImportance) {
-        mCalls.add(new CallRecord(event));
+        mCalls.add(new CallRecord(event, channel.getId()));
     }
 
     @Override
     public void logNotificationChannelGroup(NotificationChannelEvent event,
             NotificationChannelGroup channelGroup, int uid, String pkg, boolean wasBlocked) {
-        mCalls.add(new CallRecord(event));
+        mCalls.add(new CallRecord(event, channelGroup.getId()));
     }
 
     @Override
     public void logAppEvent(NotificationChannelEvent event, int uid, String pkg) {
-        mCalls.add(new CallRecord(event));
+        mCalls.add(new CallRecord(event, null));
     }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index e49b290..7e81ef2 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -62,6 +62,8 @@
 import static android.os.Build.VERSION_CODES.O_MR1;
 import static android.os.Build.VERSION_CODES.P;
 import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
+import static android.os.PowerWhitelistManager.REASON_NOTIFICATION_SERVICE;
+import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
 import static android.os.UserHandle.USER_SYSTEM;
 import static android.os.UserManager.USER_TYPE_FULL_SECONDARY;
 import static android.os.UserManager.USER_TYPE_PROFILE_CLONE;
@@ -83,6 +85,9 @@
 import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.SHOW_STICKY_HUN_FOR_DENIED_FSI;
 import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.WAKE_LOCK_FOR_POSTING_NOTIFICATION;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
+import static com.android.server.am.PendingIntentRecord.FLAG_ACTIVITY_SENDER;
+import static com.android.server.am.PendingIntentRecord.FLAG_BROADCAST_SENDER;
+import static com.android.server.am.PendingIntentRecord.FLAG_SERVICE_SENDER;
 import static com.android.server.notification.NotificationManagerService.DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE;
 import static com.android.server.notification.NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_ADJUSTED;
 import static com.android.server.notification.NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_POSTED;
@@ -186,6 +191,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Parcel;
+import android.os.Parcelable;
 import android.os.PowerManager;
 import android.os.PowerManager.WakeLock;
 import android.os.Process;
@@ -716,6 +722,7 @@
 
     @After
     public void assertAllWakeLocksReleased() {
+        waitForIdle(); // Finish async work.
         for (WakeLock wakeLock : mAcquiredWakeLocks) {
             assertThat(wakeLock.isHeld()).isFalse();
         }
@@ -5910,6 +5917,26 @@
     }
 
     @Test
+    public void testVisitUris_wearableExtender() {
+        Icon actionIcon = Icon.createWithContentUri("content://media/action");
+        Icon wearActionIcon = Icon.createWithContentUri("content://media/wearAction");
+        PendingIntent intent = PendingIntent.getActivity(mContext, 0, new Intent(),
+                PendingIntent.FLAG_IMMUTABLE);
+        Notification n = new Notification.Builder(mContext, "a")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .addAction(new Notification.Action.Builder(actionIcon, "Hey!", intent).build())
+                .extend(new Notification.WearableExtender().addAction(
+                        new Notification.Action.Builder(wearActionIcon, "Wear!", intent).build()))
+                .build();
+
+        Consumer<Uri> visitor = (Consumer<Uri>) spy(Consumer.class);
+        n.visitUris(visitor);
+
+        verify(visitor).accept(eq(actionIcon.getUri()));
+        verify(visitor).accept(eq(wearActionIcon.getUri()));
+    }
+
+    @Test
     public void testSetNotificationPolicy_preP_setOldFields() {
         ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
         mService.mZenModeHelper = mZenModeHelper;
@@ -11242,7 +11269,6 @@
         // Given: a call notification has the flag FLAG_ONGOING_EVENT set
         // feature flag: ALLOW_DISMISS_ONGOING is on
         mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, true);
-        when(mTelecomManager.isInManagedCall()).thenReturn(true);
 
         Person person = new Person.Builder()
                 .setName("caller")
@@ -12097,6 +12123,70 @@
         assertThat(mService.mNotificationList.get(0).getNotification().when).isEqualTo(111); // old
     }
 
+    @Test
+    public void enqueueNotification_allowlistsPendingIntents() throws RemoteException {
+        PendingIntent contentIntent = createPendingIntent("content");
+        PendingIntent actionIntent1 = createPendingIntent("action1");
+        PendingIntent actionIntent2 = createPendingIntent("action2");
+        Notification n = new Notification.Builder(mContext, TEST_CHANNEL_ID)
+                .setContentIntent(contentIntent)
+                .addAction(new Notification.Action.Builder(null, "action1", actionIntent1).build())
+                .addAction(new Notification.Action.Builder(null, "action2", actionIntent2).build())
+                .build();
+
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 1,
+                parcelAndUnparcel(n, Notification.CREATOR), mUserId);
+
+        verify(mAmi, times(3)).setPendingIntentAllowlistDuration(
+                any(), any(), anyLong(),
+                eq(TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED),
+                eq(REASON_NOTIFICATION_SERVICE), any());
+        verify(mAmi, times(3)).setPendingIntentAllowBgActivityStarts(any(),
+                any(), eq(FLAG_ACTIVITY_SENDER | FLAG_BROADCAST_SENDER | FLAG_SERVICE_SENDER));
+    }
+
+    @Test
+    public void enqueueNotification_allowlistsPendingIntents_includingFromPublicVersion()
+            throws RemoteException {
+        PendingIntent contentIntent = createPendingIntent("content");
+        PendingIntent actionIntent = createPendingIntent("action");
+        PendingIntent publicContentIntent = createPendingIntent("publicContent");
+        PendingIntent publicActionIntent = createPendingIntent("publicAction");
+        Notification source = new Notification.Builder(mContext, TEST_CHANNEL_ID)
+                .setContentIntent(contentIntent)
+                .addAction(new Notification.Action.Builder(null, "action", actionIntent).build())
+                .setPublicVersion(new Notification.Builder(mContext, "channel")
+                        .setContentIntent(publicContentIntent)
+                        .addAction(new Notification.Action.Builder(
+                                null, "publicAction", publicActionIntent).build())
+                        .build())
+                .build();
+
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 1,
+                parcelAndUnparcel(source, Notification.CREATOR), mUserId);
+
+        verify(mAmi, times(4)).setPendingIntentAllowlistDuration(
+                any(), any(), anyLong(),
+                eq(TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED),
+                eq(REASON_NOTIFICATION_SERVICE), any());
+        verify(mAmi, times(4)).setPendingIntentAllowBgActivityStarts(any(),
+                any(), eq(FLAG_ACTIVITY_SENDER | FLAG_BROADCAST_SENDER | FLAG_SERVICE_SENDER));
+    }
+
+    private static <T extends Parcelable> T parcelAndUnparcel(T source,
+            Parcelable.Creator<T> creator) {
+        Parcel parcel = Parcel.obtain();
+        source.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        return creator.createFromParcel(parcel);
+    }
+
+    private PendingIntent createPendingIntent(String action) {
+        return PendingIntent.getActivity(mContext, 0,
+                new Intent(action).setPackage(mContext.getPackageName()),
+                PendingIntent.FLAG_MUTABLE);
+    }
+
     private void setDpmAppOppsExemptFromDismissal(boolean isOn) {
         DeviceConfig.setProperty(
                 DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER,
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerTest.java
index 0b147c3..b522cab 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerTest.java
@@ -18,6 +18,14 @@
 
 import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.service.notification.NotificationListenerService.REASON_CANCEL;
+import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED;
+import static android.service.notification.NotificationStats.DISMISSAL_BUBBLE;
+import static android.service.notification.NotificationStats.DISMISSAL_OTHER;
+
+import static com.android.server.notification.NotificationRecordLogger.NotificationCancelledEvent.NOTIFICATION_CANCEL_CLICK;
+import static com.android.server.notification.NotificationRecordLogger.NotificationCancelledEvent.NOTIFICATION_CANCEL_GROUP_SUMMARY_CANCELED;
+import static com.android.server.notification.NotificationRecordLogger.NotificationCancelledEvent.NOTIFICATION_CANCEL_USER_OTHER;
 import static com.android.server.notification.NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_POSTED;
 import static com.android.server.notification.NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_UPDATED;
 
@@ -208,4 +216,18 @@
                 /* eventType= */ NOTIFICATION_POSTED);
         assertEquals(FrameworkStatsLog.NOTIFICATION_REPORTED__FSI_STATE__NO_FSI, fsiState);
     }
+
+    @Test
+    public void testBubbleGroupSummaryDismissal() {
+        assertEquals(NOTIFICATION_CANCEL_GROUP_SUMMARY_CANCELED,
+                NotificationRecordLogger.NotificationCancelledEvent.fromCancelReason(
+                REASON_GROUP_SUMMARY_CANCELED, DISMISSAL_BUBBLE));
+    }
+
+    @Test
+    public void testOtherNotificationCancel() {
+        assertEquals(NOTIFICATION_CANCEL_USER_OTHER,
+                NotificationRecordLogger.NotificationCancelledEvent.fromCancelReason(
+                        REASON_CANCEL, DISMISSAL_OTHER));
+    }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java
index d32289d..121e296 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java
@@ -67,6 +67,8 @@
 import java.lang.reflect.Executable;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Comparator;
@@ -88,7 +90,6 @@
     // This list should be emptied! Items can be removed as bugs are fixed.
     private static final Multimap<Class<?>, String> KNOWN_BAD =
             ImmutableMultimap.<Class<?>, String>builder()
-                    .put(Notification.WearableExtender.class, "addAction") // TODO: b/281044385
                     .put(Person.Builder.class, "setUri") // TODO: b/281044385
                     .put(RemoteViews.class, "setRemoteAdapter") // TODO: b/281044385
                     .build();
@@ -164,7 +165,7 @@
                 /* extenderClass= */ Notification.WearableExtender.class,
                 /* actionExtenderClass= */ Notification.Action.WearableExtender.class,
                 /* includeRemoteViews= */ true);
-        assertThat(notification.includedUris.size()).isAtLeast(730);
+        assertThat(notification.includedUris.size()).isAtLeast(900);
     }
 
     @Test
@@ -450,19 +451,43 @@
             Set<Class<?>> excludingClasses, SpecialParameterGenerator specialGenerator) {
         Log.i(TAG, "About to generate parameters for " + ReflectionUtils.methodToString(executable)
                 + " in " + where);
-        Class<?>[] parameterTypes = executable.getParameterTypes();
+        Type[] parameterTypes = executable.getGenericParameterTypes();
         Object[] parameterValues = new Object[parameterTypes.length];
         for (int i = 0; i < parameterTypes.length; i++) {
-            parameterValues[i] = generateObject(
+            parameterValues[i] = generateParameter(
                     parameterTypes[i],
                     where.plus(executable,
-                            String.format("[%d,%s]", i, parameterTypes[i].getName())),
+                            String.format("[%d,%s]", i, parameterTypes[i].getTypeName())),
                     excludingClasses,
                     specialGenerator);
         }
         return parameterValues;
     }
 
+    private static Object generateParameter(Type parameterType, Location where,
+            Set<Class<?>> excludingClasses, SpecialParameterGenerator specialGenerator) {
+        if (parameterType instanceof Class<?> parameterClass) {
+            return generateObject(
+                    parameterClass,
+                    where,
+                    excludingClasses,
+                    specialGenerator);
+        } else if (parameterType instanceof ParameterizedType parameterizedType) {
+            if (parameterizedType.getRawType().equals(List.class)
+                    && parameterizedType.getActualTypeArguments()[0] instanceof Class<?>) {
+                ArrayList listValue = new ArrayList();
+                for (int i = 0; i < NUM_ELEMENTS_IN_ARRAY; i++) {
+                    listValue.add(
+                            generateObject((Class<?>) parameterizedType.getActualTypeArguments()[0],
+                                    where, excludingClasses, specialGenerator));
+                }
+                return listValue;
+            }
+        }
+        throw new IllegalArgumentException(
+                "I have no idea how to produce a(n) " + parameterType + ", sorry");
+    }
+
     private static class ReflectionUtils {
         static Set<Class<?>> getConcreteSubclasses(Class<?> clazz, Class<?> containerClass) {
             return Arrays.stream(containerClass.getDeclaredClasses())
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index 47340c1..ea670bd 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -18,8 +18,19 @@
 import static android.app.AppOpsManager.MODE_ALLOWED;
 import static android.app.AppOpsManager.MODE_DEFAULT;
 import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
+import static android.app.Notification.VISIBILITY_PRIVATE;
+import static android.app.Notification.VISIBILITY_SECRET;
+import static android.app.NotificationChannel.ALLOW_BUBBLE_ON;
 import static android.app.NotificationChannel.CONVERSATION_CHANNEL_ID_FORMAT;
+import static android.app.NotificationChannel.DEFAULT_ALLOW_BUBBLE;
+import static android.app.NotificationChannel.USER_LOCKED_ALLOW_BUBBLE;
 import static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE;
+import static android.app.NotificationChannel.USER_LOCKED_LIGHTS;
+import static android.app.NotificationChannel.USER_LOCKED_PRIORITY;
+import static android.app.NotificationChannel.USER_LOCKED_SHOW_BADGE;
+import static android.app.NotificationChannel.USER_LOCKED_SOUND;
+import static android.app.NotificationChannel.USER_LOCKED_VIBRATION;
+import static android.app.NotificationChannel.USER_LOCKED_VISIBILITY;
 import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
 import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE;
 import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED;
@@ -29,16 +40,18 @@
 import static android.app.NotificationManager.IMPORTANCE_MAX;
 import static android.app.NotificationManager.IMPORTANCE_NONE;
 import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+import static android.app.NotificationManager.VISIBILITY_NO_OVERRIDE;
 import static android.media.AudioAttributes.CONTENT_TYPE_SONIFICATION;
 import static android.media.AudioAttributes.USAGE_NOTIFICATION;
 import static android.os.UserHandle.USER_SYSTEM;
 import static android.util.StatsLog.ANNOTATION_ID_IS_UID;
 
+import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.PROPAGATE_CHANNEL_UPDATES_TO_CONVERSATIONS;
 import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES;
 import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES;
-import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__NOT_REQUESTED;
-import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__GRANTED;
 import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__DENIED;
+import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__GRANTED;
+import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__NOT_REQUESTED;
 import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.CHANNEL_ID_FIELD_NUMBER;
 import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.CHANNEL_NAME_FIELD_NUMBER;
 import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.IMPORTANCE_FIELD_NUMBER;
@@ -47,10 +60,12 @@
 import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.IS_DEMOTED_CONVERSATION_FIELD_NUMBER;
 import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.IS_IMPORTANT_CONVERSATION_FIELD_NUMBER;
 import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.UID_FIELD_NUMBER;
+import static com.android.server.notification.NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_UPDATED_BY_USER;
 import static com.android.server.notification.PreferencesHelper.DEFAULT_BUBBLE_PREFERENCE;
 import static com.android.server.notification.PreferencesHelper.NOTIFICATION_CHANNEL_COUNT_LIMIT;
 import static com.android.server.notification.PreferencesHelper.NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT;
 import static com.android.server.notification.PreferencesHelper.UNKNOWN_UID;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static junit.framework.Assert.assertNull;
@@ -124,6 +139,8 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags;
+import com.android.internal.config.sysui.TestableFlagResolver;
 import com.android.modules.utils.TypedXmlPullParser;
 import com.android.modules.utils.TypedXmlSerializer;
 import com.android.os.AtomsProto.PackageNotificationPreferences;
@@ -134,6 +151,7 @@
 
 import org.json.JSONArray;
 import org.json.JSONObject;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -181,6 +199,9 @@
     private static final Uri FILE_SOUND_URI =
             Uri.parse("file://" + TEST_AUTHORITY + "/product/media/test.ogg");
 
+    private static final Uri DEFAULT_SOUND_URI = Uri.parse(
+            "content://settings/system/notification_sound");
+
     @Mock PermissionHelper mPermissionHelper;
     @Mock RankingHandler mHandler;
     @Mock PackageManager mPm;
@@ -325,6 +346,11 @@
                 NotificationManagerService.REVIEW_NOTIF_STATE_UNKNOWN);
     }
 
+    @After
+    public void tearDown() {
+        SystemUiSystemPropertiesFlags.TEST_RESOLVER = null;
+    }
+
     private ByteArrayOutputStream writeXmlAndPurge(
             String pkg, int uid, boolean forBackup, int userId, String... channelIds)
             throws Exception {
@@ -509,7 +535,7 @@
         channel2.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
         channel2.enableLights(true);
         channel2.setBypassDnd(true);
-        channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
+        channel2.setLockscreenVisibility(VISIBILITY_SECRET);
         channel2.enableVibration(true);
         channel2.setGroup(ncg.getId());
         channel2.setVibrationPattern(new long[]{100, 67, 145, 156});
@@ -577,7 +603,7 @@
         channel2.setSound(SOUND_URI, mAudioAttributes);
         channel2.enableLights(true);
         channel2.setBypassDnd(true);
-        channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
+        channel2.setLockscreenVisibility(VISIBILITY_SECRET);
         channel2.enableVibration(false);
         channel2.setGroup(ncg.getId());
         channel2.setLightColor(Color.BLUE);
@@ -1054,7 +1080,7 @@
         channel2.setSound(null, null);
         channel2.enableLights(true);
         channel2.setBypassDnd(true);
-        channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
+        channel2.setLockscreenVisibility(VISIBILITY_SECRET);
         channel2.enableVibration(false);
         channel2.setGroup(ncg.getId());
         channel2.setLightColor(Color.BLUE);
@@ -1140,7 +1166,7 @@
         channel2.setSound(null, null);
         channel2.enableLights(true);
         channel2.setBypassDnd(true);
-        channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
+        channel2.setLockscreenVisibility(VISIBILITY_SECRET);
         channel2.enableVibration(false);
         channel2.setGroup(ncg.getId());
         channel2.setLightColor(Color.BLUE);
@@ -1228,7 +1254,7 @@
         channel2.setSound(null, null);
         channel2.enableLights(true);
         channel2.setBypassDnd(true);
-        channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
+        channel2.setLockscreenVisibility(VISIBILITY_SECRET);
         channel2.enableVibration(false);
         channel2.setGroup(ncg.getId());
         channel2.setLightColor(Color.BLUE);
@@ -1621,7 +1647,7 @@
                 NotificationChannel.DEFAULT_CHANNEL_ID, false);
         assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, updated.getImportance());
         assertFalse(updated.canBypassDnd());
-        assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE, updated.getLockscreenVisibility());
+        assertEquals(VISIBILITY_NO_OVERRIDE, updated.getLockscreenVisibility());
         assertEquals(0, updated.getUserLockedFields());
     }
 
@@ -1649,9 +1675,9 @@
                 + "<package name=\"" + PKG_N_MR1
                 + "\" importance=\"" + NotificationManager.IMPORTANCE_HIGH
                 + "\" priority=\"" + Notification.PRIORITY_MAX + "\" visibility=\""
-                + Notification.VISIBILITY_SECRET + "\"" +" uid=\"" + UID_N_MR1 + "\" />\n"
+                + VISIBILITY_SECRET + "\"" + " uid=\"" + UID_N_MR1 + "\" />\n"
                 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" visibility=\""
-                + Notification.VISIBILITY_PRIVATE + "\" />\n"
+                + VISIBILITY_PRIVATE + "\" />\n"
                 + "</ranking>";
         TypedXmlPullParser parser = Xml.newFastPullParser();
         parser.setInput(new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())),
@@ -1663,10 +1689,10 @@
             mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
         assertEquals(NotificationManager.IMPORTANCE_HIGH, updated1.getImportance());
         assertTrue(updated1.canBypassDnd());
-        assertEquals(Notification.VISIBILITY_SECRET, updated1.getLockscreenVisibility());
+        assertEquals(VISIBILITY_SECRET, updated1.getLockscreenVisibility());
         assertEquals(NotificationChannel.USER_LOCKED_IMPORTANCE
-                | NotificationChannel.USER_LOCKED_PRIORITY
-                | NotificationChannel.USER_LOCKED_VISIBILITY,
+                | USER_LOCKED_PRIORITY
+                | USER_LOCKED_VISIBILITY,
                 updated1.getUserLockedFields());
 
         // No Default Channel created for updated packages
@@ -1811,7 +1837,7 @@
         channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
         channel.enableLights(true);
         channel.setBypassDnd(true);
-        channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
+        channel.setLockscreenVisibility(VISIBILITY_SECRET);
 
         assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, false, false,
                 SYSTEM_UID, true));
@@ -1838,7 +1864,7 @@
     public void testUpdate_preUpgrade_updatesAppFields() throws Exception {
         assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
         assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
-        assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
+        assertEquals(VISIBILITY_NO_OVERRIDE,
                 mHelper.getPackageVisibility(PKG_N_MR1, UID_N_MR1));
 
         NotificationChannel defaultChannel = mHelper.getNotificationChannel(
@@ -1847,7 +1873,7 @@
         defaultChannel.setShowBadge(false);
         defaultChannel.setImportance(IMPORTANCE_NONE);
         defaultChannel.setBypassDnd(true);
-        defaultChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
+        defaultChannel.setLockscreenVisibility(VISIBILITY_SECRET);
 
         mHelper.setAppImportanceLocked(PKG_N_MR1, UID_N_MR1);
         mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true,
@@ -1856,7 +1882,7 @@
         // ensure app level fields are changed
         assertFalse(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
         assertEquals(Notification.PRIORITY_MAX, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
-        assertEquals(Notification.VISIBILITY_SECRET, mHelper.getPackageVisibility(PKG_N_MR1,
+        assertEquals(VISIBILITY_SECRET, mHelper.getPackageVisibility(PKG_N_MR1,
                 UID_N_MR1));
     }
 
@@ -1868,13 +1894,13 @@
                 SYSTEM_UID, true);
         assertTrue(mHelper.canShowBadge(PKG_O, UID_O));
         assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_O, UID_O));
-        assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
+        assertEquals(VISIBILITY_NO_OVERRIDE,
                 mHelper.getPackageVisibility(PKG_O, UID_O));
 
         channel.setShowBadge(false);
         channel.setImportance(IMPORTANCE_NONE);
         channel.setBypassDnd(true);
-        channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
+        channel.setLockscreenVisibility(VISIBILITY_SECRET);
 
         mHelper.updateNotificationChannel(PKG_O, UID_O, channel, true,
                 SYSTEM_UID, true);
@@ -1882,7 +1908,7 @@
         // ensure app level fields are not changed
         assertTrue(mHelper.canShowBadge(PKG_O, UID_O));
         assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_O, UID_O));
-        assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
+        assertEquals(VISIBILITY_NO_OVERRIDE,
                 mHelper.getPackageVisibility(PKG_O, UID_O));
     }
 
@@ -1894,13 +1920,13 @@
                 SYSTEM_UID, true);
         assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
         assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
-        assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
+        assertEquals(VISIBILITY_NO_OVERRIDE,
                 mHelper.getPackageVisibility(PKG_N_MR1, UID_N_MR1));
 
         channel.setShowBadge(false);
         channel.setImportance(IMPORTANCE_NONE);
         channel.setBypassDnd(true);
-        channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
+        channel.setLockscreenVisibility(VISIBILITY_SECRET);
 
         mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true,
                 SYSTEM_UID, true);
@@ -1911,7 +1937,7 @@
         defaultChannel.setShowBadge(false);
         defaultChannel.setImportance(IMPORTANCE_NONE);
         defaultChannel.setBypassDnd(true);
-        defaultChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
+        defaultChannel.setLockscreenVisibility(VISIBILITY_SECRET);
 
         mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true,
                 SYSTEM_UID, true);
@@ -1919,7 +1945,7 @@
         // ensure app level fields are not changed
         assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
         assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
-        assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
+        assertEquals(VISIBILITY_NO_OVERRIDE,
                 mHelper.getPackageVisibility(PKG_N_MR1, UID_N_MR1));
     }
 
@@ -1935,7 +1961,7 @@
         channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
         channel.enableLights(true);
         channel.setBypassDnd(true);
-        channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
+        channel.setLockscreenVisibility(VISIBILITY_SECRET);
         channel.setShowBadge(true);
         channel.setAllowBubbles(false);
         channel.setImportantConversation(true);
@@ -1954,7 +1980,7 @@
         assertEquals(channel.getName(), savedChannel.getName());
         assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
         assertFalse(savedChannel.canBypassDnd());
-        assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
+        assertFalse(VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
         assertFalse(channel.isImportantConversation());
         assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
         assertEquals(channel.canBubble(), savedChannel.canBubble());
@@ -1969,7 +1995,7 @@
         channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
         channel.enableLights(true);
         channel.setBypassDnd(true);
-        channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
+        channel.setLockscreenVisibility(VISIBILITY_SECRET);
         channel.setShowBadge(true);
         channel.setAllowBubbles(false);
         int lockMask = 0;
@@ -1987,7 +2013,7 @@
         assertEquals(channel.getName(), savedChannel.getName());
         assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
         assertFalse(savedChannel.canBypassDnd());
-        assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
+        assertFalse(VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
         assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
         assertEquals(channel.canBubble(), savedChannel.canBubble());
     }
@@ -1998,7 +2024,7 @@
         mHelper.clearLockedFieldsLocked(channel);
         assertEquals(0, channel.getUserLockedFields());
 
-        channel.lockFields(NotificationChannel.USER_LOCKED_PRIORITY
+        channel.lockFields(USER_LOCKED_PRIORITY
                 | NotificationChannel.USER_LOCKED_IMPORTANCE);
         mHelper.clearLockedFieldsLocked(channel);
         assertEquals(0, channel.getUserLockedFields());
@@ -2012,19 +2038,19 @@
         final NotificationChannel update1 = getChannel();
         update1.setSound(new Uri.Builder().scheme("test").build(),
                 new AudioAttributes.Builder().build());
-        update1.lockFields(NotificationChannel.USER_LOCKED_PRIORITY);
+        update1.lockFields(USER_LOCKED_PRIORITY);
         mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true, SYSTEM_UID, true);
-        assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
-                | NotificationChannel.USER_LOCKED_SOUND,
+        assertEquals(USER_LOCKED_PRIORITY
+                | USER_LOCKED_SOUND,
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
                         .getUserLockedFields());
 
         NotificationChannel update2 = getChannel();
         update2.enableVibration(true);
         mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true, SYSTEM_UID, true);
-        assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
-                        | NotificationChannel.USER_LOCKED_SOUND
-                        | NotificationChannel.USER_LOCKED_VIBRATION,
+        assertEquals(USER_LOCKED_PRIORITY
+                        | USER_LOCKED_SOUND
+                        | USER_LOCKED_VIBRATION,
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
                         .getUserLockedFields());
     }
@@ -2037,15 +2063,15 @@
         final NotificationChannel update1 = getChannel();
         update1.setVibrationPattern(new long[]{7945, 46 ,246});
         mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true, SYSTEM_UID, true);
-        assertEquals(NotificationChannel.USER_LOCKED_VIBRATION,
+        assertEquals(USER_LOCKED_VIBRATION,
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
                         .getUserLockedFields());
 
         final NotificationChannel update2 = getChannel();
         update2.enableLights(true);
         mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true, SYSTEM_UID, true);
-        assertEquals(NotificationChannel.USER_LOCKED_VIBRATION
-                        | NotificationChannel.USER_LOCKED_LIGHTS,
+        assertEquals(USER_LOCKED_VIBRATION
+                        | USER_LOCKED_LIGHTS,
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
                         .getUserLockedFields());
     }
@@ -2058,7 +2084,7 @@
         final NotificationChannel update1 = getChannel();
         update1.setLightColor(Color.GREEN);
         mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true, SYSTEM_UID, true);
-        assertEquals(NotificationChannel.USER_LOCKED_LIGHTS,
+        assertEquals(USER_LOCKED_LIGHTS,
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
                         .getUserLockedFields());
 
@@ -2066,7 +2092,7 @@
         update2.setImportance(IMPORTANCE_DEFAULT);
         mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true,
                 SYSTEM_UID, true);
-        assertEquals(NotificationChannel.USER_LOCKED_LIGHTS
+        assertEquals(USER_LOCKED_LIGHTS
                         | NotificationChannel.USER_LOCKED_IMPORTANCE,
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
                         .getUserLockedFields());
@@ -2083,24 +2109,24 @@
         final NotificationChannel update1 = getChannel();
         update1.setBypassDnd(true);
         mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true, SYSTEM_UID, true);
-        assertEquals(NotificationChannel.USER_LOCKED_PRIORITY,
+        assertEquals(USER_LOCKED_PRIORITY,
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
                         .getUserLockedFields());
 
         final NotificationChannel update2 = getChannel();
-        update2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
+        update2.setLockscreenVisibility(VISIBILITY_SECRET);
         mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true, SYSTEM_UID, true);
-        assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
-                        | NotificationChannel.USER_LOCKED_VISIBILITY,
+        assertEquals(USER_LOCKED_PRIORITY
+                        | USER_LOCKED_VISIBILITY,
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
                         .getUserLockedFields());
 
         final NotificationChannel update3 = getChannel();
         update3.setShowBadge(false);
         mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update3, true, SYSTEM_UID, true);
-        assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
-                        | NotificationChannel.USER_LOCKED_VISIBILITY
-                        | NotificationChannel.USER_LOCKED_SHOW_BADGE,
+        assertEquals(USER_LOCKED_PRIORITY
+                        | USER_LOCKED_VISIBILITY
+                        | USER_LOCKED_SHOW_BADGE,
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update3.getId(), false)
                         .getUserLockedFields());
     }
@@ -2117,7 +2143,7 @@
         update.setAllowBubbles(true);
         mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true,
                 SYSTEM_UID, true);
-        assertEquals(NotificationChannel.USER_LOCKED_ALLOW_BUBBLE,
+        assertEquals(USER_LOCKED_ALLOW_BUBBLE,
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update.getId(), false)
                         .getUserLockedFields());
     }
@@ -2153,7 +2179,7 @@
         channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
         channel.enableLights(true);
         channel.setBypassDnd(true);
-        channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
+        channel.setLockscreenVisibility(VISIBILITY_SECRET);
         channel.enableVibration(true);
         channel.setVibrationPattern(new long[]{100, 67, 145, 156});
 
@@ -2181,7 +2207,7 @@
         channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
         channel.enableLights(true);
         channel.setBypassDnd(true);
-        channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
+        channel.setLockscreenVisibility(VISIBILITY_PRIVATE);
         channel.enableVibration(true);
         channel.setVibrationPattern(new long[]{100, 67, 145, 156});
         channelMap.put(channel.getId(), channel);
@@ -5115,6 +5141,231 @@
     }
 
     @Test
+    public void testUpdateConversationParent_updatesConversations() {
+        SystemUiSystemPropertiesFlags.TEST_RESOLVER = new TestableFlagResolver()
+                .setFlagOverride(PROPAGATE_CHANNEL_UPDATES_TO_CONVERSATIONS, true);
+
+        NotificationChannel parent =
+                new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
+        mHelper.createNotificationChannel(PKG_O, UID_O, parent, /* fromTargetApp= */ true,
+                /* hasDndAccess= */ false, UID_O, /* fromSystemOrSystemUi= */ false);
+        NotificationChannel convoA = new NotificationChannel("A", "With A", IMPORTANCE_DEFAULT);
+        convoA.setConversationId(parent.getId(), "A");
+        mHelper.createNotificationChannel(PKG_O, UID_O, convoA, /* fromTargetApp= */ true,
+                /* hasDndAccess= */ false, UID_O, /* fromSystemOrSystemUi= */ false);
+        NotificationChannel convoB = new NotificationChannel("B", "With B", IMPORTANCE_DEFAULT);
+        convoB.setConversationId(parent.getId(), "B");
+        mHelper.createNotificationChannel(PKG_O, UID_O, convoB, /* fromTargetApp= */ true,
+                /* hasDndAccess= */ false, UID_O, /* fromSystemOrSystemUi= */ false);
+        assertThat(mHelper.getNotificationChannel(PKG_O, UID_O, "messages", /* includeDeleted= */
+                false).shouldVibrate()).isFalse();
+        assertThat(mHelper.getNotificationChannel(PKG_O, UID_O, "A",
+                /* includeDeleted= */ false).shouldVibrate()).isFalse();
+        assertThat(mHelper.getNotificationChannel(PKG_O, UID_O, "B",
+                /* includeDeleted= */ false).shouldVibrate()).isFalse();
+        mLogger.clear();
+
+        NotificationChannel parentUpdate = cloneChannel(parent);
+        parentUpdate.enableVibration(true);
+        mHelper.updateNotificationChannel(PKG_O, UID_O, parentUpdate, /* fromUser= */ true, UID_O,
+                /* fromSystemOrSystemUi= */ true);
+
+        assertThat(mHelper.getNotificationChannel(PKG_O, UID_O, "messages",
+                /* includeDeleted= */ false).shouldVibrate()).isTrue();
+        assertThat(mHelper.getNotificationChannel(PKG_O, UID_O, "A",
+                /* includeDeleted= */ false).shouldVibrate()).isTrue();
+        assertThat(mHelper.getNotificationChannel(PKG_O, UID_O, "B",
+                /* includeDeleted= */ false).shouldVibrate()).isTrue();
+
+        // Verify that the changes to parent and children were logged.
+        assertThat(mLogger.getCalls()).containsExactly(
+                        new NotificationChannelLoggerFake.CallRecord(
+                                NOTIFICATION_CHANNEL_UPDATED_BY_USER, "messages"),
+                        new NotificationChannelLoggerFake.CallRecord(
+                                NOTIFICATION_CHANNEL_UPDATED_BY_USER, "A"),
+                        new NotificationChannelLoggerFake.CallRecord(
+                                NOTIFICATION_CHANNEL_UPDATED_BY_USER, "B"))
+                .inOrder();
+    }
+
+    @Test
+    public void testUpdateConversationParent_updatesUnlockedFields() {
+        SystemUiSystemPropertiesFlags.TEST_RESOLVER = new TestableFlagResolver()
+                .setFlagOverride(PROPAGATE_CHANNEL_UPDATES_TO_CONVERSATIONS, true);
+
+        NotificationChannel parent =
+                new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
+        mHelper.createNotificationChannel(PKG_O, UID_O, parent, /* fromTargetApp= */ true,
+                /* hasDndAccess= */ false, UID_O, /* fromSystemOrSystemUi= */ false);
+        NotificationChannel convo = new NotificationChannel("A", "With A", IMPORTANCE_DEFAULT);
+        convo.setConversationId(parent.getId(), "A");
+        mHelper.createNotificationChannel(PKG_O, UID_O, convo, /* fromTargetApp= */ true,
+                /* hasDndAccess= */ false, UID_O, /* fromSystemOrSystemUi= */ false);
+        NotificationChannel originalChild = mHelper.getNotificationChannel(PKG_O, UID_O,
+                convo.getId(), /* includeDeleted= */ false);
+        assertThat(originalChild.canBypassDnd()).isFalse();
+        assertThat(originalChild.getLockscreenVisibility()).isEqualTo(VISIBILITY_NO_OVERRIDE);
+        assertThat(originalChild.getImportance()).isEqualTo(IMPORTANCE_DEFAULT);
+        assertThat(originalChild.shouldShowLights()).isFalse();
+        assertThat(originalChild.getSound()).isEqualTo(DEFAULT_SOUND_URI);
+        assertThat(originalChild.shouldVibrate()).isFalse();
+        assertThat(originalChild.canShowBadge()).isTrue();
+        assertThat(originalChild.getAllowBubbles()).isEqualTo(DEFAULT_ALLOW_BUBBLE);
+
+        NotificationChannel parentUpdate = cloneChannel(parent);
+        parentUpdate.setBypassDnd(true);
+        parentUpdate.setLockscreenVisibility(VISIBILITY_SECRET);
+        parentUpdate.setImportance(IMPORTANCE_HIGH);
+        parentUpdate.enableLights(true);
+        parentUpdate.setSound(SOUND_URI, mAudioAttributes);
+        parentUpdate.enableVibration(true);
+        parentUpdate.setShowBadge(false);
+        parentUpdate.setAllowBubbles(true);
+        mHelper.updateNotificationChannel(PKG_O, UID_O, parentUpdate, /* fromUser= */ true,
+                UID_O, /* fromSystemOrSystemUi= */ true);
+
+        NotificationChannel updatedChild = mHelper.getNotificationChannel(PKG_O, UID_O,
+                "A", /* includeDeleted= */ false);
+        assertThat(updatedChild.canBypassDnd()).isTrue();
+        assertThat(updatedChild.getLockscreenVisibility()).isEqualTo(VISIBILITY_SECRET);
+        assertThat(updatedChild.getImportance()).isEqualTo(IMPORTANCE_HIGH);
+        assertThat(updatedChild.shouldShowLights()).isTrue();
+        assertThat(updatedChild.getSound()).isEqualTo(SOUND_URI);
+        assertThat(updatedChild.shouldVibrate()).isTrue();
+        assertThat(updatedChild.canShowBadge()).isFalse();
+        assertThat(updatedChild.getAllowBubbles()).isEqualTo(ALLOW_BUBBLE_ON);
+    }
+
+    @Test
+    public void testUpdateConversationParent_doesNotUpdateLockedFields() {
+        SystemUiSystemPropertiesFlags.TEST_RESOLVER = new TestableFlagResolver()
+                .setFlagOverride(PROPAGATE_CHANNEL_UPDATES_TO_CONVERSATIONS, true);
+        NotificationChannel parent =
+                new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
+        mHelper.createNotificationChannel(PKG_O, UID_O, parent, /* fromTargetApp= */ true,
+                /* hasDndAccess= */ false, UID_O, /* fromSystemOrSystemUi= */ false);
+        NotificationChannel convo = new NotificationChannel("A", "With A", IMPORTANCE_DEFAULT);
+        convo.setConversationId(parent.getId(), "A");
+        mHelper.createNotificationChannel(PKG_O, UID_O, convo, /* fromTargetApp= */ true,
+                /* hasDndAccess= */ false, UID_O, /* fromSystemOrSystemUi= */ false);
+        // Directly update the child to lock every field.
+        // Normally this would be the result of one or more "fromUser" updates with modified fields.
+        convo.lockFields(
+                USER_LOCKED_PRIORITY | USER_LOCKED_VISIBILITY | USER_LOCKED_IMPORTANCE
+                        | USER_LOCKED_LIGHTS | USER_LOCKED_VIBRATION | USER_LOCKED_SOUND
+                        | USER_LOCKED_SHOW_BADGE | USER_LOCKED_ALLOW_BUBBLE);
+        mLogger.clear();
+
+        NotificationChannel parentUpdate = cloneChannel(parent);
+        parentUpdate.setBypassDnd(true);
+        parentUpdate.setLockscreenVisibility(VISIBILITY_SECRET);
+        parentUpdate.setImportance(IMPORTANCE_HIGH);
+        parentUpdate.enableLights(true);
+        parentUpdate.setSound(SOUND_URI, mAudioAttributes);
+        parentUpdate.enableVibration(true);
+        parentUpdate.setShowBadge(false);
+        parentUpdate.setAllowBubbles(true);
+        mHelper.updateNotificationChannel(PKG_O, UID_O, parentUpdate, /* fromUser= */ true,
+                UID_O, /* fromSystemOrSystemUi= */ true);
+
+        NotificationChannel updatedChild = mHelper.getNotificationChannel(PKG_O, UID_O,
+                "A", /* includeDeleted= */ false);
+        assertThat(updatedChild.canBypassDnd()).isFalse();
+        assertThat(updatedChild.getLockscreenVisibility()).isEqualTo(VISIBILITY_NO_OVERRIDE);
+        assertThat(updatedChild.getImportance()).isEqualTo(IMPORTANCE_DEFAULT);
+        assertThat(updatedChild.shouldShowLights()).isFalse();
+        assertThat(updatedChild.getSound()).isEqualTo(DEFAULT_SOUND_URI);
+        assertThat(updatedChild.shouldVibrate()).isFalse();
+        assertThat(updatedChild.canShowBadge()).isTrue();
+        assertThat(updatedChild.getAllowBubbles()).isEqualTo(DEFAULT_ALLOW_BUBBLE);
+
+        // Verify that only the changes to the parent were logged.
+        assertThat(mLogger.getCalls()).containsExactly(
+                        new NotificationChannelLoggerFake.CallRecord(
+                                NOTIFICATION_CHANNEL_UPDATED_BY_USER, "messages"));
+    }
+
+    @Test
+    public void testUpdateConversationParent_updatesDemotedConversation() {
+        SystemUiSystemPropertiesFlags.TEST_RESOLVER = new TestableFlagResolver()
+                .setFlagOverride(PROPAGATE_CHANNEL_UPDATES_TO_CONVERSATIONS, true);
+        NotificationChannel parent =
+                new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
+        mHelper.createNotificationChannel(PKG_O, UID_O, parent, /* fromTargetApp= */ true,
+                /* hasDndAccess= */ false, UID_O, /* fromSystemOrSystemUi= */ false);
+        NotificationChannel convo = new NotificationChannel("A", "With A", IMPORTANCE_DEFAULT);
+        convo.setConversationId(parent.getId(), "A");
+        convo.setDemoted(true);
+        mHelper.createNotificationChannel(PKG_O, UID_O, convo, /* fromTargetApp= */ true,
+                /* hasDndAccess= */ false, UID_O, /* fromSystemOrSystemUi= */ false);
+        NotificationChannel originalChild = mHelper.getNotificationChannel(PKG_O, UID_O,
+                convo.getId(), /* includeDeleted= */ false);
+        assertThat(originalChild.shouldVibrate()).isFalse();
+
+        NotificationChannel parentUpdate = cloneChannel(parent);
+        parentUpdate.enableVibration(true);
+        mHelper.updateNotificationChannel(PKG_O, UID_O, parentUpdate, /* fromUser= */ true,
+                UID_O, /* fromSystemOrSystemUi= */ true);
+
+        NotificationChannel updatedChild = mHelper.getNotificationChannel(PKG_O, UID_O,
+                "A", /* includeDeleted= */ false);
+        assertThat(updatedChild.shouldVibrate()).isTrue();
+    }
+
+    @Test
+    public void testUpdateConversationParent_updatesDeletedConversation() {
+        SystemUiSystemPropertiesFlags.TEST_RESOLVER = new TestableFlagResolver()
+                .setFlagOverride(PROPAGATE_CHANNEL_UPDATES_TO_CONVERSATIONS, true);
+        NotificationChannel parent =
+                new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
+        mHelper.createNotificationChannel(PKG_O, UID_O, parent, /* fromTargetApp= */ true,
+                /* hasDndAccess= */ false, UID_O, /* fromSystemOrSystemUi= */ false);
+        NotificationChannel convo = new NotificationChannel("A", "With A", IMPORTANCE_DEFAULT);
+        convo.setConversationId(parent.getId(), "A");
+        mHelper.createNotificationChannel(PKG_O, UID_O, convo, /* fromTargetApp= */ true,
+                /* hasDndAccess= */ false, UID_O, /* fromSystemOrSystemUi= */ false);
+        mHelper.deleteNotificationChannel(PKG_O, UID_O, "A", UID_O,
+                /* fromSystemOrSystemUi= */ false);
+        assertThat(mHelper.getNotificationChannel(PKG_O, UID_O, "A",
+                /* includeDeleted= */ false)).isNull();
+
+        NotificationChannel parentUpdate = cloneChannel(parent);
+        parentUpdate.enableVibration(true);
+        mHelper.updateNotificationChannel(PKG_O, UID_O, parentUpdate, /* fromUser= */ true,
+                UID_O, /* fromSystemOrSystemUi= */ true);
+
+        NotificationChannel updatedChild = mHelper.getNotificationChannel(PKG_O, UID_O,
+                "A", /* includeDeleted= */ true);
+        assertThat(updatedChild.shouldVibrate()).isTrue();
+    }
+
+    @Test
+    public void testUpdateConversationParent_flagOff_doesNotUpdateConversations() {
+        SystemUiSystemPropertiesFlags.TEST_RESOLVER = new TestableFlagResolver()
+                .setFlagOverride(PROPAGATE_CHANNEL_UPDATES_TO_CONVERSATIONS, false);
+        NotificationChannel parent =
+                new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
+        mHelper.createNotificationChannel(PKG_O, UID_O, parent, /* fromTargetApp= */ true,
+                /* hasDndAccess= */ false, UID_O, /* fromSystemOrSystemUi= */ false);
+        NotificationChannel convo = new NotificationChannel("A", "With A", IMPORTANCE_DEFAULT);
+        convo.setConversationId(parent.getId(), "A");
+        mHelper.createNotificationChannel(PKG_O, UID_O, convo, /* fromTargetApp= */ true,
+                /* hasDndAccess= */ false, UID_O, /* fromSystemOrSystemUi= */ false);
+        NotificationChannel originalChild = mHelper.getNotificationChannel(PKG_O, UID_O,
+                convo.getId(), /* includeDeleted= */ false);
+        assertThat(originalChild.shouldVibrate()).isFalse();
+
+        NotificationChannel parentUpdate = cloneChannel(parent);
+        parentUpdate.enableVibration(true);
+        mHelper.updateNotificationChannel(PKG_O, UID_O, parentUpdate, /* fromUser= */ true,
+                UID_O, /* fromSystemOrSystemUi= */ true);
+
+        NotificationChannel untouchedChild = mHelper.getNotificationChannel(PKG_O, UID_O,
+                "A", /* includeDeleted= */ false);
+        assertThat(untouchedChild.shouldVibrate()).isFalse();
+    }
+
+    @Test
     public void testInvalidMessageSent() {
         // create package preferences
         mHelper.canShowBadge(PKG_P, UID_P);
@@ -5447,11 +5698,7 @@
         clearInvocations(mHandler);
         // Note: Creating a NotificationChannel identical to the original is not equals(), because
         // of mOriginalImportance. So we create a "true copy" instead.
-        Parcel parcel = Parcel.obtain();
-        original.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        NotificationChannel same = NotificationChannel.CREATOR.createFromParcel(parcel);
-        parcel.recycle();
+        NotificationChannel same = cloneChannel(original);
 
         mHelper.updateNotificationChannel(PKG_P, 0, same, false, 0, false);
 
@@ -5560,4 +5807,15 @@
 
         assertFalse(isUserSet);
     }
+
+    private static NotificationChannel cloneChannel(NotificationChannel original) {
+        Parcel parcel = Parcel.obtain();
+        try {
+            original.writeToParcel(parcel, 0);
+            parcel.setDataPosition(0);
+            return NotificationChannel.CREATOR.createFromParcel(parcel);
+        } finally {
+            parcel.recycle();
+        }
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index d179338..1ba8f7d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -74,7 +74,6 @@
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -103,6 +102,7 @@
 import android.os.IBinder;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.platform.test.annotations.Presubmit;
 import android.provider.DeviceConfig;
 import android.service.voice.IVoiceInteractionSession;
@@ -159,6 +159,9 @@
     private static final String FAKE_CALLING_PACKAGE = "com.whatever.dude";
     private static final int UNIMPORTANT_UID = 12345;
     private static final int UNIMPORTANT_UID2 = 12346;
+    private static final int SDK_SANDBOX_UID = Process.toSdkSandboxUid(UNIMPORTANT_UID);
+    private static final int SECONDARY_USER_SDK_SANDBOX_UID =
+            UserHandle.getUid(10, SDK_SANDBOX_UID);
     private static final int CURRENT_IME_UID = 12347;
 
     protected final DeviceConfigStateHelper mDeviceConfig = new DeviceConfigStateHelper(
@@ -958,6 +961,48 @@
         mockingSession.finishMocking();
     }
 
+
+    @Test
+    public void testBackgroundActivityStartsAllowed_sdkSandboxClientAppHasVisibleWindow() {
+        doReturn(false).when(mAtm).isBackgroundActivityStartsEnabled();
+        // The SDK's associated client app has a visible window
+        doReturn(true).when(mAtm).hasActiveVisibleWindow(
+                Process.getAppUidForSdkSandboxUid(SDK_SANDBOX_UID));
+        runAndVerifyBackgroundActivityStartsSubtest(
+                "allowed_sdkSandboxClientAppHasVisibleWindow", false, SDK_SANDBOX_UID,
+                false, PROCESS_STATE_TOP, SDK_SANDBOX_UID, false,
+                PROCESS_STATE_TOP, true, false, false,
+                false, false, false, false, false);
+    }
+
+    @Test
+    public void testBackgroundActivityStartsDisallowed_sdkSandboxClientHasNoVisibleWindow() {
+        doReturn(false).when(mAtm).isBackgroundActivityStartsEnabled();
+        // The SDK's associated client app does not have a visible window
+        doReturn(false).when(mAtm).hasActiveVisibleWindow(
+                Process.getAppUidForSdkSandboxUid(SDK_SANDBOX_UID));
+        runAndVerifyBackgroundActivityStartsSubtest(
+                "disallowed_sdkSandboxClientHasNoVisibleWindow", true, SDK_SANDBOX_UID,
+                false, PROCESS_STATE_TOP, SDK_SANDBOX_UID, false,
+                PROCESS_STATE_TOP, true, false, false,
+                false, false, false, false, false);
+
+    }
+
+    @Test
+    public void testBackgroundActivityStartsAllowed_sdkSandboxMultiUserClientHasVisibleWindow() {
+        doReturn(false).when(mAtm).isBackgroundActivityStartsEnabled();
+        // The SDK's associated client app has a visible window
+        doReturn(true).when(mAtm).hasActiveVisibleWindow(
+                Process.getAppUidForSdkSandboxUid(SECONDARY_USER_SDK_SANDBOX_UID));
+        runAndVerifyBackgroundActivityStartsSubtest(
+                "allowed_sdkSandboxMultiUserClientHasVisibleWindow", false,
+                SECONDARY_USER_SDK_SANDBOX_UID, false, PROCESS_STATE_TOP,
+                SECONDARY_USER_SDK_SANDBOX_UID, false, PROCESS_STATE_TOP,
+                false, false, false, false,
+                false, false, false, false);
+    }
+
     private void runAndVerifyBackgroundActivityStartsSubtest(String name, boolean shouldHaveAborted,
             int callingUid, boolean callingUidHasVisibleWindow, int callingUidProcState,
             int realCallingUid, boolean realCallingUidHasVisibleWindow, int realCallingUidProcState,
diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
index 7cb7c79d..2b19ad9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
@@ -107,6 +107,9 @@
                 InstrumentationRegistry.getInstrumentation().getContext().getCacheDir();
         mFolder = new File(cacheFolder, "launch_params_tests");
         deleteRecursively(mFolder);
+        mFolder.mkdir();
+        mUserFolderGetter.apply(TEST_USER_ID).mkdir();
+        mUserFolderGetter.apply(ALTERNATIVE_USER_ID).mkdir();
 
         mDisplayUniqueId = "test:" + sNextUniqueId++;
         mTestDisplay = new TestDisplayContent.Builder(mAtm, 1000, 1500)
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index 2d8ddfa..a82459f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -64,10 +64,19 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.clearInvocations;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.graphics.Rect;
+import android.os.Binder;
+import android.os.DeadObjectException;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.Parcel;
 import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
 import android.platform.test.annotations.Presubmit;
 import android.view.IRemoteAnimationFinishedCallback;
 import android.view.IRemoteAnimationRunner;
@@ -87,8 +96,10 @@
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
 
+import java.io.FileDescriptor;
 import java.util.ArrayList;
 import java.util.Comparator;
+import java.util.NoSuchElementException;
 
 
 /**
@@ -1404,7 +1415,7 @@
     }
 
     @Test
-    public void testAddLocalInsetsSourceProvider() {
+    public void testAddLocalInsetsFrameProvider() {
          /*
                 ___ rootTask _______________________________________________
                |        |                |                                  |
@@ -1435,19 +1446,20 @@
                 TYPE_BASE_APPLICATION);
         attrs2.setTitle("AppWindow2");
         activity2.addWindow(createWindowState(attrs2, activity2));
+        final Binder owner = new Binder();
         Rect genericOverlayInsetsRect1 = new Rect(0, 200, 1080, 700);
         Rect genericOverlayInsetsRect2 = new Rect(0, 0, 1080, 200);
         final InsetsFrameProvider provider1 =
-                new InsetsFrameProvider(null, 1, WindowInsets.Type.systemOverlays())
+                new InsetsFrameProvider(owner, 1, WindowInsets.Type.systemOverlays())
                         .setArbitraryRectangle(genericOverlayInsetsRect1);
         final InsetsFrameProvider provider2 =
-                new InsetsFrameProvider(null, 2, WindowInsets.Type.systemOverlays())
+                new InsetsFrameProvider(owner, 2, WindowInsets.Type.systemOverlays())
                         .setArbitraryRectangle(genericOverlayInsetsRect2);
         final int sourceId1 = provider1.getId();
         final int sourceId2 = provider2.getId();
 
-        rootTask.addLocalInsetsFrameProvider(provider1);
-        container.addLocalInsetsFrameProvider(provider2);
+        rootTask.addLocalInsetsFrameProvider(provider1, owner);
+        container.addLocalInsetsFrameProvider(provider2, owner);
 
         InsetsSource genericOverlayInsetsProvider1Source = new InsetsSource(
                 sourceId1, systemOverlays());
@@ -1479,7 +1491,7 @@
     }
 
     @Test
-    public void testAddLocalInsetsSourceProvider_sameType_replacesInsets() {
+    public void testAddLocalInsetsFrameProvider_sameType_replacesInsets() {
          /*
                 ___ rootTask ________________________________________
                |                  |                                  |
@@ -1494,24 +1506,25 @@
         attrs.setTitle("AppWindow0");
         activity0.addWindow(createWindowState(attrs, activity0));
 
+        final Binder owner = new Binder();
         final Rect genericOverlayInsetsRect1 = new Rect(0, 200, 1080, 700);
         final Rect genericOverlayInsetsRect2 = new Rect(0, 0, 1080, 200);
         final InsetsFrameProvider provider1 =
-                new InsetsFrameProvider(null, 1, WindowInsets.Type.systemOverlays())
+                new InsetsFrameProvider(owner, 1, WindowInsets.Type.systemOverlays())
                         .setArbitraryRectangle(genericOverlayInsetsRect1);
         final InsetsFrameProvider provider2 =
-                new InsetsFrameProvider(null, 1, WindowInsets.Type.systemOverlays())
+                new InsetsFrameProvider(owner, 1, WindowInsets.Type.systemOverlays())
                         .setArbitraryRectangle(genericOverlayInsetsRect2);
         final int sourceId1 = provider1.getId();
         final int sourceId2 = provider2.getId();
 
-        rootTask.addLocalInsetsFrameProvider(provider1);
+        rootTask.addLocalInsetsFrameProvider(provider1, owner);
         activity0.forAllWindows(window -> {
             assertEquals(genericOverlayInsetsRect1,
                     window.getInsetsState().peekSource(sourceId1).getFrame());
         }, true);
 
-        rootTask.addLocalInsetsFrameProvider(provider2);
+        rootTask.addLocalInsetsFrameProvider(provider2, owner);
 
         activity0.forAllWindows(window -> {
             assertEquals(genericOverlayInsetsRect2,
@@ -1520,7 +1533,7 @@
     }
 
     @Test
-    public void testRemoveLocalInsetsSourceProvider() {
+    public void testRemoveLocalInsetsFrameProvider() {
          /*
                 ___ rootTask _______________________________________________
                |        |                |                                  |
@@ -1554,21 +1567,22 @@
 
         activity2.addWindow(createWindowState(attrs2, activity2));
 
+        final Binder owner = new Binder();
         final Rect navigationBarInsetsRect1 = new Rect(0, 200, 1080, 700);
         final Rect navigationBarInsetsRect2 = new Rect(0, 0, 1080, 200);
         final InsetsFrameProvider provider1 =
-                new InsetsFrameProvider(null, 1, WindowInsets.Type.systemOverlays())
+                new InsetsFrameProvider(owner, 1, WindowInsets.Type.systemOverlays())
                         .setArbitraryRectangle(navigationBarInsetsRect1);
         final InsetsFrameProvider provider2 =
-                new InsetsFrameProvider(null, 2, WindowInsets.Type.systemOverlays())
+                new InsetsFrameProvider(owner, 2, WindowInsets.Type.systemOverlays())
                         .setArbitraryRectangle(navigationBarInsetsRect2);
         final int sourceId1 = provider1.getId();
         final int sourceId2 = provider2.getId();
 
-        rootTask.addLocalInsetsFrameProvider(provider1);
-        container.addLocalInsetsFrameProvider(provider2);
+        rootTask.addLocalInsetsFrameProvider(provider1, owner);
+        container.addLocalInsetsFrameProvider(provider2, owner);
         mDisplayContent.getInsetsStateController().onPostLayout();
-        rootTask.removeLocalInsetsFrameProvider(provider1);
+        rootTask.removeLocalInsetsFrameProvider(provider1, owner);
         mDisplayContent.getInsetsStateController().onPostLayout();
 
         activity0.forAllWindows(window -> {
@@ -1593,6 +1607,67 @@
         }, true);
     }
 
+    @Test
+    public void testAddLocalInsetsFrameProvider_ownerDiesAfterAdding() {
+        final Task task = createTask(mDisplayContent);
+        final TestBinder owner = new TestBinder();
+        final InsetsFrameProvider provider =
+                new InsetsFrameProvider(owner, 0, WindowInsets.Type.systemOverlays())
+                        .setArbitraryRectangle(new Rect());
+        task.addLocalInsetsFrameProvider(provider, owner);
+
+        assertTrue("The death recipient must exist.", owner.hasDeathRecipient());
+        assertTrue("The source must be added.", hasLocalSource(task, provider.getId()));
+
+        // The owner dies after adding the source.
+        owner.die();
+
+        assertFalse("The death recipient must be removed.", owner.hasDeathRecipient());
+        assertFalse("The source must be removed.", hasLocalSource(task, provider.getId()));
+    }
+
+    @Test
+    public void testAddLocalInsetsFrameProvider_ownerDiesBeforeAdding() {
+        final Task task = createTask(mDisplayContent);
+        final TestBinder owner = new TestBinder();
+
+        // The owner dies before adding the source.
+        owner.die();
+
+        final InsetsFrameProvider provider =
+                new InsetsFrameProvider(owner, 0, WindowInsets.Type.systemOverlays())
+                        .setArbitraryRectangle(new Rect());
+        task.addLocalInsetsFrameProvider(provider, owner);
+
+        assertFalse("The death recipient must not exist.", owner.hasDeathRecipient());
+        assertFalse("The source must not be added.", hasLocalSource(task, provider.getId()));
+    }
+
+    @Test
+    public void testRemoveLocalInsetsFrameProvider_removeDeathRecipient() {
+        final Task task = createTask(mDisplayContent);
+        final TestBinder owner = new TestBinder();
+        final InsetsFrameProvider provider =
+                new InsetsFrameProvider(owner, 0, WindowInsets.Type.systemOverlays())
+                        .setArbitraryRectangle(new Rect());
+        task.addLocalInsetsFrameProvider(provider, owner);
+
+        assertTrue("The death recipient must exist.", owner.hasDeathRecipient());
+        assertTrue("The source must be added.", hasLocalSource(task, provider.getId()));
+
+        task.removeLocalInsetsFrameProvider(provider, owner);
+
+        assertFalse("The death recipient must be removed.", owner.hasDeathRecipient());
+        assertFalse("The source must be removed.", hasLocalSource(task, provider.getId()));
+    }
+
+    private static boolean hasLocalSource(WindowContainer container, int sourceId) {
+        if (container.mLocalInsetsSources == null) {
+            return false;
+        }
+        return container.mLocalInsetsSources.contains(sourceId);
+    }
+
     /* Used so we can gain access to some protected members of the {@link WindowContainer} class */
     private static class TestWindowContainer extends WindowContainer<TestWindowContainer> {
         private final int mLayer;
@@ -1797,4 +1872,82 @@
             mIsVisibleRequested = isVisibleRequested;
         }
     }
+
+    private static class TestBinder implements IBinder {
+
+        private boolean mDead;
+        private final ArrayList<IBinder.DeathRecipient> mDeathRecipients = new ArrayList<>();
+
+        public void die() {
+            mDead = true;
+            for (int i = mDeathRecipients.size() - 1; i >= 0; i--) {
+                final DeathRecipient recipient = mDeathRecipients.get(i);
+                recipient.binderDied(this);
+            }
+        }
+
+        public boolean hasDeathRecipient() {
+            return !mDeathRecipients.isEmpty();
+        }
+
+        @Override
+        public void linkToDeath(@NonNull DeathRecipient recipient, int flags)
+                throws RemoteException {
+            if (mDead) {
+                throw new DeadObjectException();
+            }
+            mDeathRecipients.add(recipient);
+        }
+
+        @Override
+        public boolean unlinkToDeath(@NonNull DeathRecipient recipient, int flags) {
+            final boolean successes = mDeathRecipients.remove(recipient);
+            if (successes || mDead) {
+                return successes;
+            }
+            throw new NoSuchElementException("Given recipient has not been registered.");
+        }
+
+        @Override
+        public boolean isBinderAlive() {
+            return !mDead;
+        }
+
+        @Override
+        public boolean pingBinder() {
+            return !mDead;
+        }
+
+        @Nullable
+        @Override
+        public String getInterfaceDescriptor() throws RemoteException {
+            return null;
+        }
+
+        @Nullable
+        @Override
+        public IInterface queryLocalInterface(@NonNull String descriptor) {
+            return null;
+        }
+
+        @Override
+        public void dump(@NonNull FileDescriptor fd, @Nullable String[] args)
+                throws RemoteException { }
+
+        @Override
+        public void dumpAsync(@NonNull FileDescriptor fd, @Nullable String[] args)
+                throws RemoteException { }
+
+        @Override
+        public void shellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
+                @Nullable FileDescriptor err, @NonNull String[] args,
+                @Nullable ShellCallback shellCallback,
+                @NonNull ResultReceiver resultReceiver) throws RemoteException { }
+
+        @Override
+        public boolean transact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags)
+                throws RemoteException {
+            return false;
+        }
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
index 64330d8..b77e4cf 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -1028,7 +1028,7 @@
 
     private boolean setupLetterboxConfigurationWithBackgroundType(
             @LetterboxConfiguration.LetterboxBackgroundType int letterboxBackgroundType) {
-        mWm.mLetterboxConfiguration.setLetterboxBackgroundType(letterboxBackgroundType);
+        mWm.mLetterboxConfiguration.setLetterboxBackgroundTypeOverride(letterboxBackgroundType);
         return mWm.isLetterboxBackgroundMultiColored();
     }
 }
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index b0552b4..182d2fc 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -257,6 +257,9 @@
     // Updated based on the accessNetworkTechnology
     private boolean mIsUsingCarrierAggregation;
 
+    // Set to {@code true} when network is a non-terrestrial network.
+    private boolean mIsNonTerrestrialNetwork;
+
     /**
      * @param domain Network domain. Must be a {@link Domain}. For transport type
      * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, this must set to {@link #DOMAIN_PS}.
@@ -280,6 +283,7 @@
      * @param rplmn the registered plmn or the last plmn for attempted registration if reg failed.
      * @param voiceSpecificInfo Voice specific registration information.
      * @param dataSpecificInfo Data specific registration information.
+     * @param isNonTerrestrialNetwork {@code true} if network is a non-terrestrial network.
      */
     private NetworkRegistrationInfo(@Domain int domain, @TransportType int transportType,
             @RegistrationState int registrationState,
@@ -287,7 +291,8 @@
             boolean emergencyOnly, @Nullable @ServiceType List<Integer> availableServices,
             @Nullable CellIdentity cellIdentity, @Nullable String rplmn,
             @Nullable VoiceSpecificRegistrationInfo voiceSpecificInfo,
-            @Nullable DataSpecificRegistrationInfo dataSpecificInfo) {
+            @Nullable DataSpecificRegistrationInfo dataSpecificInfo,
+            boolean isNonTerrestrialNetwork) {
         mDomain = domain;
         mTransportType = transportType;
         mRegistrationState = registrationState;
@@ -304,6 +309,7 @@
         mRplmn = rplmn;
         mVoiceSpecificInfo = voiceSpecificInfo;
         mDataSpecificInfo = dataSpecificInfo;
+        mIsNonTerrestrialNetwork = isNonTerrestrialNetwork;
 
         updateNrState();
     }
@@ -322,7 +328,7 @@
         this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause,
                 emergencyOnly, availableServices, cellIdentity, rplmn,
                 new VoiceSpecificRegistrationInfo(cssSupported, roamingIndicator,
-                        systemIsInPrl, defaultRoamingIndicator), null);
+                        systemIsInPrl, defaultRoamingIndicator), null, false);
     }
 
     /**
@@ -344,7 +350,7 @@
                         .setNrAvailable(isNrAvailable)
                         .setEnDcAvailable(isEndcAvailable)
                         .setVopsSupportInfo(vopsSupportInfo)
-                        .build());
+                        .build(), false);
     }
 
     private NetworkRegistrationInfo(Parcel source) {
@@ -366,6 +372,7 @@
         mNrState = source.readInt();
         mRplmn = source.readString();
         mIsUsingCarrierAggregation = source.readBoolean();
+        mIsNonTerrestrialNetwork = source.readBoolean();
     }
 
     /**
@@ -382,6 +389,7 @@
         mRoamingType = nri.mRoamingType;
         mAccessNetworkTechnology = nri.mAccessNetworkTechnology;
         mIsUsingCarrierAggregation = nri.mIsUsingCarrierAggregation;
+        mIsNonTerrestrialNetwork = nri.mIsNonTerrestrialNetwork;
         mRejectCause = nri.mRejectCause;
         mEmergencyOnly = nri.mEmergencyOnly;
         mAvailableServices = new ArrayList<>(nri.mAvailableServices);
@@ -658,6 +666,27 @@
     }
 
     /**
+     * Set whether the network is a non-terrestrial network.
+     *
+     * @param isNonTerrestrialNetwork {@code true} if network is a non-terrestrial network
+     *                                            else {@code false}.
+     * @hide
+     */
+    public void setIsNonTerrestrialNetwork(boolean isNonTerrestrialNetwork) {
+        mIsNonTerrestrialNetwork = isNonTerrestrialNetwork;
+    }
+
+    /**
+     * Get whether the network is a non-terrestrial network.
+     *
+     * @return {@code true} if network is a non-terrestrial network else {@code false}.
+     * @hide
+     */
+    public boolean isNonTerrestrialNetwork() {
+        return mIsNonTerrestrialNetwork;
+    }
+
+    /**
      * @hide
      */
     @Nullable
@@ -769,6 +798,7 @@
                         ? nrStateToString(mNrState) : "****")
                 .append(" rRplmn=").append(mRplmn)
                 .append(" isUsingCarrierAggregation=").append(mIsUsingCarrierAggregation)
+                .append(" isNonTerrestrialNetwork=").append(mIsNonTerrestrialNetwork)
                 .append("}").toString();
     }
 
@@ -777,7 +807,7 @@
         return Objects.hash(mDomain, mTransportType, mRegistrationState, mNetworkRegistrationState,
                 mRoamingType, mAccessNetworkTechnology, mRejectCause, mEmergencyOnly,
                 mAvailableServices, mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState,
-                mRplmn, mIsUsingCarrierAggregation);
+                mRplmn, mIsUsingCarrierAggregation, mIsNonTerrestrialNetwork);
     }
 
     @Override
@@ -803,7 +833,8 @@
                 && Objects.equals(mVoiceSpecificInfo, other.mVoiceSpecificInfo)
                 && Objects.equals(mDataSpecificInfo, other.mDataSpecificInfo)
                 && TextUtils.equals(mRplmn, other.mRplmn)
-                && mNrState == other.mNrState;
+                && mNrState == other.mNrState
+                && mIsNonTerrestrialNetwork == other.mIsNonTerrestrialNetwork;
     }
 
     /**
@@ -827,6 +858,7 @@
         dest.writeInt(mNrState);
         dest.writeString(mRplmn);
         dest.writeBoolean(mIsUsingCarrierAggregation);
+        dest.writeBoolean(mIsNonTerrestrialNetwork);
     }
 
     /**
@@ -936,6 +968,8 @@
         @Nullable
         private VoiceSpecificRegistrationInfo mVoiceSpecificRegistrationInfo;
 
+        private boolean mIsNonTerrestrialNetwork;
+
         /**
          * Default constructor for Builder.
          */
@@ -964,6 +998,7 @@
                 mVoiceSpecificRegistrationInfo = new VoiceSpecificRegistrationInfo(
                         nri.mVoiceSpecificInfo);
             }
+            mIsNonTerrestrialNetwork = nri.mIsNonTerrestrialNetwork;
         }
 
         /**
@@ -1111,6 +1146,19 @@
         }
 
         /**
+         * Set whether the network is a non-terrestrial network.
+         *
+         * @param isNonTerrestrialNetwork {@code true} if network is a non-terrestrial network
+         *                                            else {@code false}.
+         * @return The builder.
+         * @hide
+         */
+        public @NonNull Builder setIsNonTerrestrialNetwork(boolean isNonTerrestrialNetwork) {
+            mIsNonTerrestrialNetwork = isNonTerrestrialNetwork;
+            return this;
+        }
+
+        /**
          * Build the NetworkRegistrationInfo.
          * @return the NetworkRegistrationInfo object.
          * @hide
@@ -1120,7 +1168,7 @@
             return new NetworkRegistrationInfo(mDomain, mTransportType, mNetworkRegistrationState,
                     mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
                     mCellIdentity, mRplmn, mVoiceSpecificRegistrationInfo,
-                    mDataSpecificRegistrationInfo);
+                    mDataSpecificRegistrationInfo, mIsNonTerrestrialNetwork);
         }
     }
 }
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 523d0b0..74cfbea 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -2250,4 +2250,19 @@
             return false;
         }
     }
+
+    /**
+     * Get whether device is connected to a non-terrestrial network.
+     *
+     * @return {@code true} if device is connected to a non-terrestrial network else {@code false}.
+     * @hide
+     */
+    public boolean isUsingNonTerrestrialNetwork() {
+        synchronized (mNetworkRegistrationInfos) {
+            for (NetworkRegistrationInfo nri : mNetworkRegistrationInfos) {
+                if (nri.isNonTerrestrialNetwork()) return true;
+            }
+        }
+        return false;
+    }
 }
diff --git a/tests/FlickerTests/Android.bp b/tests/FlickerTests/Android.bp
index 37b529b..72b5159 100644
--- a/tests/FlickerTests/Android.bp
+++ b/tests/FlickerTests/Android.bp
@@ -68,6 +68,13 @@
     srcs: ["src/**/rotation/*.kt"],
 }
 
+filegroup {
+    name: "FlickerServiceTests-src",
+    srcs: [
+        "src/com/android/server/wm/flicker/service/**/*.kt",
+    ],
+}
+
 java_defaults {
     name: "FlickerTestsDefault",
     manifest: "manifests/AndroidManifest.xml",
@@ -110,6 +117,7 @@
         ":FlickerTestsQuickswitch-src",
         ":FlickerTestsRotation-src",
         ":FlickerTestsNotification-src",
+        ":FlickerServiceTests-src",
     ],
 }
 
@@ -194,6 +202,18 @@
     ],
 }
 
+android_test {
+    name: "FlickerServiceTests",
+    defaults: ["FlickerTestsDefault"],
+    additional_manifests: ["manifests/AndroidManifestService.xml"],
+    package_name: "com.android.server.wm.flicker.service",
+    instrumentation_target_package: "com.android.server.wm.flicker.service",
+    srcs: [
+        ":FlickerTestsBase-src",
+        ":FlickerServiceTests-src",
+    ],
+}
+
 java_library {
     name: "wm-flicker-common-assertions",
     platform_apis: true,
diff --git a/tests/FlickerTests/AndroidTestTemplate.xml b/tests/FlickerTests/AndroidTestTemplate.xml
index ed63ec0..44a8245 100644
--- a/tests/FlickerTests/AndroidTestTemplate.xml
+++ b/tests/FlickerTests/AndroidTestTemplate.xml
@@ -87,6 +87,8 @@
                 value="/data/user/0/com.android.server.wm.flicker.rotation/files"/>
         <option name="directory-keys"
                 value="/data/user/0/com.android.server.wm.flicker.notification/files"/>
+        <option name="directory-keys"
+            value="/data/user/0/com.android.server.wm.flicker.service/files"/>
         <option name="collect-on-run-ended-only" value="true"/>
         <option name="clean-up" value="true"/>
     </metrics_collector>
diff --git a/tests/FlickerTests/manifests/AndroidManifestService.xml b/tests/FlickerTests/manifests/AndroidManifestService.xml
new file mode 100644
index 0000000..3a7bc509
--- /dev/null
+++ b/tests/FlickerTests/manifests/AndroidManifestService.xml
@@ -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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.server.wm.flicker.service">
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.server.wm.flicker.service"
+                     android:label="WindowManager Flicker Service Tests">
+    </instrumentation>
+</manifest>
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/open/OpenTrampolineActivityTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/open/OpenTrampolineActivityTest.kt
new file mode 100644
index 0000000..c05dc32
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/open/OpenTrampolineActivityTest.kt
@@ -0,0 +1,228 @@
+/*
+ * 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.wm.flicker.activityembedding
+
+import android.platform.test.annotations.Presubmit
+import android.tools.common.datatypes.Rect
+import android.tools.common.datatypes.Region
+import android.tools.common.flicker.subject.region.RegionSubject
+import android.tools.common.traces.component.ComponentNameMatcher
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
+import androidx.test.filters.RequiresDevice
+import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test launching a trampoline activity and resulting in a split state.
+ *
+ * Setup: Launch Activity A in fullscreen.
+ *
+ * Transitions: From A launch a trampoline Activity T, T launches secondary Activity B and
+ * finishes itself, end up in split A|B.
+ *
+ * To run this test: `atest FlickerTests:OpenTrampolineActivityTest`
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class OpenTrampolineActivityTest(flicker: LegacyFlickerTest) : ActivityEmbeddingTestBase(flicker) {
+    override val transition: FlickerBuilder.() -> Unit = {
+        setup {
+            tapl.setExpectedRotationCheckEnabled(false)
+            testApp.launchViaIntent(wmHelper)
+            startDisplayBounds =
+                    wmHelper.currentState.layerState.physicalDisplayBounds
+                            ?: error("Can't get display bounds")
+        }
+        transitions {
+            testApp.launchTrampolineActivity(wmHelper)
+        }
+        teardown {
+            tapl.goHome()
+            testApp.exit(wmHelper)
+        }
+    }
+
+    /** Assert the background animation layer is never visible during bounds change transition. */
+    @Presubmit
+    @Test
+    fun backgroundLayerNeverVisible() {
+        val backgroundColorLayer = ComponentNameMatcher("", "Animation Background")
+        flicker.assertLayers {
+            isInvisible(backgroundColorLayer)
+        }
+    }
+
+    /** Trampoline activity should finish itself before the end of this test. */
+    @Presubmit
+    @Test
+    fun trampolineActivityFinishes() {
+        flicker.assertWmEnd {
+            notContains(ActivityEmbeddingAppHelper.TRAMPOLINE_ACTIVITY_COMPONENT)
+        }
+    }
+
+    @Presubmit
+    @Test
+    fun trampolineLayerNeverVisible() {
+        flicker.assertLayers {
+            isInvisible(ActivityEmbeddingAppHelper.TRAMPOLINE_ACTIVITY_COMPONENT)
+        }
+    }
+
+    /** Main activity is always visible throughout this test. */
+    @Presubmit
+    @Test
+    fun mainActivityWindowAlwaysVisible() {
+        flicker.assertWm {
+            isAppWindowVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+        }
+    }
+
+    // TODO(b/289140963): After this is fixed, assert the main Activity window is visible
+    //  throughout the test instead.
+    /** Main activity layer is visible before and after the transition. */
+    @Presubmit
+    @Test
+    fun mainActivityLayerAlwaysVisible() {
+        flicker.assertLayersStart {
+            isVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+        }
+        flicker.assertLayersEnd {
+            isVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+        }
+    }
+
+    /** Secondary activity is launched from the trampoline activity. */
+    @Presubmit
+    @Test
+    fun secondaryActivityWindowLaunchedFromTrampoline() {
+        flicker.assertWm {
+            notContains(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+                    .then()
+                    .isAppWindowInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+                    .then()
+                    .isAppWindowVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+        }
+    }
+
+    /** Secondary activity is launched from the trampoline activity. */
+    @Presubmit
+    @Test
+    fun secondaryActivityLayerLaunchedFromTrampoline() {
+        flicker.assertLayers {
+            isInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+                    .then()
+                    .isVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+        }
+    }
+
+    /** Main activity should go from fullscreen to being a split with secondary activity. */
+    @Presubmit
+    @Test
+    fun mainActivityWindowGoesFromFullscreenToSplit() {
+        flicker.assertWm {
+            this.invoke("mainActivityStartsInFullscreen") {
+                it.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+                        .coversExactly(startDisplayBounds)
+            }
+                    // Begin of transition.
+                    .then()
+                    .isAppWindowInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+                    .then()
+                    .invoke("mainAndSecondaryInSplit") {
+                        val mainActivityRegion =
+                                RegionSubject(
+                                        it.visibleRegion(
+                                                ActivityEmbeddingAppHelper
+                                                        .MAIN_ACTIVITY_COMPONENT).region,
+                                        it.timestamp)
+                        val secondaryActivityRegion =
+                                RegionSubject(
+                                        it.visibleRegion(
+                                                ActivityEmbeddingAppHelper
+                                                        .SECONDARY_ACTIVITY_COMPONENT).region,
+                                        it.timestamp)
+                        check { "height" }
+                                .that(mainActivityRegion.region.height)
+                                .isEqual(secondaryActivityRegion.region.height)
+                        check { "width" }
+                                .that(mainActivityRegion.region.width)
+                                .isEqual(secondaryActivityRegion.region.width)
+                        mainActivityRegion
+                                .plus(secondaryActivityRegion.region)
+                                .coversExactly(startDisplayBounds)
+                    }
+        }
+    }
+
+    /** Main activity should go from fullscreen to being a split with secondary activity. */
+    @Presubmit
+    @Test
+    fun mainActivityLayerGoesFromFullscreenToSplit() {
+        flicker.assertLayers {
+            this.invoke("mainActivityStartsInFullscreen") {
+                it.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+                        .coversExactly(startDisplayBounds)
+            }
+                    .then()
+                    .isInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+                    .then()
+                    .isVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+        }
+        flicker.assertLayersEnd {
+            val leftLayerRegion = visibleRegion(
+                    ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+            val rightLayerRegion =
+                    visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+            // Compare dimensions of two splits, given we're using default split attributes,
+            // both activities take up the same visible size on the display.
+            check { "height" }
+                    .that(leftLayerRegion.region.height)
+                    .isEqual(rightLayerRegion.region.height)
+            check { "width" }
+                    .that(leftLayerRegion.region.width)
+                    .isEqual(rightLayerRegion.region.width)
+            leftLayerRegion.notOverlaps(rightLayerRegion.region)
+            // Layers of two activities sum to be fullscreen size on display.
+            leftLayerRegion.plus(rightLayerRegion.region).coversExactly(startDisplayBounds)
+        }
+    }
+
+    companion object {
+        /** {@inheritDoc} */
+        private var startDisplayBounds = Rect.EMPTY
+
+        /**
+         * Creates the test configurations.
+         *
+         * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
+         * navigation modes.
+         */
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
+    }
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt
index ced7a1e..eac8813 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt
@@ -77,6 +77,25 @@
     }
 
     /**
+     * Clicks the button to launch the trampoline activity, which should launch the secondary
+     * activity and finish itself.
+     */
+    fun launchTrampolineActivity(wmHelper: WindowManagerStateHelper) {
+        val launchButton =
+                uiDevice.wait(
+                        Until.findObject(By.res(getPackage(), "launch_trampoline_button")),
+                        FIND_TIMEOUT
+                )
+        require(launchButton != null) { "Can't find launch trampoline activity button on screen." }
+        launchButton.click()
+        wmHelper
+                .StateSyncBuilder()
+                .withActivityState(SECONDARY_ACTIVITY_COMPONENT, PlatformConsts.STATE_RESUMED)
+                .withActivityRemoved(TRAMPOLINE_ACTIVITY_COMPONENT)
+                .waitForAndVerify()
+    }
+
+    /**
      * Clicks the button to finishes the secondary activity launched through
      * [launchSecondaryActivity], waits for the main activity to resume.
      */
@@ -197,6 +216,9 @@
             ActivityOptions.ActivityEmbedding.PlaceholderSecondaryActivity.COMPONENT
                 .toFlickerComponent()
 
+        val TRAMPOLINE_ACTIVITY_COMPONENT =
+                ActivityOptions.ActivityEmbedding.TrampolineActivity.COMPONENT.toFlickerComponent()
+
         @JvmStatic
         fun getWindowExtensions(): WindowExtensions? {
             try {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/Utils.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/Utils.kt
new file mode 100644
index 0000000..8242e9a
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/Utils.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.server.wm.flicker.service
+
+import android.app.Instrumentation
+import android.platform.test.rule.NavigationModeRule
+import android.platform.test.rule.PressHomeRule
+import android.platform.test.rule.UnlockScreenRule
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.device.apphelpers.MessagingAppHelper
+import android.tools.device.flicker.rules.ChangeDisplayOrientationRule
+import android.tools.device.flicker.rules.LaunchAppRule
+import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule
+import androidx.test.platform.app.InstrumentationRegistry
+import org.junit.rules.RuleChain
+
+object Utils {
+    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+
+    fun testSetupRule(navigationMode: NavBar, rotation: Rotation): RuleChain {
+        return RuleChain.outerRule(UnlockScreenRule())
+            .around(
+                NavigationModeRule(navigationMode.value, /* changeNavigationModeAfterTest */ false)
+            )
+            .around(
+                LaunchAppRule(MessagingAppHelper(instrumentation), clearCacheAfterParsing = false)
+            )
+            .around(RemoveAllTasksButHomeRule())
+            .around(
+                ChangeDisplayOrientationRule(
+                    rotation,
+                    resetOrientationAfterTest = false,
+                    clearCacheAfterParsing = false
+                )
+            )
+            .around(PressHomeRule())
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButton3ButtonLandscape.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButton3ButtonLandscape.kt
new file mode 100644
index 0000000..030b292
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButton3ButtonLandscape.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.service.close.flicker
+
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.close.scenarios.CloseAppBackButton
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class CloseAppBackButton3ButtonLandscape :
+    CloseAppBackButton(NavBar.MODE_3BUTTON, Rotation.ROTATION_90) {
+    @ExpectedScenarios(["APP_CLOSE_TO_HOME"])
+    @Test
+    override fun closeAppBackButtonTest() = super.closeAppBackButtonTest()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButton3ButtonPortrait.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButton3ButtonPortrait.kt
new file mode 100644
index 0000000..770da143
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButton3ButtonPortrait.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.service.close.flicker
+
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.close.scenarios.CloseAppBackButton
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class CloseAppBackButton3ButtonPortrait :
+    CloseAppBackButton(NavBar.MODE_3BUTTON, Rotation.ROTATION_0) {
+    @ExpectedScenarios(["APP_CLOSE_TO_HOME"])
+    @Test
+    override fun closeAppBackButtonTest() = super.closeAppBackButtonTest()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButtonGesturalNavLandscape.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButtonGesturalNavLandscape.kt
new file mode 100644
index 0000000..4b2206d7
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButtonGesturalNavLandscape.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.service.close.flicker
+
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.close.scenarios.CloseAppBackButton
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class CloseAppBackButtonGesturalNavLandscape :
+    CloseAppBackButton(NavBar.MODE_GESTURAL, Rotation.ROTATION_90) {
+    @ExpectedScenarios(["APP_CLOSE_TO_HOME"])
+    @Test
+    override fun closeAppBackButtonTest() = super.closeAppBackButtonTest()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButtonGesturalNavPortrait.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButtonGesturalNavPortrait.kt
new file mode 100644
index 0000000..54b471e
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButtonGesturalNavPortrait.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.service.close.flicker
+
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.close.scenarios.CloseAppBackButton
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class CloseAppBackButtonGesturalNavPortrait :
+    CloseAppBackButton(NavBar.MODE_GESTURAL, Rotation.ROTATION_0) {
+    @ExpectedScenarios(["APP_CLOSE_TO_HOME"])
+    @Test
+    override fun closeAppBackButtonTest() = super.closeAppBackButtonTest()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppHomeButton3ButtonLandscape.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppHomeButton3ButtonLandscape.kt
new file mode 100644
index 0000000..47c2529
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppHomeButton3ButtonLandscape.kt
@@ -0,0 +1,42 @@
+/*
+ * 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.wm.flicker.service.close.flicker
+
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.close.scenarios.CloseAppHomeButton
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class CloseAppHomeButton3ButtonLandscape : CloseAppHomeButton(Rotation.ROTATION_90) {
+    @ExpectedScenarios(["APP_CLOSE_TO_HOME"])
+    @Test
+    override fun closeAppHomeButton() = super.closeAppHomeButton()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppHomeButton3ButtonPortrait.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppHomeButton3ButtonPortrait.kt
new file mode 100644
index 0000000..b18148f
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppHomeButton3ButtonPortrait.kt
@@ -0,0 +1,42 @@
+/*
+ * 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.wm.flicker.service.close.flicker
+
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.close.scenarios.CloseAppHomeButton
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class CloseAppHomeButton3ButtonPortrait : CloseAppHomeButton(Rotation.ROTATION_0) {
+    @ExpectedScenarios(["APP_CLOSE_TO_HOME"])
+    @Test
+    override fun closeAppHomeButton() = super.closeAppHomeButton()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppSwipeToHomeGesturalNavLandscape.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppSwipeToHomeGesturalNavLandscape.kt
new file mode 100644
index 0000000..8543015
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppSwipeToHomeGesturalNavLandscape.kt
@@ -0,0 +1,42 @@
+/*
+ * 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.wm.flicker.service.close.flicker
+
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.close.scenarios.CloseAppSwipeToHome
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class CloseAppSwipeToHomeGesturalNavLandscape : CloseAppSwipeToHome(Rotation.ROTATION_90) {
+    @ExpectedScenarios(["APP_CLOSE_TO_HOME"])
+    @Test
+    override fun closeAppSwipeToHome() = super.closeAppSwipeToHome()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppSwipeToHomeGesturalNavPortrait.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppSwipeToHomeGesturalNavPortrait.kt
new file mode 100644
index 0000000..f88963b
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppSwipeToHomeGesturalNavPortrait.kt
@@ -0,0 +1,42 @@
+/*
+ * 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.wm.flicker.service.close.flicker
+
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.close.scenarios.CloseAppSwipeToHome
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class CloseAppSwipeToHomeGesturalNavPortrait : CloseAppSwipeToHome(Rotation.ROTATION_0) {
+    @ExpectedScenarios(["APP_CLOSE_TO_HOME"])
+    @Test
+    override fun closeAppSwipeToHome() = super.closeAppSwipeToHome()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/scenarios/CloseAppBackButton.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/scenarios/CloseAppBackButton.kt
new file mode 100644
index 0000000..2aaacde
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/scenarios/CloseAppBackButton.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.service.close.scenarios
+
+import android.app.Instrumentation
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.device.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.server.wm.flicker.service.Utils
+import org.junit.After
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+
+@Ignore("Base Test Class")
+abstract class CloseAppBackButton(
+    val gestureMode: NavBar = NavBar.MODE_GESTURAL,
+    val rotation: Rotation = Rotation.ROTATION_0
+) {
+    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+    private val tapl = LauncherInstrumentation()
+    private val wmHelper = WindowManagerStateHelper(instrumentation)
+    private val testApp = SimpleAppHelper(instrumentation)
+
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(gestureMode, rotation)
+
+    @Before
+    fun setup() {
+        tapl.setExpectedRotation(rotation.value)
+        testApp.launchViaIntent(wmHelper)
+    }
+
+    @Test
+    open fun closeAppBackButtonTest() {
+        tapl.pressBack()
+        wmHelper.StateSyncBuilder().withHomeActivityVisible().waitForAndVerify()
+    }
+
+    @After
+    fun teardown() {
+        testApp.exit(wmHelper)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/scenarios/CloseAppHomeButton.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/scenarios/CloseAppHomeButton.kt
new file mode 100644
index 0000000..08683a3
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/scenarios/CloseAppHomeButton.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.service.close.scenarios
+
+import android.app.Instrumentation
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.device.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.server.wm.flicker.service.Utils
+import org.junit.After
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+
+@Ignore("Base Test Class")
+abstract class CloseAppHomeButton(val rotation: Rotation = Rotation.ROTATION_0) {
+    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+    private val tapl = LauncherInstrumentation()
+    private val wmHelper = WindowManagerStateHelper(instrumentation)
+    private val testApp = SimpleAppHelper(instrumentation)
+
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_3BUTTON, rotation)
+
+    @Before
+    fun setup() {
+        tapl.setExpectedRotation(rotation.value)
+        testApp.launchViaIntent(wmHelper)
+        tapl.setExpectedRotationCheckEnabled(false)
+    }
+
+    @Test
+    open fun closeAppHomeButton() {
+        tapl.goHome()
+        wmHelper.StateSyncBuilder().withHomeActivityVisible().waitForAndVerify()
+    }
+
+    @After
+    fun teardown() {
+        testApp.exit(wmHelper)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/scenarios/CloseAppSwipeToHome.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/scenarios/CloseAppSwipeToHome.kt
new file mode 100644
index 0000000..360e114
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/scenarios/CloseAppSwipeToHome.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.service.close.scenarios
+
+import android.app.Instrumentation
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.device.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.server.wm.flicker.service.Utils
+import org.junit.After
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+
+@Ignore("Base Test Class")
+abstract class CloseAppSwipeToHome(val rotation: Rotation = Rotation.ROTATION_0) {
+    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+    private val tapl = LauncherInstrumentation()
+    private val wmHelper = WindowManagerStateHelper(instrumentation)
+    private val testApp = SimpleAppHelper(instrumentation)
+
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
+
+    @Before
+    fun setup() {
+        tapl.setExpectedRotation(rotation.value)
+        testApp.launchViaIntent(wmHelper)
+        tapl.setExpectedRotationCheckEnabled(false)
+    }
+
+    @Test
+    open fun closeAppSwipeToHome() {
+        tapl.goHome()
+        wmHelper.StateSyncBuilder().withHomeActivityVisible().waitForAndVerify()
+    }
+
+    @After
+    fun teardown() {
+        testApp.exit(wmHelper)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationCold3ButtonNavLandscape.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationCold3ButtonNavLandscape.kt
new file mode 100644
index 0000000..bb18770
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationCold3ButtonNavLandscape.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.wm.flicker.service.notification.flicker
+
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.notification.scenarios.OpenAppFromLockscreenNotificationCold
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class OpenAppFromLockscreenNotificationCold3ButtonNavLandscape :
+    OpenAppFromLockscreenNotificationCold(NavBar.MODE_3BUTTON, Rotation.ROTATION_90) {
+    @ExpectedScenarios(["APP_LAUNCH_FROM_NOTIFICATION"])
+    @Test
+    override fun openAppFromLockscreenNotificationCold() =
+        super.openAppFromLockscreenNotificationCold()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationCold3ButtonNavPortrait.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationCold3ButtonNavPortrait.kt
new file mode 100644
index 0000000..1c3cc21
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationCold3ButtonNavPortrait.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.wm.flicker.service.notification.flicker
+
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.notification.scenarios.OpenAppFromLockscreenNotificationCold
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class OpenAppFromLockscreenNotificationCold3ButtonNavPortrait :
+    OpenAppFromLockscreenNotificationCold(NavBar.MODE_3BUTTON, Rotation.ROTATION_0) {
+    @ExpectedScenarios(["APP_LAUNCH_FROM_NOTIFICATION"])
+    @Test
+    override fun openAppFromLockscreenNotificationCold() =
+        super.openAppFromLockscreenNotificationCold()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationColdGesturalNavLandscape.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationColdGesturalNavLandscape.kt
new file mode 100644
index 0000000..46d36db
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationColdGesturalNavLandscape.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.wm.flicker.service.notification.flicker
+
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.notification.scenarios.OpenAppFromLockscreenNotificationCold
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class OpenAppFromLockscreenNotificationColdGesturalNavLandscape :
+    OpenAppFromLockscreenNotificationCold(NavBar.MODE_GESTURAL, Rotation.ROTATION_90) {
+    @ExpectedScenarios(["APP_LAUNCH_FROM_NOTIFICATION"])
+    @Test
+    override fun openAppFromLockscreenNotificationCold() =
+        super.openAppFromLockscreenNotificationCold()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationColdGesturalNavPortrait.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationColdGesturalNavPortrait.kt
new file mode 100644
index 0000000..f6a668fe
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationColdGesturalNavPortrait.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.wm.flicker.service.notification.flicker
+
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.notification.scenarios.OpenAppFromLockscreenNotificationCold
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class OpenAppFromLockscreenNotificationColdGesturalNavPortrait :
+    OpenAppFromLockscreenNotificationCold(NavBar.MODE_GESTURAL, Rotation.ROTATION_0) {
+    @ExpectedScenarios(["APP_LAUNCH_FROM_NOTIFICATION"])
+    @Test
+    override fun openAppFromLockscreenNotificationCold() =
+        super.openAppFromLockscreenNotificationCold()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWarm3ButtonNavLandscape.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWarm3ButtonNavLandscape.kt
new file mode 100644
index 0000000..93200ba
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWarm3ButtonNavLandscape.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.wm.flicker.service.notification.flicker
+
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.notification.scenarios.OpenAppFromLockscreenNotificationWarm
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class OpenAppFromLockscreenNotificationWarm3ButtonNavLandscape :
+    OpenAppFromLockscreenNotificationWarm(NavBar.MODE_3BUTTON, Rotation.ROTATION_90) {
+    @ExpectedScenarios(["APP_LAUNCH_FROM_NOTIFICATION"])
+    @Test
+    override fun openAppFromLockscreenNotificationWarm() =
+        super.openAppFromLockscreenNotificationWarm()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWarm3ButtonNavPortrait.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWarm3ButtonNavPortrait.kt
new file mode 100644
index 0000000..f5d41d2
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWarm3ButtonNavPortrait.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.wm.flicker.service.notification.flicker
+
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.notification.scenarios.OpenAppFromLockscreenNotificationWarm
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class OpenAppFromLockscreenNotificationWarm3ButtonNavPortrait :
+    OpenAppFromLockscreenNotificationWarm(NavBar.MODE_3BUTTON, Rotation.ROTATION_0) {
+    @ExpectedScenarios(["APP_LAUNCH_FROM_NOTIFICATION"])
+    @Test
+    override fun openAppFromLockscreenNotificationWarm() =
+        super.openAppFromLockscreenNotificationWarm()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWarmGesturalNavLandscape.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWarmGesturalNavLandscape.kt
new file mode 100644
index 0000000..28f322b
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWarmGesturalNavLandscape.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.wm.flicker.service.notification.flicker
+
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.notification.scenarios.OpenAppFromLockscreenNotificationWarm
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class OpenAppFromLockscreenNotificationWarmGesturalNavLandscape :
+    OpenAppFromLockscreenNotificationWarm(NavBar.MODE_GESTURAL, Rotation.ROTATION_90) {
+    @ExpectedScenarios(["APP_LAUNCH_FROM_NOTIFICATION"])
+    @Test
+    override fun openAppFromLockscreenNotificationWarm() =
+        super.openAppFromLockscreenNotificationWarm()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWarmGesturalNavPortrait.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWarmGesturalNavPortrait.kt
new file mode 100644
index 0000000..beb3fae
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWarmGesturalNavPortrait.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.wm.flicker.service.notification.flicker
+
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.notification.scenarios.OpenAppFromLockscreenNotificationWarm
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class OpenAppFromLockscreenNotificationWarmGesturalNavPortrait :
+    OpenAppFromLockscreenNotificationWarm(NavBar.MODE_GESTURAL, Rotation.ROTATION_0) {
+    @ExpectedScenarios(["APP_LAUNCH_FROM_NOTIFICATION"])
+    @Test
+    override fun openAppFromLockscreenNotificationWarm() =
+        super.openAppFromLockscreenNotificationWarm()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayApp3ButtonNavLandscape.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayApp3ButtonNavLandscape.kt
new file mode 100644
index 0000000..b34da72
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayApp3ButtonNavLandscape.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.wm.flicker.service.notification.flicker
+
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.notification.scenarios.OpenAppFromLockscreenNotificationWithOverlayApp
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class OpenAppFromLockscreenNotificationWithOverlayApp3ButtonNavLandscape :
+    OpenAppFromLockscreenNotificationWithOverlayApp(NavBar.MODE_3BUTTON, Rotation.ROTATION_90) {
+    @ExpectedScenarios(["APP_LAUNCH_FROM_NOTIFICATION"])
+    @Test
+    override fun openAppFromLockscreenNotificationWithOverlayApp() =
+        super.openAppFromLockscreenNotificationWithOverlayApp()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayApp3ButtonNavPortrait.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayApp3ButtonNavPortrait.kt
new file mode 100644
index 0000000..b163897
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayApp3ButtonNavPortrait.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.wm.flicker.service.notification.flicker
+
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.notification.scenarios.OpenAppFromLockscreenNotificationWithOverlayApp
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class OpenAppFromLockscreenNotificationWithOverlayApp3ButtonNavPortrait :
+    OpenAppFromLockscreenNotificationWithOverlayApp(NavBar.MODE_3BUTTON, Rotation.ROTATION_0) {
+    @ExpectedScenarios(["APP_LAUNCH_FROM_NOTIFICATION"])
+    @Test
+    override fun openAppFromLockscreenNotificationWithOverlayApp() =
+        super.openAppFromLockscreenNotificationWithOverlayApp()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayAppGesturalNavLandscape.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayAppGesturalNavLandscape.kt
new file mode 100644
index 0000000..19b533e
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayAppGesturalNavLandscape.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.wm.flicker.service.notification.flicker
+
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.notification.scenarios.OpenAppFromLockscreenNotificationWithOverlayApp
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class OpenAppFromLockscreenNotificationWithOverlayAppGesturalNavLandscape :
+    OpenAppFromLockscreenNotificationWithOverlayApp(NavBar.MODE_GESTURAL, Rotation.ROTATION_90) {
+    @ExpectedScenarios(["APP_LAUNCH_FROM_NOTIFICATION"])
+    @Test
+    override fun openAppFromLockscreenNotificationWithOverlayApp() =
+        super.openAppFromLockscreenNotificationWithOverlayApp()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayAppGesturalNavPortrait.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayAppGesturalNavPortrait.kt
new file mode 100644
index 0000000..c9ed4f4
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromLockscreenNotificationWithOverlayAppGesturalNavPortrait.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.wm.flicker.service.notification.flicker
+
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.notification.scenarios.OpenAppFromLockscreenNotificationWithOverlayApp
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class OpenAppFromLockscreenNotificationWithOverlayAppGesturalNavPortrait :
+    OpenAppFromLockscreenNotificationWithOverlayApp(NavBar.MODE_GESTURAL, Rotation.ROTATION_0) {
+    @ExpectedScenarios(["APP_LAUNCH_FROM_NOTIFICATION"])
+    @Test
+    override fun openAppFromLockscreenNotificationWithOverlayApp() =
+        super.openAppFromLockscreenNotificationWithOverlayApp()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromNotificationCold3ButtonNavLandscape.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromNotificationCold3ButtonNavLandscape.kt
new file mode 100644
index 0000000..866190f
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromNotificationCold3ButtonNavLandscape.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.service.notification.flicker
+
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.notification.scenarios.OpenAppFromNotificationCold
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class OpenAppFromNotificationCold3ButtonNavLandscape :
+    OpenAppFromNotificationCold(NavBar.MODE_3BUTTON, Rotation.ROTATION_90) {
+    @ExpectedScenarios(["APP_LAUNCH_FROM_NOTIFICATION"])
+    @Test
+    override fun openAppFromNotificationCold() = super.openAppFromNotificationCold()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromNotificationCold3ButtonNavPortrait.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromNotificationCold3ButtonNavPortrait.kt
new file mode 100644
index 0000000..a8d6283
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromNotificationCold3ButtonNavPortrait.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.service.notification.flicker
+
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.notification.scenarios.OpenAppFromNotificationCold
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class OpenAppFromNotificationCold3ButtonNavPortrait :
+    OpenAppFromNotificationCold(NavBar.MODE_3BUTTON, Rotation.ROTATION_0) {
+    @ExpectedScenarios(["APP_LAUNCH_FROM_NOTIFICATION"])
+    @Test
+    override fun openAppFromNotificationCold() = super.openAppFromNotificationCold()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromNotificationColdGesturalNavLandscape.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromNotificationColdGesturalNavLandscape.kt
new file mode 100644
index 0000000..ef84c3f
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromNotificationColdGesturalNavLandscape.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.service.notification.flicker
+
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.notification.scenarios.OpenAppFromNotificationCold
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class OpenAppFromNotificationColdGesturalNavLandscape :
+    OpenAppFromNotificationCold(NavBar.MODE_GESTURAL, Rotation.ROTATION_90) {
+    @ExpectedScenarios(["APP_LAUNCH_FROM_NOTIFICATION"])
+    @Test
+    override fun openAppFromNotificationCold() = super.openAppFromNotificationCold()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromNotificationColdGesturalNavPortrait.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromNotificationColdGesturalNavPortrait.kt
new file mode 100644
index 0000000..5bb6b37
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromNotificationColdGesturalNavPortrait.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.service.notification.flicker
+
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.notification.scenarios.OpenAppFromNotificationCold
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class OpenAppFromNotificationColdGesturalNavPortrait :
+    OpenAppFromNotificationCold(NavBar.MODE_GESTURAL, Rotation.ROTATION_0) {
+    @ExpectedScenarios(["APP_LAUNCH_FROM_NOTIFICATION"])
+    @Test
+    override fun openAppFromNotificationCold() = super.openAppFromNotificationCold()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromNotificationWarm3ButtonNavLandscape.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromNotificationWarm3ButtonNavLandscape.kt
new file mode 100644
index 0000000..39f25e9
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromNotificationWarm3ButtonNavLandscape.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.service.notification.flicker
+
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.notification.scenarios.OpenAppFromNotificationWarm
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class OpenAppFromNotificationWarm3ButtonNavLandscape :
+    OpenAppFromNotificationWarm(NavBar.MODE_3BUTTON, Rotation.ROTATION_90) {
+    @ExpectedScenarios(["APP_LAUNCH_FROM_NOTIFICATION"])
+    @Test
+    override fun openAppFromNotificationWarm() = super.openAppFromNotificationWarm()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromNotificationWarm3ButtonNavPortrait.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromNotificationWarm3ButtonNavPortrait.kt
new file mode 100644
index 0000000..28816bc
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromNotificationWarm3ButtonNavPortrait.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.service.notification.flicker
+
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.notification.scenarios.OpenAppFromNotificationWarm
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class OpenAppFromNotificationWarm3ButtonNavPortrait :
+    OpenAppFromNotificationWarm(NavBar.MODE_3BUTTON, Rotation.ROTATION_0) {
+    @ExpectedScenarios(["APP_LAUNCH_FROM_NOTIFICATION"])
+    @Test
+    override fun openAppFromNotificationWarm() = super.openAppFromNotificationWarm()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromNotificationWarmGesturalNavLandscape.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromNotificationWarmGesturalNavLandscape.kt
new file mode 100644
index 0000000..94ffe4e
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromNotificationWarmGesturalNavLandscape.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.service.notification.flicker
+
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.notification.scenarios.OpenAppFromNotificationWarm
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class OpenAppFromNotificationWarmGesturalNavLandscape :
+    OpenAppFromNotificationWarm(NavBar.MODE_GESTURAL, Rotation.ROTATION_90) {
+    @ExpectedScenarios(["APP_LAUNCH_FROM_NOTIFICATION"])
+    @Test
+    override fun openAppFromNotificationWarm() = super.openAppFromNotificationWarm()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromNotificationWarmGesturalNavPortrait.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromNotificationWarmGesturalNavPortrait.kt
new file mode 100644
index 0000000..e5f5ec4
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/flicker/OpenAppFromNotificationWarmGesturalNavPortrait.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.service.notification.flicker
+
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.notification.scenarios.OpenAppFromNotificationWarm
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class OpenAppFromNotificationWarmGesturalNavPortrait :
+    OpenAppFromNotificationWarm(NavBar.MODE_GESTURAL, Rotation.ROTATION_0) {
+    @ExpectedScenarios(["APP_LAUNCH_FROM_NOTIFICATION"])
+    @Test
+    override fun openAppFromNotificationWarm() = super.openAppFromNotificationWarm()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/scenarios/NotificationUtils.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/scenarios/NotificationUtils.kt
new file mode 100644
index 0000000..ac4e169
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/scenarios/NotificationUtils.kt
@@ -0,0 +1,66 @@
+/*
+ * 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.wm.flicker.service.notification.scenarios
+
+import android.app.Instrumentation
+import android.tools.device.traces.parsers.WindowManagerStateHelper
+import android.view.WindowInsets
+import android.view.WindowManager
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.By
+import androidx.test.uiautomator.UiDevice
+import androidx.test.uiautomator.Until
+import com.android.launcher3.tapl.LauncherInstrumentation
+
+object NotificationUtils {
+    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+    private val tapl = LauncherInstrumentation()
+    private val wmHelper = WindowManagerStateHelper(instrumentation)
+    private val device = UiDevice.getInstance(instrumentation)
+
+    fun openNotification(openingNotificationsFromLockScreen: Boolean) {
+        var startY = 10
+        var endY = 3 * device.displayHeight / 4
+        var steps = 25
+        if (openingNotificationsFromLockScreen) {
+            val wm: WindowManager =
+                instrumentation.context.getSystemService(WindowManager::class.java)
+                    ?: error("Unable to connect to WindowManager service")
+            val metricInsets = wm.currentWindowMetrics.windowInsets
+            val insets =
+                metricInsets.getInsetsIgnoringVisibility(
+                    WindowInsets.Type.statusBars() or WindowInsets.Type.displayCutout()
+                )
+
+            startY = insets.top + 100
+            endY = device.displayHeight / 2
+            steps = 4
+        }
+
+        // Swipe down to show the notification shade
+        val x = device.displayWidth / 2
+        device.swipe(x, startY, x, endY, steps)
+        device.waitForIdle(2000)
+        instrumentation.uiAutomation.syncInputTransactions()
+
+        // Launch the activity by clicking the notification
+        val notification =
+            device.wait(Until.findObject(By.text("Flicker Test Notification")), 2000L)
+        notification?.click() ?: error("Notification not found")
+        instrumentation.uiAutomation.syncInputTransactions()
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/scenarios/OpenAppFromLockscreenNotificationCold.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/scenarios/OpenAppFromLockscreenNotificationCold.kt
new file mode 100644
index 0000000..9c53ab3
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/scenarios/OpenAppFromLockscreenNotificationCold.kt
@@ -0,0 +1,81 @@
+/*
+ * 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.wm.flicker.service.notification.scenarios
+
+import android.app.Instrumentation
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.device.helpers.wakeUpAndGoToHomeScreen
+import android.tools.device.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.NotificationAppHelper
+import com.android.server.wm.flicker.service.Utils
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+
+abstract class OpenAppFromLockscreenNotificationCold(
+    val gestureMode: NavBar = NavBar.MODE_GESTURAL,
+    val rotation: Rotation = Rotation.ROTATION_0
+) {
+    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+    private val tapl = LauncherInstrumentation()
+    private val wmHelper = WindowManagerStateHelper(instrumentation)
+    private val device = UiDevice.getInstance(instrumentation)
+    private val testApp: NotificationAppHelper = NotificationAppHelper(instrumentation)
+
+    val openingNotificationsFromLockScreen = true
+
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(gestureMode, rotation)
+
+    @Before
+    fun setup() {
+        device.wakeUpAndGoToHomeScreen()
+        testApp.launchViaIntent(wmHelper)
+        wmHelper.StateSyncBuilder().withFullScreenApp(testApp).waitForAndVerify()
+        testApp.postNotification(wmHelper)
+        device.pressHome()
+        wmHelper.StateSyncBuilder().withHomeActivityVisible().waitForAndVerify()
+
+        // Close the app that posted the notification to trigger a cold start next time
+        // it is open - can't just kill it because that would remove the notification.
+        tapl.setExpectedRotationCheckEnabled(false)
+        tapl.goHome()
+        tapl.workspace.switchToOverview()
+        tapl.overview.dismissAllTasks()
+
+        device.sleep()
+        wmHelper.StateSyncBuilder().withoutTopVisibleAppWindows().waitForAndVerify()
+    }
+
+    @Test
+    open fun openAppFromLockscreenNotificationCold() {
+        device.wakeUp()
+
+        NotificationUtils.openNotification(openingNotificationsFromLockScreen)
+        // Wait for the app to launch
+        wmHelper.StateSyncBuilder().withFullScreenApp(testApp).waitForAndVerify()
+    }
+
+    @After
+    fun teardown() {
+        testApp.exit(wmHelper)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/scenarios/OpenAppFromLockscreenNotificationWarm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/scenarios/OpenAppFromLockscreenNotificationWarm.kt
new file mode 100644
index 0000000..31f55d9
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/scenarios/OpenAppFromLockscreenNotificationWarm.kt
@@ -0,0 +1,74 @@
+/*
+ * 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.wm.flicker.service.notification.scenarios
+
+import android.app.Instrumentation
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.device.helpers.wakeUpAndGoToHomeScreen
+import android.tools.device.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.NotificationAppHelper
+import com.android.server.wm.flicker.service.Utils
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+
+abstract class OpenAppFromLockscreenNotificationWarm(
+    val gestureMode: NavBar = NavBar.MODE_GESTURAL,
+    val rotation: Rotation = Rotation.ROTATION_0
+) {
+    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+    private val tapl = LauncherInstrumentation()
+    private val wmHelper = WindowManagerStateHelper(instrumentation)
+    private val device = UiDevice.getInstance(instrumentation)
+    private val testApp: NotificationAppHelper = NotificationAppHelper(instrumentation)
+
+    private val openingNotificationsFromLockScreen = true
+
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(gestureMode, rotation)
+
+    @Before
+    fun setup() {
+        device.wakeUpAndGoToHomeScreen()
+        testApp.launchViaIntent(wmHelper)
+        wmHelper.StateSyncBuilder().withFullScreenApp(testApp).waitForAndVerify()
+        testApp.postNotification(wmHelper)
+        device.pressHome()
+        wmHelper.StateSyncBuilder().withHomeActivityVisible().waitForAndVerify()
+
+        device.sleep()
+        wmHelper.StateSyncBuilder().withoutTopVisibleAppWindows().waitForAndVerify()
+    }
+
+    @Test
+    open fun openAppFromLockscreenNotificationWarm() {
+        device.wakeUp()
+
+        NotificationUtils.openNotification(openingNotificationsFromLockScreen)
+        // Wait for the app to launch
+        wmHelper.StateSyncBuilder().withFullScreenApp(testApp).waitForAndVerify()
+    }
+
+    @After
+    fun teardown() {
+        testApp.exit(wmHelper)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/scenarios/OpenAppFromLockscreenNotificationWithOverlayApp.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/scenarios/OpenAppFromLockscreenNotificationWithOverlayApp.kt
new file mode 100644
index 0000000..b971555
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/scenarios/OpenAppFromLockscreenNotificationWithOverlayApp.kt
@@ -0,0 +1,94 @@
+/*
+ * 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.wm.flicker.service.notification.scenarios
+
+import android.app.Instrumentation
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.device.helpers.wakeUpAndGoToHomeScreen
+import android.tools.device.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.NotificationAppHelper
+import com.android.server.wm.flicker.helpers.ShowWhenLockedAppHelper
+import com.android.server.wm.flicker.service.Utils
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+
+abstract class OpenAppFromLockscreenNotificationWithOverlayApp(
+    val gestureMode: NavBar = NavBar.MODE_GESTURAL,
+    val rotation: Rotation = Rotation.ROTATION_0
+) {
+    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+    private val tapl = LauncherInstrumentation()
+    private val wmHelper = WindowManagerStateHelper(instrumentation)
+    private val device = UiDevice.getInstance(instrumentation)
+    private val showWhenLockedApp = ShowWhenLockedAppHelper(instrumentation)
+    private val testApp: NotificationAppHelper = NotificationAppHelper(instrumentation)
+
+    // Although we are technically still locked here, the overlay app means we should open the
+    // notification shade as if we were unlocked.
+    private val openingNotificationsFromLockScreen = false
+
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(gestureMode, rotation)
+
+    @Before
+    fun setup() {
+        device.wakeUpAndGoToHomeScreen()
+        testApp.launchViaIntent(wmHelper)
+        wmHelper.StateSyncBuilder().withFullScreenApp(testApp).waitForAndVerify()
+        testApp.postNotification(wmHelper)
+        device.pressHome()
+        wmHelper.StateSyncBuilder().withHomeActivityVisible().waitForAndVerify()
+
+        // Close the app that posted the notification to trigger a cold start next time
+        // it is open - can't just kill it because that would remove the notification.
+        tapl.setExpectedRotationCheckEnabled(false)
+        tapl.goHome()
+        tapl.workspace.switchToOverview()
+        tapl.overview.dismissAllTasks()
+
+        device.sleep()
+        wmHelper.StateSyncBuilder().withoutTopVisibleAppWindows().waitForAndVerify()
+
+        device.wakeUpAndGoToHomeScreen()
+
+        // Launch an activity that is shown when the device is locked
+        showWhenLockedApp.launchViaIntent(wmHelper)
+        wmHelper.StateSyncBuilder().withFullScreenApp(showWhenLockedApp).waitForAndVerify()
+
+        device.sleep()
+        wmHelper.StateSyncBuilder().withoutTopVisibleAppWindows().waitForAndVerify()
+    }
+
+    @Test
+    open fun openAppFromLockscreenNotificationWithOverlayApp() {
+        device.wakeUp()
+        NotificationUtils.openNotification(openingNotificationsFromLockScreen)
+        // Wait for the app to launch
+        wmHelper.StateSyncBuilder().withFullScreenApp(testApp).waitForAndVerify()
+    }
+
+    @After
+    fun teardown() {
+        testApp.exit(wmHelper)
+        showWhenLockedApp.exit(wmHelper)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/scenarios/OpenAppFromNotificationCold.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/scenarios/OpenAppFromNotificationCold.kt
new file mode 100644
index 0000000..fed077e
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/scenarios/OpenAppFromNotificationCold.kt
@@ -0,0 +1,76 @@
+/*
+ * 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.wm.flicker.service.notification.scenarios
+
+import android.app.Instrumentation
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.device.helpers.wakeUpAndGoToHomeScreen
+import android.tools.device.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.NotificationAppHelper
+import com.android.server.wm.flicker.service.Utils
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+
+abstract class OpenAppFromNotificationCold(
+    val gestureMode: NavBar = NavBar.MODE_GESTURAL,
+    val rotation: Rotation = Rotation.ROTATION_0
+) {
+    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+    private val tapl = LauncherInstrumentation()
+    private val device = UiDevice.getInstance(instrumentation)
+    private val wmHelper = WindowManagerStateHelper(instrumentation)
+    private val testApp: NotificationAppHelper = NotificationAppHelper(instrumentation)
+
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(gestureMode, rotation)
+
+    private val openingNotificationsFromLockScreen = false
+
+    @Before
+    fun setup() {
+        device.wakeUpAndGoToHomeScreen()
+        testApp.launchViaIntent(wmHelper)
+        wmHelper.StateSyncBuilder().withFullScreenApp(testApp).waitForAndVerify()
+        testApp.postNotification(wmHelper)
+        device.pressHome()
+        wmHelper.StateSyncBuilder().withHomeActivityVisible().waitForAndVerify()
+
+        // Close the app that posted the notification to trigger a cold start next time
+        // it is open - can't just kill it because that would remove the notification.
+        tapl.setExpectedRotationCheckEnabled(false)
+        tapl.goHome()
+        tapl.workspace.switchToOverview()
+        tapl.overview.dismissAllTasks()
+    }
+
+    @Test
+    open fun openAppFromNotificationCold() {
+        NotificationUtils.openNotification(openingNotificationsFromLockScreen)
+        // Wait for the app to launch
+        wmHelper.StateSyncBuilder().withFullScreenApp(testApp).waitForAndVerify()
+    }
+
+    @After
+    fun teardown() {
+        testApp.exit(wmHelper)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/scenarios/OpenAppFromNotificationWarm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/scenarios/OpenAppFromNotificationWarm.kt
new file mode 100644
index 0000000..403790e
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/notification/scenarios/OpenAppFromNotificationWarm.kt
@@ -0,0 +1,69 @@
+/*
+ * 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.wm.flicker.service.notification.scenarios
+
+import android.app.Instrumentation
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.device.helpers.wakeUpAndGoToHomeScreen
+import android.tools.device.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.NotificationAppHelper
+import com.android.server.wm.flicker.service.Utils
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+
+abstract class OpenAppFromNotificationWarm(
+    val gestureMode: NavBar = NavBar.MODE_GESTURAL,
+    val rotation: Rotation = Rotation.ROTATION_0
+) {
+    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+    private val tapl = LauncherInstrumentation()
+    private val device = UiDevice.getInstance(instrumentation)
+    private val wmHelper = WindowManagerStateHelper(instrumentation)
+    private val testApp: NotificationAppHelper = NotificationAppHelper(instrumentation)
+
+    private val openingNotificationsFromLockScreen = false
+
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(gestureMode, rotation)
+
+    @Before
+    fun setup() {
+        device.wakeUpAndGoToHomeScreen()
+        testApp.launchViaIntent(wmHelper)
+        wmHelper.StateSyncBuilder().withFullScreenApp(testApp).waitForAndVerify()
+        testApp.postNotification(wmHelper)
+        device.pressHome()
+        wmHelper.StateSyncBuilder().withHomeActivityVisible().waitForAndVerify()
+    }
+
+    @Test
+    open fun openAppFromNotificationWarm() {
+        NotificationUtils.openNotification(openingNotificationsFromLockScreen)
+        // Wait for the app to launch
+        wmHelper.StateSyncBuilder().withFullScreenApp(testApp).waitForAndVerify()
+    }
+
+    @After
+    fun teardown() {
+        testApp.exit(wmHelper)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/flicker/QuickSwitchBetweenTwoAppsBackGesturalNavLandscape.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/flicker/QuickSwitchBetweenTwoAppsBackGesturalNavLandscape.kt
new file mode 100644
index 0000000..d611a42
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/flicker/QuickSwitchBetweenTwoAppsBackGesturalNavLandscape.kt
@@ -0,0 +1,43 @@
+/*
+ * 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.wm.flicker.service.quickswitch.flicker
+
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.quickswitch.scenarios.QuickSwitchBetweenTwoAppsBack
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class QuickSwitchBetweenTwoAppsBackGesturalNavLandscape :
+    QuickSwitchBetweenTwoAppsBack(Rotation.ROTATION_90) {
+    @ExpectedScenarios(["QUICKSWITCH"])
+    @Test
+    override fun quickSwitchBetweenTwoAppsBack() = super.quickSwitchBetweenTwoAppsBack()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/flicker/QuickSwitchBetweenTwoAppsBackGesturalNavPortrait.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/flicker/QuickSwitchBetweenTwoAppsBackGesturalNavPortrait.kt
new file mode 100644
index 0000000..e6bcbba
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/flicker/QuickSwitchBetweenTwoAppsBackGesturalNavPortrait.kt
@@ -0,0 +1,43 @@
+/*
+ * 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.wm.flicker.service.quickswitch.flicker
+
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.quickswitch.scenarios.QuickSwitchBetweenTwoAppsBack
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class QuickSwitchBetweenTwoAppsBackGesturalNavPortrait :
+    QuickSwitchBetweenTwoAppsBack(Rotation.ROTATION_0) {
+    @ExpectedScenarios(["QUICKSWITCH"])
+    @Test
+    override fun quickSwitchBetweenTwoAppsBack() = super.quickSwitchBetweenTwoAppsBack()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/flicker/QuickSwitchBetweenTwoAppsForwardGesturalNavLandscape.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/flicker/QuickSwitchBetweenTwoAppsForwardGesturalNavLandscape.kt
new file mode 100644
index 0000000..2a26d63
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/flicker/QuickSwitchBetweenTwoAppsForwardGesturalNavLandscape.kt
@@ -0,0 +1,43 @@
+/*
+ * 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.wm.flicker.service.quickswitch.flicker
+
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.quickswitch.scenarios.QuickSwitchBetweenTwoAppsForward
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class QuickSwitchBetweenTwoAppsForwardGesturalNavLandscape :
+    QuickSwitchBetweenTwoAppsForward(Rotation.ROTATION_90) {
+    @ExpectedScenarios(["QUICKSWITCH"])
+    @Test
+    override fun quickSwitchBetweenTwoAppsForward() = super.quickSwitchBetweenTwoAppsForward()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/flicker/QuickSwitchBetweenTwoAppsForwardGesturalNavPortrait.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/flicker/QuickSwitchBetweenTwoAppsForwardGesturalNavPortrait.kt
new file mode 100644
index 0000000..5ce7143
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/flicker/QuickSwitchBetweenTwoAppsForwardGesturalNavPortrait.kt
@@ -0,0 +1,43 @@
+/*
+ * 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.wm.flicker.service.quickswitch.flicker
+
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.quickswitch.scenarios.QuickSwitchBetweenTwoAppsForward
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class QuickSwitchBetweenTwoAppsForwardGesturalNavPortrait :
+    QuickSwitchBetweenTwoAppsForward(Rotation.ROTATION_0) {
+    @ExpectedScenarios(["QUICKSWITCH"])
+    @Test
+    override fun quickSwitchBetweenTwoAppsForward() = super.quickSwitchBetweenTwoAppsForward()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/flicker/QuickSwitchFromLauncherGesturalNavLandscape.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/flicker/QuickSwitchFromLauncherGesturalNavLandscape.kt
new file mode 100644
index 0000000..cff47bb
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/flicker/QuickSwitchFromLauncherGesturalNavLandscape.kt
@@ -0,0 +1,42 @@
+/*
+ * 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.wm.flicker.service.quickswitch.flicker
+
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.quickswitch.scenarios.QuickSwitchFromLauncher
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class QuickSwitchFromLauncherGesturalNavLandscape : QuickSwitchFromLauncher(Rotation.ROTATION_90) {
+    @ExpectedScenarios(["QUICKSWITCH"])
+    @Test
+    override fun quickSwitchFromLauncher() = super.quickSwitchFromLauncher()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/flicker/QuickSwitchFromLauncherGesturalNavPortrait.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/flicker/QuickSwitchFromLauncherGesturalNavPortrait.kt
new file mode 100644
index 0000000..33095a6
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/flicker/QuickSwitchFromLauncherGesturalNavPortrait.kt
@@ -0,0 +1,42 @@
+/*
+ * 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.wm.flicker.service.quickswitch.flicker
+
+import android.tools.common.Rotation
+import android.tools.common.flicker.FlickerConfig
+import android.tools.common.flicker.annotation.ExpectedScenarios
+import android.tools.common.flicker.annotation.FlickerConfigProvider
+import android.tools.common.flicker.config.FlickerConfig
+import android.tools.common.flicker.config.FlickerServiceConfig
+import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.service.quickswitch.scenarios.QuickSwitchFromLauncher
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class QuickSwitchFromLauncherGesturalNavPortrait : QuickSwitchFromLauncher(Rotation.ROTATION_0) {
+    @ExpectedScenarios(["QUICKSWITCH"])
+    @Test
+    override fun quickSwitchFromLauncher() = super.quickSwitchFromLauncher()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/scenarios/QuickSwitchBetweenTwoAppsBack.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/scenarios/QuickSwitchBetweenTwoAppsBack.kt
new file mode 100644
index 0000000..93130c4
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/scenarios/QuickSwitchBetweenTwoAppsBack.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.service.quickswitch.scenarios
+
+import android.app.Instrumentation
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.device.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.NonResizeableAppHelper
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.server.wm.flicker.service.Utils
+import org.junit.After
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+
+@Ignore("Base Test Class")
+abstract class QuickSwitchBetweenTwoAppsBack(val rotation: Rotation = Rotation.ROTATION_0) {
+    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+    private val tapl = LauncherInstrumentation()
+    private val wmHelper = WindowManagerStateHelper(instrumentation)
+    private val testApp1 = SimpleAppHelper(instrumentation)
+    private val testApp2 = NonResizeableAppHelper(instrumentation)
+
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
+
+    @Before
+    fun setup() {
+        tapl.setExpectedRotation(rotation.value)
+        tapl.setIgnoreTaskbarVisibility(true)
+        testApp1.launchViaIntent(wmHelper)
+        testApp2.launchViaIntent(wmHelper)
+    }
+
+    @Test
+    open fun quickSwitchBetweenTwoAppsBack() {
+        tapl.launchedAppState.quickSwitchToPreviousApp()
+        wmHelper
+            .StateSyncBuilder()
+            .withFullScreenApp(testApp1)
+            .withNavOrTaskBarVisible()
+            .withStatusBarVisible()
+            .waitForAndVerify()
+    }
+
+    @After
+    fun teardown() {
+        testApp1.exit(wmHelper)
+        testApp2.exit(wmHelper)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/scenarios/QuickSwitchBetweenTwoAppsForward.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/scenarios/QuickSwitchBetweenTwoAppsForward.kt
new file mode 100644
index 0000000..4941eea
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/scenarios/QuickSwitchBetweenTwoAppsForward.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.service.quickswitch.scenarios
+
+import android.app.Instrumentation
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.device.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.NonResizeableAppHelper
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.server.wm.flicker.service.Utils
+import org.junit.After
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+
+@Ignore("Base Test Class")
+abstract class QuickSwitchBetweenTwoAppsForward(val rotation: Rotation = Rotation.ROTATION_0) {
+    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+    private val tapl = LauncherInstrumentation()
+    private val wmHelper = WindowManagerStateHelper(instrumentation)
+    private val testApp1 = SimpleAppHelper(instrumentation)
+    private val testApp2 = NonResizeableAppHelper(instrumentation)
+
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
+
+    @Before
+    fun setup() {
+        tapl.setExpectedRotation(rotation.value)
+
+        testApp1.launchViaIntent(wmHelper)
+        testApp2.launchViaIntent(wmHelper)
+        tapl.launchedAppState.quickSwitchToPreviousApp()
+        wmHelper
+            .StateSyncBuilder()
+            .withFullScreenApp(testApp1)
+            .withNavOrTaskBarVisible()
+            .withStatusBarVisible()
+            .waitForAndVerify()
+    }
+
+    @Test
+    open fun quickSwitchBetweenTwoAppsForward() {
+        tapl.launchedAppState.quickSwitchToPreviousAppSwipeLeft()
+        wmHelper
+            .StateSyncBuilder()
+            .withFullScreenApp(testApp2)
+            .withNavOrTaskBarVisible()
+            .withStatusBarVisible()
+            .waitForAndVerify()
+    }
+
+    @After
+    fun teardown() {
+        testApp1.exit(wmHelper)
+        testApp2.exit(wmHelper)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/scenarios/QuickSwitchFromLauncher.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/scenarios/QuickSwitchFromLauncher.kt
new file mode 100644
index 0000000..7afe526
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/scenarios/QuickSwitchFromLauncher.kt
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.service.quickswitch.scenarios
+
+import android.app.Instrumentation
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.device.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.server.wm.flicker.service.Utils
+import org.junit.After
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+
+@Ignore("Base Test Class")
+abstract class QuickSwitchFromLauncher(val rotation: Rotation = Rotation.ROTATION_0) {
+    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+    private val tapl = LauncherInstrumentation()
+    private val wmHelper = WindowManagerStateHelper(instrumentation)
+    private val testApp = SimpleAppHelper(instrumentation)
+
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
+
+    @Before
+    fun setup() {
+        tapl.setExpectedRotationCheckEnabled(false)
+
+        tapl.setExpectedRotation(rotation.value)
+
+        testApp.launchViaIntent(wmHelper)
+        tapl.goHome()
+        wmHelper
+            .StateSyncBuilder()
+            .withHomeActivityVisible()
+            .withWindowSurfaceDisappeared(testApp)
+            .waitForAndVerify()
+    }
+
+    @Test
+    open fun quickSwitchFromLauncher() {
+        tapl.workspace.quickSwitchToPreviousApp()
+        wmHelper
+            .StateSyncBuilder()
+            .withFullScreenApp(testApp)
+            .withNavOrTaskBarVisible()
+            .withStatusBarVisible()
+            .waitForAndVerify()
+    }
+
+    @After
+    fun teardown() {
+        testApp.exit(wmHelper)
+    }
+}
diff --git a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
index 7a2e74b..68ae806 100644
--- a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
@@ -193,6 +193,14 @@
             </intent-filter>
         </activity>
         <activity
+            android:name=".ActivityEmbeddingTrampolineActivity"
+            android:label="ActivityEmbedding Trampoline"
+            android:taskAffinity="com.android.server.wm.flicker.testapp.ActivityEmbedding"
+            android:theme="@style/CutoutShortEdges"
+            android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
+            android:exported="false">
+        </activity>
+        <activity
             android:name=".ActivityEmbeddingSecondaryActivity"
             android:label="ActivityEmbedding Secondary"
             android:taskAffinity="com.android.server.wm.flicker.testapp.ActivityEmbedding"
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_main_layout.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_main_layout.xml
index b9d789b..e32a709 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_main_layout.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_main_layout.xml
@@ -60,4 +60,12 @@
         android:tag="RIGHT_TO_LEFT"
         android:text="Launch Placeholder Split in RTL" />
 
+    <Button
+        android:id="@+id/launch_trampoline_button"
+        android:layout_width="wrap_content"
+        android:layout_height="48dp"
+        android:onClick="launchTrampolineActivity"
+        android:tag="LEFT_TO_RIGHT"
+        android:text="Launch Trampoline Activity" />
+
 </LinearLayout>
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingMainActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingMainActivity.java
index 817c79c..3b1a859 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingMainActivity.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingMainActivity.java
@@ -16,14 +16,12 @@
 
 package com.android.server.wm.flicker.testapp;
 
-
+import androidx.annotation.NonNull;
 import android.app.Activity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.view.View;
 
-import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper;
-import androidx.annotation.NonNull;
 import androidx.window.embedding.ActivityFilter;
 import androidx.window.embedding.ActivityRule;
 import androidx.window.embedding.EmbeddingAspectRatio;
@@ -59,6 +57,15 @@
         mRuleController = RuleController.getInstance(this);
     }
 
+    /** R.id.launch_trampoline_button onClick */
+    public void launchTrampolineActivity(View view) {
+        final String layoutDirection = view.getTag().toString();
+        mRuleController.clearRules();
+        mRuleController.addRule(createSplitPairRules(layoutDirection));
+        startActivity(new Intent().setComponent(
+                ActivityOptions.ActivityEmbedding.TrampolineActivity.COMPONENT));
+    }
+
     /** R.id.launch_secondary_activity_button onClick */
     public void launchSecondaryActivity(View view) {
         final String layoutDirection = view.getTag().toString();
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingTrampolineActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingTrampolineActivity.java
new file mode 100644
index 0000000..67eac2e
--- /dev/null
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingTrampolineActivity.java
@@ -0,0 +1,36 @@
+/*
+ * 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.wm.flicker.testapp;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+/**
+ * A Trampoline Activity that launches {@link ActivityEmbeddingSecondaryActivity} and then
+ * finishes itself.
+ */
+public class ActivityEmbeddingTrampolineActivity extends Activity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        // Trampoline activity doesn't have a view.
+        startActivity(new Intent().setComponent(
+                ActivityOptions.ActivityEmbedding.SecondaryActivity.COMPONENT));
+        finish();
+    }
+}
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java
index d84ac42..95c86ac 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java
@@ -122,6 +122,12 @@
             public static final ComponentName COMPONENT = new ComponentName(FLICKER_APP_PACKAGE,
                     FLICKER_APP_PACKAGE + ".ActivityEmbeddingPlaceholderSecondaryActivity");
         }
+
+        public static class TrampolineActivity {
+            public static final String LABEL = "ActivityEmbeddingTrampolineActivity";
+            public static final ComponentName COMPONENT = new ComponentName(FLICKER_APP_PACKAGE,
+                    FLICKER_APP_PACKAGE + ".ActivityEmbeddingTrampolineActivity");
+        }
     }
 
     public static class Notification {
diff --git a/tests/testables/src/com/android/internal/config/sysui/TestableFlagResolver.java b/tests/testables/src/com/android/internal/config/sysui/TestableFlagResolver.java
index a8815dc..6a6ab00 100644
--- a/tests/testables/src/com/android/internal/config/sysui/TestableFlagResolver.java
+++ b/tests/testables/src/com/android/internal/config/sysui/TestableFlagResolver.java
@@ -27,7 +27,9 @@
         return mOverrides.getOrDefault(flag.mSysPropKey, flag.mDefaultValue);
     }
 
-    public void setFlagOverride(SystemUiSystemPropertiesFlags.Flag flag, boolean isEnabled) {
+    public TestableFlagResolver setFlagOverride(SystemUiSystemPropertiesFlags.Flag flag,
+            boolean isEnabled) {
         mOverrides.put(flag.mSysPropKey, isEnabled);
+        return this;
     }
 }