Merge "Send system user broadcasts in headless system user mode." into tm-qpr-dev
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 70a23cd..8c00c6a 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1139,7 +1139,6 @@
   public final class CameraManager {
     method public String[] getCameraIdListNoLazy() throws android.hardware.camera2.CameraAccessException;
     method @RequiresPermission(allOf={android.Manifest.permission.SYSTEM_CAMERA, android.Manifest.permission.CAMERA}) public void openCamera(@NonNull String, int, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.CameraDevice.StateCallback) throws android.hardware.camera2.CameraAccessException;
-    field public static final long OVERRIDE_FRONT_CAMERA_APP_COMPAT = 250678880L; // 0xef10e60L
   }
 
   public abstract static class CameraManager.AvailabilityCallback {
@@ -2412,6 +2411,7 @@
   public abstract class DreamOverlayService extends android.app.Service {
     ctor public DreamOverlayService();
     method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
+    method public void onEndDream();
     method public abstract void onStartDream(@NonNull android.view.WindowManager.LayoutParams);
     method public final void requestExit();
     method public final boolean shouldShowComplications();
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index d24b677..03a97ba 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -997,6 +997,8 @@
 
     private ComponentCallbacksController mCallbacksController;
 
+    @Nullable private IVoiceInteractionManagerService mVoiceInteractionManagerService;
+
     private final WindowControllerCallback mWindowControllerCallback =
             new WindowControllerCallback() {
         /**
@@ -1606,18 +1608,17 @@
 
     private void notifyVoiceInteractionManagerServiceActivityEvent(
             @VoiceInteractionSession.VoiceInteractionActivityEventType int type) {
-
-        final IVoiceInteractionManagerService service =
-                IVoiceInteractionManagerService.Stub.asInterface(
-                        ServiceManager.getService(Context.VOICE_INTERACTION_MANAGER_SERVICE));
-        if (service == null) {
-            Log.w(TAG, "notifyVoiceInteractionManagerServiceActivityEvent: Can not get "
-                    + "VoiceInteractionManagerService");
-            return;
+        if (mVoiceInteractionManagerService == null) {
+            mVoiceInteractionManagerService = IVoiceInteractionManagerService.Stub.asInterface(
+                    ServiceManager.getService(Context.VOICE_INTERACTION_MANAGER_SERVICE));
+            if (mVoiceInteractionManagerService == null) {
+                Log.w(TAG, "notifyVoiceInteractionManagerServiceActivityEvent: Can not get "
+                        + "VoiceInteractionManagerService");
+                return;
+            }
         }
-
         try {
-            service.notifyActivityEventChanged(mToken, type);
+            mVoiceInteractionManagerService.notifyActivityEventChanged(mToken, type);
         } catch (RemoteException e) {
             // Empty
         }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 8b41aa4..46d8481 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -7944,8 +7944,6 @@
          * @hide
          */
         public MessagingStyle setShortcutIcon(@Nullable Icon conversationIcon) {
-            // TODO(b/228941516): This icon should be downscaled to avoid using too much memory,
-            // see reduceImageSizes.
             mShortcutIcon = conversationIcon;
             return this;
         }
diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java
index a51b9d3..27f9f54 100644
--- a/core/java/android/app/PropertyInvalidatedCache.java
+++ b/core/java/android/app/PropertyInvalidatedCache.java
@@ -1406,6 +1406,17 @@
     }
 
     /**
+     * Return the number of entries in the cache.  This is used for testing and has package-only
+     * visibility.
+     * @hide
+     */
+    public int size() {
+        synchronized (mLock) {
+            return mCache.size();
+        }
+    }
+
+    /**
      * Returns a list of caches alive at the current time.
      */
     @GuardedBy("sGlobalLock")
@@ -1612,8 +1623,12 @@
      * @hide
      */
     public static void onTrimMemory() {
-        for (PropertyInvalidatedCache pic : getActiveCaches()) {
-            pic.clear();
+        ArrayList<PropertyInvalidatedCache> activeCaches;
+        synchronized (sGlobalLock) {
+            activeCaches = getActiveCaches();
+        }
+        for (int i = 0; i < activeCaches.size(); i++) {
+            activeCaches.get(i).clear();
         }
     }
 }
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index 7635138..5258542 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -720,7 +720,7 @@
      * apps targeting SDK Version {@link android.os.Build.VERSION_CODES#S}
      * or higher are not allowed to start foreground services from the background.
      * See
-     * <a href="{@docRoot}/about/versions/12/behavior-changes-12">
+     * <a href="{@docRoot}about/versions/12/behavior-changes-12">
      * Behavior changes: Apps targeting Android 12
      * </a>
      * for more details.
@@ -769,7 +769,7 @@
    * apps targeting SDK Version {@link android.os.Build.VERSION_CODES#S}
    * or higher are not allowed to start foreground services from the background.
    * See
-   * <a href="{@docRoot}/about/versions/12/behavior-changes-12">
+   * <a href="{@docRoot}about/versions/12/behavior-changes-12">
    * Behavior changes: Apps targeting Android 12
    * </a>
    * for more details.
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 7eacc3c..dea1a05 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -753,6 +753,19 @@
     }
 
     /**
+     * Temporary method for project b/197814683
+     * Starting from U, this will return true if the new wallpaper logic is enabled,
+     * i.e. if the lockscreen wallpaper always uses a wallpaperService and not a static image.
+     * In T, this is just a stub method that always return false.
+     *
+     * @return false
+     * @hide
+     */
+    public boolean isLockscreenLiveWallpaperEnabled() {
+        return false;
+    }
+
+    /**
      * Indicate whether wcg (Wide Color Gamut) should be enabled.
      * <p>
      * Some devices lack of capability of mixed color spaces composition,
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 8e09939..bab2061 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1128,6 +1128,9 @@
      * <p>Use only for device owner provisioning. This extra can be returned by the admin app when
      * performing the admin-integrated provisioning flow as a result of the {@link
      * #ACTION_GET_PROVISIONING_MODE} activity.
+     *
+     * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an NFC bump. It can also be used for QR code provisioning.
      */
     public static final String EXTRA_PROVISIONING_TIME_ZONE
         = "android.app.extra.PROVISIONING_TIME_ZONE";
@@ -1139,6 +1142,9 @@
      * <p>Use only for device owner provisioning. This extra can be returned by the admin app when
      * performing the admin-integrated provisioning flow as a result of the {@link
      * #ACTION_GET_PROVISIONING_MODE} activity.
+     *
+     * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an NFC bump. It can also be used for QR code provisioning.
      */
     public static final String EXTRA_PROVISIONING_LOCAL_TIME
         = "android.app.extra.PROVISIONING_LOCAL_TIME";
@@ -1150,6 +1156,9 @@
      * <p>Use only for device owner provisioning. This extra can be returned by the admin app when
      * performing the admin-integrated provisioning flow as a result of the {@link
      * #ACTION_GET_PROVISIONING_MODE} activity.
+     *
+     * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an NFC bump. It can also be used for QR code provisioning.
      */
     public static final String EXTRA_PROVISIONING_LOCALE
         = "android.app.extra.PROVISIONING_LOCALE";
@@ -1159,7 +1168,7 @@
      * owner provisioning for downloading the mobile device management application.
      *
      * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
-     * provisioning via an NFC bump.
+     * provisioning via an NFC bump. It can also be used for QR code provisioning.
      */
     public static final String EXTRA_PROVISIONING_WIFI_SSID
         = "android.app.extra.PROVISIONING_WIFI_SSID";
@@ -1169,7 +1178,7 @@
      * is hidden or not.
      *
      * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
-     * provisioning via an NFC bump.
+     * provisioning via an NFC bump. It can also be used for QR code provisioning.
      */
     public static final String EXTRA_PROVISIONING_WIFI_HIDDEN
         = "android.app.extra.PROVISIONING_WIFI_HIDDEN";
@@ -1180,7 +1189,7 @@
      * {@code WEP} or {@code EAP}.
      *
      * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
-     * provisioning via an NFC bump.
+     * provisioning via an NFC bump. It can also be used for QR code provisioning.
      */
     public static final String EXTRA_PROVISIONING_WIFI_SECURITY_TYPE
         = "android.app.extra.PROVISIONING_WIFI_SECURITY_TYPE";
@@ -1190,7 +1199,7 @@
      * {@link #EXTRA_PROVISIONING_WIFI_SSID}.
      *
      * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
-     * provisioning via an NFC bump.
+     * provisioning via an NFC bump. It can also be used for QR code provisioning.
      */
     public static final String EXTRA_PROVISIONING_WIFI_PASSWORD =
             "android.app.extra.PROVISIONING_WIFI_PASSWORD";
@@ -1281,7 +1290,7 @@
      * {@link #EXTRA_PROVISIONING_WIFI_SSID}.
      *
      * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
-     * provisioning via an NFC bump.
+     * provisioning via an NFC bump. It can also be used for QR code provisioning.
      */
     public static final String EXTRA_PROVISIONING_WIFI_PROXY_HOST
         = "android.app.extra.PROVISIONING_WIFI_PROXY_HOST";
@@ -1291,7 +1300,7 @@
      * {@link #EXTRA_PROVISIONING_WIFI_SSID}.
      *
      * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
-     * provisioning via an NFC bump.
+     * provisioning via an NFC bump. It can also be used for QR code provisioning.
      */
     public static final String EXTRA_PROVISIONING_WIFI_PROXY_PORT
         = "android.app.extra.PROVISIONING_WIFI_PROXY_PORT";
@@ -1301,7 +1310,7 @@
      * {@link #EXTRA_PROVISIONING_WIFI_SSID}.
      *
      * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
-     * provisioning via an NFC bump.
+     * provisioning via an NFC bump. It can also be used for QR code provisioning.
      */
     public static final String EXTRA_PROVISIONING_WIFI_PROXY_BYPASS
         = "android.app.extra.PROVISIONING_WIFI_PROXY_BYPASS";
@@ -1311,7 +1320,7 @@
      * {@link #EXTRA_PROVISIONING_WIFI_SSID}.
      *
      * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
-     * provisioning via an NFC bump.
+     * provisioning via an NFC bump. It can also be used for QR code provisioning.
      */
     public static final String EXTRA_PROVISIONING_WIFI_PAC_URL
         = "android.app.extra.PROVISIONING_WIFI_PAC_URL";
@@ -1321,7 +1330,7 @@
      * package. When not provided it is assumed that the device admin package is already installed.
      *
      * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
-     * provisioning via an NFC bump.
+     * provisioning via an NFC bump. It can also be used for QR code provisioning.
      */
     public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION
         = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION";
@@ -1401,7 +1410,7 @@
      * installed package is less than this version code.
      *
      * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
-     * provisioning via an NFC bump.
+     * provisioning via an NFC bump. It can also be used for QR code provisioning.
      */
     public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE
         = "android.app.extra.PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE";
@@ -1411,7 +1420,7 @@
      * url specified in {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION}.
      *
      * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
-     * provisioning via an NFC bump.
+     * provisioning via an NFC bump. It can also be used for QR code provisioning.
      */
     public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER
         = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER";
@@ -1426,7 +1435,7 @@
      * be asked to factory reset the device.
      *
      * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
-     * provisioning via an NFC bump.
+     * provisioning via an NFC bump. It can also be used for QR code provisioning.
      *
      * <p><strong>Note:</strong> for devices running {@link android.os.Build.VERSION_CODES#LOLLIPOP}
      * and {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} only SHA-1 hash is supported.
@@ -1472,7 +1481,7 @@
      * the user will be asked to factory reset the device.
      *
      * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
-     * provisioning via an NFC bump.
+     * provisioning via an NFC bump. It can also be used for QR code provisioning.
      */
     public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM
         = "android.app.extra.PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM";
@@ -6778,6 +6787,8 @@
      * {@link #ENCRYPTION_STATUS_UNSUPPORTED}, {@link #ENCRYPTION_STATUS_INACTIVE},
      * {@link #ENCRYPTION_STATUS_ACTIVATING}, {@link #ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY},
      * {@link #ENCRYPTION_STATUS_ACTIVE}, or {@link #ENCRYPTION_STATUS_ACTIVE_PER_USER}.
+     *
+     * @throws SecurityException if called on a parent instance.
      */
     public int getStorageEncryptionStatus() {
         throwIfParentInstance("getStorageEncryptionStatus");
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 5ca8b05..a320f1e 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -65,6 +65,7 @@
 import android.provider.DocumentsProvider;
 import android.provider.MediaStore;
 import android.provider.OpenableColumns;
+import android.service.chooser.ChooserAction;
 import android.telecom.PhoneAccount;
 import android.telecom.TelecomManager;
 import android.text.TextUtils;
@@ -5731,6 +5732,25 @@
             = "android.intent.extra.CHOOSER_REFINEMENT_INTENT_SENDER";
 
     /**
+     * A Parcelable[] of {@link ChooserAction} objects to provide the Android Sharesheet with
+     * app-specific actions to be presented to the user when invoking {@link #ACTION_CHOOSER}.
+     * @hide
+     */
+    public static final String EXTRA_CHOOSER_CUSTOM_ACTIONS =
+            "android.intent.extra.EXTRA_CHOOSER_CUSTOM_ACTIONS";
+
+    /**
+     * Optional argument to be used with {@link #ACTION_CHOOSER}.
+     * A {@link android.app.PendingIntent} to be sent when the user wants to do payload reselection
+     * in the sharesheet.
+     * A reselection action allows the user to return to the source app to change the content being
+     * shared.
+     * @hide
+     */
+    public static final String EXTRA_CHOOSER_PAYLOAD_RESELECTION_ACTION =
+            "android.intent.extra.EXTRA_CHOOSER_PAYLOAD_RESELECTION_ACTION";
+
+    /**
      * An {@code ArrayList} of {@code String} annotations describing content for
      * {@link #ACTION_CHOOSER}.
      *
@@ -11468,7 +11488,7 @@
     private void toUriInner(StringBuilder uri, String scheme, String defAction,
             String defPackage, int flags) {
         if (scheme != null) {
-            uri.append("scheme=").append(scheme).append(';');
+            uri.append("scheme=").append(Uri.encode(scheme)).append(';');
         }
         if (mAction != null && !mAction.equals(defAction)) {
             uri.append("action=").append(Uri.encode(mAction)).append(';');
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 4be5e14..2e3b5d2 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -1022,6 +1022,19 @@
     public @interface SizeChangesSupportMode {}
 
     /**
+     * This change id enables compat policy that ignores app requested orientation in
+     * response to an app calling {@link android.app.Activity#setRequestedOrientation}. See
+     * com.android.server.wm.LetterboxUiController#shouldIgnoreRequestedOrientation for
+     * details.
+     * @hide
+     */
+    @ChangeId
+    @Overridable
+    @Disabled
+    public static final long OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION =
+            254631730L; // buganizer id
+
+    /**
      * This change id forces the packages it is applied to never have Display API sandboxing
      * applied for a letterbox or SCM activity. The Display APIs will continue to provide
      * DisplayArea bounds.
@@ -1045,6 +1058,41 @@
     public static final long ALWAYS_SANDBOX_DISPLAY_APIS = 185004937L; // buganizer id
 
     /**
+     * This change id excludes the packages it is applied to from the camera compat force rotation
+     * treatment. See com.android.server.wm.DisplayRotationCompatPolicy for context.
+     * @hide
+     */
+    @ChangeId
+    @Overridable
+    @Disabled
+    public static final long OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION =
+            263959004L; // buganizer id
+
+    /**
+     * This change id excludes the packages it is applied to from activity refresh after camera
+     * compat force rotation treatment. See com.android.server.wm.DisplayRotationCompatPolicy for
+     * context.
+     * @hide
+     */
+    @ChangeId
+    @Overridable
+    @Disabled
+    public static final long OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH = 264304459L; // buganizer id
+
+    /**
+     * This change id makes the packages it is applied to do activity refresh after camera compat
+     * force rotation treatment using "resumed -> paused -> resumed" cycle rather than "resumed ->
+     * ... -> stopped -> ... -> resumed" cycle. See
+     * com.android.server.wm.DisplayRotationCompatPolicy for context.
+     * @hide
+     */
+    @ChangeId
+    @Overridable
+    @Disabled
+    public static final long OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE =
+            264301586L; // buganizer id
+
+    /**
      * This change id is the gatekeeper for all treatments that force a given min aspect ratio.
      * Enabling this change will allow the following min aspect ratio treatments to be applied:
      * OVERRIDE_MIN_ASPECT_RATIO_MEDIUM
@@ -1129,6 +1177,17 @@
     public static final long OVERRIDE_MIN_ASPECT_RATIO_EXCLUDE_PORTRAIT_FULLSCREEN = 218959984L;
 
     /**
+     * Enables sending fake focus for unfocused apps in splitscreen. Some game engines
+     * wait to get focus before drawing the content of the app so fake focus helps them to avoid
+     * staying blacked out when they are resumed and do not have focus yet.
+     * @hide
+     */
+    @ChangeId
+    @Disabled
+    @Overridable
+    public static final long OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS = 263259275L;
+
+    /**
      * Compares activity window layout min width/height with require space for multi window to
      * determine if it can be put into multi window mode.
      */
diff --git a/core/java/android/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException.java b/core/java/android/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException.java
index 41f2f9c..b86b97c 100644
--- a/core/java/android/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException.java
+++ b/core/java/android/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException.java
@@ -17,7 +17,7 @@
 package android.database.sqlite;
 
 /**
- * Thrown if the the bind or column parameter index is out of range
+ * Thrown if the bind or column parameter index is out of range.
  */
 public class SQLiteBindOrColumnIndexOutOfRangeException extends SQLiteException {
     public SQLiteBindOrColumnIndexOutOfRangeException() {}
diff --git a/core/java/android/database/sqlite/SQLiteDiskIOException.java b/core/java/android/database/sqlite/SQLiteDiskIOException.java
index 01b2069..152d90a 100644
--- a/core/java/android/database/sqlite/SQLiteDiskIOException.java
+++ b/core/java/android/database/sqlite/SQLiteDiskIOException.java
@@ -17,7 +17,7 @@
 package android.database.sqlite;
 
 /**
- * An exception that indicates that an IO error occured while accessing the 
+ * Indicates that an IO error occurred while accessing the
  * SQLite database file.
  */
 public class SQLiteDiskIOException extends SQLiteException {
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 5291d2b..7ccf07a 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -29,7 +29,6 @@
 import android.annotation.SdkConstant.SdkConstantType;
 import android.app.ActivityThread;
 import android.app.AppOpsManager;
-import android.app.compat.CompatChanges;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.graphics.ImageFormat;
@@ -47,7 +46,6 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.SystemProperties;
 import android.renderscript.Allocation;
 import android.renderscript.Element;
 import android.renderscript.RSIllegalArgumentException;
@@ -284,14 +282,6 @@
      */
     public native static int getNumberOfCameras();
 
-    private static final boolean sLandscapeToPortrait =
-            SystemProperties.getBoolean(CameraManager.LANDSCAPE_TO_PORTRAIT_PROP, false);
-
-    private static boolean shouldOverrideToPortrait() {
-        return CompatChanges.isChangeEnabled(CameraManager.OVERRIDE_FRONT_CAMERA_APP_COMPAT)
-                && sLandscapeToPortrait;
-    }
-
     /**
      * Returns the information about a particular camera.
      * If {@link #getNumberOfCameras()} returns N, the valid id is 0 to N-1.
@@ -301,7 +291,8 @@
      *    low-level failure).
      */
     public static void getCameraInfo(int cameraId, CameraInfo cameraInfo) {
-        boolean overrideToPortrait = shouldOverrideToPortrait();
+        boolean overrideToPortrait = CameraManager.shouldOverrideToPortrait(
+                ActivityThread.currentApplication().getApplicationContext());
 
         _getCameraInfo(cameraId, overrideToPortrait, cameraInfo);
         IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
@@ -498,7 +489,8 @@
             mEventHandler = null;
         }
 
-        boolean overrideToPortrait = shouldOverrideToPortrait();
+        boolean overrideToPortrait = CameraManager.shouldOverrideToPortrait(
+                ActivityThread.currentApplication().getApplicationContext());
         return native_setup(new WeakReference<Camera>(this), cameraId,
                 ActivityThread.currentOpPackageName(), overrideToPortrait);
     }
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index be99f0f..4dc6e93 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -115,8 +115,14 @@
     @ChangeId
     @Overridable
     @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.BASE)
-    @TestApi
-    public static final long OVERRIDE_FRONT_CAMERA_APP_COMPAT = 250678880L;
+    public static final long OVERRIDE_CAMERA_LANDSCAPE_TO_PORTRAIT = 250678880L;
+
+    /**
+     * Package-level opt in/out for the above.
+     * @hide
+     */
+    public static final String PROPERTY_COMPAT_OVERRIDE_LANDSCAPE_TO_PORTRAIT =
+            "android.camera.PROPERTY_COMPAT_OVERRIDE_LANDSCAPE_TO_PORTRAIT";
 
     /**
      * System property for allowing the above
@@ -386,6 +392,23 @@
      * except that it uses {@link java.util.concurrent.Executor} as an argument
      * instead of {@link android.os.Handler}.</p>
      *
+     * <p>Note: If the order between some availability callbacks matters, the implementation of the
+     * executor should handle those callbacks in the same thread to maintain the callbacks' order.
+     * Some examples are:</p>
+     *
+     * <ul>
+     *
+     * <li>{@link AvailabilityCallback#onCameraAvailable} and
+     * {@link AvailabilityCallback#onCameraUnavailable} of the same camera ID.</li>
+     *
+     * <li>{@link AvailabilityCallback#onCameraAvailable} or
+     * {@link AvailabilityCallback#onCameraUnavailable} of a logical multi-camera, and {@link
+     * AvailabilityCallback#onPhysicalCameraUnavailable} or
+     * {@link AvailabilityCallback#onPhysicalCameraAvailable} of its physical
+     * cameras.</li>
+     *
+     * </ul>
+     *
      * @param executor The executor which will be used to invoke the callback.
      * @param callback the new callback to send camera availability notices to
      *
@@ -602,7 +625,7 @@
             try {
                 Size displaySize = getDisplaySize();
 
-                boolean overrideToPortrait = shouldOverrideToPortrait();
+                boolean overrideToPortrait = shouldOverrideToPortrait(mContext);
                 CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId,
                         mContext.getApplicationInfo().targetSdkVersion, overrideToPortrait);
                 try {
@@ -722,7 +745,7 @@
                         "Camera service is currently unavailable");
                 }
 
-                boolean overrideToPortrait = shouldOverrideToPortrait();
+                boolean overrideToPortrait = shouldOverrideToPortrait(mContext);
                 cameraUser = cameraService.connectDevice(callbacks, cameraId,
                     mContext.getOpPackageName(), mContext.getAttributionTag(), uid,
                     oomScoreOffset, mContext.getApplicationInfo().targetSdkVersion,
@@ -1154,9 +1177,26 @@
         return CameraManagerGlobal.get().getTorchStrengthLevel(cameraId);
     }
 
-    private static boolean shouldOverrideToPortrait() {
-        return CompatChanges.isChangeEnabled(OVERRIDE_FRONT_CAMERA_APP_COMPAT)
-                && CameraManagerGlobal.sLandscapeToPortrait;
+    /**
+     * @hide
+     */
+    public static boolean shouldOverrideToPortrait(@Nullable Context context) {
+        if (!CameraManagerGlobal.sLandscapeToPortrait) {
+            return false;
+        }
+
+        if (context != null) {
+            PackageManager packageManager = context.getPackageManager();
+
+            try {
+                return packageManager.getProperty(context.getOpPackageName(),
+                            PROPERTY_COMPAT_OVERRIDE_LANDSCAPE_TO_PORTRAIT).getBoolean();
+            } catch (PackageManager.NameNotFoundException e) {
+                // No such property
+            }
+        }
+
+        return CompatChanges.isChangeEnabled(OVERRIDE_CAMERA_LANDSCAPE_TO_PORTRAIT);
     }
 
     /**
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index a6c79b3..0c2468e 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -87,6 +87,7 @@
 
     // TODO: guard every function with if (!mRemoteDevice) check (if it was closed)
     private ICameraDeviceUserWrapper mRemoteDevice;
+    private boolean mRemoteDeviceInit = false;
 
     // Lock to synchronize cross-thread access to device public interface
     final Object mInterfaceLock = new Object(); // access from this class and Session only!
@@ -338,6 +339,8 @@
 
             mDeviceExecutor.execute(mCallOnOpened);
             mDeviceExecutor.execute(mCallOnUnconfigured);
+
+            mRemoteDeviceInit = true;
         }
     }
 
@@ -1754,8 +1757,8 @@
         }
 
         synchronized(mInterfaceLock) {
-            if (mRemoteDevice == null) {
-                return; // Camera already closed
+            if (mRemoteDevice == null && mRemoteDeviceInit) {
+                return; // Camera already closed, user is not interested in errors anymore.
             }
 
             // Redirect device callback to the offline session in case we are in the middle
diff --git a/core/java/android/hardware/devicestate/DeviceStateManager.java b/core/java/android/hardware/devicestate/DeviceStateManager.java
index dba1a5e..6a667fe 100644
--- a/core/java/android/hardware/devicestate/DeviceStateManager.java
+++ b/core/java/android/hardware/devicestate/DeviceStateManager.java
@@ -251,6 +251,10 @@
         @Nullable
         private Boolean lastResult;
 
+        public FoldStateListener(Context context) {
+            this(context, folded -> {});
+        }
+
         public FoldStateListener(Context context, Consumer<Boolean> listener) {
             mFoldedDeviceStates = context.getResources().getIntArray(
                     com.android.internal.R.array.config_foldedDeviceStates);
@@ -266,5 +270,10 @@
                 mDelegate.accept(folded);
             }
         }
+
+        @Nullable
+        public Boolean getFolded() {
+            return lastResult;
+        }
     }
 }
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index baf8836..b6cd06e 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -168,7 +168,7 @@
      * The <code>android:label</code> attribute specifies a human-readable descriptive
      * label to describe the keyboard layout in the user interface, such as "English (US)".
      * The <code>android:keyboardLayout</code> attribute refers to a
-     * <a href="http://source.android.com/tech/input/key-character-map-files.html">
+     * <a href="https://source.android.com/docs/core/interaction/input/key-character-map-files">
      * key character map</a> resource that defines the keyboard layout.
      * </p>
      */
diff --git a/core/java/android/os/BinderProxy.java b/core/java/android/os/BinderProxy.java
index 6330661..1929a4d 100644
--- a/core/java/android/os/BinderProxy.java
+++ b/core/java/android/os/BinderProxy.java
@@ -536,8 +536,8 @@
             mWarnOnBlocking = false;
             warnOnBlocking = false;
 
-            if (Build.IS_USERDEBUG) {
-                // Log this as a WTF on userdebug builds.
+            if (Build.IS_USERDEBUG || Build.IS_ENG) {
+                // Log this as a WTF on userdebug and eng builds.
                 Log.wtf(Binder.TAG,
                         "Outgoing transactions from this process must be FLAG_ONEWAY",
                         new Throwable());
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index e1d15de..125bdaf 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -74,6 +74,7 @@
     String getUserAccount(int userId);
     void setUserAccount(int userId, String accountName);
     long getUserCreationTime(int userId);
+    int getUserSwitchability(int userId);
     boolean isUserSwitcherEnabled(int mUserId);
     boolean isRestricted(int userId);
     boolean canHaveRestrictedProfile(int userId);
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 5487a12..aa0ac31 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -58,7 +58,6 @@
 import android.graphics.drawable.Drawable;
 import android.location.LocationManager;
 import android.provider.Settings;
-import android.telephony.TelephonyManager;
 import android.util.AndroidException;
 import android.util.ArraySet;
 import android.util.Log;
@@ -595,8 +594,11 @@
     /**
      * Specifies if a user is disallowed from transferring files over USB.
      *
-     * <p>This restriction can only be set by a device owner, a profile owner on the primary
-     * user or a profile owner of an organization-owned managed profile on the parent profile.
+     * <p>This restriction can only be set by a <a href="https://developers.google.com/android/work/terminology#device_owner_do">
+     * device owner</a> or a <a href="https://developers.google.com/android/work/terminology#profile_owner_po">
+     * profile owner</a> on the primary user's profile or a profile owner of an organization-owned
+     * <a href="https://developers.google.com/android/work/terminology#managed_profile">
+     * managed profile</a> on the parent profile.
      * When it is set by a device owner, it applies globally. When it is set by a profile owner
      * on the primary user or by a profile owner of an organization-owned managed profile on
      * the parent profile, it disables the primary user from transferring files over USB. No other
@@ -1670,7 +1672,7 @@
     public static final int SWITCHABILITY_STATUS_SYSTEM_USER_LOCKED = 1 << 2;
 
     /**
-     * Result returned in {@link #getUserSwitchability()} indicating user swichability.
+     * Result returned in {@link #getUserSwitchability()} indicating user switchability.
      * @hide
      */
     @Retention(RetentionPolicy.SOURCE)
@@ -2037,25 +2039,16 @@
      * @hide
      */
     @Deprecated
-    @RequiresPermission(allOf = {
-            Manifest.permission.READ_PHONE_STATE,
-            Manifest.permission.MANAGE_USERS}, // Can be INTERACT_ACROSS_USERS instead.
-            conditional = true)
+    @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS,
+            android.Manifest.permission.INTERACT_ACROSS_USERS})
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     @UserHandleAware
     public boolean canSwitchUsers() {
-        boolean allowUserSwitchingWhenSystemUserLocked = Settings.Global.getInt(
-                mContext.getContentResolver(),
-                Settings.Global.ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED, 0) != 0;
-        boolean isSystemUserUnlocked = isUserUnlocked(UserHandle.SYSTEM);
-        boolean inCall = false;
-        TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
-        if (telephonyManager != null) {
-            inCall = telephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE;
+        try {
+            return mService.getUserSwitchability(mUserId) == SWITCHABILITY_STATUS_OK;
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
         }
-        boolean isUserSwitchDisallowed = hasUserRestrictionForUser(DISALLOW_USER_SWITCH, mUserId);
-        return (allowUserSwitchingWhenSystemUserLocked || isSystemUserUnlocked) && !inCall
-                && !isUserSwitchDisallowed;
     }
 
     /**
@@ -2089,34 +2082,14 @@
      * @return A {@link UserSwitchabilityResult} flag indicating if the user is switchable.
      * @hide
      */
-    @RequiresPermission(allOf = {Manifest.permission.READ_PHONE_STATE,
-            android.Manifest.permission.MANAGE_USERS,
-            android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional = true)
+    @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS,
+            android.Manifest.permission.INTERACT_ACROSS_USERS})
     public @UserSwitchabilityResult int getUserSwitchability(UserHandle userHandle) {
-        final TelephonyManager tm =
-                (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
-
-        int flags = SWITCHABILITY_STATUS_OK;
-        if (tm.getCallState() != TelephonyManager.CALL_STATE_IDLE) {
-            flags |= SWITCHABILITY_STATUS_USER_IN_CALL;
+        try {
+            return mService.getUserSwitchability(userHandle.getIdentifier());
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
         }
-        if (hasUserRestrictionForUser(DISALLOW_USER_SWITCH, userHandle)) {
-            flags |= SWITCHABILITY_STATUS_USER_SWITCH_DISALLOWED;
-        }
-
-        // System User is always unlocked in Headless System User Mode, so ignore this flag
-        if (!isHeadlessSystemUserMode()) {
-            final boolean allowUserSwitchingWhenSystemUserLocked = Settings.Global.getInt(
-                    mContext.getContentResolver(),
-                    Settings.Global.ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED, 0) != 0;
-            final boolean systemUserUnlocked = isUserUnlocked(UserHandle.SYSTEM);
-
-            if (!allowUserSwitchingWhenSystemUserLocked && !systemUserUnlocked) {
-                flags |= SWITCHABILITY_STATUS_SYSTEM_USER_LOCKED;
-            }
-        }
-
-        return flags;
     }
 
     /**
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 497bfa6..d9604b3f 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -2555,6 +2555,8 @@
      * This API doesn't require any special permissions, though typical implementations
      * will require being called from an SELinux domain that allows setting file attributes
      * related to quota (eg the GID or project ID).
+     * If the calling user has MANAGE_EXTERNAL_STORAGE permissions, quota for shared profile's
+     * volumes is also updated.
      *
      * The default platform user of this API is the MediaProvider process, which is
      * responsible for managing all of external storage.
@@ -2575,7 +2577,14 @@
             @QuotaType int quotaType) throws IOException {
         long projectId;
         final String filePath = path.getCanonicalPath();
-        final StorageVolume volume = getStorageVolume(path);
+        int volFlags = FLAG_REAL_STATE | FLAG_INCLUDE_INVISIBLE;
+        // If caller has MANAGE_EXTERNAL_STORAGE permission, results from User Profile(s) are also
+        // returned by enabling FLAG_INCLUDE_SHARED_PROFILE.
+        if (mContext.checkSelfPermission(MANAGE_EXTERNAL_STORAGE) == PERMISSION_GRANTED) {
+            volFlags |= FLAG_INCLUDE_SHARED_PROFILE;
+        }
+        final StorageVolume[] availableVolumes = getVolumeList(mContext.getUserId(), volFlags);
+        final StorageVolume volume = getStorageVolume(availableVolumes, path);
         if (volume == null) {
             Log.w(TAG, "Failed to update quota type for " + filePath);
             return;
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 94a6382..ce4a735 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -9233,6 +9233,14 @@
         public static final int DOCK_SETUP_PROMPTED = 3;
 
         /**
+         * Indicates that the user has started dock setup but never finished it.
+         * One of the possible states for {@link #DOCK_SETUP_STATE}.
+         *
+         * @hide
+         */
+        public static final int DOCK_SETUP_INCOMPLETE = 4;
+
+        /**
          * Indicates that the user has completed dock setup.
          * One of the possible states for {@link #DOCK_SETUP_STATE}.
          *
@@ -9240,6 +9248,14 @@
          */
         public static final int DOCK_SETUP_COMPLETED = 10;
 
+        /**
+         * Indicates that dock setup timed out before the user could complete it.
+         * One of the possible states for {@link #DOCK_SETUP_STATE}.
+         *
+         * @hide
+         */
+        public static final int DOCK_SETUP_TIMED_OUT = 11;
+
         /** @hide */
         @Retention(RetentionPolicy.SOURCE)
         @IntDef({
@@ -9247,7 +9263,9 @@
                 DOCK_SETUP_STARTED,
                 DOCK_SETUP_PAUSED,
                 DOCK_SETUP_PROMPTED,
-                DOCK_SETUP_COMPLETED
+                DOCK_SETUP_INCOMPLETE,
+                DOCK_SETUP_COMPLETED,
+                DOCK_SETUP_TIMED_OUT
         })
         public @interface DockSetupState {
         }
@@ -9516,7 +9534,7 @@
         /**
          * Indicates whether "seen" notifications should be suppressed from the lockscreen.
          * <p>
-         * Type: int (0 for false, 1 for true)
+         * Type: int (0 for unset, 1 for true, 2 for false)
          *
          * @hide
          */
@@ -9819,11 +9837,12 @@
                 "fingerprint_side_fps_auth_downtime";
 
         /**
-         * Whether or not a SFPS device is required to be interactive for auth to unlock the device.
+         * Whether or not a SFPS device is enabling the performant auth setting.
+         * The "_V2" suffix was added to re-introduce the default behavior for
+         * users. See b/265264294 fore more details.
          * @hide
          */
-        public static final String SFPS_REQUIRE_SCREEN_ON_TO_AUTH_ENABLED =
-                "sfps_require_screen_on_to_auth_enabled";
+        public static final String SFPS_PERFORMANT_AUTH_ENABLED = "sfps_performant_auth_enabled_v2";
 
         /**
          * Whether or not debugging is enabled.
diff --git a/core/java/android/service/appprediction/AppPredictionService.java b/core/java/android/service/appprediction/AppPredictionService.java
index 4f37cd9..a2ffa5d 100644
--- a/core/java/android/service/appprediction/AppPredictionService.java
+++ b/core/java/android/service/appprediction/AppPredictionService.java
@@ -328,7 +328,7 @@
                 Slog.e(TAG, "Callback is null, likely the binder has died.");
                 return false;
             }
-            return mCallback.equals(callback);
+            return mCallback.asBinder().equals(callback.asBinder());
         }
 
         public void destroy() {
diff --git a/core/java/android/service/autofill/FillEventHistory.java b/core/java/android/service/autofill/FillEventHistory.java
index 0fb9f57..b0e847c 100644
--- a/core/java/android/service/autofill/FillEventHistory.java
+++ b/core/java/android/service/autofill/FillEventHistory.java
@@ -166,7 +166,7 @@
     }
 
     /**
-     * Description of an event that occured after the latest call to
+     * Description of an event that occurred after the latest call to
      * {@link FillCallback#onSuccess(FillResponse)}.
      */
     public static final class Event {
diff --git a/core/java/android/service/chooser/ChooserAction.java b/core/java/android/service/chooser/ChooserAction.java
new file mode 100644
index 0000000..3010049
--- /dev/null
+++ b/core/java/android/service/chooser/ChooserAction.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.chooser;
+
+import android.annotation.NonNull;
+import android.app.PendingIntent;
+import android.graphics.drawable.Icon;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import java.util.Objects;
+
+/**
+ * A ChooserAction is an app-defined action that can be provided to the Android Sharesheet to
+ * be shown to the user when {@link android.content.Intent.ACTION_CHOOSER} is invoked.
+ *
+ * @see android.content.Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS
+ * @see android.content.Intent.EXTRA_CHOOSER_PAYLOAD_RESELECTION_ACTION
+ * @hide
+ */
+public final class ChooserAction implements Parcelable {
+    private final Icon mIcon;
+    private final CharSequence mLabel;
+    private final PendingIntent mAction;
+
+    private ChooserAction(
+            Icon icon,
+            CharSequence label,
+            PendingIntent action) {
+        mIcon = icon;
+        mLabel = label;
+        mAction = action;
+    }
+
+    /**
+     * Return a user-readable label for this action.
+     */
+    @NonNull
+    public CharSequence getLabel() {
+        return mLabel;
+    }
+
+    /**
+     * Return an {@link Icon} representing this action.
+     */
+    @NonNull
+    public Icon getIcon() {
+        return mIcon;
+    }
+
+    /**
+     * Return the action intent.
+     */
+    @NonNull
+    public PendingIntent getAction() {
+        return mAction;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        mIcon.writeToParcel(dest, flags);
+        TextUtils.writeToParcel(mLabel, dest, flags);
+        mAction.writeToParcel(dest, flags);
+    }
+
+    @Override
+    public String toString() {
+        return "ChooserAction {" + "label=" + mLabel + ", intent=" + mAction + "}";
+    }
+
+    public static final Parcelable.Creator<ChooserAction> CREATOR =
+            new Creator<ChooserAction>() {
+                @Override
+                public ChooserAction createFromParcel(Parcel source) {
+                    return new ChooserAction(
+                            Icon.CREATOR.createFromParcel(source),
+                            TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source),
+                            PendingIntent.CREATOR.createFromParcel(source));
+                }
+
+                @Override
+                public ChooserAction[] newArray(int size) {
+                    return new ChooserAction[size];
+                }
+            };
+
+    /**
+     * Builder class for {@link ChooserAction} objects
+     */
+    public static final class Builder {
+        private final Icon mIcon;
+        private final CharSequence mLabel;
+        private final PendingIntent mAction;
+
+        /**
+         * Construct a new builder for {@link ChooserAction} object.
+         *
+         * @param icon an {@link Icon} representing this action, consisting of a white foreground
+         * atop a transparent background.
+         * @param label label the user-readable label for this action.
+         * @param action {@link PendingIntent} to be invoked when the action is selected.
+         */
+        public Builder(
+                @NonNull Icon icon,
+                @NonNull CharSequence label,
+                @NonNull PendingIntent action) {
+            Objects.requireNonNull(icon, "icon can not be null");
+            Objects.requireNonNull(label, "label can not be null");
+            Objects.requireNonNull(action, "pending intent can not be null");
+            mIcon = icon;
+            mLabel = label;
+            mAction = action;
+        }
+
+        /**
+         * Combine all of the options that have been set and return a new {@link ChooserAction}
+         * object.
+         * @return the built action
+         */
+        public ChooserAction build() {
+            return new ChooserAction(mIcon, mLabel, mAction);
+        }
+    }
+}
diff --git a/core/java/android/service/chooser/OWNERS b/core/java/android/service/chooser/OWNERS
index a5acba5..dcd4a7b 100644
--- a/core/java/android/service/chooser/OWNERS
+++ b/core/java/android/service/chooser/OWNERS
@@ -1,4 +1,3 @@
-asc@google.com
-mpietal@google.com
-dsandler@android.com
-dsandler@google.com
+mrcasey@google.com
+ayepin@google.com
+joshtrask@google.com
diff --git a/core/java/android/service/dreams/DreamOverlayService.java b/core/java/android/service/dreams/DreamOverlayService.java
index 6e8198b..bf5b970 100644
--- a/core/java/android/service/dreams/DreamOverlayService.java
+++ b/core/java/android/service/dreams/DreamOverlayService.java
@@ -51,6 +51,11 @@
         }
 
         @Override
+        public void endDream() {
+            onEndDream();
+        }
+
+        @Override
         public void wakeUp() {
             onWakeUp(() -> {
                 try {
@@ -83,13 +88,22 @@
 
     /**
      * This method is overridden by implementations to handle when the dream has been requested
-     * to wakeup. This allows any overlay animations to run.
+     * to wakeup. This allows any overlay animations to run. By default, the method will invoke
+     * the callback immediately.
      *
      * @param onCompleteCallback The callback to trigger to notify the dream service that the
      *                           overlay has completed waking up.
      * @hide
      */
     public void onWakeUp(@NonNull Runnable onCompleteCallback) {
+        onCompleteCallback.run();
+    }
+
+    /**
+     * This method is overridden by implementations to handle when the dream has ended. There may
+     * be earlier signals leading up to this step, such as @{@link #onWakeUp(Runnable)}.
+     */
+    public void onEndDream() {
     }
 
     /**
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index 8b9852a..d378886 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -297,14 +297,20 @@
         }
 
         public void addConsumer(Consumer<IDreamOverlay> consumer) {
-            mConsumers.add(consumer);
-            if (mOverlay != null) {
-                consumer.accept(mOverlay);
-            }
+            execute(() -> {
+                mConsumers.add(consumer);
+                if (mOverlay != null) {
+                    consumer.accept(mOverlay);
+                }
+            });
         }
 
         public void removeConsumer(Consumer<IDreamOverlay> consumer) {
-            mConsumers.remove(consumer);
+            execute(() -> mConsumers.remove(consumer));
+        }
+
+        public void clearConsumers() {
+            execute(() -> mConsumers.clear());
         }
     }
 
@@ -1383,6 +1389,17 @@
 
                     @Override
                     public void onViewDetachedFromWindow(View v) {
+                        if (mOverlayConnection != null) {
+                            mOverlayConnection.addConsumer(overlay -> {
+                                try {
+                                    overlay.endDream();
+                                } catch (RemoteException e) {
+                                    Log.e(mTag, "could not inform overlay of dream end:" + e);
+                                }
+                            });
+                            mOverlayConnection.clearConsumers();
+                        }
+
                         if (mActivity == null || !mActivity.isChangingConfigurations()) {
                             // Only stop the dream if the view is not detached by relaunching
                             // activity for configuration changes. It is important to also clear
@@ -1391,9 +1408,6 @@
                             mActivity = null;
                             finish();
                         }
-                        if (mOverlayConnection != null && mDreamStartOverlayConsumer != null) {
-                            mOverlayConnection.removeConsumer(mDreamStartOverlayConsumer);
-                        }
                     }
                 });
     }
diff --git a/core/java/android/service/dreams/IDreamOverlay.aidl b/core/java/android/service/dreams/IDreamOverlay.aidl
index 7aeceb2c..0e4bd3b 100644
--- a/core/java/android/service/dreams/IDreamOverlay.aidl
+++ b/core/java/android/service/dreams/IDreamOverlay.aidl
@@ -41,4 +41,7 @@
 
     /** Called when the dream is waking, to do any exit animations */
     void wakeUp();
+
+    /** Called when the dream has ended. */
+    void endDream();
 }
diff --git a/core/java/android/service/notification/Adjustment.java b/core/java/android/service/notification/Adjustment.java
index 4b25c88..182a497 100644
--- a/core/java/android/service/notification/Adjustment.java
+++ b/core/java/android/service/notification/Adjustment.java
@@ -52,7 +52,7 @@
     /** @hide */
     @StringDef (prefix = { "KEY_" }, value = {
             KEY_CONTEXTUAL_ACTIONS, KEY_GROUP_KEY, KEY_IMPORTANCE, KEY_PEOPLE, KEY_SNOOZE_CRITERIA,
-            KEY_TEXT_REPLIES, KEY_USER_SENTIMENT
+            KEY_TEXT_REPLIES, KEY_USER_SENTIMENT, KEY_IMPORTANCE_PROPOSAL
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface Keys {}
@@ -122,6 +122,19 @@
     public static final String KEY_IMPORTANCE = "key_importance";
 
     /**
+     * Weaker than {@link #KEY_IMPORTANCE}, this adjustment suggests an importance rather than
+     * mandates an importance change.
+     *
+     * A notification listener can interpet this suggestion to show the user a prompt to change
+     * notification importance for the notification (or type, or app) moving forward.
+     *
+     * Data type: int, one of importance values e.g.
+     * {@link android.app.NotificationManager#IMPORTANCE_MIN}.
+     * @hide
+     */
+    public static final String KEY_IMPORTANCE_PROPOSAL = "key_importance_proposal";
+
+    /**
      * Data type: float, a ranking score from 0 (lowest) to 1 (highest).
      * Used to rank notifications inside that fall under the same classification (i.e. alerting,
      * silenced).
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index ad2e9d5..dc4cb9f 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -1711,6 +1711,8 @@
         private ShortcutInfo mShortcutInfo;
         private @RankingAdjustment int mRankingAdjustment;
         private boolean mIsBubble;
+        // Notification assistant importance suggestion
+        private int mProposedImportance;
 
         private static final int PARCEL_VERSION = 2;
 
@@ -1748,6 +1750,7 @@
             out.writeParcelable(mShortcutInfo, flags);
             out.writeInt(mRankingAdjustment);
             out.writeBoolean(mIsBubble);
+            out.writeInt(mProposedImportance);
         }
 
         /** @hide */
@@ -1786,6 +1789,7 @@
             mShortcutInfo = in.readParcelable(cl, android.content.pm.ShortcutInfo.class);
             mRankingAdjustment = in.readInt();
             mIsBubble = in.readBoolean();
+            mProposedImportance = in.readInt();
         }
 
 
@@ -1878,6 +1882,22 @@
         }
 
         /**
+         * Returns the proposed importance provided by the {@link NotificationAssistantService}.
+         *
+         * This can be used to suggest that the user change the importance of this type of
+         * notification moving forward. A value of
+         * {@link NotificationManager#IMPORTANCE_UNSPECIFIED} means that the NAS has not recommended
+         * a change to the importance, and no UI should be shown to the user. See
+         * {@link Adjustment#KEY_IMPORTANCE_PROPOSAL}.
+         *
+         * @return the importance of the notification
+         * @hide
+         */
+        public @NotificationManager.Importance int getProposedImportance() {
+            return mProposedImportance;
+        }
+
+        /**
          * If the system has overridden the group key, then this will be non-null, and this
          * key should be used to bundle notifications.
          */
@@ -2041,7 +2061,7 @@
                 boolean noisy, ArrayList<Notification.Action> smartActions,
                 ArrayList<CharSequence> smartReplies, boolean canBubble,
                 boolean isTextChanged, boolean isConversation, ShortcutInfo shortcutInfo,
-                int rankingAdjustment, boolean isBubble) {
+                int rankingAdjustment, boolean isBubble, int proposedImportance) {
             mKey = key;
             mRank = rank;
             mIsAmbient = importance < NotificationManager.IMPORTANCE_LOW;
@@ -2067,6 +2087,7 @@
             mShortcutInfo = shortcutInfo;
             mRankingAdjustment = rankingAdjustment;
             mIsBubble = isBubble;
+            mProposedImportance = proposedImportance;
         }
 
         /**
@@ -2107,7 +2128,8 @@
                     other.mIsConversation,
                     other.mShortcutInfo,
                     other.mRankingAdjustment,
-                    other.mIsBubble);
+                    other.mIsBubble,
+                    other.mProposedImportance);
         }
 
         /**
@@ -2166,7 +2188,8 @@
                     &&  Objects.equals((mShortcutInfo == null ? 0 : mShortcutInfo.getId()),
                     (other.mShortcutInfo == null ? 0 : other.mShortcutInfo.getId()))
                     && Objects.equals(mRankingAdjustment, other.mRankingAdjustment)
-                    && Objects.equals(mIsBubble, other.mIsBubble);
+                    && Objects.equals(mIsBubble, other.mIsBubble)
+                    && Objects.equals(mProposedImportance, other.mProposedImportance);
         }
     }
 
diff --git a/core/java/android/service/resumeonreboot/OWNERS b/core/java/android/service/resumeonreboot/OWNERS
index 721fbaf..8ffb76a 100644
--- a/core/java/android/service/resumeonreboot/OWNERS
+++ b/core/java/android/service/resumeonreboot/OWNERS
@@ -1 +1,2 @@
+aveena@google.com
 ejyzhang@google.com
\ No newline at end of file
diff --git a/core/java/android/service/smartspace/SmartspaceService.java b/core/java/android/service/smartspace/SmartspaceService.java
index 3a148df..b13a069 100644
--- a/core/java/android/service/smartspace/SmartspaceService.java
+++ b/core/java/android/service/smartspace/SmartspaceService.java
@@ -302,7 +302,7 @@
                 Slog.e(TAG, "Callback is null, likely the binder has died.");
                 return false;
             }
-            return mCallback.equals(callback);
+            return mCallback.asBinder().equals(callback.asBinder());
         }
 
         @Override
diff --git a/core/java/android/text/TextShaper.java b/core/java/android/text/TextShaper.java
index a1d6cc8..6da0b63 100644
--- a/core/java/android/text/TextShaper.java
+++ b/core/java/android/text/TextShaper.java
@@ -173,7 +173,7 @@
     private TextShaper() {}
 
     /**
-     * An consumer interface for accepting text shape result.
+     * A consumer interface for accepting text shape result.
      */
     public interface GlyphsConsumer {
         /**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 6f4a63c..43bbcfb 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -73,6 +73,7 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_OPTIMIZE_MEASURE;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
@@ -1274,7 +1275,7 @@
                     mTmpFrames.attachedFrame = attachedFrame;
                     mTmpFrames.compatScale = compatScale[0];
                     mInvCompatScale = 1f / compatScale[0];
-                } catch (RemoteException e) {
+                } catch (RemoteException | RuntimeException e) {
                     mAdded = false;
                     mView = null;
                     mAttachInfo.mRootView = null;
@@ -2766,7 +2767,7 @@
      * TODO(b/260382739): Apply this to all windows.
      */
     private static boolean shouldOptimizeMeasure(final WindowManager.LayoutParams lp) {
-        return lp.type == TYPE_NOTIFICATION_SHADE;
+        return (lp.privateFlags & PRIVATE_FLAG_OPTIMIZE_MEASURE) != 0;
     }
 
     private Rect getWindowBoundsInsetSystemBars() {
@@ -5045,7 +5046,7 @@
     }
 
     void reportKeepClearAreasChanged() {
-        if (!mHasPendingKeepClearAreaChange) {
+        if (!mHasPendingKeepClearAreaChange || mView == null) {
             return;
         }
         mHasPendingKeepClearAreaChange = false;
@@ -8747,6 +8748,10 @@
             mAdded = false;
             AnimationHandler.removeRequestor(this);
         }
+        if (mSyncBufferCallback != null) {
+            mSyncBufferCallback.onBufferReady(null);
+            mSyncBufferCallback = null;
+        }
         WindowManagerGlobal.getInstance().doRemoveView(this);
     }
 
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 2f77901..a37c244 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -814,6 +814,182 @@
     }
 
     /**
+     * Activity level {@link android.content.pm.PackageManager.Property PackageManager
+     * .Property} for an app to inform the system that the activity can be opted-in or opted-out
+     * from the compatibility treatment that avoids {@link
+     * android.app.Activity#setRequestedOrientation} loops. The loop can be trigerred by
+     * ignoreRequestedOrientation display setting enabled on the device or by the landscape natural
+     * orientation of the device.
+     *
+     * <p>The treatment is disabled by default but device manufacturers can enable the treatment
+     * using their discretion to improve display compatibility.
+     *
+     * <p>With this property set to {@code true}, the system could ignore {@link
+     * android.app.Activity#setRequestedOrientation} call from an app if one of the following
+     * conditions are true:
+     * <ul>
+     *     <li>Activity is relaunching due to the previous {@link
+     *     android.app.Activity#setRequestedOrientation} call.
+     *     <li>Camera compatibility force rotation treatment is active for the package.
+     * </ul>
+     *
+     * <p>Setting this property to {@code false} informs the system that the activity must be
+     * opted-out from the compatibility treatment even if the device manufacturer has opted the app
+     * into the treatment.
+     *
+     * <p><b>Syntax:</b>
+     * <pre>
+     * &lt;activity&gt;
+     *   &lt;property
+     *     android:name="android.window.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION"
+     *     android:value="true|false"/&gt;
+     * &lt;/activity&gt;
+     * </pre>
+     *
+     * @hide
+     */
+    // TODO(b/263984287): Make this public API.
+    String PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION =
+            "android.window.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION";
+
+    /**
+     * Activity level {@link android.content.pm.PackageManager.Property PackageManager
+     * .Property} for an app to inform the system that the activity should be excluded from the
+     * camera compatibility force rotation treatment.
+     *
+     * <p>The camera compatibility treatment aligns orientations of portrait app window and natural
+     * orientation of the device and set opposite to natural orientation for a landscape app
+     * window. Mismatch between them can lead to camera issues like sideways or stretched
+     * viewfinder since this is one of the strongest assumptions that apps make when they implement
+     * camera previews. Since app and natural display orientations aren't guaranteed to match, the
+     * rotation can cause letterboxing. The forced rotation is triggered as soon as app opens to
+     * camera and is removed once camera is closed.
+     *
+     * <p>The camera compatibility can be enabled by device manufacturers on the displays that have
+     * ignoreOrientationRequest display setting enabled (enables compatibility mode for fixed
+     * orientation, see <a href="https://developer.android.com/guide/practices/enhanced-letterboxing">Enhanced letterboxing</a>
+     * for more details).
+     *
+     * <p>With this property set to {@code true} or unset, the system may apply the force rotation
+     * treatment to fixed orientation activities. Device manufacturers can exclude packages from the
+     * treatment using their discretion to improve display compatibility.
+     *
+     * <p>With this property set to {@code false}, the system will not apply the force rotation
+     * treatment.
+     *
+     * <p><b>Syntax:</b>
+     * <pre>
+     * &lt;activity&gt;
+     *   &lt;property
+     *     android:name="android.window.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION"
+     *     android:value="true|false"/&gt;
+     * &lt;/activity&gt;
+     * </pre>
+     *
+     * @hide
+     */
+    // TODO(b/263984287): Make this public API.
+    String PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION =
+            "android.window.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION";
+
+    /**
+     * Activity level {@link android.content.pm.PackageManager.Property PackageManager
+     * .Property} for an app to inform the system that the activity should be excluded
+     * from the activity "refresh" after the camera compatibility force rotation treatment.
+     *
+     * <p>The camera compatibility treatment aligns orientations of portrait app window and natural
+     * orientation of the device and set opposite to natural orientation for a landscape app
+     * window. Mismatch between them can lead to camera issues like sideways or stretched
+     * viewfinder since this is one of the strongest assumptions that apps make when they implement
+     * camera previews. Since app and natural display orientations aren't guaranteed to match, the
+     * rotation can cause letterboxing. The forced rotation is triggered as soon as app opens to
+     * camera and is removed once camera is closed.
+     *
+     * <p>Force rotation is followed by the "Refresh" of the activity by going through "resumed ->
+     * ... -> stopped -> ... -> resumed" cycle (by default) or "resumed -> paused -> resumed" cycle
+     * (if overridden, see {@link #PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE} for context).
+     * This allows to clear cached values in apps (e.g. display or camera rotation) that influence
+     * camera preview and can lead to sideways or stretching issues persisting even after force
+     * rotation.
+     *
+     * <p>The camera compatibility can be enabled by device manufacturers on the displays that have
+     * ignoreOrientationRequest display setting enabled (enables compatibility mode for fixed
+     * orientation, see <a href="https://developer.android.com/guide/practices/enhanced-letterboxing">Enhanced letterboxing</a>
+     * for more details).
+     *
+     * <p>With this property set to {@code true} or unset, the system may "refresh" activity after
+     * the force rotation treatment. Device manufacturers can exclude packages from the "refresh"
+     * using their discretion to improve display compatibility.
+     *
+     * <p>With this property set to {@code false}, the system will not "refresh" activity after the
+     * force rotation treatment.
+     *
+     * <p><b>Syntax:</b>
+     * <pre>
+     * &lt;activity&gt;
+     *   &lt;property
+     *     android:name="android.window.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH"
+     *     android:value="true|false"/&gt;
+     * &lt;/activity&gt;
+     * </pre>
+     *
+     * @hide
+     */
+    // TODO(b/263984287): Make this public API.
+    String PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH =
+            "android.window.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH";
+
+    /**
+     * Activity level {@link android.content.pm.PackageManager.Property PackageManager
+     * .Property} for an app to inform the system that the activity should be or shouldn't be
+     * "refreshed" after the camera compatibility force rotation treatment using "paused ->
+     * resumed" cycle rather than "stopped -> resumed".
+     *
+     * <p>The camera compatibility treatment aligns orientations of portrait app window and natural
+     * orientation of the device and set opposite to natural orientation for a landscape app
+     * window. Mismatch between them can lead to camera issues like sideways or stretched
+     * viewfinder since this is one of the strongest assumptions that apps make when they implement
+     * camera previews. Since app and natural display orientations aren't guaranteed to match, the
+     * rotation can cause letterboxing. The forced rotation is triggered as soon as app opens to
+     * camera and is removed once camera is closed.
+     *
+     * <p>Force rotation is followed by the "Refresh" of the activity by going through "resumed ->
+     * ... -> stopped -> ... -> resumed" cycle (by default) or "resumed -> paused -> resumed" cycle
+     * (if overridden by device manufacturers or using this property). This allows to clear cached
+     * values in apps (e.g., display or camera rotation) that influence camera preview and can lead
+     * to sideways or stretching issues persisting even after force rotation.
+     *
+     * <p>The camera compatibility can be enabled by device manufacturers on the displays that have
+     * ignoreOrientationRequest display setting enabled (enables compatibility mode for fixed
+     * orientation, see <a href="https://developer.android.com/guide/practices/enhanced-letterboxing">Enhanced letterboxing</a>
+     * for more details).
+     *
+     * <p>Device manufacturers can override packages to "refresh" via "resumed -> paused -> resumed"
+     * cycle using their discretion to improve display compatibility.
+     *
+     * <p>With this property set to {@code true}, the system will "refresh" activity after the
+     * force rotation treatment using "resumed -> paused -> resumed" cycle.
+     *
+     * <p>With this property set to {@code false}, the system will not "refresh" activity after the
+     * force rotation treatment using "resumed -> paused -> resumed" cycle even if the device
+     * manufacturer adds the corresponding override.
+     *
+     * <p><b>Syntax:</b>
+     * <pre>
+     * &lt;activity&gt;
+     *   &lt;property
+     *     android:name="android.window.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE"
+     *     android:value="true|false"/&gt;
+     * &lt;/activity&gt;
+     * </pre>
+     *
+     * @hide
+     */
+    // TODO(b/263984287): Make this public API.
+    String PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE =
+            "android.window.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE";
+
+    /**
      * @hide
      */
     public static final String PARCEL_KEY_SHORTCUTS_ARRAY = "shortcuts_array";
@@ -2404,6 +2580,15 @@
         public static final int PRIVATE_FLAG_SYSTEM_ERROR = 0x00000100;
 
         /**
+         * Flag to indicate that the view hierarchy of the window can only be measured when
+         * necessary. If a window size can be known by the LayoutParams, we can use the size to
+         * relayout window, and we don't have to measure the view hierarchy before laying out the
+         * views. This reduces the chances to perform measure.
+         * {@hide}
+         */
+        public static final int PRIVATE_FLAG_OPTIMIZE_MEASURE = 0x00000200;
+
+        /**
          * Flag that prevents the wallpaper behind the current window from receiving touch events.
          *
          * {@hide}
@@ -2605,6 +2790,7 @@
                 PRIVATE_FLAG_NO_MOVE_ANIMATION,
                 PRIVATE_FLAG_COMPATIBLE_WINDOW,
                 PRIVATE_FLAG_SYSTEM_ERROR,
+                PRIVATE_FLAG_OPTIMIZE_MEASURE,
                 PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS,
                 PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR,
                 PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT,
@@ -2665,6 +2851,10 @@
                         equals = PRIVATE_FLAG_SYSTEM_ERROR,
                         name = "SYSTEM_ERROR"),
                 @ViewDebug.FlagToString(
+                        mask = PRIVATE_FLAG_OPTIMIZE_MEASURE,
+                        equals = PRIVATE_FLAG_OPTIMIZE_MEASURE,
+                        name = "OPTIMIZE_MEASURE"),
+                @ViewDebug.FlagToString(
                         mask = PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS,
                         equals = PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS,
                         name = "DISABLE_WALLPAPER_TOUCH_EVENTS"),
diff --git a/core/java/android/view/WindowManagerPolicyConstants.java b/core/java/android/view/WindowManagerPolicyConstants.java
index 43d427d..4c49f2c 100644
--- a/core/java/android/view/WindowManagerPolicyConstants.java
+++ b/core/java/android/view/WindowManagerPolicyConstants.java
@@ -169,6 +169,9 @@
             case PowerManager.WAKE_REASON_POWER_BUTTON:
             case PowerManager.WAKE_REASON_PLUGGED_IN:
             case PowerManager.WAKE_REASON_GESTURE:
+            case PowerManager.WAKE_REASON_TAP:
+            case PowerManager.WAKE_REASON_LIFT:
+            case PowerManager.WAKE_REASON_BIOMETRIC:
             case PowerManager.WAKE_REASON_CAMERA_LAUNCH:
             case PowerManager.WAKE_REASON_WAKE_KEY:
             case PowerManager.WAKE_REASON_WAKE_MOTION:
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index d067d4b..497f066 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -66,8 +66,7 @@
 import java.util.function.Consumer;
 
 /**
- * <p>The {@link ContentCaptureManager} provides additional ways for for apps to
- * integrate with the content capture subsystem.
+ * <p>Provides additional ways for apps to integrate with the content capture subsystem.
  *
  * <p>Content capture provides real-time, continuous capture of application activity, display and
  * events to an intelligence service that is provided by the Android system. The intelligence
diff --git a/core/java/android/webkit/WebResourceError.java b/core/java/android/webkit/WebResourceError.java
index 11f1b6f1..4c87489 100644
--- a/core/java/android/webkit/WebResourceError.java
+++ b/core/java/android/webkit/WebResourceError.java
@@ -19,7 +19,7 @@
 import android.annotation.SystemApi;
 
 /**
- * Encapsulates information about errors occured during loading of web resources. See
+ * Encapsulates information about errors that occurred during loading of web resources. See
  * {@link WebViewClient#onReceivedError(WebView, WebResourceRequest, WebResourceError) WebViewClient.onReceivedError(WebView, WebResourceRequest, WebResourceError)}
  */
 public abstract class WebResourceError {
diff --git a/core/java/android/window/BackEvent.java b/core/java/android/window/BackEvent.java
index 1024e2e..4a4f561 100644
--- a/core/java/android/window/BackEvent.java
+++ b/core/java/android/window/BackEvent.java
@@ -18,10 +18,8 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.view.RemoteAnimationTarget;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -52,8 +50,6 @@
 
     @SwipeEdge
     private final int mSwipeEdge;
-    @Nullable
-    private final RemoteAnimationTarget mDepartingAnimationTarget;
 
     /**
      * Creates a new {@link BackEvent} instance.
@@ -62,16 +58,12 @@
      * @param touchY Absolute Y location of the touch point of this event.
      * @param progress Value between 0 and 1 on how far along the back gesture is.
      * @param swipeEdge Indicates which edge the swipe starts from.
-     * @param departingAnimationTarget The remote animation target of the departing application
-     *                                 window.
      */
-    public BackEvent(float touchX, float touchY, float progress, @SwipeEdge int swipeEdge,
-            @Nullable RemoteAnimationTarget departingAnimationTarget) {
+    public BackEvent(float touchX, float touchY, float progress, @SwipeEdge int swipeEdge) {
         mTouchX = touchX;
         mTouchY = touchY;
         mProgress = progress;
         mSwipeEdge = swipeEdge;
-        mDepartingAnimationTarget = departingAnimationTarget;
     }
 
     private BackEvent(@NonNull Parcel in) {
@@ -79,7 +71,6 @@
         mTouchY = in.readFloat();
         mProgress = in.readFloat();
         mSwipeEdge = in.readInt();
-        mDepartingAnimationTarget = in.readTypedObject(RemoteAnimationTarget.CREATOR);
     }
 
     public static final Creator<BackEvent> CREATOR = new Creator<BackEvent>() {
@@ -105,7 +96,6 @@
         dest.writeFloat(mTouchY);
         dest.writeFloat(mProgress);
         dest.writeInt(mSwipeEdge);
-        dest.writeTypedObject(mDepartingAnimationTarget, flags);
     }
 
     /**
@@ -136,16 +126,6 @@
         return mSwipeEdge;
     }
 
-    /**
-     * Returns the {@link RemoteAnimationTarget} of the top departing application window,
-     * or {@code null} if the top window should not be moved for the current type of back
-     * destination.
-     */
-    @Nullable
-    public RemoteAnimationTarget getDepartingAnimationTarget() {
-        return mDepartingAnimationTarget;
-    }
-
     @Override
     public String toString() {
         return "BackEvent{"
@@ -153,7 +133,6 @@
                 + ", mTouchY=" + mTouchY
                 + ", mProgress=" + mProgress
                 + ", mSwipeEdge" + mSwipeEdge
-                + ", mDepartingAnimationTarget" + mDepartingAnimationTarget
                 + "}";
     }
 }
diff --git a/core/java/android/window/BackMotionEvent.aidl b/core/java/android/window/BackMotionEvent.aidl
new file mode 100644
index 0000000..7c675c3
--- /dev/null
+++ b/core/java/android/window/BackMotionEvent.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.window;
+
+/**
+ * @hide
+ */
+parcelable BackMotionEvent;
diff --git a/core/java/android/window/BackMotionEvent.java b/core/java/android/window/BackMotionEvent.java
new file mode 100644
index 0000000..8012a1c
--- /dev/null
+++ b/core/java/android/window/BackMotionEvent.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.window;
+
+import android.annotation.FloatRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.view.RemoteAnimationTarget;
+
+/**
+ * Object used to report back gesture progress. Holds information about a {@link BackEvent} plus
+ * any {@link RemoteAnimationTarget} the gesture manipulates.
+ *
+ * @see BackEvent
+ * @hide
+ */
+public final class BackMotionEvent implements Parcelable {
+    private final float mTouchX;
+    private final float mTouchY;
+    private final float mProgress;
+
+    @BackEvent.SwipeEdge
+    private final int mSwipeEdge;
+    @Nullable
+    private final RemoteAnimationTarget mDepartingAnimationTarget;
+
+    /**
+     * Creates a new {@link BackMotionEvent} instance.
+     *
+     * @param touchX Absolute X location of the touch point of this event.
+     * @param touchY Absolute Y location of the touch point of this event.
+     * @param progress Value between 0 and 1 on how far along the back gesture is.
+     * @param swipeEdge Indicates which edge the swipe starts from.
+     * @param departingAnimationTarget The remote animation target of the departing
+     *                                 application window.
+     */
+    public BackMotionEvent(float touchX, float touchY, float progress,
+            @BackEvent.SwipeEdge int swipeEdge,
+            @Nullable RemoteAnimationTarget departingAnimationTarget) {
+        mTouchX = touchX;
+        mTouchY = touchY;
+        mProgress = progress;
+        mSwipeEdge = swipeEdge;
+        mDepartingAnimationTarget = departingAnimationTarget;
+    }
+
+    private BackMotionEvent(@NonNull Parcel in) {
+        mTouchX = in.readFloat();
+        mTouchY = in.readFloat();
+        mProgress = in.readFloat();
+        mSwipeEdge = in.readInt();
+        mDepartingAnimationTarget = in.readTypedObject(RemoteAnimationTarget.CREATOR);
+    }
+
+    @NonNull
+    public static final Creator<BackMotionEvent> CREATOR = new Creator<BackMotionEvent>() {
+        @Override
+        public BackMotionEvent createFromParcel(Parcel in) {
+            return new BackMotionEvent(in);
+        }
+
+        @Override
+        public BackMotionEvent[] newArray(int size) {
+            return new BackMotionEvent[size];
+        }
+    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeFloat(mTouchX);
+        dest.writeFloat(mTouchY);
+        dest.writeFloat(mProgress);
+        dest.writeInt(mSwipeEdge);
+        dest.writeTypedObject(mDepartingAnimationTarget, flags);
+    }
+
+    /**
+     * Returns the progress of a {@link BackEvent}.
+     *
+     * @see BackEvent#getProgress()
+     */
+    @FloatRange(from = 0, to = 1)
+    public float getProgress() {
+        return mProgress;
+    }
+
+    /**
+     * Returns the absolute X location of the touch point.
+     */
+    public float getTouchX() {
+        return mTouchX;
+    }
+
+    /**
+     * Returns the absolute Y location of the touch point.
+     */
+    public float getTouchY() {
+        return mTouchY;
+    }
+
+    /**
+     * Returns the screen edge that the swipe starts from.
+     */
+    @BackEvent.SwipeEdge
+    public int getSwipeEdge() {
+        return mSwipeEdge;
+    }
+
+    /**
+     * Returns the {@link RemoteAnimationTarget} of the top departing application window,
+     * or {@code null} if the top window should not be moved for the current type of back
+     * destination.
+     */
+    @Nullable
+    public RemoteAnimationTarget getDepartingAnimationTarget() {
+        return mDepartingAnimationTarget;
+    }
+
+    @Override
+    public String toString() {
+        return "BackMotionEvent{"
+                + "mTouchX=" + mTouchX
+                + ", mTouchY=" + mTouchY
+                + ", mProgress=" + mProgress
+                + ", mSwipeEdge" + mSwipeEdge
+                + ", mDepartingAnimationTarget" + mDepartingAnimationTarget
+                + "}";
+    }
+}
diff --git a/core/java/android/window/BackProgressAnimator.java b/core/java/android/window/BackProgressAnimator.java
index dd4385c..38c52e7 100644
--- a/core/java/android/window/BackProgressAnimator.java
+++ b/core/java/android/window/BackProgressAnimator.java
@@ -40,7 +40,7 @@
     private final SpringAnimation mSpring;
     private ProgressCallback mCallback;
     private float mProgress = 0;
-    private BackEvent mLastBackEvent;
+    private BackMotionEvent mLastBackEvent;
     private boolean mStarted = false;
 
     private void setProgress(float progress) {
@@ -82,9 +82,9 @@
     /**
      * Sets a new target position for the back progress.
      *
-     * @param event the {@link BackEvent} containing the latest target progress.
+     * @param event the {@link BackMotionEvent} containing the latest target progress.
      */
-    public void onBackProgressed(BackEvent event) {
+    public void onBackProgressed(BackMotionEvent event) {
         if (!mStarted) {
             return;
         }
@@ -95,11 +95,11 @@
     /**
      * Starts the back progress animation.
      *
-     * @param event the {@link BackEvent} that started the gesture.
+     * @param event the {@link BackMotionEvent} that started the gesture.
      * @param callback the back callback to invoke for the gesture. It will receive back progress
      *                 dispatches as the progress animation updates.
      */
-    public void onBackStarted(BackEvent event, ProgressCallback callback) {
+    public void onBackStarted(BackMotionEvent event, ProgressCallback callback) {
         reset();
         mLastBackEvent = event;
         mCallback = callback;
@@ -129,8 +129,7 @@
         }
         mCallback.onProgressUpdate(
                 new BackEvent(mLastBackEvent.getTouchX(), mLastBackEvent.getTouchY(),
-                        progress / SCALE_FACTOR, mLastBackEvent.getSwipeEdge(),
-                        mLastBackEvent.getDepartingAnimationTarget()));
+                        progress / SCALE_FACTOR, mLastBackEvent.getSwipeEdge()));
     }
 
 }
diff --git a/core/java/android/window/IOnBackInvokedCallback.aidl b/core/java/android/window/IOnBackInvokedCallback.aidl
index 6af8ddd..159c0e8 100644
--- a/core/java/android/window/IOnBackInvokedCallback.aidl
+++ b/core/java/android/window/IOnBackInvokedCallback.aidl
@@ -17,7 +17,7 @@
 
 package android.window;
 
-import android.window.BackEvent;
+import android.window.BackMotionEvent;
 
 /**
  * Interface that wraps a {@link OnBackInvokedCallback} object, to be stored in window manager
@@ -30,18 +30,19 @@
     * Called when a back gesture has been started, or back button has been pressed down.
     * Wraps {@link OnBackInvokedCallback#onBackStarted(BackEvent)}.
     *
-    * @param backEvent The {@link BackEvent} containing information about the touch or button press.
+    * @param backMotionEvent The {@link BackMotionEvent} containing information about the touch
+    *        or button press.
     */
-    void onBackStarted(in BackEvent backEvent);
+    void onBackStarted(in BackMotionEvent backMotionEvent);
 
     /**
      * Called on back gesture progress.
      * Wraps {@link OnBackInvokedCallback#onBackProgressed(BackEvent)}.
      *
-     * @param backEvent The {@link BackEvent} containing information about the latest touch point
-     *                  and the progress that the back animation should seek to.
+     * @param backMotionEvent The {@link BackMotionEvent} containing information about the latest
+     *                        touch point and the progress that the back animation should seek to.
      */
-    void onBackProgressed(in BackEvent backEvent);
+    void onBackProgressed(in BackMotionEvent backMotionEvent);
 
     /**
      * Called when a back gesture or back button press has been cancelled.
diff --git a/core/java/android/window/ITaskOrganizerController.aidl b/core/java/android/window/ITaskOrganizerController.aidl
index e6bb1f6..0032b9c 100644
--- a/core/java/android/window/ITaskOrganizerController.aidl
+++ b/core/java/android/window/ITaskOrganizerController.aidl
@@ -40,7 +40,8 @@
     void unregisterTaskOrganizer(ITaskOrganizer organizer);
 
     /** Creates a persistent root task in WM for a particular windowing-mode. */
-    void createRootTask(int displayId, int windowingMode, IBinder launchCookie);
+    void createRootTask(int displayId, int windowingMode, IBinder launchCookie,
+            boolean removeWithTaskOrganizer);
 
     /** Deletes a persistent root task in WM */
     boolean deleteRootTask(in WindowContainerToken task);
diff --git a/core/java/android/window/ImeOnBackInvokedDispatcher.java b/core/java/android/window/ImeOnBackInvokedDispatcher.java
index 9152e78..a0bd7f7 100644
--- a/core/java/android/window/ImeOnBackInvokedDispatcher.java
+++ b/core/java/android/window/ImeOnBackInvokedDispatcher.java
@@ -220,16 +220,14 @@
      * @param previous the previously focused {@link ViewRootImpl}.
      * @param current the currently focused {@link ViewRootImpl}.
      */
-    // TODO(b/232845902): Add CTS to test IME back behavior when there's root view change while
-    // IME is up.
     public void switchRootView(ViewRootImpl previous, ViewRootImpl current) {
         for (ImeOnBackInvokedCallback imeCallback : mImeCallbacks) {
             if (previous != null) {
                 previous.getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(imeCallback);
             }
             if (current != null) {
-                current.getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
-                        imeCallback.mPriority, imeCallback);
+                current.getOnBackInvokedDispatcher().registerOnBackInvokedCallbackUnchecked(
+                        imeCallback, imeCallback.mPriority);
             }
         }
     }
diff --git a/core/java/android/window/TaskFragmentAnimationParams.aidl b/core/java/android/window/TaskFragmentAnimationParams.aidl
new file mode 100644
index 0000000..8ae84c2
--- /dev/null
+++ b/core/java/android/window/TaskFragmentAnimationParams.aidl
@@ -0,0 +1,23 @@
+/*
+ * 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.window;
+
+/**
+ * Data object for animation related override of TaskFragment.
+ * @hide
+ */
+parcelable TaskFragmentAnimationParams;
diff --git a/core/java/android/window/TaskFragmentAnimationParams.java b/core/java/android/window/TaskFragmentAnimationParams.java
new file mode 100644
index 0000000..12ad914
--- /dev/null
+++ b/core/java/android/window/TaskFragmentAnimationParams.java
@@ -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 android.window;
+
+import android.annotation.ColorInt;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Data object for animation related override of TaskFragment.
+ * @hide
+ */
+// TODO(b/206557124): Add more animation customization options.
+public final class TaskFragmentAnimationParams implements Parcelable {
+
+    /** The default {@link TaskFragmentAnimationParams} to use when there is no app override. */
+    public static final TaskFragmentAnimationParams DEFAULT =
+            new TaskFragmentAnimationParams.Builder().build();
+
+    @ColorInt
+    private final int mAnimationBackgroundColor;
+
+    private TaskFragmentAnimationParams(@ColorInt int animationBackgroundColor) {
+        mAnimationBackgroundColor = animationBackgroundColor;
+    }
+
+    /**
+     * The {@link ColorInt} to use for the background during the animation with this TaskFragment if
+     * the animation requires a background.
+     *
+     * The default value is {@code 0}, which is to use the theme window background.
+     */
+    @ColorInt
+    public int getAnimationBackgroundColor() {
+        return mAnimationBackgroundColor;
+    }
+
+    private TaskFragmentAnimationParams(Parcel in) {
+        mAnimationBackgroundColor = in.readInt();
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mAnimationBackgroundColor);
+    }
+
+    @NonNull
+    public static final Creator<TaskFragmentAnimationParams> CREATOR =
+            new Creator<TaskFragmentAnimationParams>() {
+                @Override
+                public TaskFragmentAnimationParams createFromParcel(Parcel in) {
+                    return new TaskFragmentAnimationParams(in);
+                }
+
+                @Override
+                public TaskFragmentAnimationParams[] newArray(int size) {
+                    return new TaskFragmentAnimationParams[size];
+                }
+            };
+
+    @Override
+    public String toString() {
+        return "TaskFragmentAnimationParams{"
+                + " animationBgColor=" + Integer.toHexString(mAnimationBackgroundColor)
+                + "}";
+    }
+
+    @Override
+    public int hashCode() {
+        return mAnimationBackgroundColor;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (!(obj instanceof TaskFragmentAnimationParams)) {
+            return false;
+        }
+        final TaskFragmentAnimationParams other = (TaskFragmentAnimationParams) obj;
+        return mAnimationBackgroundColor == other.mAnimationBackgroundColor;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /** Builder to construct the {@link TaskFragmentAnimationParams}. */
+    public static final class Builder {
+
+        @ColorInt
+        private int mAnimationBackgroundColor = 0;
+
+        /**
+         * Sets the {@link ColorInt} to use for the background during the animation with this
+         * TaskFragment if the animation requires a background. The default value is
+         * {@code 0}, which is to use the theme window background.
+         *
+         * @param color a packed color int, {@code AARRGGBB}, for the animation background color.
+         * @return this {@link Builder}.
+         */
+        @NonNull
+        public Builder setAnimationBackgroundColor(@ColorInt int color) {
+            mAnimationBackgroundColor = color;
+            return this;
+        }
+
+        /** Constructs the {@link TaskFragmentAnimationParams}. */
+        @NonNull
+        public TaskFragmentAnimationParams build() {
+            return new TaskFragmentAnimationParams(mAnimationBackgroundColor);
+        }
+    }
+}
diff --git a/core/java/android/window/TaskFragmentCreationParams.java b/core/java/android/window/TaskFragmentCreationParams.java
index c9ddf92..203d79a 100644
--- a/core/java/android/window/TaskFragmentCreationParams.java
+++ b/core/java/android/window/TaskFragmentCreationParams.java
@@ -71,20 +71,42 @@
      *
      * This is needed in case we need to launch a placeholder Activity to split below a transparent
      * always-expand Activity.
+     *
+     * This should not be used with {@link #mPairedActivityToken}.
      */
     @Nullable
     private final IBinder mPairedPrimaryFragmentToken;
 
+    /**
+     * The Activity token to place the new TaskFragment on top of.
+     * When it is set, the new TaskFragment will be positioned right above the target Activity.
+     * Otherwise, the new TaskFragment will be positioned on the top of the Task by default.
+     *
+     * This is needed in case we need to place an Activity into TaskFragment to launch placeholder
+     * below a transparent always-expand Activity, or when there is another Intent being started in
+     * a TaskFragment above.
+     *
+     * This should not be used with {@link #mPairedPrimaryFragmentToken}.
+     */
+    @Nullable
+    private final IBinder mPairedActivityToken;
+
     private TaskFragmentCreationParams(
             @NonNull TaskFragmentOrganizerToken organizer, @NonNull IBinder fragmentToken,
             @NonNull IBinder ownerToken, @NonNull Rect initialBounds,
-            @WindowingMode int windowingMode, @Nullable IBinder pairedPrimaryFragmentToken) {
+            @WindowingMode int windowingMode, @Nullable IBinder pairedPrimaryFragmentToken,
+            @Nullable IBinder pairedActivityToken) {
+        if (pairedPrimaryFragmentToken != null && pairedActivityToken != null) {
+            throw new IllegalArgumentException("pairedPrimaryFragmentToken and"
+                    + " pairedActivityToken should not be set at the same time.");
+        }
         mOrganizer = organizer;
         mFragmentToken = fragmentToken;
         mOwnerToken = ownerToken;
         mInitialBounds.set(initialBounds);
         mWindowingMode = windowingMode;
         mPairedPrimaryFragmentToken = pairedPrimaryFragmentToken;
+        mPairedActivityToken = pairedActivityToken;
     }
 
     @NonNull
@@ -121,6 +143,15 @@
         return mPairedPrimaryFragmentToken;
     }
 
+    /**
+     * TODO(b/232476698): remove the hide with adding CTS for this in next release.
+     * @hide
+     */
+    @Nullable
+    public IBinder getPairedActivityToken() {
+        return mPairedActivityToken;
+    }
+
     private TaskFragmentCreationParams(Parcel in) {
         mOrganizer = TaskFragmentOrganizerToken.CREATOR.createFromParcel(in);
         mFragmentToken = in.readStrongBinder();
@@ -128,6 +159,7 @@
         mInitialBounds.readFromParcel(in);
         mWindowingMode = in.readInt();
         mPairedPrimaryFragmentToken = in.readStrongBinder();
+        mPairedActivityToken = in.readStrongBinder();
     }
 
     /** @hide */
@@ -139,6 +171,7 @@
         mInitialBounds.writeToParcel(dest, flags);
         dest.writeInt(mWindowingMode);
         dest.writeStrongBinder(mPairedPrimaryFragmentToken);
+        dest.writeStrongBinder(mPairedActivityToken);
     }
 
     @NonNull
@@ -164,6 +197,7 @@
                 + " initialBounds=" + mInitialBounds
                 + " windowingMode=" + mWindowingMode
                 + " pairedFragmentToken=" + mPairedPrimaryFragmentToken
+                + " pairedActivityToken=" + mPairedActivityToken
                 + "}";
     }
 
@@ -194,6 +228,9 @@
         @Nullable
         private IBinder mPairedPrimaryFragmentToken;
 
+        @Nullable
+        private IBinder mPairedActivityToken;
+
         public Builder(@NonNull TaskFragmentOrganizerToken organizer,
                 @NonNull IBinder fragmentToken, @NonNull IBinder ownerToken) {
             mOrganizer = organizer;
@@ -224,6 +261,8 @@
          * This is needed in case we need to launch a placeholder Activity to split below a
          * transparent always-expand Activity.
          *
+         * This should not be used with {@link #setPairedActivityToken}.
+         *
          * TODO(b/232476698): remove the hide with adding CTS for this in next release.
          * @hide
          */
@@ -233,11 +272,32 @@
             return this;
         }
 
+        /**
+         * Sets the Activity token to place the new TaskFragment on top of.
+         * When it is set, the new TaskFragment will be positioned right above the target Activity.
+         * Otherwise, the new TaskFragment will be positioned on the top of the Task by default.
+         *
+         * This is needed in case we need to place an Activity into TaskFragment to launch
+         * placeholder below a transparent always-expand Activity, or when there is another Intent
+         * being started in a TaskFragment above.
+         *
+         * This should not be used with {@link #setPairedPrimaryFragmentToken}.
+         *
+         * TODO(b/232476698): remove the hide with adding CTS for this in next release.
+         * @hide
+         */
+        @NonNull
+        public Builder setPairedActivityToken(@Nullable IBinder activityToken) {
+            mPairedActivityToken = activityToken;
+            return this;
+        }
+
         /** Constructs the options to create TaskFragment with. */
         @NonNull
         public TaskFragmentCreationParams build() {
             return new TaskFragmentCreationParams(mOrganizer, mFragmentToken, mOwnerToken,
-                    mInitialBounds, mWindowingMode, mPairedPrimaryFragmentToken);
+                    mInitialBounds, mWindowingMode, mPairedPrimaryFragmentToken,
+                    mPairedActivityToken);
         }
     }
 }
diff --git a/core/java/android/window/TaskFragmentOperation.aidl b/core/java/android/window/TaskFragmentOperation.aidl
new file mode 100644
index 0000000..c1ed0c7
--- /dev/null
+++ b/core/java/android/window/TaskFragmentOperation.aidl
@@ -0,0 +1,23 @@
+/*
+ * 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.window;
+
+/**
+ * Data object of params for TaskFragment related {@link WindowContainerTransaction} operation.
+ * @hide
+ */
+parcelable TaskFragmentOperation;
diff --git a/core/java/android/window/TaskFragmentOperation.java b/core/java/android/window/TaskFragmentOperation.java
new file mode 100644
index 0000000..0f30b79
--- /dev/null
+++ b/core/java/android/window/TaskFragmentOperation.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 android.window;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Data object of params for TaskFragment related {@link WindowContainerTransaction} operation.
+ *
+ * @see WindowContainerTransaction#setTaskFragmentOperation(IBinder, TaskFragmentOperation).
+ * @hide
+ */
+// TODO(b/263436063): move other TaskFragment related operation here.
+public final class TaskFragmentOperation implements Parcelable {
+
+    /** Sets the {@link TaskFragmentAnimationParams} for the given TaskFragment. */
+    public static final int OP_TYPE_SET_ANIMATION_PARAMS = 0;
+
+    @IntDef(prefix = { "OP_TYPE_" }, value = {
+            OP_TYPE_SET_ANIMATION_PARAMS
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface OperationType {}
+
+    @OperationType
+    private final int mOpType;
+
+    @Nullable
+    private final TaskFragmentAnimationParams mAnimationParams;
+
+    private TaskFragmentOperation(@OperationType int opType,
+            @Nullable TaskFragmentAnimationParams animationParams) {
+        mOpType = opType;
+        mAnimationParams = animationParams;
+    }
+
+    private TaskFragmentOperation(Parcel in) {
+        mOpType = in.readInt();
+        mAnimationParams = in.readTypedObject(TaskFragmentAnimationParams.CREATOR);
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mOpType);
+        dest.writeTypedObject(mAnimationParams, flags);
+    }
+
+    @NonNull
+    public static final Creator<TaskFragmentOperation> CREATOR =
+            new Creator<TaskFragmentOperation>() {
+                @Override
+                public TaskFragmentOperation createFromParcel(Parcel in) {
+                    return new TaskFragmentOperation(in);
+                }
+
+                @Override
+                public TaskFragmentOperation[] newArray(int size) {
+                    return new TaskFragmentOperation[size];
+                }
+            };
+
+    /**
+     * Gets the {@link OperationType} of this {@link TaskFragmentOperation}.
+     */
+    @OperationType
+    public int getOpType() {
+        return mOpType;
+    }
+
+    /**
+     * Gets the animation related override of TaskFragment.
+     */
+    @Nullable
+    public TaskFragmentAnimationParams getAnimationParams() {
+        return mAnimationParams;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("TaskFragmentOperation{ opType=").append(mOpType);
+        if (mAnimationParams != null) {
+            sb.append(", animationParams=").append(mAnimationParams);
+        }
+
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public int hashCode() {
+        int result = mOpType;
+        result = result * 31 + mAnimationParams.hashCode();
+        return result;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (!(obj instanceof TaskFragmentOperation)) {
+            return false;
+        }
+        final TaskFragmentOperation other = (TaskFragmentOperation) obj;
+        return mOpType == other.mOpType
+                && Objects.equals(mAnimationParams, other.mAnimationParams);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /** Builder to construct the {@link TaskFragmentOperation}. */
+    public static final class Builder {
+
+        @OperationType
+        private final int mOpType;
+
+        @Nullable
+        private TaskFragmentAnimationParams mAnimationParams;
+
+        /**
+         * @param opType the {@link OperationType} of this {@link TaskFragmentOperation}.
+         */
+        public Builder(@OperationType int opType) {
+            mOpType = opType;
+        }
+
+        /**
+         * Sets the {@link TaskFragmentAnimationParams} for the given TaskFragment.
+         */
+        @NonNull
+        public Builder setAnimationParams(@Nullable TaskFragmentAnimationParams animationParams) {
+            mAnimationParams = animationParams;
+            return this;
+        }
+
+        /**
+         * Constructs the {@link TaskFragmentOperation}.
+         */
+        @NonNull
+        public TaskFragmentOperation build() {
+            return new TaskFragmentOperation(mOpType, mAnimationParams);
+        }
+    }
+}
diff --git a/core/java/android/window/TaskOrganizer.java b/core/java/android/window/TaskOrganizer.java
index bffd4e4..02878f8 100644
--- a/core/java/android/window/TaskOrganizer.java
+++ b/core/java/android/window/TaskOrganizer.java
@@ -152,15 +152,31 @@
      * @param windowingMode Windowing mode to put the root task in.
      * @param launchCookie Launch cookie to associate with the task so that is can be identified
      *                     when the {@link ITaskOrganizer#onTaskAppeared} callback is called.
+     * @param removeWithTaskOrganizer True if this task should be removed when organizer destroyed.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
+    public void createRootTask(int displayId, int windowingMode, @Nullable IBinder launchCookie,
+            boolean removeWithTaskOrganizer) {
+        try {
+            mTaskOrganizerController.createRootTask(displayId, windowingMode, launchCookie,
+                    removeWithTaskOrganizer);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Creates a persistent root task in WM for a particular windowing-mode.
+     * @param displayId The display to create the root task on.
+     * @param windowingMode Windowing mode to put the root task in.
+     * @param launchCookie Launch cookie to associate with the task so that is can be identified
+     *                     when the {@link ITaskOrganizer#onTaskAppeared} callback is called.
      */
     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
     @Nullable
     public void createRootTask(int displayId, int windowingMode, @Nullable IBinder launchCookie) {
-        try {
-            mTaskOrganizerController.createRootTask(displayId, windowingMode, launchCookie);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        createRootTask(displayId, windowingMode, launchCookie, false /* removeWithTaskOrganizer */);
     }
 
     /** Deletes a persistent root task in WM */
diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java
index f90353a..d7b4929 100644
--- a/core/java/android/window/WindowContainerTransaction.java
+++ b/core/java/android/window/WindowContainerTransaction.java
@@ -763,6 +763,30 @@
     }
 
     /**
+     * Sets the {@link TaskFragmentOperation} to apply to the given TaskFragment.
+     *
+     * @param fragmentToken client assigned unique token to create TaskFragment with specified in
+     *                      {@link TaskFragmentCreationParams#getFragmentToken()}.
+     * @param taskFragmentOperation the {@link TaskFragmentOperation} to apply to the given
+     *                              TaskFramgent.
+     * @hide
+     */
+    @NonNull
+    public WindowContainerTransaction setTaskFragmentOperation(@NonNull IBinder fragmentToken,
+            @NonNull TaskFragmentOperation taskFragmentOperation) {
+        Objects.requireNonNull(fragmentToken);
+        Objects.requireNonNull(taskFragmentOperation);
+        final HierarchyOp hierarchyOp =
+                new HierarchyOp.Builder(
+                        HierarchyOp.HIERARCHY_OP_TYPE_SET_TASK_FRAGMENT_OPERATION)
+                        .setContainer(fragmentToken)
+                        .setTaskFragmentOperation(taskFragmentOperation)
+                        .build();
+        mHierarchyOps.add(hierarchyOp);
+        return this;
+    }
+
+    /**
      * Sets/removes the always on top flag for this {@code windowContainer}. See
      * {@link com.android.server.wm.ConfigurationContainer#setAlwaysOnTop(boolean)}.
      * Please note that this method is only intended to be used for a
@@ -1262,6 +1286,7 @@
         public static final int HIERARCHY_OP_TYPE_FINISH_ACTIVITY = 21;
         public static final int HIERARCHY_OP_TYPE_SET_COMPANION_TASK_FRAGMENT = 22;
         public static final int HIERARCHY_OP_TYPE_SET_REPARENT_LEAF_TASK_IF_RELAUNCH = 23;
+        public static final int HIERARCHY_OP_TYPE_SET_TASK_FRAGMENT_OPERATION = 24;
 
         // The following key(s) are for use with mLaunchOptions:
         // When launching a task (eg. from recents), this is the taskId to be launched.
@@ -1302,10 +1327,14 @@
         @Nullable
         private Intent mActivityIntent;
 
-        // Used as options for WindowContainerTransaction#createTaskFragment().
+        /** Used as options for {@link #createTaskFragment}. */
         @Nullable
         private TaskFragmentCreationParams mTaskFragmentCreationOptions;
 
+        /** Used as options for {@link #setTaskFragmentOperation}. */
+        @Nullable
+        private TaskFragmentOperation mTaskFragmentOperation;
+
         @Nullable
         private PendingIntent mPendingIntent;
 
@@ -1418,6 +1447,7 @@
             mLaunchOptions = copy.mLaunchOptions;
             mActivityIntent = copy.mActivityIntent;
             mTaskFragmentCreationOptions = copy.mTaskFragmentCreationOptions;
+            mTaskFragmentOperation = copy.mTaskFragmentOperation;
             mPendingIntent = copy.mPendingIntent;
             mShortcutInfo = copy.mShortcutInfo;
             mAlwaysOnTop = copy.mAlwaysOnTop;
@@ -1441,6 +1471,7 @@
             mLaunchOptions = in.readBundle();
             mActivityIntent = in.readTypedObject(Intent.CREATOR);
             mTaskFragmentCreationOptions = in.readTypedObject(TaskFragmentCreationParams.CREATOR);
+            mTaskFragmentOperation = in.readTypedObject(TaskFragmentOperation.CREATOR);
             mPendingIntent = in.readTypedObject(PendingIntent.CREATOR);
             mShortcutInfo = in.readTypedObject(ShortcutInfo.CREATOR);
             mAlwaysOnTop = in.readBoolean();
@@ -1529,6 +1560,11 @@
         }
 
         @Nullable
+        public TaskFragmentOperation getTaskFragmentOperation() {
+            return mTaskFragmentOperation;
+        }
+
+        @Nullable
         public PendingIntent getPendingIntent() {
             return mPendingIntent;
         }
@@ -1604,6 +1640,9 @@
                 case HIERARCHY_OP_TYPE_SET_REPARENT_LEAF_TASK_IF_RELAUNCH:
                     return "{setReparentLeafTaskIfRelaunch: container= " + mContainer
                             + " reparentLeafTaskIfRelaunch= " + mReparentLeafTaskIfRelaunch + "}";
+                case HIERARCHY_OP_TYPE_SET_TASK_FRAGMENT_OPERATION:
+                    return "{setTaskFragmentOperation: fragmentToken= " + mContainer
+                            + " operation= " + mTaskFragmentOperation + "}";
                 default:
                     return "{mType=" + mType + " container=" + mContainer + " reparent=" + mReparent
                             + " mToTop=" + mToTop
@@ -1631,6 +1670,7 @@
             dest.writeBundle(mLaunchOptions);
             dest.writeTypedObject(mActivityIntent, flags);
             dest.writeTypedObject(mTaskFragmentCreationOptions, flags);
+            dest.writeTypedObject(mTaskFragmentOperation, flags);
             dest.writeTypedObject(mPendingIntent, flags);
             dest.writeTypedObject(mShortcutInfo, flags);
             dest.writeBoolean(mAlwaysOnTop);
@@ -1688,6 +1728,9 @@
             private TaskFragmentCreationParams mTaskFragmentCreationOptions;
 
             @Nullable
+            private TaskFragmentOperation mTaskFragmentOperation;
+
+            @Nullable
             private PendingIntent mPendingIntent;
 
             @Nullable
@@ -1767,6 +1810,12 @@
                 return this;
             }
 
+            Builder setTaskFragmentOperation(
+                    @Nullable TaskFragmentOperation taskFragmentOperation) {
+                mTaskFragmentOperation = taskFragmentOperation;
+                return this;
+            }
+
             Builder setReparentLeafTaskIfRelaunch(boolean reparentLeafTaskIfRelaunch) {
                 mReparentLeafTaskIfRelaunch = reparentLeafTaskIfRelaunch;
                 return this;
@@ -1796,6 +1845,7 @@
                 hierarchyOp.mPendingIntent = mPendingIntent;
                 hierarchyOp.mAlwaysOnTop = mAlwaysOnTop;
                 hierarchyOp.mTaskFragmentCreationOptions = mTaskFragmentCreationOptions;
+                hierarchyOp.mTaskFragmentOperation = mTaskFragmentOperation;
                 hierarchyOp.mShortcutInfo = mShortcutInfo;
                 hierarchyOp.mReparentLeafTaskIfRelaunch = mReparentLeafTaskIfRelaunch;
 
diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java
index fda39c1..dd9483a 100644
--- a/core/java/android/window/WindowOnBackInvokedDispatcher.java
+++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java
@@ -229,19 +229,21 @@
         }
 
         @Override
-        public void onBackStarted(BackEvent backEvent) {
+        public void onBackStarted(BackMotionEvent backEvent) {
             Handler.getMain().post(() -> {
                 final OnBackAnimationCallback callback = getBackAnimationCallback();
                 if (callback != null) {
                     mProgressAnimator.onBackStarted(backEvent, event ->
                             callback.onBackProgressed(event));
-                    callback.onBackStarted(backEvent);
+                    callback.onBackStarted(new BackEvent(
+                            backEvent.getTouchX(), backEvent.getTouchY(),
+                            backEvent.getProgress(), backEvent.getSwipeEdge()));
                 }
             });
         }
 
         @Override
-        public void onBackProgressed(BackEvent backEvent) {
+        public void onBackProgressed(BackMotionEvent backEvent) {
             Handler.getMain().post(() -> {
                 final OnBackAnimationCallback callback = getBackAnimationCallback();
                 if (callback != null) {
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 1fcfe7d..011232f 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -2953,12 +2953,24 @@
 
     private boolean shouldShowStickyContentPreviewNoOrientationCheck() {
         return shouldShowTabs()
-                && mMultiProfilePagerAdapter.getListAdapterForUserHandle(
-                UserHandle.of(UserHandle.myUserId())).getCount() > 0
+                && (mMultiProfilePagerAdapter.getListAdapterForUserHandle(
+                        UserHandle.of(UserHandle.myUserId())).getCount() > 0
+                    || shouldShowContentPreviewWhenEmpty())
                 && shouldShowContentPreview();
     }
 
     /**
+     * This method could be used to override the default behavior when we hide the preview area
+     * when the current tab doesn't have any items.
+     *
+     * @return true if we want to show the content preview area even if the tab for the current
+     *         user is empty
+     */
+    protected boolean shouldShowContentPreviewWhenEmpty() {
+        return false;
+    }
+
+    /**
      * @return true if we want to show the content preview area
      */
     protected boolean shouldShowContentPreview() {
diff --git a/core/java/com/android/internal/app/OWNERS b/core/java/com/android/internal/app/OWNERS
index 3833976..970728f 100644
--- a/core/java/com/android/internal/app/OWNERS
+++ b/core/java/com/android/internal/app/OWNERS
@@ -2,6 +2,7 @@
 per-file *Resolver* = file:/packages/SystemUI/OWNERS
 per-file *Chooser* = file:/packages/SystemUI/OWNERS
 per-file SimpleIconFactory.java = file:/packages/SystemUI/OWNERS
+per-file AbstractMultiProfilePagerAdapter.java = file:/packages/SystemUI/OWNERS
 per-file NetInitiatedActivity.java = file:/location/java/android/location/OWNERS
 per-file *BatteryStats* = file:/BATTERY_STATS_OWNERS
 
@@ -11,4 +12,4 @@
 per-file *Voice* = file:/core/java/android/service/voice/OWNERS
 
 # System language settings
-per-file *Locale* = file:platform/packages/apps/Settings:/src/com/android/settings/localepicker/OWNERS
\ No newline at end of file
+per-file *Locale* = file:platform/packages/apps/Settings:/src/com/android/settings/localepicker/OWNERS
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index f8b764b..19e4ba4 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -209,7 +209,7 @@
      * <p>Can only be used if there is a work profile.
      * <p>Possible values can be either {@link #PROFILE_PERSONAL} or {@link #PROFILE_WORK}.
      */
-    static final String EXTRA_SELECTED_PROFILE =
+    protected static final String EXTRA_SELECTED_PROFILE =
             "com.android.internal.app.ResolverActivity.EXTRA_SELECTED_PROFILE";
 
     /**
@@ -224,8 +224,8 @@
     static final String EXTRA_CALLING_USER =
             "com.android.internal.app.ResolverActivity.EXTRA_CALLING_USER";
 
-    static final int PROFILE_PERSONAL = AbstractMultiProfilePagerAdapter.PROFILE_PERSONAL;
-    static final int PROFILE_WORK = AbstractMultiProfilePagerAdapter.PROFILE_WORK;
+    protected static final int PROFILE_PERSONAL = AbstractMultiProfilePagerAdapter.PROFILE_PERSONAL;
+    protected static final int PROFILE_WORK = AbstractMultiProfilePagerAdapter.PROFILE_WORK;
 
     private BroadcastReceiver mWorkProfileStateReceiver;
     private UserHandle mHeaderCreatorUser;
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 017bf3f..04fc4a6 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -338,4 +338,11 @@
      * @param leftOrTop indicates where the stage split is.
      */
     void enterStageSplitFromRunningApp(boolean leftOrTop);
+
+    /**
+     * Shows the media output switcher dialog.
+     *
+     * @param packageName of the session for which the output switcher is shown.
+     */
+    void showMediaOutputSwitcher(String packageName);
 }
diff --git a/core/java/com/android/internal/util/ObservableServiceConnection.java b/core/java/com/android/internal/util/ObservableServiceConnection.java
index 3165d29..45256fd 100644
--- a/core/java/com/android/internal/util/ObservableServiceConnection.java
+++ b/core/java/com/android/internal/util/ObservableServiceConnection.java
@@ -165,6 +165,13 @@
     }
 
     /**
+     * Executes code on the executor specified at construction.
+     */
+    public void execute(Runnable runnable) {
+        mExecutor.execute(runnable);
+    }
+
+    /**
      * Initiate binding to the service.
      *
      * @return {@code true} if initiating binding succeed, {@code false} if the binding failed or
diff --git a/core/java/com/android/internal/util/ScreenshotHelper.java b/core/java/com/android/internal/util/ScreenshotHelper.java
index 79c5196..3a393b6 100644
--- a/core/java/com/android/internal/util/ScreenshotHelper.java
+++ b/core/java/com/android/internal/util/ScreenshotHelper.java
@@ -1,7 +1,7 @@
 package com.android.internal.util;
 
 import static android.content.Intent.ACTION_USER_SWITCHED;
-import static android.view.WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE;
+import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -11,29 +11,18 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
-import android.graphics.Bitmap;
-import android.graphics.ColorSpace;
-import android.graphics.Insets;
-import android.graphics.ParcelableColorSpace;
-import android.graphics.Rect;
-import android.hardware.HardwareBuffer;
 import android.net.Uri;
-import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
 import android.os.Messenger;
-import android.os.Parcel;
-import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.Log;
 import android.view.WindowManager.ScreenshotSource;
-import android.view.WindowManager.ScreenshotType;
 
 import com.android.internal.annotations.VisibleForTesting;
 
-import java.util.Objects;
 import java.util.function.Consumer;
 
 public class ScreenshotHelper {
@@ -41,212 +30,6 @@
     public static final int SCREENSHOT_MSG_URI = 1;
     public static final int SCREENSHOT_MSG_PROCESS_COMPLETE = 2;
 
-    /**
-     * Describes a screenshot request.
-     */
-    public static class ScreenshotRequest implements Parcelable {
-        @ScreenshotType
-        private final int mType;
-
-        @ScreenshotSource
-        private final int mSource;
-
-        private final Bundle mBitmapBundle;
-        private final Rect mBoundsInScreen;
-        private final Insets mInsets;
-        private final int mTaskId;
-        private final int mUserId;
-        private final ComponentName mTopComponent;
-
-
-        public ScreenshotRequest(@ScreenshotType int type, @ScreenshotSource int source) {
-            this(type, source, /* topComponent */ null);
-        }
-
-        public ScreenshotRequest(@ScreenshotType int type, @ScreenshotSource int source,
-                ComponentName topComponent) {
-            this(type,
-                source,
-                /* bitmapBundle*/ null,
-                /* boundsInScreen */ null,
-                /* insets */ null,
-                /* taskId */ -1,
-                /* userId */ -1,
-                topComponent);
-        }
-
-        public ScreenshotRequest(@ScreenshotType int type, @ScreenshotSource int source,
-                Bundle bitmapBundle, Rect boundsInScreen, Insets insets, int taskId, int userId,
-                ComponentName topComponent) {
-            mType = type;
-            mSource = source;
-            mBitmapBundle = bitmapBundle;
-            mBoundsInScreen = boundsInScreen;
-            mInsets = insets;
-            mTaskId = taskId;
-            mUserId = userId;
-            mTopComponent = topComponent;
-        }
-
-        ScreenshotRequest(Parcel in) {
-            mType = in.readInt();
-            mSource = in.readInt();
-            if (in.readInt() == 1) {
-                mBitmapBundle = in.readBundle(getClass().getClassLoader());
-                mBoundsInScreen = in.readParcelable(Rect.class.getClassLoader(), Rect.class);
-                mInsets = in.readParcelable(Insets.class.getClassLoader(), Insets.class);
-                mTaskId = in.readInt();
-                mUserId = in.readInt();
-                mTopComponent = in.readParcelable(ComponentName.class.getClassLoader(),
-                        ComponentName.class);
-            } else {
-                mBitmapBundle = null;
-                mBoundsInScreen = null;
-                mInsets = null;
-                mTaskId = -1;
-                mUserId = -1;
-                mTopComponent = null;
-            }
-        }
-
-        @ScreenshotType
-        public int getType() {
-            return mType;
-        }
-
-        @ScreenshotSource
-        public int getSource() {
-            return mSource;
-        }
-
-        public Bundle getBitmapBundle() {
-            return mBitmapBundle;
-        }
-
-        public Rect getBoundsInScreen() {
-            return mBoundsInScreen;
-        }
-
-        public Insets getInsets() {
-            return mInsets;
-        }
-
-        public int getTaskId() {
-            return mTaskId;
-        }
-
-        public int getUserId() {
-            return mUserId;
-        }
-
-        public ComponentName getTopComponent() {
-            return mTopComponent;
-        }
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(mType);
-            dest.writeInt(mSource);
-            if (mBitmapBundle == null) {
-                dest.writeInt(0);
-            } else {
-                dest.writeInt(1);
-                dest.writeBundle(mBitmapBundle);
-                dest.writeParcelable(mBoundsInScreen, 0);
-                dest.writeParcelable(mInsets, 0);
-                dest.writeInt(mTaskId);
-                dest.writeInt(mUserId);
-                dest.writeParcelable(mTopComponent, 0);
-            }
-        }
-
-        @NonNull
-        public static final Parcelable.Creator<ScreenshotRequest> CREATOR =
-                new Parcelable.Creator<ScreenshotRequest>() {
-
-                    @Override
-                    public ScreenshotRequest createFromParcel(Parcel source) {
-                        return new ScreenshotRequest(source);
-                    }
-
-                    @Override
-                    public ScreenshotRequest[] newArray(int size) {
-                        return new ScreenshotRequest[size];
-                    }
-                };
-    }
-
-    /**
-     * Bundler used to convert between a hardware bitmap and a bundle without copying the internal
-     * content. This is expected to be used together with {@link #provideScreenshot} to handle a
-     * hardware bitmap as a screenshot.
-     */
-    public static final class HardwareBitmapBundler {
-        private static final String KEY_BUFFER = "bitmap_util_buffer";
-        private static final String KEY_COLOR_SPACE = "bitmap_util_color_space";
-
-        private HardwareBitmapBundler() {
-        }
-
-        /**
-         * Creates a Bundle that represents the given Bitmap.
-         * <p>The Bundle will contain a wrapped version of the Bitmaps HardwareBuffer, so will avoid
-         * copies when passing across processes, only pass to processes you trust.
-         *
-         * <p>Returns a new Bundle rather than modifying an exiting one to avoid key collisions, the
-         * returned Bundle should be treated as a standalone object.
-         *
-         * @param bitmap to convert to bundle
-         * @return a Bundle representing the bitmap, should only be parsed by
-         * {@link #bundleToHardwareBitmap(Bundle)}
-         */
-        public static Bundle hardwareBitmapToBundle(Bitmap bitmap) {
-            if (bitmap.getConfig() != Bitmap.Config.HARDWARE) {
-                throw new IllegalArgumentException(
-                        "Passed bitmap must have hardware config, found: " + bitmap.getConfig());
-            }
-
-            // Bitmap assumes SRGB for null color space
-            ParcelableColorSpace colorSpace =
-                    bitmap.getColorSpace() == null
-                            ? new ParcelableColorSpace(ColorSpace.get(ColorSpace.Named.SRGB))
-                            : new ParcelableColorSpace(bitmap.getColorSpace());
-
-            Bundle bundle = new Bundle();
-            bundle.putParcelable(KEY_BUFFER, bitmap.getHardwareBuffer());
-            bundle.putParcelable(KEY_COLOR_SPACE, colorSpace);
-
-            return bundle;
-        }
-
-        /**
-         * Extracts the Bitmap added to a Bundle with {@link #hardwareBitmapToBundle(Bitmap)} .}
-         *
-         * <p>This Bitmap contains the HardwareBuffer from the original caller, be careful passing
-         * this Bitmap on to any other source.
-         *
-         * @param bundle containing the bitmap
-         * @return a hardware Bitmap
-         */
-        public static Bitmap bundleToHardwareBitmap(Bundle bundle) {
-            if (!bundle.containsKey(KEY_BUFFER) || !bundle.containsKey(KEY_COLOR_SPACE)) {
-                throw new IllegalArgumentException("Bundle does not contain a hardware bitmap");
-            }
-
-            HardwareBuffer buffer = bundle.getParcelable(KEY_BUFFER, HardwareBuffer.class);
-            ParcelableColorSpace colorSpace = bundle.getParcelable(KEY_COLOR_SPACE,
-                    ParcelableColorSpace.class);
-
-            return Bitmap.wrapHardwareBuffer(Objects.requireNonNull(buffer),
-                    colorSpace.getColorSpace());
-        }
-    }
-
     private static final String TAG = "ScreenshotHelper";
 
     // Time until we give up on the screenshot & show an error instead.
@@ -277,20 +60,35 @@
     /**
      * Request a screenshot be taken.
      * <p>
-     * Added to support reducing unit test duration; the method variant without a timeout argument
-     * is recommended for general use.
+     * Convenience method for taking a full screenshot with provided source.
      *
-     * @param type The type of screenshot, defined by {@link ScreenshotType}
-     * @param source The source of the screenshot request, defined by {@link ScreenshotSource}
-     * @param handler used to process messages received from the screenshot service
+     * @param source             source of the screenshot request, defined by {@link
+     *                           ScreenshotSource}
+     * @param handler            used to process messages received from the screenshot service
      * @param completionConsumer receives the URI of the captured screenshot, once saved or
-     *         null if no screenshot was saved
+     *                           null if no screenshot was saved
      */
-    public void takeScreenshot(@ScreenshotType int type, @ScreenshotSource int source,
-            @NonNull Handler handler, @Nullable Consumer<Uri> completionConsumer) {
-        ScreenshotRequest screenshotRequest = new ScreenshotRequest(type, source);
-        takeScreenshot(handler, screenshotRequest, SCREENSHOT_TIMEOUT_MS,
-                completionConsumer);
+    public void takeScreenshot(@ScreenshotSource int source, @NonNull Handler handler,
+            @Nullable Consumer<Uri> completionConsumer) {
+        ScreenshotRequest request =
+                new ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, source).build();
+        takeScreenshot(request, handler, completionConsumer);
+    }
+
+    /**
+     * Request a screenshot be taken.
+     * <p>
+     *
+     * @param request            description of the screenshot request, either for taking a
+     *                           screenshot or
+     *                           providing a bitmap
+     * @param handler            used to process messages received from the screenshot service
+     * @param completionConsumer receives the URI of the captured screenshot, once saved or
+     *                           null if no screenshot was saved
+     */
+    public void takeScreenshot(ScreenshotRequest request, @NonNull Handler handler,
+            @Nullable Consumer<Uri> completionConsumer) {
+        takeScreenshotInternal(request, handler, completionConsumer, SCREENSHOT_TIMEOUT_MS);
     }
 
     /**
@@ -299,46 +97,16 @@
      * Added to support reducing unit test duration; the method variant without a timeout argument
      * is recommended for general use.
      *
-     * @param type The type of screenshot, defined by {@link ScreenshotType}
-     * @param source The source of the screenshot request, defined by {@link ScreenshotSource}
-     * @param handler used to process messages received from the screenshot service
-     * @param timeoutMs time limit for processing, intended only for testing
+     * @param request            description of the screenshot request, either for taking a
+     *                           screenshot or providing a bitmap
+     * @param handler            used to process messages received from the screenshot service
+     * @param timeoutMs          time limit for processing, intended only for testing
      * @param completionConsumer receives the URI of the captured screenshot, once saved or
-     *         null if no screenshot was saved
+     *                           null if no screenshot was saved
      */
     @VisibleForTesting
-    public void takeScreenshot(@ScreenshotType int type, @ScreenshotSource int source,
-            @NonNull Handler handler, long timeoutMs, @Nullable Consumer<Uri> completionConsumer) {
-        ScreenshotRequest screenshotRequest = new ScreenshotRequest(type, source);
-        takeScreenshot(handler, screenshotRequest, timeoutMs, completionConsumer);
-    }
-
-    /**
-     * Request that provided image be handled as if it was a screenshot.
-     *
-     * @param screenshotBundle Bundle containing the buffer and color space of the screenshot.
-     * @param boundsInScreen The bounds in screen coordinates that the bitmap originated from.
-     * @param insets The insets that the image was shown with, inside the screen bounds.
-     * @param taskId The taskId of the task that the screen shot was taken of.
-     * @param userId The userId of user running the task provided in taskId.
-     * @param topComponent The component name of the top component running in the task.
-     * @param source The source of the screenshot request, defined by {@link ScreenshotSource}
-     * @param handler A handler used in case the screenshot times out
-     * @param completionConsumer receives the URI of the captured screenshot, once saved or
-     *         null if no screenshot was saved
-     */
-    public void provideScreenshot(@NonNull Bundle screenshotBundle, @NonNull Rect boundsInScreen,
-            @NonNull Insets insets, int taskId, int userId, ComponentName topComponent,
-            @ScreenshotSource int source, @NonNull Handler handler,
-            @Nullable Consumer<Uri> completionConsumer) {
-        ScreenshotRequest screenshotRequest = new ScreenshotRequest(TAKE_SCREENSHOT_PROVIDED_IMAGE,
-                source, screenshotBundle, boundsInScreen, insets, taskId, userId, topComponent);
-        takeScreenshot(handler, screenshotRequest, SCREENSHOT_TIMEOUT_MS, completionConsumer);
-    }
-
-    private void takeScreenshot(@NonNull Handler handler,
-            ScreenshotRequest screenshotRequest, long timeoutMs,
-            @Nullable Consumer<Uri> completionConsumer) {
+    public void takeScreenshotInternal(ScreenshotRequest request, @NonNull Handler handler,
+            @Nullable Consumer<Uri> completionConsumer, long timeoutMs) {
         synchronized (mScreenshotLock) {
 
             final Runnable mScreenshotTimeout = () -> {
@@ -354,7 +122,7 @@
                 }
             };
 
-            Message msg = Message.obtain(null, 0, screenshotRequest);
+            Message msg = Message.obtain(null, 0, request);
 
             Handler h = new Handler(handler.getLooper()) {
                 @Override
@@ -471,5 +239,4 @@
                 Intent.FLAG_RECEIVER_FOREGROUND);
         mContext.sendBroadcastAsUser(errorIntent, UserHandle.CURRENT);
     }
-
 }
diff --git a/core/java/com/android/internal/util/ScreenshotRequest.aidl b/core/java/com/android/internal/util/ScreenshotRequest.aidl
new file mode 100644
index 0000000..b08905d
--- /dev/null
+++ b/core/java/com/android/internal/util/ScreenshotRequest.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.util;
+
+parcelable ScreenshotRequest;
\ No newline at end of file
diff --git a/core/java/com/android/internal/util/ScreenshotRequest.java b/core/java/com/android/internal/util/ScreenshotRequest.java
new file mode 100644
index 0000000..1902f80
--- /dev/null
+++ b/core/java/com/android/internal/util/ScreenshotRequest.java
@@ -0,0 +1,332 @@
+/*
+ * 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.util;
+
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+import static android.os.UserHandle.USER_NULL;
+import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;
+import static android.view.WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE;
+
+import android.annotation.NonNull;
+import android.content.ComponentName;
+import android.graphics.Bitmap;
+import android.graphics.ColorSpace;
+import android.graphics.Insets;
+import android.graphics.ParcelableColorSpace;
+import android.graphics.Rect;
+import android.hardware.HardwareBuffer;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+import android.view.WindowManager;
+
+import java.util.Objects;
+
+/**
+ * Describes a screenshot request.
+ */
+public class ScreenshotRequest implements Parcelable {
+    private static final String TAG = "ScreenshotRequest";
+
+    @WindowManager.ScreenshotType
+    private final int mType;
+    @WindowManager.ScreenshotSource
+    private final int mSource;
+    private final ComponentName mTopComponent;
+    private final int mTaskId;
+    private final int mUserId;
+    private final Bitmap mBitmap;
+    private final Rect mBoundsInScreen;
+    private final Insets mInsets;
+
+    private ScreenshotRequest(
+            @WindowManager.ScreenshotType int type, @WindowManager.ScreenshotSource int source,
+            ComponentName topComponent, int taskId, int userId,
+            Bitmap bitmap, Rect boundsInScreen, Insets insets) {
+        mType = type;
+        mSource = source;
+        mTopComponent = topComponent;
+        mTaskId = taskId;
+        mUserId = userId;
+        mBitmap = bitmap;
+        mBoundsInScreen = boundsInScreen;
+        mInsets = insets;
+    }
+
+    ScreenshotRequest(Parcel in) {
+        mType = in.readInt();
+        mSource = in.readInt();
+        mTopComponent = in.readTypedObject(ComponentName.CREATOR);
+        mTaskId = in.readInt();
+        mUserId = in.readInt();
+        mBitmap = HardwareBitmapBundler.bundleToHardwareBitmap(in.readTypedObject(Bundle.CREATOR));
+        mBoundsInScreen = in.readTypedObject(Rect.CREATOR);
+        mInsets = in.readTypedObject(Insets.CREATOR);
+    }
+
+    @WindowManager.ScreenshotType
+    public int getType() {
+        return mType;
+    }
+
+    @WindowManager.ScreenshotSource
+    public int getSource() {
+        return mSource;
+    }
+
+    public Bitmap getBitmap() {
+        return mBitmap;
+    }
+
+    public Rect getBoundsInScreen() {
+        return mBoundsInScreen;
+    }
+
+    public Insets getInsets() {
+        return mInsets;
+    }
+
+    public int getTaskId() {
+        return mTaskId;
+    }
+
+    public int getUserId() {
+        return mUserId;
+    }
+
+    public ComponentName getTopComponent() {
+        return mTopComponent;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mType);
+        dest.writeInt(mSource);
+        dest.writeTypedObject(mTopComponent, 0);
+        dest.writeInt(mTaskId);
+        dest.writeInt(mUserId);
+        dest.writeTypedObject(HardwareBitmapBundler.hardwareBitmapToBundle(mBitmap), 0);
+        dest.writeTypedObject(mBoundsInScreen, 0);
+        dest.writeTypedObject(mInsets, 0);
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<ScreenshotRequest> CREATOR =
+            new Parcelable.Creator<ScreenshotRequest>() {
+
+                @Override
+                public ScreenshotRequest createFromParcel(Parcel source) {
+                    return new ScreenshotRequest(source);
+                }
+
+                @Override
+                public ScreenshotRequest[] newArray(int size) {
+                    return new ScreenshotRequest[size];
+                }
+            };
+
+    /**
+     * Builder class for {@link ScreenshotRequest} objects.
+     */
+    public static class Builder {
+        @WindowManager.ScreenshotType
+        private final int mType;
+
+        @WindowManager.ScreenshotSource
+        private final int mSource;
+
+        private Bitmap mBitmap;
+        private Rect mBoundsInScreen;
+        private Insets mInsets = Insets.NONE;
+        private int mTaskId = INVALID_TASK_ID;
+        private int mUserId = USER_NULL;
+        private ComponentName mTopComponent;
+
+        /**
+         * Begin building a ScreenshotRequest.
+         *
+         * @param type   The type of the screenshot request, defined by {@link
+         *               WindowManager.ScreenshotType}
+         * @param source The source of the screenshot request, defined by {@link
+         *               WindowManager.ScreenshotSource}
+         */
+        public Builder(
+                @WindowManager.ScreenshotType int type,
+                @WindowManager.ScreenshotSource int source) {
+            mType = type;
+            mSource = source;
+        }
+
+        /**
+         * Construct a new {@link ScreenshotRequest} with the set parameters.
+         */
+        public ScreenshotRequest build() {
+            if (mType == TAKE_SCREENSHOT_FULLSCREEN && mBitmap != null) {
+                Log.w(TAG, "Bitmap provided, but request is fullscreen. Bitmap will be ignored.");
+            }
+            if (mType == TAKE_SCREENSHOT_PROVIDED_IMAGE && mBitmap == null) {
+                throw new IllegalStateException(
+                        "Request is PROVIDED_IMAGE, but no bitmap is provided!");
+            }
+
+            return new ScreenshotRequest(mType, mSource, mTopComponent, mTaskId, mUserId, mBitmap,
+                    mBoundsInScreen, mInsets);
+        }
+
+        /**
+         * Set the top component associated with this request.
+         *
+         * @param topComponent The component name of the top component running in the task.
+         */
+        public Builder setTopComponent(ComponentName topComponent) {
+            mTopComponent = topComponent;
+            return this;
+        }
+
+        /**
+         * Set the task id associated with this request.
+         *
+         * @param taskId The taskId of the task that the screenshot was taken of.
+         */
+        public Builder setTaskId(int taskId) {
+            mTaskId = taskId;
+            return this;
+        }
+
+        /**
+         * Set the user id associated with this request.
+         *
+         * @param userId The userId of user running the task provided in taskId.
+         */
+        public Builder setUserId(int userId) {
+            mUserId = userId;
+            return this;
+        }
+
+        /**
+         * Set the bitmap associated with this request.
+         *
+         * @param bitmap The provided screenshot.
+         */
+        public Builder setBitmap(Bitmap bitmap) {
+            mBitmap = bitmap;
+            return this;
+        }
+
+        /**
+         * Set the bounds for the provided bitmap.
+         *
+         * @param bounds The bounds in screen coordinates that the bitmap originated from.
+         */
+        public Builder setBoundsOnScreen(Rect bounds) {
+            mBoundsInScreen = bounds;
+            return this;
+        }
+
+        /**
+         * Set the insets for the provided bitmap.
+         *
+         * @param insets The insets that the image was shown with, inside the screen bounds.
+         */
+        public Builder setInsets(@NonNull Insets insets) {
+            mInsets = insets;
+            return this;
+        }
+    }
+
+    /**
+     * Bundler used to convert between a hardware bitmap and a bundle without copying the internal
+     * content. This is used together with a fully-defined ScreenshotRequest to handle a hardware
+     * bitmap as a screenshot.
+     */
+    private static final class HardwareBitmapBundler {
+        private static final String KEY_BUFFER = "bitmap_util_buffer";
+        private static final String KEY_COLOR_SPACE = "bitmap_util_color_space";
+
+        private HardwareBitmapBundler() {
+        }
+
+        /**
+         * Creates a Bundle that represents the given Bitmap.
+         * <p>The Bundle will contain a wrapped version of the Bitmaps HardwareBuffer, so will
+         * avoid
+         * copies when passing across processes, only pass to processes you trust.
+         *
+         * <p>Returns a new Bundle rather than modifying an exiting one to avoid key collisions,
+         * the
+         * returned Bundle should be treated as a standalone object.
+         *
+         * @param bitmap to convert to bundle
+         * @return a Bundle representing the bitmap, should only be parsed by
+         * {@link #bundleToHardwareBitmap(Bundle)}
+         */
+        private static Bundle hardwareBitmapToBundle(Bitmap bitmap) {
+            if (bitmap == null) {
+                return null;
+            }
+            if (bitmap.getConfig() != Bitmap.Config.HARDWARE) {
+                throw new IllegalArgumentException(
+                        "Passed bitmap must have hardware config, found: "
+                                + bitmap.getConfig());
+            }
+
+            // Bitmap assumes SRGB for null color space
+            ParcelableColorSpace colorSpace =
+                    bitmap.getColorSpace() == null
+                            ? new ParcelableColorSpace(ColorSpace.get(ColorSpace.Named.SRGB))
+                            : new ParcelableColorSpace(bitmap.getColorSpace());
+
+            Bundle bundle = new Bundle();
+            bundle.putParcelable(KEY_BUFFER, bitmap.getHardwareBuffer());
+            bundle.putParcelable(KEY_COLOR_SPACE, colorSpace);
+
+            return bundle;
+        }
+
+        /**
+         * Extracts the Bitmap added to a Bundle with {@link #hardwareBitmapToBundle(Bitmap)}.
+         *
+         * <p>This Bitmap contains the HardwareBuffer from the original caller, be careful
+         * passing
+         * this Bitmap on to any other source.
+         *
+         * @param bundle containing the bitmap
+         * @return a hardware Bitmap
+         */
+        private static Bitmap bundleToHardwareBitmap(Bundle bundle) {
+            if (bundle == null) {
+                return null;
+            }
+            if (!bundle.containsKey(KEY_BUFFER) || !bundle.containsKey(KEY_COLOR_SPACE)) {
+                throw new IllegalArgumentException("Bundle does not contain a hardware bitmap");
+            }
+
+            HardwareBuffer buffer = bundle.getParcelable(KEY_BUFFER, HardwareBuffer.class);
+            ParcelableColorSpace colorSpace = bundle.getParcelable(KEY_COLOR_SPACE,
+                    ParcelableColorSpace.class);
+
+            return Bitmap.wrapHardwareBuffer(Objects.requireNonNull(buffer),
+                    colorSpace.getColorSpace());
+        }
+    }
+}
diff --git a/core/java/com/android/internal/view/RotationPolicy.java b/core/java/com/android/internal/view/RotationPolicy.java
index 869da1f..058c6ec 100644
--- a/core/java/com/android/internal/view/RotationPolicy.java
+++ b/core/java/com/android/internal/view/RotationPolicy.java
@@ -106,7 +106,9 @@
      * Enables or disables rotation lock from the system UI toggle.
      */
     public static void setRotationLock(Context context, final boolean enabled) {
-        final int rotation = areAllRotationsAllowed(context) ? CURRENT_ROTATION : NATURAL_ROTATION;
+        final int rotation = areAllRotationsAllowed(context)
+                || useCurrentRotationOnRotationLockChange(context) ? CURRENT_ROTATION
+                : NATURAL_ROTATION;
         setRotationLockAtAngle(context, enabled, rotation);
     }
 
@@ -139,6 +141,11 @@
         return context.getResources().getBoolean(R.bool.config_allowAllRotations);
     }
 
+    private static boolean useCurrentRotationOnRotationLockChange(Context context) {
+        return context.getResources().getBoolean(
+                R.bool.config_useCurrentRotationOnRotationLockChange);
+    }
+
     private static void setRotationLock(final boolean enabled, final int rotation) {
         AsyncTask.execute(new Runnable() {
             @Override
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index d83e40c..6a80d1c 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -258,6 +258,7 @@
         android:name="com.android.bluetooth.BluetoothMapContentObserver.action.MESSAGE_DELIVERY" />
     <protected-broadcast
         android:name="android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED" />
+    <protected-broadcast android:name="android.bluetooth.action.HAP_CONNECTION_STATE_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.action.LE_AUDIO_CONNECTION_STATE_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.action.LE_AUDIO_ACTIVE_DEVICE_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.action.LE_AUDIO_CONF_CHANGED" />
diff --git a/core/res/OWNERS b/core/res/OWNERS
index c54638a..8c041b2 100644
--- a/core/res/OWNERS
+++ b/core/res/OWNERS
@@ -26,6 +26,11 @@
 tsuji@google.com
 yamasani@google.com
 
+# WindowManager team
+# TODO(262451702): Move WindowManager configs out of config.xml in a separate file
+per-file res/values/config.xml = file:/services/core/java/com/android/server/wm/OWNERS
+per-file res/values/symbols.xml = file:/services/core/java/com/android/server/wm/OWNERS
+
 # Resources finalization
 per-file res/xml/public-staging.xml = file:/tools/aapt2/OWNERS
 per-file res/xml/public-final.xml = file:/tools/aapt2/OWNERS
diff --git a/core/res/res/layout/autofill_fill_dialog.xml b/core/res/res/layout/autofill_fill_dialog.xml
index c382a65..2e65800 100644
--- a/core/res/res/layout/autofill_fill_dialog.xml
+++ b/core/res/res/layout/autofill_fill_dialog.xml
@@ -93,7 +93,7 @@
             android:layout_height="36dp"
             android:layout_marginTop="6dp"
             android:layout_marginBottom="6dp"
-            style="@style/AutofillHalfSheetOutlinedButton"
+            style="?android:attr/borderlessButtonStyle"
             android:text="@string/autofill_save_no">
         </Button>
 
diff --git a/core/res/res/layout/autofill_save.xml b/core/res/res/layout/autofill_save.xml
index fd08241..3c0b789 100644
--- a/core/res/res/layout/autofill_save.xml
+++ b/core/res/res/layout/autofill_save.xml
@@ -81,7 +81,7 @@
                 android:layout_height="36dp"
                 android:layout_marginTop="6dp"
                 android:layout_marginBottom="6dp"
-                style="@style/AutofillHalfSheetOutlinedButton"
+                style="?android:attr/borderlessButtonStyle"
                 android:text="@string/autofill_save_no">
             </Button>
 
diff --git a/core/res/res/values-b+sr+Latn-television/strings.xml b/core/res/res/values-b+sr+Latn-television/strings.xml
index 8643593..df5d8ea 100644
--- a/core/res/res/values-b+sr+Latn-television/strings.xml
+++ b/core/res/res/values-b+sr+Latn-television/strings.xml
@@ -17,6 +17,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="7002619958660406548">"Микрофон је блокиран"</string>
-    <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="2131954635322568179">"Камера је блокирана"</string>
+    <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="7002619958660406548">"Mikrofon je blokiran"</string>
+    <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="2131954635322568179">"Kamera je blokirana"</string>
 </resources>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index f606c8f2c..c183da8 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -27,805 +27,805 @@
     <string name="terabyteShort" msgid="1822367128583886496">"TB"</string>
     <string name="petabyteShort" msgid="5651571254228534832">"PB"</string>
     <string name="fileSizeSuffix" msgid="4233671691980131257">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="untitled" msgid="3381766946944136678">"&lt;Без имена&gt;"</string>
-    <string name="emptyPhoneNumber" msgid="5812172618020360048">"(Нема броја телефона)"</string>
-    <string name="unknownName" msgid="7078697621109055330">"Непознато"</string>
-    <string name="defaultVoiceMailAlphaTag" msgid="2190754495304236490">"Гласовна пошта"</string>
+    <string name="untitled" msgid="3381766946944136678">"&lt;Bez imena&gt;"</string>
+    <string name="emptyPhoneNumber" msgid="5812172618020360048">"(Nema broja telefona)"</string>
+    <string name="unknownName" msgid="7078697621109055330">"Nepoznato"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2190754495304236490">"Glasovna pošta"</string>
     <string name="defaultMsisdnAlphaTag" msgid="2285034592902077488">"MSISDN1"</string>
-    <string name="mmiError" msgid="2862759606579822246">"Проблеми са везом или неважећи MMI кôд."</string>
-    <string name="mmiErrorNotSupported" msgid="5001803469335286099">"Функција није подржана."</string>
-    <string name="mmiFdnError" msgid="3975490266767565852">"Рад је ограничен само на бројеве фиксног бирања."</string>
-    <string name="mmiErrorWhileRoaming" msgid="1204173664713870114">"Не можете да промените подешавања преусмеравања позива са телефона док сте у ромингу."</string>
-    <string name="serviceEnabled" msgid="7549025003394765639">"Услуга је омогућена."</string>
-    <string name="serviceEnabledFor" msgid="1463104778656711613">"Услуга је омогућена за:"</string>
-    <string name="serviceDisabled" msgid="641878791205871379">"Услуга је онемогућена."</string>
-    <string name="serviceRegistered" msgid="3856192211729577482">"Регистрација је успела."</string>
-    <string name="serviceErased" msgid="997354043770513494">"Брисање је довршено."</string>
-    <string name="passwordIncorrect" msgid="917087532676155877">"Неисправна лозинка."</string>
-    <string name="mmiComplete" msgid="6341884570892520140">"MMI кôд је извршен."</string>
-    <string name="badPin" msgid="888372071306274355">"Стари PIN који сте унели није тачан."</string>
-    <string name="badPuk" msgid="4232069163733147376">"PUK који сте унели није тачан."</string>
-    <string name="mismatchPin" msgid="2929611853228707473">"PIN кодови које сте унели се не подударају."</string>
-    <string name="invalidPin" msgid="7542498253319440408">"Откуцајте PIN који има од 4 до 8 бројева."</string>
-    <string name="invalidPuk" msgid="8831151490931907083">"Унесите PUK који се састоји од 8 цифара или више."</string>
-    <string name="needPuk" msgid="7321876090152422918">"SIM картица је закључана PUK кодом. Унесите PUK кôд да бисте је откључали."</string>
-    <string name="needPuk2" msgid="7032612093451537186">"Унесите PUK2 да бисте одблокирали SIM картицу."</string>
-    <string name="enablePin" msgid="2543771964137091212">"Није успело. Омогућите закључавање SIM/RUIM картице."</string>
+    <string name="mmiError" msgid="2862759606579822246">"Problemi sa vezom ili nevažeći MMI kôd."</string>
+    <string name="mmiErrorNotSupported" msgid="5001803469335286099">"Funkcija nije podržana."</string>
+    <string name="mmiFdnError" msgid="3975490266767565852">"Rad je ograničen samo na brojeve fiksnog biranja."</string>
+    <string name="mmiErrorWhileRoaming" msgid="1204173664713870114">"Ne možete da promenite podešavanja preusmeravanja poziva sa telefona dok ste u romingu."</string>
+    <string name="serviceEnabled" msgid="7549025003394765639">"Usluga je omogućena."</string>
+    <string name="serviceEnabledFor" msgid="1463104778656711613">"Usluga je omogućena za:"</string>
+    <string name="serviceDisabled" msgid="641878791205871379">"Usluga je onemogućena."</string>
+    <string name="serviceRegistered" msgid="3856192211729577482">"Registracija je uspela."</string>
+    <string name="serviceErased" msgid="997354043770513494">"Brisanje je dovršeno."</string>
+    <string name="passwordIncorrect" msgid="917087532676155877">"Neispravna lozinka."</string>
+    <string name="mmiComplete" msgid="6341884570892520140">"MMI kôd je izvršen."</string>
+    <string name="badPin" msgid="888372071306274355">"Stari PIN koji ste uneli nije tačan."</string>
+    <string name="badPuk" msgid="4232069163733147376">"PUK koji ste uneli nije tačan."</string>
+    <string name="mismatchPin" msgid="2929611853228707473">"PIN kodovi koje ste uneli se ne podudaraju."</string>
+    <string name="invalidPin" msgid="7542498253319440408">"Otkucajte PIN koji ima od 4 do 8 brojeva."</string>
+    <string name="invalidPuk" msgid="8831151490931907083">"Unesite PUK koji se sastoji od 8 cifara ili više."</string>
+    <string name="needPuk" msgid="7321876090152422918">"SIM kartica je zaključana PUK kodom. Unesite PUK kôd da biste je otključali."</string>
+    <string name="needPuk2" msgid="7032612093451537186">"Unesite PUK2 da biste odblokirali SIM karticu."</string>
+    <string name="enablePin" msgid="2543771964137091212">"Nije uspelo. Omogućite zaključavanje SIM/RUIM kartice."</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
-      <item quantity="one">Имате још <xliff:g id="NUMBER_1">%d</xliff:g> покушај пре него што се SIM картица закључа.</item>
-      <item quantity="few">Имате још <xliff:g id="NUMBER_1">%d</xliff:g> покушаја пре него што се SIM картица закључа.</item>
-      <item quantity="other">Имате још <xliff:g id="NUMBER_1">%d</xliff:g> покушаја пре него што се SIM картица закључа.</item>
+      <item quantity="one">Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaj pre nego što se SIM kartica zaključa.</item>
+      <item quantity="few">Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja pre nego što se SIM kartica zaključa.</item>
+      <item quantity="other">Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja pre nego što se SIM kartica zaključa.</item>
     </plurals>
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
-    <string name="ClipMmi" msgid="4110549342447630629">"Долазни ИД позиваоца"</string>
-    <string name="ClirMmi" msgid="6752346475055446417">"Сакријте ИД одлазног позиваоца"</string>
-    <string name="ColpMmi" msgid="4736462893284419302">"ИД повезане линије"</string>
-    <string name="ColrMmi" msgid="5889782479745764278">"Ограничење ИД-а повезане линије"</string>
-    <string name="CfMmi" msgid="8390012691099787178">"Преусмеравање позива"</string>
-    <string name="CwMmi" msgid="3164609577675404761">"Позив на чекању"</string>
-    <string name="BaMmi" msgid="7205614070543372167">"Ограничавање позива"</string>
-    <string name="PwdMmi" msgid="3360991257288638281">"Промена лозинке"</string>
-    <string name="PinMmi" msgid="7133542099618330959">"Промена PIN кода"</string>
-    <string name="CnipMmi" msgid="4897531155968151160">"Позивање постојећег броја"</string>
-    <string name="CnirMmi" msgid="885292039284503036">"Позивање броја је ограничено"</string>
-    <string name="ThreeWCMmi" msgid="2436550866139999411">"Тросмерно позивање"</string>
-    <string name="RuacMmi" msgid="1876047385848991110">"Одбијање непожељних позива"</string>
-    <string name="CndMmi" msgid="185136449405618437">"Испорука броја за позивање"</string>
-    <string name="DndMmi" msgid="8797375819689129800">"Не узнемиравај"</string>
-    <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"ИД позиваоца је подразумевано ограничен. Следећи позив: ограничен."</string>
-    <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"ИД позиваоца је подразумевано ограничен. Следећи позив: Није ограничен."</string>
-    <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"ИД позиваоца подразумевано није ограничен. Следећи позив: ограничен."</string>
-    <string name="CLIRDefaultOffNextCallOff" msgid="2491576172356463443">"ИД позиваоца подразумевано није ограничен. Следећи позив: Није ограничен."</string>
-    <string name="serviceNotProvisioned" msgid="8289333510236766193">"Услуга није добављена."</string>
-    <string name="CLIRPermanent" msgid="166443681876381118">"Не можете да промените подешавање ИД-а корисника."</string>
-    <string name="RestrictedOnDataTitle" msgid="1500576417268169774">"Нема услуге мобилних података"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="2852916906106191866">"Хитни позиви нису доступни"</string>
-    <string name="RestrictedOnNormalTitle" msgid="7009474589746551737">"Нема гласовне услуге"</string>
-    <string name="RestrictedOnAllVoiceTitle" msgid="3982069078579103087">"Нема гласовне услуге ни хитних позива"</string>
-    <string name="RestrictedStateContent" msgid="7693575344608618926">"Привремено искључио мобилни оператер"</string>
-    <string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Привремено је искључио мобилни оператер за SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
-    <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Повезивање са мобилном мрежом није успело"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Пробајте да промените жељену мрежу. Додирните да бисте променили."</string>
-    <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Хитни позиви нису доступни"</string>
-    <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Не можете да упућујете хитне позиве преко Wi‑Fi-ја"</string>
-    <string name="notification_channel_network_alert" msgid="4788053066033851841">"Обавештења"</string>
-    <string name="notification_channel_call_forward" msgid="8230490317314272406">"Преусмеравање позива"</string>
-    <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Режим за хитан повратни позив"</string>
-    <string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"Статус мобилних података"</string>
-    <string name="notification_channel_sms" msgid="1243384981025535724">"SMS-ови"</string>
-    <string name="notification_channel_voice_mail" msgid="8457433203106654172">"Поруке говорне поште"</string>
-    <string name="notification_channel_wfc" msgid="9048240466765169038">"Позивање преко WiFi мреже"</string>
-    <string name="notification_channel_sim" msgid="5098802350325677490">"Статус SIM-а"</string>
-    <string name="notification_channel_sim_high_prio" msgid="642361929452850928">"Обавештења SIM картице са статусом „висок приоритет“"</string>
-    <string name="peerTtyModeFull" msgid="337553730440832160">"Корисник захтева ПОТПУН режим TTY"</string>
-    <string name="peerTtyModeHco" msgid="5626377160840915617">"Корисник захтева ПРЕНОС ЗВУКА за режим TTY"</string>
-    <string name="peerTtyModeVco" msgid="572208600818270944">"Корисник захтева ПРЕНОС ГЛАСА за режим TTY"</string>
-    <string name="peerTtyModeOff" msgid="2420380956369226583">"Корисник захтева ИСКЉУЧЕН режим TTY"</string>
+    <string name="ClipMmi" msgid="4110549342447630629">"Dolazni ID pozivaoca"</string>
+    <string name="ClirMmi" msgid="6752346475055446417">"Sakrijte ID odlaznog pozivaoca"</string>
+    <string name="ColpMmi" msgid="4736462893284419302">"ID povezane linije"</string>
+    <string name="ColrMmi" msgid="5889782479745764278">"Ograničenje ID-a povezane linije"</string>
+    <string name="CfMmi" msgid="8390012691099787178">"Preusmeravanje poziva"</string>
+    <string name="CwMmi" msgid="3164609577675404761">"Poziv na čekanju"</string>
+    <string name="BaMmi" msgid="7205614070543372167">"Ograničavanje poziva"</string>
+    <string name="PwdMmi" msgid="3360991257288638281">"Promena lozinke"</string>
+    <string name="PinMmi" msgid="7133542099618330959">"Promena PIN koda"</string>
+    <string name="CnipMmi" msgid="4897531155968151160">"Pozivanje postojećeg broja"</string>
+    <string name="CnirMmi" msgid="885292039284503036">"Pozivanje broja je ograničeno"</string>
+    <string name="ThreeWCMmi" msgid="2436550866139999411">"Trosmerno pozivanje"</string>
+    <string name="RuacMmi" msgid="1876047385848991110">"Odbijanje nepoželjnih poziva"</string>
+    <string name="CndMmi" msgid="185136449405618437">"Isporuka broja za pozivanje"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Ne uznemiravaj"</string>
+    <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"ID pozivaoca je podrazumevano ograničen. Sledeći poziv: ograničen."</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"ID pozivaoca je podrazumevano ograničen. Sledeći poziv: Nije ograničen."</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"ID pozivaoca podrazumevano nije ograničen. Sledeći poziv: ograničen."</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2491576172356463443">"ID pozivaoca podrazumevano nije ograničen. Sledeći poziv: Nije ograničen."</string>
+    <string name="serviceNotProvisioned" msgid="8289333510236766193">"Usluga nije dobavljena."</string>
+    <string name="CLIRPermanent" msgid="166443681876381118">"Ne možete da promenite podešavanje ID-a korisnika."</string>
+    <string name="RestrictedOnDataTitle" msgid="1500576417268169774">"Nema usluge mobilnih podataka"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="2852916906106191866">"Hitni pozivi nisu dostupni"</string>
+    <string name="RestrictedOnNormalTitle" msgid="7009474589746551737">"Nema glasovne usluge"</string>
+    <string name="RestrictedOnAllVoiceTitle" msgid="3982069078579103087">"Nema glasovne usluge ni hitnih poziva"</string>
+    <string name="RestrictedStateContent" msgid="7693575344608618926">"Privremeno isključio mobilni operater"</string>
+    <string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Privremeno je isključio mobilni operater za SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
+    <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Povezivanje sa mobilnom mrežom nije uspelo"</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Probajte da promenite željenu mrežu. Dodirnite da biste promenili."</string>
+    <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Hitni pozivi nisu dostupni"</string>
+    <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Ne možete da upućujete hitne pozive preko Wi‑Fi-ja"</string>
+    <string name="notification_channel_network_alert" msgid="4788053066033851841">"Obaveštenja"</string>
+    <string name="notification_channel_call_forward" msgid="8230490317314272406">"Preusmeravanje poziva"</string>
+    <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Režim za hitan povratni poziv"</string>
+    <string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"Status mobilnih podataka"</string>
+    <string name="notification_channel_sms" msgid="1243384981025535724">"SMS-ovi"</string>
+    <string name="notification_channel_voice_mail" msgid="8457433203106654172">"Poruke govorne pošte"</string>
+    <string name="notification_channel_wfc" msgid="9048240466765169038">"Pozivanje preko WiFi mreže"</string>
+    <string name="notification_channel_sim" msgid="5098802350325677490">"Status SIM-a"</string>
+    <string name="notification_channel_sim_high_prio" msgid="642361929452850928">"Obaveštenja SIM kartice sa statusom „visok prioritet“"</string>
+    <string name="peerTtyModeFull" msgid="337553730440832160">"Korisnik zahteva POTPUN režim TTY"</string>
+    <string name="peerTtyModeHco" msgid="5626377160840915617">"Korisnik zahteva PRENOS ZVUKA za režim TTY"</string>
+    <string name="peerTtyModeVco" msgid="572208600818270944">"Korisnik zahteva PRENOS GLASA za režim TTY"</string>
+    <string name="peerTtyModeOff" msgid="2420380956369226583">"Korisnik zahteva ISKLJUČEN režim TTY"</string>
     <string name="serviceClassVoice" msgid="2065556932043454987">"Voice"</string>
-    <string name="serviceClassData" msgid="4148080018967300248">"Подаци"</string>
-    <string name="serviceClassFAX" msgid="2561653371698904118">"ФАКС"</string>
+    <string name="serviceClassData" msgid="4148080018967300248">"Podaci"</string>
+    <string name="serviceClassFAX" msgid="2561653371698904118">"FAKS"</string>
     <string name="serviceClassSMS" msgid="1547664561704509004">"SMS"</string>
-    <string name="serviceClassDataAsync" msgid="2029856900898545984">"Асинхрони подаци"</string>
-    <string name="serviceClassDataSync" msgid="7895071363569133704">"Синхронизовано"</string>
-    <string name="serviceClassPacket" msgid="1430642951399303804">"Пакет"</string>
-    <string name="serviceClassPAD" msgid="6850244583416306321">"ПОДЛОГА"</string>
-    <string name="roamingText0" msgid="7793257871609854208">"Индикатор роминга је укључен"</string>
-    <string name="roamingText1" msgid="5073028598334616445">"Индикатор роминга је искључен"</string>
-    <string name="roamingText2" msgid="2834048284153110598">"Треперење индикатора роминга"</string>
-    <string name="roamingText3" msgid="831690234035748988">"Изван комшилука"</string>
-    <string name="roamingText4" msgid="2171252529065590728">"Изван зграде"</string>
-    <string name="roamingText5" msgid="4294671587635796641">"Роминг – жељени систем"</string>
-    <string name="roamingText6" msgid="5536156746637992029">"Роминг – доступни систем"</string>
-    <string name="roamingText7" msgid="1783303085512907706">"Роминг – партнер"</string>
-    <string name="roamingText8" msgid="7774800704373721973">"Роминг – премијум партнер"</string>
-    <string name="roamingText9" msgid="1933460020190244004">"Роминг – потпуно функционисање услуге"</string>
-    <string name="roamingText10" msgid="7434767033595769499">"Роминг – делимично функционисање услуге"</string>
-    <string name="roamingText11" msgid="5245687407203281407">"Банер роминга је укључен"</string>
-    <string name="roamingText12" msgid="673537506362152640">"Банер роминга је искључен"</string>
-    <string name="roamingTextSearching" msgid="5323235489657753486">"Претраживање услуге"</string>
-    <string name="wfcRegErrorTitle" msgid="3193072971584858020">"Подешавање позивања преко WiFi-а није успело"</string>
+    <string name="serviceClassDataAsync" msgid="2029856900898545984">"Asinhroni podaci"</string>
+    <string name="serviceClassDataSync" msgid="7895071363569133704">"Sinhronizovano"</string>
+    <string name="serviceClassPacket" msgid="1430642951399303804">"Paket"</string>
+    <string name="serviceClassPAD" msgid="6850244583416306321">"PODLOGA"</string>
+    <string name="roamingText0" msgid="7793257871609854208">"Indikator rominga je uključen"</string>
+    <string name="roamingText1" msgid="5073028598334616445">"Indikator rominga je isključen"</string>
+    <string name="roamingText2" msgid="2834048284153110598">"Treperenje indikatora rominga"</string>
+    <string name="roamingText3" msgid="831690234035748988">"Izvan komšiluka"</string>
+    <string name="roamingText4" msgid="2171252529065590728">"Izvan zgrade"</string>
+    <string name="roamingText5" msgid="4294671587635796641">"Roming – željeni sistem"</string>
+    <string name="roamingText6" msgid="5536156746637992029">"Roming – dostupni sistem"</string>
+    <string name="roamingText7" msgid="1783303085512907706">"Roming – partner"</string>
+    <string name="roamingText8" msgid="7774800704373721973">"Roming – premijum partner"</string>
+    <string name="roamingText9" msgid="1933460020190244004">"Roming – potpuno funkcionisanje usluge"</string>
+    <string name="roamingText10" msgid="7434767033595769499">"Roming – delimično funkcionisanje usluge"</string>
+    <string name="roamingText11" msgid="5245687407203281407">"Baner rominga je uključen"</string>
+    <string name="roamingText12" msgid="673537506362152640">"Baner rominga je isključen"</string>
+    <string name="roamingTextSearching" msgid="5323235489657753486">"Pretraživanje usluge"</string>
+    <string name="wfcRegErrorTitle" msgid="3193072971584858020">"Podešavanje pozivanja preko WiFi-a nije uspelo"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="468830943567116703">"Да бисте упућивали позиве и слали поруке преко WiFi-а, прво затражите од мобилног оператера да вам омогући ову услугу. Затим у Подешавањима поново укључите Позивање преко WiFi-а. (кôд грешке: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
+    <item msgid="468830943567116703">"Da biste upućivali pozive i slali poruke preko WiFi-a, prvo zatražite od mobilnog operatera da vam omogući ovu uslugu. Zatim u Podešavanjima ponovo uključite Pozivanje preko WiFi-a. (kôd greške: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="4795145070505729156">"Проблем у вези са регистровањем позивања преко Wi‑Fi-ја код мобилног оператера: <xliff:g id="CODE">%1$s</xliff:g>"</item>
+    <item msgid="4795145070505729156">"Problem u vezi sa registrovanjem pozivanja preko Wi‑Fi-ja kod mobilnog operatera: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
     <!-- no translation found for wfcSpnFormat_spn (2982505428519096311) -->
     <skip />
-    <string name="wfcSpnFormat_spn_wifi_calling" msgid="3165949348000906194">"<xliff:g id="SPN">%s</xliff:g> позивање преко WiFi-а"</string>
-    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="3836827895369365298">"<xliff:g id="SPN">%s</xliff:g> – позивање преко WiFi-а"</string>
-    <string name="wfcSpnFormat_wlan_call" msgid="4895315549916165700">"WLAN позив"</string>
-    <string name="wfcSpnFormat_spn_wlan_call" msgid="255919245825481510">"<xliff:g id="SPN">%s</xliff:g> WLAN позив"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="3165949348000906194">"<xliff:g id="SPN">%s</xliff:g> pozivanje preko WiFi-a"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="3836827895369365298">"<xliff:g id="SPN">%s</xliff:g> – pozivanje preko WiFi-a"</string>
+    <string name="wfcSpnFormat_wlan_call" msgid="4895315549916165700">"WLAN poziv"</string>
+    <string name="wfcSpnFormat_spn_wlan_call" msgid="255919245825481510">"<xliff:g id="SPN">%s</xliff:g> WLAN poziv"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="7232899594327126970">"<xliff:g id="SPN">%s</xliff:g> WiFi"</string>
-    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="8383917598312067365">"Позивање преко WiFi-а | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="8383917598312067365">"Pozivanje preko WiFi-a | <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_vowifi" msgid="6865214948822061486">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
-    <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Позивање преко WiFi-а"</string>
+    <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Pozivanje preko WiFi-a"</string>
     <string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"WiFi"</string>
-    <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Позивање преко WiFi-а"</string>
+    <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Pozivanje preko WiFi-a"</string>
     <string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
-    <string name="wifi_calling_off_summary" msgid="5626710010766902560">"Искључено"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Позивање преко WiFi-а"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Позив преко мобилне мреже"</string>
-    <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Само WiFi"</string>
+    <string name="wifi_calling_off_summary" msgid="5626710010766902560">"Isključeno"</string>
+    <string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Pozivanje preko WiFi-a"</string>
+    <string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Poziv preko mobilne mreže"</string>
+    <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Samo WiFi"</string>
     <!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
     <skip />
-    <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> резервни начин за позивање"</string>
-    <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Није прослеђено"</string>
+    <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> rezervni način za pozivanje"</string>
+    <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nije prosleđeno"</string>
     <string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
-    <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> након <xliff:g id="TIME_DELAY">{2}</xliff:g> секунде/и"</string>
-    <string name="cfTemplateRegistered" msgid="5619930473441550596">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Није прослеђено"</string>
-    <string name="cfTemplateRegisteredTime" msgid="5222794399642525045">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Није прослеђено"</string>
-    <string name="fcComplete" msgid="1080909484660507044">"Кôд функције је извршен."</string>
-    <string name="fcError" msgid="5325116502080221346">"Проблеми са везом или неважећи кôд функције."</string>
-    <string name="httpErrorOk" msgid="6206751415788256357">"Потврди"</string>
-    <string name="httpError" msgid="3406003584150566720">"Дошло је до грешке на мрежи."</string>
-    <string name="httpErrorLookup" msgid="3099834738227549349">"Није могуће пронаћи URL адресу"</string>
-    <string name="httpErrorUnsupportedAuthScheme" msgid="3976195595501606787">"Шема потврда аутентичности сајта није подржана."</string>
-    <string name="httpErrorAuth" msgid="469553140922938968">"Није могуће потврдити аутентичност."</string>
-    <string name="httpErrorProxyAuth" msgid="7229662162030113406">"Потврда идентитета преко прокси сервера није успела."</string>
-    <string name="httpErrorConnect" msgid="3295081579893205617">"Није могуће повезати се са сервером."</string>
-    <string name="httpErrorIO" msgid="3860318696166314490">"Није могуће комуницирати са сервером. Пробајте поново касније."</string>
-    <string name="httpErrorTimeout" msgid="7446272815190334204">"Веза са сервером је истекла."</string>
-    <string name="httpErrorRedirectLoop" msgid="8455757777509512098">"Страница садржи превише веза за преусмеравање са сервера."</string>
-    <string name="httpErrorUnsupportedScheme" msgid="2664108769858966374">"Протокол није подржан."</string>
-    <string name="httpErrorFailedSslHandshake" msgid="546319061228876290">"Није могуће успоставити безбедну везу."</string>
-    <string name="httpErrorBadUrl" msgid="754447723314832538">"Страницу није могуће отворити зато што је URL адреса неважећа."</string>
-    <string name="httpErrorFile" msgid="3400658466057744084">"Није могуће приступити датотеци."</string>
-    <string name="httpErrorFileNotFound" msgid="5191433324871147386">"Није могуће пронаћи тражену датотеку."</string>
-    <string name="httpErrorTooManyRequests" msgid="2149677715552037198">"Превише захтева се обрађује. Пробајте поново касније."</string>
-    <string name="notification_title" msgid="5783748077084481121">"Грешка при пријављивању за <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
-    <string name="contentServiceSync" msgid="2341041749565687871">"Синхронизација"</string>
-    <string name="contentServiceSyncNotificationTitle" msgid="5766411446676388623">"Синхронизација није успела"</string>
-    <string name="contentServiceTooManyDeletesNotificationDesc" msgid="4562226280528716090">"Превише покушаја брисања садржаја <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
-    <string name="low_memory" product="tablet" msgid="5557552311566179924">"Меморија таблета је пуна! Избришите неке датотеке да бисте ослободили простор."</string>
-    <string name="low_memory" product="watch" msgid="3479447988234030194">"Меморија сата је пуна. Избришите неке датотеке да бисте ослободили простор."</string>
-    <string name="low_memory" product="tv" msgid="6663680413790323318">"Меморијски простор на Android TV уређају је пун. Избришите неке датотеке да бисте ослободили простор."</string>
-    <string name="low_memory" product="default" msgid="2539532364144025569">"Меморија телефона је пуна! Избришите неке датотеке да бисте ослободили простор."</string>
-    <string name="ssl_ca_cert_warning" msgid="7233573909730048571">"{count,plural, =1{Инсталиран је ауторитет за издавање сертификата}one{Инсталирани су ауторитети за издавање сертификата}few{Инсталирани су ауторитети за издавање сертификата}other{Инсталирани су ауторитети за издавање сертификата}}"</string>
-    <string name="ssl_ca_cert_noti_by_unknown" msgid="4961102218216815242">"Од стране непознате треће стране"</string>
-    <string name="ssl_ca_cert_noti_by_administrator" msgid="4564941950768783879">"Од стране администратора пословног профила"</string>
-    <string name="ssl_ca_cert_noti_managed" msgid="217337232273211674">"Од стране <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
-    <string name="work_profile_deleted" msgid="5891181538182009328">"Пословни профил је избрисан"</string>
-    <string name="work_profile_deleted_details" msgid="3773706828364418016">"Апликација за администраторе на пословном профилу недостаје или је оштећена. Због тога су пословни профил и повезани подаци избрисани. Обратите се администратору за помоћ."</string>
-    <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Пословни профил више није доступан на овом уређају"</string>
-    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Превише покушаја уноса лозинке"</string>
-    <string name="device_ownership_relinquished" msgid="4080886992183195724">"Администратор је уступио уређај за личну употребу"</string>
-    <string name="network_logging_notification_title" msgid="554983187553845004">"Уређајем се управља"</string>
-    <string name="network_logging_notification_text" msgid="1327373071132562512">"Организација управља овим уређајем и може да надгледа мрежни саобраћај. Додирните за детаље."</string>
-    <string name="location_changed_notification_title" msgid="3620158742816699316">"Апликације могу да приступају вашој локацији"</string>
-    <string name="location_changed_notification_text" msgid="7158423339982706912">"Обратите се ИТ администратору да бисте сазнали више"</string>
-    <string name="geofencing_service" msgid="3826902410740315456">"Услуга виртуелног географског опсега"</string>
-    <string name="country_detector" msgid="7023275114706088854">"Детектор земље"</string>
-    <string name="location_service" msgid="2439187616018455546">"Услуга локације"</string>
-    <string name="gnss_service" msgid="8907781262179951385">"GNSS услуга"</string>
-    <string name="sensor_notification_service" msgid="7474531979178682676">"Услуга обавештења сензора"</string>
-    <string name="twilight_service" msgid="8964898045693187224">"Услуга Сумрак"</string>
-    <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS услуга за ажурирање времена"</string>
-    <string name="device_policy_manager_service" msgid="5085762851388850332">"Услуга Менаџер смерница за уређаје"</string>
-    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Услуга Менаџер препознавања музике"</string>
-    <string name="factory_reset_warning" msgid="6858705527798047809">"Уређај ће бити обрисан"</string>
-    <string name="factory_reset_message" msgid="2657049595153992213">"Не можете да користите ову апликацију за администраторе. Уређај ће сада бити обрисан.\n\nАко имате питања, контактирајте администратора организације."</string>
-    <string name="printing_disabled_by" msgid="3517499806528864633">"Штампање је онемогућила апликација <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
-    <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Укључите пословни профил"</string>
-    <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Личне апликације су блокиране док не укључите пословни профил"</string>
-    <string name="personal_apps_suspension_soon_text" msgid="8123898693479590">"Личне апликације ће бити блокиране: <xliff:g id="DATE">%1$s</xliff:g> у <xliff:g id="TIME">%2$s</xliff:g>. ИТ администратор не дозвољава да пословни профил буде искључен дуже од <xliff:g id="NUMBER">%3$d</xliff:g> дана."</string>
-    <string name="personal_apps_suspended_turn_profile_on" msgid="2758012869627513689">"Укључи"</string>
-    <string name="me" msgid="6207584824693813140">"Ја"</string>
-    <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Опције за таблет"</string>
-    <string name="power_dialog" product="tv" msgid="7792839006640933763">"Опције Android TV-а"</string>
-    <string name="power_dialog" product="default" msgid="1107775420270203046">"Опције телефона"</string>
-    <string name="silent_mode" msgid="8796112363642579333">"Нечујни режим"</string>
-    <string name="turn_on_radio" msgid="2961717788170634233">"Укључи бежични сигнал"</string>
-    <string name="turn_off_radio" msgid="7222573978109933360">"Искључи бежични сигнал"</string>
-    <string name="screen_lock" msgid="2072642720826409809">"Закључај екран"</string>
-    <string name="power_off" msgid="4111692782492232778">"Угаси"</string>
-    <string name="silent_mode_silent" msgid="5079789070221150912">"Звоно је искључено"</string>
-    <string name="silent_mode_vibrate" msgid="8821830448369552678">"Вибрација звона"</string>
-    <string name="silent_mode_ring" msgid="6039011004781526678">"Звоно је укључено"</string>
-    <string name="reboot_to_update_title" msgid="2125818841916373708">"Android ажурирање система"</string>
-    <string name="reboot_to_update_prepare" msgid="6978842143587422365">"Ажурирање се припрема…"</string>
-    <string name="reboot_to_update_package" msgid="4644104795527534811">"Пакет ажурирања се обрађује..."</string>
-    <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_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>
-    <string name="shutdown_confirm" product="default" msgid="136816458966692315">"Телефон ће се искључити."</string>
-    <string name="shutdown_confirm_question" msgid="796151167261608447">"Да ли желите да искључите телефон?"</string>
-    <string name="reboot_safemode_title" msgid="5853949122655346734">"Рестартуј систем у безбедном режиму"</string>
-    <string name="reboot_safemode_confirm" msgid="1658357874737219624">"Да ли желите да поново покренете систем у безбедном режиму? Ово ће онемогућити све инсталиране апликације независних произвођача. Оне ће бити враћене када поново покренете систем."</string>
-    <string name="recent_tasks_title" msgid="8183172372995396653">"Недавно"</string>
-    <string name="no_recent_tasks" msgid="9063946524312275906">"Нема недавних апликација."</string>
-    <string name="global_actions" product="tablet" msgid="4412132498517933867">"Опције за таблет"</string>
-    <string name="global_actions" product="tv" msgid="3871763739487450369">"Опције Android TV-а"</string>
-    <string name="global_actions" product="default" msgid="6410072189971495460">"Опције телефона"</string>
-    <string name="global_action_lock" msgid="6949357274257655383">"Закључај екран"</string>
-    <string name="global_action_power_off" msgid="4404936470711393203">"Угаси"</string>
-    <string name="global_action_power_options" msgid="1185286119330160073">"Напајање"</string>
-    <string name="global_action_restart" msgid="4678451019561687074">"Рестартуј"</string>
-    <string name="global_action_emergency" msgid="1387617624177105088">"Хитан позив"</string>
-    <string name="global_action_bug_report" msgid="5127867163044170003">"Извештај о грешци"</string>
-    <string name="global_action_logout" msgid="6093581310002476511">"Заврши сесију"</string>
-    <string name="global_action_screenshot" msgid="2610053466156478564">"Снимак екрана"</string>
-    <string name="bugreport_title" msgid="8549990811777373050">"Извештај о грешци"</string>
-    <string name="bugreport_message" msgid="5212529146119624326">"Овим ће се прикупити информације о тренутном стању уређаја како би биле послате у поруци е-поште. Од започињања извештаја о грешци до тренутка за његово слање проћи ће неко време; будите стрпљиви."</string>
-    <string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Интерактив. извештај"</string>
-    <string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"Користите ово у већини случајева. То вам омогућава да пратите напредак извештаја, да уносите додатне детаље о проблему и да снимате снимке екрана. Вероватно ће изоставити неке мање коришћене одељке за које прављење извештаја дуго траје."</string>
-    <string name="bugreport_option_full_title" msgid="7681035745950045690">"Комплетан извештај"</string>
-    <string name="bugreport_option_full_summary" msgid="1975130009258435885">"Користите ову опцију ради минималних системских сметњи када уређај не реагује, преспор је или су вам потребни сви одељци извештаја. Не дозвољава вам унос додатних детаља нити снимање додатних снимака екрана."</string>
-    <string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{Направићемо снимак екрана ради извештаја о грешци за # секунду.}one{Направићемо снимак екрана ради извештаја о грешци за # секунду.}few{Направићемо снимак екрана ради извештаја о грешци за # секунде.}other{Направићемо снимак екрана ради извештаја о грешци за # секунди.}}"</string>
-    <string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"Екран са извештајем о грешци је снимљен"</string>
-    <string name="bugreport_screenshot_failure_toast" msgid="6736320861311294294">"Снимање екрана са извештајем о грешци није успело"</string>
-    <string name="global_action_toggle_silent_mode" msgid="8464352592860372188">"Нечујни режим"</string>
-    <string name="global_action_silent_mode_on_status" msgid="2371892537738632013">"Звук је ИСКЉУЧЕН"</string>
-    <string name="global_action_silent_mode_off_status" msgid="6608006545950920042">"Звук је УКЉУЧЕН"</string>
-    <string name="global_actions_toggle_airplane_mode" msgid="6911684460146916206">"Режим рада у авиону"</string>
-    <string name="global_actions_airplane_mode_on_status" msgid="5508025516695361936">"Режим рада у авиону је УКЉУЧЕН"</string>
-    <string name="global_actions_airplane_mode_off_status" msgid="8522219771500505475">"Режим рада у авиону је ИСКЉУЧЕН"</string>
-    <string name="global_action_settings" msgid="4671878836947494217">"Подешавања"</string>
-    <string name="global_action_assist" msgid="2517047220311505805">"Помоћ"</string>
-    <string name="global_action_voice_assist" msgid="6655788068555086695">"Гласовна помоћ"</string>
-    <string name="global_action_lockdown" msgid="2475471405907902963">"Закључавање"</string>
+    <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> nakon <xliff:g id="TIME_DELAY">{2}</xliff:g> sekunde/i"</string>
+    <string name="cfTemplateRegistered" msgid="5619930473441550596">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nije prosleđeno"</string>
+    <string name="cfTemplateRegisteredTime" msgid="5222794399642525045">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nije prosleđeno"</string>
+    <string name="fcComplete" msgid="1080909484660507044">"Kôd funkcije je izvršen."</string>
+    <string name="fcError" msgid="5325116502080221346">"Problemi sa vezom ili nevažeći kôd funkcije."</string>
+    <string name="httpErrorOk" msgid="6206751415788256357">"Potvrdi"</string>
+    <string name="httpError" msgid="3406003584150566720">"Došlo je do greške na mreži."</string>
+    <string name="httpErrorLookup" msgid="3099834738227549349">"Nije moguće pronaći URL adresu"</string>
+    <string name="httpErrorUnsupportedAuthScheme" msgid="3976195595501606787">"Šema potvrda autentičnosti sajta nije podržana."</string>
+    <string name="httpErrorAuth" msgid="469553140922938968">"Nije moguće potvrditi autentičnost."</string>
+    <string name="httpErrorProxyAuth" msgid="7229662162030113406">"Potvrda identiteta preko proksi servera nije uspela."</string>
+    <string name="httpErrorConnect" msgid="3295081579893205617">"Nije moguće povezati se sa serverom."</string>
+    <string name="httpErrorIO" msgid="3860318696166314490">"Nije moguće komunicirati sa serverom. Probajte ponovo kasnije."</string>
+    <string name="httpErrorTimeout" msgid="7446272815190334204">"Veza sa serverom je istekla."</string>
+    <string name="httpErrorRedirectLoop" msgid="8455757777509512098">"Stranica sadrži previše veza za preusmeravanje sa servera."</string>
+    <string name="httpErrorUnsupportedScheme" msgid="2664108769858966374">"Protokol nije podržan."</string>
+    <string name="httpErrorFailedSslHandshake" msgid="546319061228876290">"Nije moguće uspostaviti bezbednu vezu."</string>
+    <string name="httpErrorBadUrl" msgid="754447723314832538">"Stranicu nije moguće otvoriti zato što je URL adresa nevažeća."</string>
+    <string name="httpErrorFile" msgid="3400658466057744084">"Nije moguće pristupiti datoteci."</string>
+    <string name="httpErrorFileNotFound" msgid="5191433324871147386">"Nije moguće pronaći traženu datoteku."</string>
+    <string name="httpErrorTooManyRequests" msgid="2149677715552037198">"Previše zahteva se obrađuje. Probajte ponovo kasnije."</string>
+    <string name="notification_title" msgid="5783748077084481121">"Greška pri prijavljivanju za <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
+    <string name="contentServiceSync" msgid="2341041749565687871">"Sinhronizacija"</string>
+    <string name="contentServiceSyncNotificationTitle" msgid="5766411446676388623">"Sinhronizacija nije uspela"</string>
+    <string name="contentServiceTooManyDeletesNotificationDesc" msgid="4562226280528716090">"Previše pokušaja brisanja sadržaja <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
+    <string name="low_memory" product="tablet" msgid="5557552311566179924">"Memorija tableta je puna! Izbrišite neke datoteke da biste oslobodili prostor."</string>
+    <string name="low_memory" product="watch" msgid="3479447988234030194">"Memorija sata je puna. Izbrišite neke datoteke da biste oslobodili prostor."</string>
+    <string name="low_memory" product="tv" msgid="6663680413790323318">"Memorijski prostor na Android TV uređaju je pun. Izbrišite neke datoteke da biste oslobodili prostor."</string>
+    <string name="low_memory" product="default" msgid="2539532364144025569">"Memorija telefona je puna! Izbrišite neke datoteke da biste oslobodili prostor."</string>
+    <string name="ssl_ca_cert_warning" msgid="7233573909730048571">"{count,plural, =1{Instaliran je autoritet za izdavanje sertifikata}one{Instalirani su autoriteti za izdavanje sertifikata}few{Instalirani su autoriteti za izdavanje sertifikata}other{Instalirani su autoriteti za izdavanje sertifikata}}"</string>
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4961102218216815242">"Od strane nepoznate treće strane"</string>
+    <string name="ssl_ca_cert_noti_by_administrator" msgid="4564941950768783879">"Od strane administratora poslovnog profila"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="217337232273211674">"Od strane <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
+    <string name="work_profile_deleted" msgid="5891181538182009328">"Poslovni profil je izbrisan"</string>
+    <string name="work_profile_deleted_details" msgid="3773706828364418016">"Aplikacija za administratore na poslovnom profilu nedostaje ili je oštećena. Zbog toga su poslovni profil i povezani podaci izbrisani. Obratite se administratoru za pomoć."</string>
+    <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Poslovni profil više nije dostupan na ovom uređaju"</string>
+    <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Previše pokušaja unosa lozinke"</string>
+    <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrator je ustupio uređaj za ličnu upotrebu"</string>
+    <string name="network_logging_notification_title" msgid="554983187553845004">"Uređajem se upravlja"</string>
+    <string name="network_logging_notification_text" msgid="1327373071132562512">"Organizacija upravlja ovim uređajem i može da nadgleda mrežni saobraćaj. Dodirnite za detalje."</string>
+    <string name="location_changed_notification_title" msgid="3620158742816699316">"Aplikacije mogu da pristupaju vašoj lokaciji"</string>
+    <string name="location_changed_notification_text" msgid="7158423339982706912">"Obratite se IT administratoru da biste saznali više"</string>
+    <string name="geofencing_service" msgid="3826902410740315456">"Usluga virtuelnog geografskog opsega"</string>
+    <string name="country_detector" msgid="7023275114706088854">"Detektor zemlje"</string>
+    <string name="location_service" msgid="2439187616018455546">"Usluga lokacije"</string>
+    <string name="gnss_service" msgid="8907781262179951385">"GNSS usluga"</string>
+    <string name="sensor_notification_service" msgid="7474531979178682676">"Usluga obaveštenja senzora"</string>
+    <string name="twilight_service" msgid="8964898045693187224">"Usluga Sumrak"</string>
+    <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS usluga za ažuriranje vremena"</string>
+    <string name="device_policy_manager_service" msgid="5085762851388850332">"Usluga Menadžer smernica za uređaje"</string>
+    <string name="music_recognition_manager_service" msgid="7481956037950276359">"Usluga Menadžer prepoznavanja muzike"</string>
+    <string name="factory_reset_warning" msgid="6858705527798047809">"Uređaj će biti obrisan"</string>
+    <string name="factory_reset_message" msgid="2657049595153992213">"Ne možete da koristite ovu aplikaciju za administratore. Uređaj će sada biti obrisan.\n\nAko imate pitanja, kontaktirajte administratora organizacije."</string>
+    <string name="printing_disabled_by" msgid="3517499806528864633">"Štampanje je onemogućila aplikacija <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
+    <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Uključite poslovni profil"</string>
+    <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Lične aplikacije su blokirane dok ne uključite poslovni profil"</string>
+    <string name="personal_apps_suspension_soon_text" msgid="8123898693479590">"Lične aplikacije će biti blokirane: <xliff:g id="DATE">%1$s</xliff:g> u <xliff:g id="TIME">%2$s</xliff:g>. IT administrator ne dozvoljava da poslovni profil bude isključen duže od <xliff:g id="NUMBER">%3$d</xliff:g> dana."</string>
+    <string name="personal_apps_suspended_turn_profile_on" msgid="2758012869627513689">"Uključi"</string>
+    <string name="me" msgid="6207584824693813140">"Ja"</string>
+    <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Opcije za tablet"</string>
+    <string name="power_dialog" product="tv" msgid="7792839006640933763">"Opcije Android TV-a"</string>
+    <string name="power_dialog" product="default" msgid="1107775420270203046">"Opcije telefona"</string>
+    <string name="silent_mode" msgid="8796112363642579333">"Nečujni režim"</string>
+    <string name="turn_on_radio" msgid="2961717788170634233">"Uključi bežični signal"</string>
+    <string name="turn_off_radio" msgid="7222573978109933360">"Isključi bežični signal"</string>
+    <string name="screen_lock" msgid="2072642720826409809">"Zaključaj ekran"</string>
+    <string name="power_off" msgid="4111692782492232778">"Ugasi"</string>
+    <string name="silent_mode_silent" msgid="5079789070221150912">"Zvono je isključeno"</string>
+    <string name="silent_mode_vibrate" msgid="8821830448369552678">"Vibracija zvona"</string>
+    <string name="silent_mode_ring" msgid="6039011004781526678">"Zvono je uključeno"</string>
+    <string name="reboot_to_update_title" msgid="2125818841916373708">"Android ažuriranje sistema"</string>
+    <string name="reboot_to_update_prepare" msgid="6978842143587422365">"Ažuriranje se priprema…"</string>
+    <string name="reboot_to_update_package" msgid="4644104795527534811">"Paket ažuriranja se obrađuje..."</string>
+    <string name="reboot_to_update_reboot" msgid="4474726009984452312">"Ponovo se pokreće..."</string>
+    <string name="reboot_to_reset_title" msgid="2226229680017882787">"Resetovanje na fabrička podešavanja"</string>
+    <string name="reboot_to_reset_message" msgid="3347690497972074356">"Ponovo se pokreće..."</string>
+    <string name="shutdown_progress" msgid="5017145516412657345">"Isključivanje…"</string>
+    <string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"Tablet će se isključiti."</string>
+    <string name="shutdown_confirm" product="tv" msgid="7975942887313518330">"Android TV uređaj će se ugasiti."</string>
+    <string name="shutdown_confirm" product="watch" msgid="2977299851200240146">"Sat će se ugasiti."</string>
+    <string name="shutdown_confirm" product="default" msgid="136816458966692315">"Telefon će se isključiti."</string>
+    <string name="shutdown_confirm_question" msgid="796151167261608447">"Da li želite da isključite telefon?"</string>
+    <string name="reboot_safemode_title" msgid="5853949122655346734">"Restartuj sistem u bezbednom režimu"</string>
+    <string name="reboot_safemode_confirm" msgid="1658357874737219624">"Da li želite da ponovo pokrenete sistem u bezbednom režimu? Ovo će onemogućiti sve instalirane aplikacije nezavisnih proizvođača. One će biti vraćene kada ponovo pokrenete sistem."</string>
+    <string name="recent_tasks_title" msgid="8183172372995396653">"Nedavno"</string>
+    <string name="no_recent_tasks" msgid="9063946524312275906">"Nema nedavnih aplikacija."</string>
+    <string name="global_actions" product="tablet" msgid="4412132498517933867">"Opcije za tablet"</string>
+    <string name="global_actions" product="tv" msgid="3871763739487450369">"Opcije Android TV-a"</string>
+    <string name="global_actions" product="default" msgid="6410072189971495460">"Opcije telefona"</string>
+    <string name="global_action_lock" msgid="6949357274257655383">"Zaključaj ekran"</string>
+    <string name="global_action_power_off" msgid="4404936470711393203">"Ugasi"</string>
+    <string name="global_action_power_options" msgid="1185286119330160073">"Napajanje"</string>
+    <string name="global_action_restart" msgid="4678451019561687074">"Restartuj"</string>
+    <string name="global_action_emergency" msgid="1387617624177105088">"Hitan poziv"</string>
+    <string name="global_action_bug_report" msgid="5127867163044170003">"Izveštaj o grešci"</string>
+    <string name="global_action_logout" msgid="6093581310002476511">"Završi sesiju"</string>
+    <string name="global_action_screenshot" msgid="2610053466156478564">"Snimak ekrana"</string>
+    <string name="bugreport_title" msgid="8549990811777373050">"Izveštaj o grešci"</string>
+    <string name="bugreport_message" msgid="5212529146119624326">"Ovim će se prikupiti informacije o trenutnom stanju uređaja kako bi bile poslate u poruci e-pošte. Od započinjanja izveštaja o grešci do trenutka za njegovo slanje proći će neko vreme; budite strpljivi."</string>
+    <string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interaktiv. izveštaj"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"Koristite ovo u većini slučajeva. To vam omogućava da pratite napredak izveštaja, da unosite dodatne detalje o problemu i da snimate snimke ekrana. Verovatno će izostaviti neke manje korišćene odeljke za koje pravljenje izveštaja dugo traje."</string>
+    <string name="bugreport_option_full_title" msgid="7681035745950045690">"Kompletan izveštaj"</string>
+    <string name="bugreport_option_full_summary" msgid="1975130009258435885">"Koristite ovu opciju radi minimalnih sistemskih smetnji kada uređaj ne reaguje, prespor je ili su vam potrebni svi odeljci izveštaja. Ne dozvoljava vam unos dodatnih detalja niti snimanje dodatnih snimaka ekrana."</string>
+    <string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{Napravićemo snimak ekrana radi izveštaja o grešci za # sekundu.}one{Napravićemo snimak ekrana radi izveštaja o grešci za # sekundu.}few{Napravićemo snimak ekrana radi izveštaja o grešci za # sekunde.}other{Napravićemo snimak ekrana radi izveštaja o grešci za # sekundi.}}"</string>
+    <string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"Ekran sa izveštajem o grešci je snimljen"</string>
+    <string name="bugreport_screenshot_failure_toast" msgid="6736320861311294294">"Snimanje ekrana sa izveštajem o grešci nije uspelo"</string>
+    <string name="global_action_toggle_silent_mode" msgid="8464352592860372188">"Nečujni režim"</string>
+    <string name="global_action_silent_mode_on_status" msgid="2371892537738632013">"Zvuk je ISKLJUČEN"</string>
+    <string name="global_action_silent_mode_off_status" msgid="6608006545950920042">"Zvuk je UKLJUČEN"</string>
+    <string name="global_actions_toggle_airplane_mode" msgid="6911684460146916206">"Režim rada u avionu"</string>
+    <string name="global_actions_airplane_mode_on_status" msgid="5508025516695361936">"Režim rada u avionu je UKLJUČEN"</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="8522219771500505475">"Režim rada u avionu je ISKLJUČEN"</string>
+    <string name="global_action_settings" msgid="4671878836947494217">"Podešavanja"</string>
+    <string name="global_action_assist" msgid="2517047220311505805">"Pomoć"</string>
+    <string name="global_action_voice_assist" msgid="6655788068555086695">"Glasovna pomoć"</string>
+    <string name="global_action_lockdown" msgid="2475471405907902963">"Zaključavanje"</string>
     <string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
-    <string name="notification_hidden_text" msgid="2835519769868187223">"Ново обавештење"</string>
-    <string name="notification_channel_virtual_keyboard" msgid="6465975799223304567">"Виртуелна тастатура"</string>
-    <string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Физичка тастатура"</string>
-    <string name="notification_channel_security" msgid="8516754650348238057">"Безбедност"</string>
-    <string name="notification_channel_car_mode" msgid="2123919247040988436">"Режим рада у аутомобилу"</string>
-    <string name="notification_channel_account" msgid="6436294521740148173">"Статус налога"</string>
-    <string name="notification_channel_developer" msgid="1691059964407549150">"Поруке за програмере"</string>
-    <string name="notification_channel_developer_important" msgid="7197281908918789589">"Важне поруке програмера"</string>
-    <string name="notification_channel_updates" msgid="7907863984825495278">"Ажурирања"</string>
-    <string name="notification_channel_network_status" msgid="2127687368725272809">"Статус мреже"</string>
-    <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Обавештења у вези са мрежом"</string>
-    <string name="notification_channel_network_available" msgid="6083697929214165169">"Мрежа је доступна"</string>
-    <string name="notification_channel_vpn" msgid="1628529026203808999">"Статус VPN-а"</string>
-    <string name="notification_channel_device_admin" msgid="6384932669406095506">"Обавештења од ИТ администратора"</string>
-    <string name="notification_channel_alerts" msgid="5070241039583668427">"Обавештења"</string>
-    <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Режим демонстрације за малопродајне објекте"</string>
-    <string name="notification_channel_usb" msgid="1528280969406244896">"USB веза"</string>
-    <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Активна апликација"</string>
-    <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Апликације које троше батерију"</string>
-    <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Увећање"</string>
-    <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Коришћење Приступачности"</string>
-    <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> користи батерију"</string>
-    <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"Апликације (<xliff:g id="NUMBER">%1$d</xliff:g>) користе батерију"</string>
-    <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Додирните за детаље о батерији и потрошњи података"</string>
+    <string name="notification_hidden_text" msgid="2835519769868187223">"Novo obaveštenje"</string>
+    <string name="notification_channel_virtual_keyboard" msgid="6465975799223304567">"Virtuelna tastatura"</string>
+    <string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fizička tastatura"</string>
+    <string name="notification_channel_security" msgid="8516754650348238057">"Bezbednost"</string>
+    <string name="notification_channel_car_mode" msgid="2123919247040988436">"Režim rada u automobilu"</string>
+    <string name="notification_channel_account" msgid="6436294521740148173">"Status naloga"</string>
+    <string name="notification_channel_developer" msgid="1691059964407549150">"Poruke za programere"</string>
+    <string name="notification_channel_developer_important" msgid="7197281908918789589">"Važne poruke programera"</string>
+    <string name="notification_channel_updates" msgid="7907863984825495278">"Ažuriranja"</string>
+    <string name="notification_channel_network_status" msgid="2127687368725272809">"Status mreže"</string>
+    <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Obaveštenja u vezi sa mrežom"</string>
+    <string name="notification_channel_network_available" msgid="6083697929214165169">"Mreža je dostupna"</string>
+    <string name="notification_channel_vpn" msgid="1628529026203808999">"Status VPN-a"</string>
+    <string name="notification_channel_device_admin" msgid="6384932669406095506">"Obaveštenja od IT administratora"</string>
+    <string name="notification_channel_alerts" msgid="5070241039583668427">"Obaveštenja"</string>
+    <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Režim demonstracije za maloprodajne objekte"</string>
+    <string name="notification_channel_usb" msgid="1528280969406244896">"USB veza"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aktivna aplikacija"</string>
+    <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplikacije koje troše bateriju"</string>
+    <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Uvećanje"</string>
+    <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Korišćenje Pristupačnosti"</string>
+    <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> koristi bateriju"</string>
+    <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"Aplikacije (<xliff:g id="NUMBER">%1$d</xliff:g>) koriste bateriju"</string>
+    <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Dodirnite za detalje o bateriji i potrošnji podataka"</string>
     <string name="foreground_service_multiple_separator" msgid="5002287361849863168">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
-    <string name="safeMode" msgid="8974401416068943888">"Безбедни режим"</string>
-    <string name="android_system_label" msgid="5974767339591067210">"Android систем"</string>
-    <string name="user_owner_label" msgid="8628726904184471211">"Пређи на лични профил"</string>
-    <string name="managed_profile_label" msgid="7316778766973512382">"Пређи на пословни профил"</string>
-    <string name="permgrouplab_contacts" msgid="4254143639307316920">"Контакти"</string>
-    <string name="permgroupdesc_contacts" msgid="9163927941244182567">"приступи контактима"</string>
-    <string name="permgrouplab_location" msgid="1858277002233964394">"Локација"</string>
-    <string name="permgroupdesc_location" msgid="1995955142118450685">"приступи локацији овог уређаја"</string>
-    <string name="permgrouplab_calendar" msgid="6426860926123033230">"Календар"</string>
-    <string name="permgroupdesc_calendar" msgid="6762751063361489379">"приступи календару"</string>
+    <string name="safeMode" msgid="8974401416068943888">"Bezbedni režim"</string>
+    <string name="android_system_label" msgid="5974767339591067210">"Android sistem"</string>
+    <string name="user_owner_label" msgid="8628726904184471211">"Pređi na lični profil"</string>
+    <string name="managed_profile_label" msgid="7316778766973512382">"Pređi na poslovni profil"</string>
+    <string name="permgrouplab_contacts" msgid="4254143639307316920">"Kontakti"</string>
+    <string name="permgroupdesc_contacts" msgid="9163927941244182567">"pristupi kontaktima"</string>
+    <string name="permgrouplab_location" msgid="1858277002233964394">"Lokacija"</string>
+    <string name="permgroupdesc_location" msgid="1995955142118450685">"pristupi lokaciji ovog uređaja"</string>
+    <string name="permgrouplab_calendar" msgid="6426860926123033230">"Kalendar"</string>
+    <string name="permgroupdesc_calendar" msgid="6762751063361489379">"pristupi kalendaru"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
-    <string name="permgroupdesc_sms" msgid="5726462398070064542">"шаље и прегледа SMS поруке"</string>
-    <string name="permgrouplab_storage" msgid="17339216290379241">"Фајлови"</string>
-    <string name="permgroupdesc_storage" msgid="5378659041354582769">"приступ фајловима на уређају"</string>
-    <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Музика и звук"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"приступ музици и аудио садржају на уређају"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Слике и видео снимци"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"приступ сликама и видео снимцима на уређају"</string>
-    <string name="permgrouplab_microphone" msgid="2480597427667420076">"Микрофон"</string>
-    <string name="permgroupdesc_microphone" msgid="1047786732792487722">"снима звук"</string>
-    <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Физичке активности"</string>
-    <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"приступ физичким активностима"</string>
-    <string name="permgrouplab_camera" msgid="9090413408963547706">"Камера"</string>
-    <string name="permgroupdesc_camera" msgid="7585150538459320326">"снима слике и видео"</string>
-    <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Уређаји у близини"</string>
-    <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"откривање уређаја у близини и повезивање са њима"</string>
-    <string name="permgrouplab_calllog" msgid="7926834372073550288">"Евиденције позива"</string>
-    <string name="permgroupdesc_calllog" msgid="2026996642917801803">"читање и писање евиденције позива на телефону"</string>
-    <string name="permgrouplab_phone" msgid="570318944091926620">"Телефон"</string>
-    <string name="permgroupdesc_phone" msgid="270048070781478204">"упућује телефонске позиве и управља њима"</string>
-    <string name="permgrouplab_sensors" msgid="9134046949784064495">"Сензори за тело"</string>
-    <string name="permgroupdesc_sensors" msgid="2610631290633747752">"приступа подацима сензора о виталним функцијама"</string>
-    <string name="permgrouplab_notifications" msgid="5472972361980668884">"Обавештења"</string>
-    <string name="permgroupdesc_notifications" msgid="4608679556801506580">"приказивање обавештења"</string>
-    <string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"да преузима садржај прозора"</string>
-    <string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Проверава садржај прозора са којим остварујете интеракцију."</string>
-    <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"да укључи Истраживања додиром"</string>
-    <string name="capability_desc_canRequestTouchExploration" msgid="4394677060796752976">"Ставке које додирнете ће бити изговорене наглас, а можете да се крећете по екрану покретима."</string>
-    <string name="capability_title_canRequestFilterKeyEvents" msgid="2772371671541753254">"да прати текст који уносите"</string>
-    <string name="capability_desc_canRequestFilterKeyEvents" msgid="2381315802405773092">"Обухвата личне податке као што су бројеви кредитних картица и лозинке."</string>
-    <string name="capability_title_canControlMagnification" msgid="7701572187333415795">"да управља увећањем приказа"</string>
-    <string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"Управља нивоом зумирања приказа и одређивањем положаја."</string>
-    <string name="capability_title_canPerformGestures" msgid="9106545062106728987">"Обављање покрета"</string>
-    <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Може да додирује, листа, скупља приказ и обавља друге покрете."</string>
-    <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Покрети за отисак прста"</string>
-    <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Може да региструје покрете на сензору за отисак прста на уређају."</string>
-    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Направи снимак екрана"</string>
-    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Може да направи снимак екрана."</string>
-    <string name="permlab_statusBar" msgid="8798267849526214017">"онемогућавање или измена статусне траке"</string>
-    <string name="permdesc_statusBar" msgid="5809162768651019642">"Дозвољава апликацији да онемогући статусну траку или да додаје и уклања системске иконе."</string>
-    <string name="permlab_statusBarService" msgid="2523421018081437981">"функционисање као статусна трака"</string>
-    <string name="permdesc_statusBarService" msgid="6652917399085712557">"Дозвољава апликацији да функционише као статусна трака."</string>
-    <string name="permlab_expandStatusBar" msgid="1184232794782141698">"проширење/скупљање статусне траке"</string>
-    <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Дозвољава апликацији да проширује или скупља статусну траку."</string>
-    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"приказује обавештења као активности преко целог екрана на закључаном уређају"</string>
-    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Омогућава апликацији да на закључаном уређају приказује обавештења као активности преко целог екрана."</string>
-    <string name="permlab_install_shortcut" msgid="7451554307502256221">"Инсталирање пречица"</string>
-    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"да додају пречице на почетни екран без интервенције корисника."</string>
-    <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"деинсталирање пречица"</string>
-    <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Омогућава апликацији да уклања пречице са почетног екрана без интервенције корисника."</string>
-    <string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"преусмеравање одлазних позива"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="7833149750590606334">"Дозвољава апликацији да види који број се бира при одлазном позиву уз опцију да преусмери позив на други број или га потпуно прекине."</string>
-    <string name="permlab_answerPhoneCalls" msgid="4131324833663725855">"одговарај на телефонске позиве"</string>
-    <string name="permdesc_answerPhoneCalls" msgid="894386681983116838">"Дозвољава апликацији да одговори на долазни телефонски позив."</string>
-    <string name="permlab_receiveSms" msgid="505961632050451881">"пријем текстуалних порука (SMS)"</string>
-    <string name="permdesc_receiveSms" msgid="1797345626687832285">"Дозвољава апликацији да прима и обрађује SMS поруке. То значи да апликација може да надгледа или брише поруке које се шаљу уређају, а да вам их не прикаже."</string>
-    <string name="permlab_receiveMms" msgid="4000650116674380275">"пријем текстуалних порука (MMS)"</string>
-    <string name="permdesc_receiveMms" msgid="958102423732219710">"Дозвољава апликацији да прима и обрађује MMS поруке. То значи да апликација може да надгледа или брише поруке које се шаљу уређају, а да вам их не прикаже."</string>
-    <string name="permlab_bindCellBroadcastService" msgid="586746677002040651">"Прослеђивање порука за мобилне уређаје на локалитету"</string>
-    <string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"Дозвољава апликацији да се везује за модул порука за мобилне уређаје на локалитету да би прослеђивала поруке за мобилне уређаје на локалитету онако како су примљене. Обавештења порука за мобилне уређаје на локалитету се на неким локацијама примају као упозорења на хитне случајеве. Злонамерне апликације могу да утичу на перформансе или ометају рад уређаја када се прими порука о хитном случају за мобилне уређаје на локалитету."</string>
-    <string name="permlab_manageOngoingCalls" msgid="281244770664231782">"Управљање одлазним позивима"</string>
-    <string name="permdesc_manageOngoingCalls" msgid="7003138133829915265">"Омогућава апликацији да види детаље о одлазним позивима на уређају и да контролише те позиве."</string>
-    <string name="permlab_readCellBroadcasts" msgid="5869884450872137693">"читање порука инфо сервиса"</string>
-    <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"Омогућава апликацији да чита поруке инфо сервиса које уређај прима. Упозорења инфо сервиса се на неким локацијама примају као упозорења на хитне случајеве. Злонамерне апликације могу да утичу на перформансе или ометају функционисање уређаја када се прими порука инфо сервиса о хитном случају."</string>
-    <string name="permlab_subscribedFeedsRead" msgid="217624769238425461">"читање пријављених фидова"</string>
-    <string name="permdesc_subscribedFeedsRead" msgid="6911349196661811865">"Дозвољава апликацији да преузима детаље о тренутно синхронизованим фидовима."</string>
-    <string name="permlab_sendSms" msgid="7757368721742014252">"шаље и прегледа SMS поруке"</string>
-    <string name="permdesc_sendSms" msgid="6757089798435130769">"Дозвољава апликацији да шаље SMS поруке. Ово може да доведе до неочекиваних трошкова. Злонамерне апликације могу да шаљу поруке без ваше потврде, што може да изазове трошкове."</string>
-    <string name="permlab_readSms" msgid="5164176626258800297">"читање текстуалних порука (SMS или MMS)"</string>
-    <string name="permdesc_readSms" product="tablet" msgid="7912990447198112829">"Ова апликација може да чита све SMS (текстуалне) поруке које се чувају на таблету."</string>
-    <string name="permdesc_readSms" product="tv" msgid="3054753345758011986">"Ова апликација може да чита све SMS (текстуалне) поруке које се чувају на Android TV уређају."</string>
-    <string name="permdesc_readSms" product="default" msgid="774753371111699782">"Ова апликација може да чита све SMS (текстуалне) поруке које се чувају на телефону."</string>
-    <string name="permlab_receiveWapPush" msgid="4223747702856929056">"пријем текстуалних порука (WAP)"</string>
-    <string name="permdesc_receiveWapPush" msgid="1638677888301778457">"Дозвољава апликацији да прима и обрађује WAP поруке. Ова дозвола укључује могућност праћења или брисања порука које вам се шаљу, а које вам се не приказују."</string>
-    <string name="permlab_getTasks" msgid="7460048811831750262">"преузимање покренутих апликација"</string>
-    <string name="permdesc_getTasks" msgid="7388138607018233726">"Дозвољава апликацији да преузима информације о актуелним и недавно покренутим задацима. Ово може да омогући апликацији да открије информације о томе које се апликације користе на уређају."</string>
-    <string name="permlab_manageProfileAndDeviceOwners" msgid="639849495253987493">"управљање власницима профила и уређаја"</string>
-    <string name="permdesc_manageProfileAndDeviceOwners" msgid="7304240671781989283">"Дозвољава апликацији да подеси власнике профила и власника уређаја."</string>
-    <string name="permlab_reorderTasks" msgid="7598562301992923804">"промена редоследа покренутих апликација"</string>
-    <string name="permdesc_reorderTasks" msgid="8796089937352344183">"Дозвољава апликацији да премешта задатке у први план и у позадину. Апликација може да ради ово без вашег уноса."</string>
-    <string name="permlab_enableCarMode" msgid="893019409519325311">"омогућавање режима рада у аутомобилу"</string>
-    <string name="permdesc_enableCarMode" msgid="56419168820473508">"Дозвољава апликацији да омогући режим рада у аутомобилу."</string>
-    <string name="permlab_killBackgroundProcesses" msgid="6559320515561928348">"затварање других апликација"</string>
-    <string name="permdesc_killBackgroundProcesses" msgid="2357013583055434685">"Дозвољава апликацији да заустави позадинске процесе других апликација. Ово може да заустави друге апликације."</string>
-    <string name="permlab_systemAlertWindow" msgid="5757218350944719065">"Ова апликација може да се приказује преко других апликација"</string>
-    <string name="permdesc_systemAlertWindow" msgid="1145660714855738308">"Ова апликација може да се приказује преко других апликација или других делова делова екрана. То може да омета стандардно коришћење апликација и начин на који се друге апликације приказују."</string>
-    <string name="permlab_runInBackground" msgid="541863968571682785">"покретање у позадини"</string>
-    <string name="permdesc_runInBackground" msgid="4344539472115495141">"Ова апликација може да се покреће у позадини. То може брже да истроши батерију."</string>
-    <string name="permlab_useDataInBackground" msgid="783415807623038947">"коришћење података у позадини"</string>
-    <string name="permdesc_useDataInBackground" msgid="1230753883865891987">"Ова апликација може да користи податке у позадини. То може да повећа потрошњу података."</string>
-    <string name="permlab_persistentActivity" msgid="464970041740567970">"омогућавање непрекидне активности апликације"</string>
-    <string name="permdesc_persistentActivity" product="tablet" msgid="6055271149187369916">"Дозвољава апликацији да учини сопствене компоненте трајним у меморији. Ово може да ограничи меморију доступну другим апликацијама и успори таблет."</string>
-    <string name="permdesc_persistentActivity" product="tv" msgid="6800526387664131321">"Дозвољава апликацији да трајно задржи неке своје делове у меморији. Ово може да ограничи меморију доступну другим апликацијама и успори Android TV уређај."</string>
-    <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Дозвољава апликацији да учини сопствене компоненте трајним у меморији. Ово може да ограничи меморију доступну другим апликацијама и успори телефон."</string>
-    <string name="permlab_foregroundService" msgid="1768855976818467491">"покрени услугу у првом плану"</string>
-    <string name="permdesc_foregroundService" msgid="8720071450020922795">"Дозвољава апликацији да користи услуге у првом плану."</string>
-    <string name="permlab_getPackageSize" msgid="375391550792886641">"мерење меморијског простора у апликацији"</string>
-    <string name="permdesc_getPackageSize" msgid="742743530909966782">"Дозвољава апликацији да преузме величине кôда, података и кеша."</string>
-    <string name="permlab_writeSettings" msgid="8057285063719277394">"измена подешавања система"</string>
-    <string name="permdesc_writeSettings" msgid="8293047411196067188">"Дозвољава апликацији да мења податке о подешавању система. Злонамерне апликације могу да оштете конфигурацију система."</string>
-    <string name="permlab_receiveBootCompleted" msgid="6643339400247325379">"покретање при покретању система"</string>
-    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="5565659082718177484">"Омогућава да се апликација покрене одмах након покретања система. То може да успори покретање таблета, при чему ова апликација може да успори функционисање целог таблета тиме што ће увек бити активна."</string>
-    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"Дозвољава апликацији да се покрене одмах по укључивању система. То може да успори покретање Android TV уређаја и апликација може да успори функционисање уређаја у целини тако што ће увек бити активна."</string>
-    <string name="permdesc_receiveBootCompleted" product="default" msgid="7912677044558690092">"Омогућава да се апликација покрене чим се систем покрене. То може да успори покретање телефона, при чему ова апликација може да успори функционисање целог телефона тиме што ће увек бити активна."</string>
-    <string name="permlab_broadcastSticky" msgid="4552241916400572230">"слање пријемчивих емитовања"</string>
-    <string name="permdesc_broadcastSticky" product="tablet" msgid="5058486069846384013">"Дозвољава апликацији да шаље пријемчива емитовања, која остају по завршетку емитовања. Прекомерна употреба може да успори или дестабилизује таблет тако што ће га приморати да троши превише меморије."</string>
-    <string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Дозвољава апликацији да шаље лепљива емитовања која остају по завршетку емитовања. Прекомерна употреба може да успори или дестабилизује Android TV уређај тако што ће га приморати да троши превише меморије."</string>
-    <string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Дозвољава апликацији да шаље пријемчива емитовања, која остају по завршетку емитовања. Прекомерна употреба може да успори или дестабилизује телефон тако што ће га приморати да троши превише меморије."</string>
-    <string name="permlab_readContacts" msgid="8776395111787429099">"читање контаката"</string>
-    <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Дозвољава апликацији да чита податке о контактима које чувате на таблету. Апликације ће имати приступ и налозима на вашем таблету на којима су направљени контакти. Ту могу да спадају налози које су отвориле апликације које сте инсталирали. Ова дозвола омогућава апликацијама да чувају податке о контактима и злонамерне апликације могу да деле податке о контактима без вашег знања."</string>
-    <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Дозвољава апликацији да чита податке о контактима које чувате на Android TV уређају. Апликације ће имати приступ и налозима на вашем Android TV уређају на којима су направљени контакти. Ту могу да спадају налози које су отвориле апликације које сте инсталирали. Ова дозвола омогућава апликацијама да чувају податке о контактима и злонамерне апликације могу да деле податке о контактима без вашег знања."</string>
-    <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Дозвољава апликацији да чита податке о контактима које чувате на телефону. Апликације ће имати приступ и налозима на вашем телефону на којима су направљени контакти. Ту могу да спадају налози које су отвориле апликације које сте инсталирали. Ова дозвола омогућава апликацијама да чувају податке о контактима и злонамерне апликације могу да деле податке о контактима без вашег знања."</string>
-    <string name="permlab_writeContacts" msgid="8919430536404830430">"измена контаката"</string>
-    <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Дозвољава апликацији да мења податке о контактима које чувате на таблету. Ова дозвола омогућава апликацијама да бришу податке о контактима."</string>
-    <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Дозвољава апликацији да мења податке о контактима које чувате на Android TV уређају. Ова дозвола омогућава апликацијама да бришу податке о контактима."</string>
-    <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Дозвољава апликацији да мења податке о контактима које чувате на телефону. Ова дозвола омогућава апликацијама да бришу податке о контактима."</string>
-    <string name="permlab_readCallLog" msgid="1739990210293505948">"читање евиденције позива"</string>
-    <string name="permdesc_readCallLog" msgid="8964770895425873433">"Ова апликација може да чита историју позива."</string>
-    <string name="permlab_writeCallLog" msgid="670292975137658895">"писање евиденције позива"</string>
-    <string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Дозвољава апликацији да мења евиденцију позива на таблету, укључујући податке о долазним и одлазним позивима. Злонамерне апликације могу ово да користе да би брисале или мењале евиденцију позива."</string>
-    <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Дозвољава апликацији да мења евиденцију позива на Android TV уређају, укључујући податке о долазним и одлазним позивима. Злонамерне апликације могу ово да користе за брисање или мењање евиденције позива."</string>
-    <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Дозвољава апликацији да мења евиденцију позива на телефону, укључујући податке о долазним и одлазним позивима. Злонамерне апликације могу ово да користе да би брисале или мењале евиденцију позива."</string>
-    <string name="permlab_bodySensors" msgid="662918578601619569">"Приступ подацима сензора за тело, као што је пулс, у току коришћења"</string>
-    <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Дозвољава апликацији да приступа подацима сензора за тело, као што су пулс, температура и проценат кисеоника у крви док се апликација користи."</string>
-    <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Приступ подацима сензора за тело, као што је пулс, у позадини"</string>
-    <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Дозвољава апликацији да приступа подацима сензора за тело, као што су пулс, температура и проценат кисеоника у крви док је апликација у позадини."</string>
-    <string name="permlab_readCalendar" msgid="6408654259475396200">"Читање догађаја и података из календара"</string>
-    <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ова апликација може да чита све догађаје из календара које чувате на таблету, као и да дели или чува податке из календара."</string>
-    <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ова апликација може да чита све догађаје из календара које чувате на Android TV уређају, као и да дели или чува податке из календара."</string>
-    <string name="permdesc_readCalendar" product="default" msgid="9118823807655829957">"Ова апликација може да чита све догађаје из календара које чувате на телефону, као и да дели или чува податке из календара."</string>
-    <string name="permlab_writeCalendar" msgid="6422137308329578076">"додавање или измена календарских догађаја и слање порука е-поште гостима без знања власника"</string>
-    <string name="permdesc_writeCalendar" product="tablet" msgid="8722230940717092850">"Ова апликацији може да додаје, уклања или мења догађаје из календара на таблету. Ова апликација може да шаље поруке које изгледају као да их шаљу власници календара или да мења догађаје без знања власника."</string>
-    <string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"Ова апликација може да додаје, уклања или мења догађаје из календара на Android TV уређају. Ова апликација може да шаље поруке које изгледају као да их шаљу власници календара или да мења догађаје без знања власника."</string>
-    <string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Ова апликацији може да додаје, уклања или мења догађаје из календара на телефону. Ова апликација може да шаље поруке које изгледају као да их шаљу власници календара или да мења догађаје без знања власника."</string>
-    <string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"приступ додатним командама добављача локације"</string>
-    <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Омогућава апликацији да приступа додатним командама даваоца услуга локације. То може да омогући апликацији да утиче на рад GPS-а или других извора локације."</string>
-    <string name="permlab_accessFineLocation" msgid="6426318438195622966">"приступ прецизној локацији само у првом плану"</string>
-    <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Ова апликација може да одреди вашу тачну локацију на основу услуга локације док се апликација користи. Услуге локације за уређај морају да буду укључене да би апликација одредила локацију. То може да повећа потрошњу батерије."</string>
-    <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"приступ приближној локацији само у првом плану"</string>
-    <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Ова апликација може да одреди вашу приближну локацију на основу услуга локације док се апликација користи. Услуге локације за уређај морају да буду укључене да би апликација одредила локацију."</string>
-    <string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"приступ локацији у позадини"</string>
-    <string name="permdesc_accessBackgroundLocation" msgid="8264885066095638105">"Ова апликација може да приступа локацији у било ком тренутку, чак и док се апликација не користи."</string>
-    <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"промена аудио подешавања"</string>
-    <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Дозвољава апликацији да мења глобална аудио подешавања као што су јачина звука и избор звучника који се користи као излаз."</string>
-    <string name="permlab_recordAudio" msgid="1208457423054219147">"снимање аудио записа"</string>
-    <string name="permdesc_recordAudio" msgid="5857246765327514062">"Ова апликација може да снима звук помоћу микрофона док се апликација користи."</string>
-    <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"да снима звук у позадини"</string>
-    <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Ова апликација може да снима звук помоћу микрофона у било ком тренутку."</string>
-    <string name="permlab_sim_communication" msgid="176788115994050692">"слање команди на SIM"</string>
-    <string name="permdesc_sim_communication" msgid="4179799296415957960">"Омогућава апликацији да шаље команде SIM картици. То је веома опасно."</string>
-    <string name="permlab_activityRecognition" msgid="1782303296053990884">"препознавање физичких активности"</string>
-    <string name="permdesc_activityRecognition" msgid="8667484762991357519">"Ова апликација може да препозна физичке активности."</string>
-    <string name="permlab_camera" msgid="6320282492904119413">"снимање фотографија и видео снимака"</string>
-    <string name="permdesc_camera" msgid="5240801376168647151">"Ова апликација може да снима слике и видео снимке помоћу камере док се апликација користи."</string>
-    <string name="permlab_backgroundCamera" msgid="7549917926079731681">"да снима слике и видео снимке у позадини"</string>
-    <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"Ова апликација може да снима фотографије и видео снимке помоћу камере у било ком тренутку."</string>
-    <string name="permlab_systemCamera" msgid="3642917457796210580">"Дозволите некој апликацији или услузи да приступа камерама система да би снимала слике и видео снимке"</string>
-    <string name="permdesc_systemCamera" msgid="5938360914419175986">"Ова привилегована системска апликација може да снима слике и видео снимке помоћу камере система у било ком тренутку. Апликација треба да има и дозволу android.permission.CAMERA"</string>
-    <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Дозволите апликацији или услузи да добија повратне позиве о отварању или затварању уређаја са камером."</string>
-    <string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"Ова апликација може да добија повратне позиве када се било који уређај са камером отвара или затвара (помоћу неке апликације)."</string>
-    <string name="permlab_vibrate" msgid="8596800035791962017">"контрола вибрације"</string>
-    <string name="permdesc_vibrate" msgid="8733343234582083721">"Дозвољава апликацији да контролише вибрацију."</string>
-    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Дозвољава апликацији да приступа стању вибрирања."</string>
-    <string name="permlab_callPhone" msgid="1798582257194643320">"директно позивање бројева телефона"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Дозвољава апликацији да позива бројеве телефона без ваше дозволе. Ово може да доведе до неочекиваних трошкова или позива. Имајте на уму да ово не дозвољава апликацији да позива бројеве за хитне случајеве. Злонамерне апликације могу да позивају без ваше потврде, што може да доведе до трошкова."</string>
-    <string name="permlab_accessImsCallService" msgid="442192920714863782">"приступ услузи позива помоћу размене тренутних порука"</string>
-    <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Дозвољава апликацији да користи услугу размене тренутних порука да би упућивала позиве без ваше интервенције."</string>
-    <string name="permlab_readPhoneState" msgid="8138526903259297969">"читање статуса и идентитета телефона"</string>
-    <string name="permdesc_readPhoneState" msgid="7229063553502788058">"Дозвољава апликацији да приступа функцијама телефона на уређају. Ова дозвола омогућава апликацији да утврди број телефона и ИД-ове уређаја, затим да ли је позив активан, као и број даљинског уређаја са којим је успостављен позив."</string>
-    <string name="permlab_readBasicPhoneState" msgid="3214853233263871347">"очитавање основног телефонског статуса и идентитета"</string>
-    <string name="permdesc_readBasicPhoneState" msgid="828185691675460520">"Омогућава апликацији да приступа основним телефонским функцијама уређаја."</string>
-    <string name="permlab_manageOwnCalls" msgid="9033349060307561370">"преусмеравање позива преко система"</string>
-    <string name="permdesc_manageOwnCalls" msgid="4431178362202142574">"Дозвољава апликацији да преусмерава позиве преко система да би побољшала доживљај позивања."</string>
-    <string name="permlab_callCompanionApp" msgid="3654373653014126884">"преглед и контрола позива преко система."</string>
-    <string name="permdesc_callCompanionApp" msgid="8474168926184156261">"Дозвољава апликацији да прегледа и контролише тренутне позиве на уређају. То обухвата информације попут бројева телефона и статуса позива."</string>
-    <string name="permlab_exemptFromAudioRecordRestrictions" msgid="1164725468350759486">"изузимање из ограничења за снимање звука"</string>
-    <string name="permdesc_exemptFromAudioRecordRestrictions" msgid="2425117015896871976">"Изузмите апликацију из ограничења за снимање звука."</string>
-    <string name="permlab_acceptHandover" msgid="2925523073573116523">"настави позив у другој апликацији"</string>
-    <string name="permdesc_acceptHandovers" msgid="7129026180128626870">"Дозвољава апликацији да настави позив који је започет у другој апликацији."</string>
-    <string name="permlab_readPhoneNumbers" msgid="5668704794723365628">"читање бројева телефона"</string>
-    <string name="permdesc_readPhoneNumbers" msgid="7368652482818338871">"Дозвољава апликацији да приступа бројевима телефона на уређају."</string>
-    <string name="permlab_wakeLock" product="automotive" msgid="1904736682319375676">"не искључуј екран у аутомобилу"</string>
-    <string name="permlab_wakeLock" product="tablet" msgid="1527660973931694000">"спречавање преласка таблета у стање спавања"</string>
-    <string name="permlab_wakeLock" product="tv" msgid="2856941418123343518">"спречава Android TV уређај да пређе у стање спавања"</string>
-    <string name="permlab_wakeLock" product="default" msgid="569409726861695115">"спречавање преласка телефона у стање спавања"</string>
-    <string name="permdesc_wakeLock" product="automotive" msgid="5995045369683254571">"Дозвољава апликацији да не искључује екран у аутомобилу."</string>
-    <string name="permdesc_wakeLock" product="tablet" msgid="2441742939101526277">"Дозвољава апликацији да спречи таблет да пређе у стање спавања."</string>
-    <string name="permdesc_wakeLock" product="tv" msgid="2329298966735118796">"Дозвољава апликацији да спречи Android TV уређај да пређе у стање спавања."</string>
-    <string name="permdesc_wakeLock" product="default" msgid="3689523792074007163">"Дозвољава апликацији да спречи телефон да пређе у стање спавања."</string>
-    <string name="permlab_transmitIr" msgid="8077196086358004010">"пренос инфрацрвених зрака"</string>
-    <string name="permdesc_transmitIr" product="tablet" msgid="5884738958581810253">"Дозвољава апликацији да користи одашиљач инфрацрвених зрака таблета."</string>
-    <string name="permdesc_transmitIr" product="tv" msgid="3278506969529173281">"Дозвољава да апликација користи одашиљач инфрацрвених зрака на Android TV уређају."</string>
-    <string name="permdesc_transmitIr" product="default" msgid="8484193849295581808">"Дозвољава апликацији да користи одашиљач инфрацрвених зрака телефона."</string>
-    <string name="permlab_setWallpaper" msgid="6959514622698794511">"подешавање позадине"</string>
-    <string name="permdesc_setWallpaper" msgid="2973996714129021397">"Дозвољава апликацији да поставља позадину система."</string>
-    <string name="permlab_setWallpaperHints" msgid="1153485176642032714">"прилагођавање величине позадине"</string>
-    <string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"Дозвољава апликацији да подеси савете за системску величину позадине."</string>
-    <string name="permlab_setTimeZone" msgid="7922618798611542432">"подешавање временске зоне"</string>
-    <string name="permdesc_setTimeZone" product="tablet" msgid="1788868809638682503">"Дозвољава апликацији да промени временску зону таблета."</string>
-    <string name="permdesc_setTimeZone" product="tv" msgid="9069045914174455938">"Дозвољава апликацији да мења временску зону Android TV уређаја."</string>
-    <string name="permdesc_setTimeZone" product="default" msgid="4611828585759488256">"Дозвољава апликацији да промени временску зону телефона."</string>
-    <string name="permlab_getAccounts" msgid="5304317160463582791">"проналажење налога на уређају"</string>
-    <string name="permdesc_getAccounts" product="tablet" msgid="1784452755887604512">"Дозвољава апликацији да преузима листу налога познатих таблету. Ово може да обухвата било које налоге које праве апликације које инсталирате."</string>
-    <string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"Дозвољава апликацији да дође до листе налога познатих Android TV уређају. Ово може да обухвата све налоге које отварају апликације које сте инсталирали."</string>
-    <string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"Дозвољава апликацији да преузима листу налога познатих телефону. Ово може да обухвата било које налоге које праве апликације које инсталирате."</string>
-    <string name="permlab_accessNetworkState" msgid="2349126720783633918">"преглед мрежних веза"</string>
-    <string name="permdesc_accessNetworkState" msgid="4394564702881662849">"Дозвољава апликацији да прегледа информације о мрежним везама као што су информације о томе које мреже постоје и које мреже су повезане."</string>
-    <string name="permlab_createNetworkSockets" msgid="3224420491603590541">"има пун мрежни приступ"</string>
-    <string name="permdesc_createNetworkSockets" msgid="7722020828749535988">"Дозвољава апликацији да прави мрежне прикључке и користи прилагођене мрежне протоколе. Прегледач и друге апликације омогућавају слање података на Интернет, па ова дозвола није потребна за слање података на Интернет."</string>
-    <string name="permlab_changeNetworkState" msgid="8945711637530425586">"промена везе са мрежом"</string>
-    <string name="permdesc_changeNetworkState" msgid="649341947816898736">"Дозвољава апликацији да мења статус повезивања са мрежом."</string>
-    <string name="permlab_changeTetherState" msgid="9079611809931863861">"промена повезивања привезивањем"</string>
-    <string name="permdesc_changeTetherState" msgid="3025129606422533085">"Дозвољава апликацији да мења статус везе са привезаном мрежом."</string>
-    <string name="permlab_accessWifiState" msgid="5552488500317911052">"преглед WiFi веза"</string>
-    <string name="permdesc_accessWifiState" msgid="6913641669259483363">"Дозвољава апликацији да прегледа информације о WiFi умрежавању, као што су информације о томе да ли је WiFi омогућен и називи повезаних WiFi уређаја."</string>
-    <string name="permlab_changeWifiState" msgid="7947824109713181554">"повезивање и прекид везе са WiFi мрежом"</string>
-    <string name="permdesc_changeWifiState" msgid="7170350070554505384">"Дозвољава апликацији да се повезује са приступним тачкама за WiFi и прекида везу са њима, као и да уноси промене у конфигурацију уређаја за WiFi мреже."</string>
-    <string name="permlab_changeWifiMulticastState" msgid="285626875870754696">"омогућавање пријема вишесмерног WiFi саобраћаја"</string>
-    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="191079868596433554">"Дозвољава апликацији да прима пакете који се шаљу на све уређаје на WiFi мрежи помоћу вишесмерних адреса, а не само на таблет. Користи више напајања од режима једносмерног саобраћаја."</string>
-    <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"Дозвољава апликацији да прима пакете који се шаљу на све уређаје на WiFi мрежи помоћу вишесмерних адреса, а не само на Android TV уређај. Користи више енергије од режима без вишесмерног слања."</string>
-    <string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"Дозвољава апликацији да прима пакете који се шаљу на све уређаје на WiFi мрежи помоћу вишесмерних адреса, а не само на телефон. Користи више напајања од режима једносмерног саобраћаја."</string>
-    <string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"приступ Bluetooth подешавањима"</string>
-    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"Дозвољава апликацији да конфигурише локални Bluetooth таблет, као и да открије даљинске уређаје и упари се са њима."</string>
-    <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"Дозвољава апликацији да конфигурише Bluetooth на Android TV уређају и да открије удаљене уређаје и упари се са њима."</string>
-    <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"Дозвољава апликацији да конфигурише локални Bluetooth телефон, као и да открије даљинске уређаје и упари се са њима."</string>
-    <string name="permlab_accessWimaxState" msgid="7029563339012437434">"повезивање и прекид везе са WiMAX-ом"</string>
-    <string name="permdesc_accessWimaxState" msgid="5372734776802067708">"Дозвољава апликацији да утврди да ли је WiMAX омогућен, као и информације о било којим повезаним WiMAX мрежама."</string>
-    <string name="permlab_changeWimaxState" msgid="6223305780806267462">"промени WiMAX статуса"</string>
-    <string name="permdesc_changeWimaxState" product="tablet" msgid="4011097664859480108">"Дозвољава апликацији да повезује таблет са WiMAX мрежама и прекида везе са њима."</string>
-    <string name="permdesc_changeWimaxState" product="tv" msgid="5373274458799425276">"Дозвољава апликацији да повезује Android TV уређај са WiMAX мрежама и да прекида ту везу."</string>
-    <string name="permdesc_changeWimaxState" product="default" msgid="1551666203780202101">"Дозвољава апликацији да повезује телефон са WiMAX мрежама и прекида везе са њима."</string>
-    <string name="permlab_bluetooth" msgid="586333280736937209">"упаривање са Bluetooth уређајима"</string>
-    <string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Дозвољава апликацији да прегледа конфигурацију Bluetooth-а на таблету, као и да успоставља и прихвата везе са упареним уређајима."</string>
-    <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Дозвољава апликацији да прегледа конфигурацију Bluetooth-а на Android TV уређају и да успоставља и прихвата везе са упареним уређајима."</string>
-    <string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Дозвољава апликацији да прегледа конфигурацију Bluetooth-а на телефону, као и да успоставља и прихвата везе са упареним уређајима."</string>
-    <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"откривање и упаривање са оближњим Bluetooth уређ."</string>
-    <string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Дозвољава апликацији да открива Bluetooth уређаје у близини и упарује се са њима"</string>
-    <string name="permlab_bluetooth_connect" msgid="6657463246355003528">"повезивање са упареним Bluetooth уређајима"</string>
-    <string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Дозвољава апликацији да се повезује са упареним Bluetooth уређајима"</string>
-    <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"оглашавање на Bluetooth уређајима у близини"</string>
-    <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Дозвољава апликацији да се оглашава на Bluetooth уређајима у близини"</string>
-    <string name="permlab_uwb_ranging" msgid="8141915781475770665">"одређивање раздаљине између уређаја ултра-широког појаса у близини"</string>
-    <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Дозвољава апликацији да одређује релативну раздаљину између уређаја ултра-широког појаса у близини"</string>
-    <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"интеракција са WiFi уређајима у близини"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Дозвољава апликацији да се оглашава, повезује и утврђује релативну позицију WiFi уређаја у близини"</string>
-    <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Информације о жељеној NFC услузи за плаћање"</string>
-    <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дозвољава апликацији да преузима информације о жељеној NFC услузи за плаћање, попут регистрованих идентификатора апликација и одредишта преусмеравања."</string>
-    <string name="permlab_nfc" msgid="1904455246837674977">"контрола комуникације у ужем пољу (Near Field Communication)"</string>
-    <string name="permdesc_nfc" msgid="8352737680695296741">"Дозвољава апликацији да комуницира са ознакама, картицама и читачима комуникације кратког домета (NFC)."</string>
-    <string name="permlab_disableKeyguard" msgid="3605253559020928505">"онемогућавање закључавања екрана"</string>
-    <string name="permdesc_disableKeyguard" msgid="3223710003098573038">"Дозвољава апликацији да онемогући закључавање тастатуре и све повезане безбедносне мере са лозинкама. На пример, телефон онемогућава закључавање тастатуре при пријему долазног телефонског позива, а затим га поново омогућава по завршетку позива."</string>
-    <string name="permlab_requestPasswordComplexity" msgid="1808977190557794109">"тражење сложености закључавања екрана"</string>
-    <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Дозвољава апликацији да сазна ниво сложености закључавања екрана (висока, средња, ниска или ниједна), што указује на могући опсег трајања и тип закључавања екрана. Апликација може и да предлаже корисницима да ажурирају закључавање екрана на одређени ниво, али корисници слободно могу да занемаре то и да иду на друге странице. Имајте на уму да се подаци за закључавање екрана не чувају као обичан текст, па апликација не зна тачну лозинку."</string>
-    <string name="permlab_postNotification" msgid="4875401198597803658">"приказивање обавештења"</string>
-    <string name="permdesc_postNotification" msgid="5974977162462877075">"Дозвољава апликацији да приказује обавештења"</string>
-    <string name="permlab_useBiometric" msgid="6314741124749633786">"користи биометријски хардвер"</string>
-    <string name="permdesc_useBiometric" msgid="7502858732677143410">"Дозвољава апликацији да користи биометријски хардвер за потврду идентитета"</string>
-    <string name="permlab_manageFingerprint" msgid="7432667156322821178">"управљај хардвером за отиске прстију"</string>
-    <string name="permdesc_manageFingerprint" msgid="2025616816437339865">"Дозвољава апликацији да активира методе за додавање и брисање шаблона отисака прстију који ће се користити."</string>
-    <string name="permlab_useFingerprint" msgid="1001421069766751922">"користи хардвер за отиске прстију"</string>
-    <string name="permdesc_useFingerprint" msgid="412463055059323742">"Дозвољава апликацији да користи хардвер за отиске прстију ради потврде идентитета"</string>
-    <string name="permlab_audioWrite" msgid="8501705294265669405">"измена музичке колекције"</string>
-    <string name="permdesc_audioWrite" msgid="8057399517013412431">"Дозвољава апликацији да мења музичку колекцију."</string>
-    <string name="permlab_videoWrite" msgid="5940738769586451318">"измена видео колекције"</string>
-    <string name="permdesc_videoWrite" msgid="6124731210613317051">"Дозвољава апликацији да мења видео колекцију."</string>
-    <string name="permlab_imagesWrite" msgid="1774555086984985578">"измена колекције слика"</string>
-    <string name="permdesc_imagesWrite" msgid="5195054463269193317">"Дозвољава апликацији да мења колекцију слика."</string>
-    <string name="permlab_mediaLocation" msgid="7368098373378598066">"читање локација из медијске колекције"</string>
-    <string name="permdesc_mediaLocation" msgid="597912899423578138">"Дозвољава апликацији да чита локације из медијске колекције."</string>
-    <string name="biometric_app_setting_name" msgid="3339209978734534457">"Користите биометрију"</string>
-    <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Користите биометрију или закључавање екрана"</string>
-    <string name="biometric_dialog_default_title" msgid="55026799173208210">"Потврдите свој идентитет"</string>
-    <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Користите биометријски податак да бисте наставили"</string>
-    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Користите биометријски податак или закључавање екрана да бисте наставили"</string>
-    <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометријски хардвер није доступан"</string>
-    <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Потврда идентитета је отказана"</string>
-    <string name="biometric_not_recognized" msgid="5106687642694635888">"Није препознато"</string>
-    <string name="biometric_error_canceled" msgid="8266582404844179778">"Потврда идентитета је отказана"</string>
-    <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Нисте подесили ни PIN, ни шаблон, ни лозинку"</string>
-    <string name="biometric_error_generic" msgid="6784371929985434439">"Грешка при потврди идентитета"</string>
-    <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Користите закључавање екрана"</string>
-    <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Употребите закључавање екрана да бисте наставили"</string>
-    <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Јако притисните сензор"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Препознавање отиска прста није успело. Пробајте поново."</string>
-    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Обришите сензор за отисак прста и пробајте поново"</string>
-    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Обришите сензор и пробајте поново"</string>
-    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Јако притисните сензор"</string>
-    <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Превише споро сте померили прст. Пробајте поново."</string>
-    <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Пробајте са другим отиском прста"</string>
-    <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Превише је светло"</string>
-    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Откривен је притисак дугмета за укључивање"</string>
-    <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Пробајте да прилагодите"</string>
-    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Сваки пут помало промените положај прста"</string>
+    <string name="permgroupdesc_sms" msgid="5726462398070064542">"šalje i pregleda SMS poruke"</string>
+    <string name="permgrouplab_storage" msgid="17339216290379241">"Fajlovi"</string>
+    <string name="permgroupdesc_storage" msgid="5378659041354582769">"pristup fajlovima na uređaju"</string>
+    <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Muzika i zvuk"</string>
+    <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"pristup muzici i audio sadržaju na uređaju"</string>
+    <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Slike i video snimci"</string>
+    <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"pristup slikama i video snimcima na uređaju"</string>
+    <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
+    <string name="permgroupdesc_microphone" msgid="1047786732792487722">"snima zvuk"</string>
+    <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fizičke aktivnosti"</string>
+    <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"pristup fizičkim aktivnostima"</string>
+    <string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
+    <string name="permgroupdesc_camera" msgid="7585150538459320326">"snima slike i video"</string>
+    <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Uređaji u blizini"</string>
+    <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"otkrivanje uređaja u blizini i povezivanje sa njima"</string>
+    <string name="permgrouplab_calllog" msgid="7926834372073550288">"Evidencije poziva"</string>
+    <string name="permgroupdesc_calllog" msgid="2026996642917801803">"čitanje i pisanje evidencije poziva na telefonu"</string>
+    <string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string>
+    <string name="permgroupdesc_phone" msgid="270048070781478204">"upućuje telefonske pozive i upravlja njima"</string>
+    <string name="permgrouplab_sensors" msgid="9134046949784064495">"Senzori za telo"</string>
+    <string name="permgroupdesc_sensors" msgid="2610631290633747752">"pristupa podacima senzora o vitalnim funkcijama"</string>
+    <string name="permgrouplab_notifications" msgid="5472972361980668884">"Obaveštenja"</string>
+    <string name="permgroupdesc_notifications" msgid="4608679556801506580">"prikazivanje obaveštenja"</string>
+    <string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"da preuzima sadržaj prozora"</string>
+    <string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Proverava sadržaj prozora sa kojim ostvarujete interakciju."</string>
+    <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"da uključi Istraživanja dodirom"</string>
+    <string name="capability_desc_canRequestTouchExploration" msgid="4394677060796752976">"Stavke koje dodirnete će biti izgovorene naglas, a možete da se krećete po ekranu pokretima."</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2772371671541753254">"da prati tekst koji unosite"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="2381315802405773092">"Obuhvata lične podatke kao što su brojevi kreditnih kartica i lozinke."</string>
+    <string name="capability_title_canControlMagnification" msgid="7701572187333415795">"da upravlja uvećanjem prikaza"</string>
+    <string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"Upravlja nivoom zumiranja prikaza i određivanjem položaja."</string>
+    <string name="capability_title_canPerformGestures" msgid="9106545062106728987">"Obavljanje pokreta"</string>
+    <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Može da dodiruje, lista, skuplja prikaz i obavlja druge pokrete."</string>
+    <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Pokreti za otisak prsta"</string>
+    <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Može da registruje pokrete na senzoru za otisak prsta na uređaju."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Napravi snimak ekrana"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Može da napravi snimak ekrana."</string>
+    <string name="permlab_statusBar" msgid="8798267849526214017">"onemogućavanje ili izmena statusne trake"</string>
+    <string name="permdesc_statusBar" msgid="5809162768651019642">"Dozvoljava aplikaciji da onemogući statusnu traku ili da dodaje i uklanja sistemske ikone."</string>
+    <string name="permlab_statusBarService" msgid="2523421018081437981">"funkcionisanje kao statusna traka"</string>
+    <string name="permdesc_statusBarService" msgid="6652917399085712557">"Dozvoljava aplikaciji da funkcioniše kao statusna traka."</string>
+    <string name="permlab_expandStatusBar" msgid="1184232794782141698">"proširenje/skupljanje statusne trake"</string>
+    <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Dozvoljava aplikaciji da proširuje ili skuplja statusnu traku."</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"prikazuje obaveštenja kao aktivnosti preko celog ekrana na zaključanom uređaju"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Omogućava aplikaciji da na zaključanom uređaju prikazuje obaveštenja kao aktivnosti preko celog ekrana."</string>
+    <string name="permlab_install_shortcut" msgid="7451554307502256221">"Instaliranje prečica"</string>
+    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"da dodaju prečice na početni ekran bez intervencije korisnika."</string>
+    <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"deinstaliranje prečica"</string>
+    <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Omogućava aplikaciji da uklanja prečice sa početnog ekrana bez intervencije korisnika."</string>
+    <string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"preusmeravanje odlaznih poziva"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="7833149750590606334">"Dozvoljava aplikaciji da vidi koji broj se bira pri odlaznom pozivu uz opciju da preusmeri poziv na drugi broj ili ga potpuno prekine."</string>
+    <string name="permlab_answerPhoneCalls" msgid="4131324833663725855">"odgovaraj na telefonske pozive"</string>
+    <string name="permdesc_answerPhoneCalls" msgid="894386681983116838">"Dozvoljava aplikaciji da odgovori na dolazni telefonski poziv."</string>
+    <string name="permlab_receiveSms" msgid="505961632050451881">"prijem tekstualnih poruka (SMS)"</string>
+    <string name="permdesc_receiveSms" msgid="1797345626687832285">"Dozvoljava aplikaciji da prima i obrađuje SMS poruke. To znači da aplikacija može da nadgleda ili briše poruke koje se šalju uređaju, a da vam ih ne prikaže."</string>
+    <string name="permlab_receiveMms" msgid="4000650116674380275">"prijem tekstualnih poruka (MMS)"</string>
+    <string name="permdesc_receiveMms" msgid="958102423732219710">"Dozvoljava aplikaciji da prima i obrađuje MMS poruke. To znači da aplikacija može da nadgleda ili briše poruke koje se šalju uređaju, a da vam ih ne prikaže."</string>
+    <string name="permlab_bindCellBroadcastService" msgid="586746677002040651">"Prosleđivanje poruka za mobilne uređaje na lokalitetu"</string>
+    <string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"Dozvoljava aplikaciji da se vezuje za modul poruka za mobilne uređaje na lokalitetu da bi prosleđivala poruke za mobilne uređaje na lokalitetu onako kako su primljene. Obaveštenja poruka za mobilne uređaje na lokalitetu se na nekim lokacijama primaju kao upozorenja na hitne slučajeve. Zlonamerne aplikacije mogu da utiču na performanse ili ometaju rad uređaja kada se primi poruka o hitnom slučaju za mobilne uređaje na lokalitetu."</string>
+    <string name="permlab_manageOngoingCalls" msgid="281244770664231782">"Upravljanje odlaznim pozivima"</string>
+    <string name="permdesc_manageOngoingCalls" msgid="7003138133829915265">"Omogućava aplikaciji da vidi detalje o odlaznim pozivima na uređaju i da kontroliše te pozive."</string>
+    <string name="permlab_readCellBroadcasts" msgid="5869884450872137693">"čitanje poruka info servisa"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"Omogućava aplikaciji da čita poruke info servisa koje uređaj prima. Upozorenja info servisa se na nekim lokacijama primaju kao upozorenja na hitne slučajeve. Zlonamerne aplikacije mogu da utiču na performanse ili ometaju funkcionisanje uređaja kada se primi poruka info servisa o hitnom slučaju."</string>
+    <string name="permlab_subscribedFeedsRead" msgid="217624769238425461">"čitanje prijavljenih fidova"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="6911349196661811865">"Dozvoljava aplikaciji da preuzima detalje o trenutno sinhronizovanim fidovima."</string>
+    <string name="permlab_sendSms" msgid="7757368721742014252">"šalje i pregleda SMS poruke"</string>
+    <string name="permdesc_sendSms" msgid="6757089798435130769">"Dozvoljava aplikaciji da šalje SMS poruke. Ovo može da dovede do neočekivanih troškova. Zlonamerne aplikacije mogu da šalju poruke bez vaše potvrde, što može da izazove troškove."</string>
+    <string name="permlab_readSms" msgid="5164176626258800297">"čitanje tekstualnih poruka (SMS ili MMS)"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="7912990447198112829">"Ova aplikacija može da čita sve SMS (tekstualne) poruke koje se čuvaju na tabletu."</string>
+    <string name="permdesc_readSms" product="tv" msgid="3054753345758011986">"Ova aplikacija može da čita sve SMS (tekstualne) poruke koje se čuvaju na Android TV uređaju."</string>
+    <string name="permdesc_readSms" product="default" msgid="774753371111699782">"Ova aplikacija može da čita sve SMS (tekstualne) poruke koje se čuvaju na telefonu."</string>
+    <string name="permlab_receiveWapPush" msgid="4223747702856929056">"prijem tekstualnih poruka (WAP)"</string>
+    <string name="permdesc_receiveWapPush" msgid="1638677888301778457">"Dozvoljava aplikaciji da prima i obrađuje WAP poruke. Ova dozvola uključuje mogućnost praćenja ili brisanja poruka koje vam se šalju, a koje vam se ne prikazuju."</string>
+    <string name="permlab_getTasks" msgid="7460048811831750262">"preuzimanje pokrenutih aplikacija"</string>
+    <string name="permdesc_getTasks" msgid="7388138607018233726">"Dozvoljava aplikaciji da preuzima informacije o aktuelnim i nedavno pokrenutim zadacima. Ovo može da omogući aplikaciji da otkrije informacije o tome koje se aplikacije koriste na uređaju."</string>
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="639849495253987493">"upravljanje vlasnicima profila i uređaja"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="7304240671781989283">"Dozvoljava aplikaciji da podesi vlasnike profila i vlasnika uređaja."</string>
+    <string name="permlab_reorderTasks" msgid="7598562301992923804">"promena redosleda pokrenutih aplikacija"</string>
+    <string name="permdesc_reorderTasks" msgid="8796089937352344183">"Dozvoljava aplikaciji da premešta zadatke u prvi plan i u pozadinu. Aplikacija može da radi ovo bez vašeg unosa."</string>
+    <string name="permlab_enableCarMode" msgid="893019409519325311">"omogućavanje režima rada u automobilu"</string>
+    <string name="permdesc_enableCarMode" msgid="56419168820473508">"Dozvoljava aplikaciji da omogući režim rada u automobilu."</string>
+    <string name="permlab_killBackgroundProcesses" msgid="6559320515561928348">"zatvaranje drugih aplikacija"</string>
+    <string name="permdesc_killBackgroundProcesses" msgid="2357013583055434685">"Dozvoljava aplikaciji da zaustavi pozadinske procese drugih aplikacija. Ovo može da zaustavi druge aplikacije."</string>
+    <string name="permlab_systemAlertWindow" msgid="5757218350944719065">"Ova aplikacija može da se prikazuje preko drugih aplikacija"</string>
+    <string name="permdesc_systemAlertWindow" msgid="1145660714855738308">"Ova aplikacija može da se prikazuje preko drugih aplikacija ili drugih delova delova ekrana. To može da ometa standardno korišćenje aplikacija i način na koji se druge aplikacije prikazuju."</string>
+    <string name="permlab_runInBackground" msgid="541863968571682785">"pokretanje u pozadini"</string>
+    <string name="permdesc_runInBackground" msgid="4344539472115495141">"Ova aplikacija može da se pokreće u pozadini. To može brže da istroši bateriju."</string>
+    <string name="permlab_useDataInBackground" msgid="783415807623038947">"korišćenje podataka u pozadini"</string>
+    <string name="permdesc_useDataInBackground" msgid="1230753883865891987">"Ova aplikacija može da koristi podatke u pozadini. To može da poveća potrošnju podataka."</string>
+    <string name="permlab_persistentActivity" msgid="464970041740567970">"omogućavanje neprekidne aktivnosti aplikacije"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="6055271149187369916">"Dozvoljava aplikaciji da učini sopstvene komponente trajnim u memoriji. Ovo može da ograniči memoriju dostupnu drugim aplikacijama i uspori tablet."</string>
+    <string name="permdesc_persistentActivity" product="tv" msgid="6800526387664131321">"Dozvoljava aplikaciji da trajno zadrži neke svoje delove u memoriji. Ovo može da ograniči memoriju dostupnu drugim aplikacijama i uspori Android TV uređaj."</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Dozvoljava aplikaciji da učini sopstvene komponente trajnim u memoriji. Ovo može da ograniči memoriju dostupnu drugim aplikacijama i uspori telefon."</string>
+    <string name="permlab_foregroundService" msgid="1768855976818467491">"pokreni uslugu u prvom planu"</string>
+    <string name="permdesc_foregroundService" msgid="8720071450020922795">"Dozvoljava aplikaciji da koristi usluge u prvom planu."</string>
+    <string name="permlab_getPackageSize" msgid="375391550792886641">"merenje memorijskog prostora u aplikaciji"</string>
+    <string name="permdesc_getPackageSize" msgid="742743530909966782">"Dozvoljava aplikaciji da preuzme veličine kôda, podataka i keša."</string>
+    <string name="permlab_writeSettings" msgid="8057285063719277394">"izmena podešavanja sistema"</string>
+    <string name="permdesc_writeSettings" msgid="8293047411196067188">"Dozvoljava aplikaciji da menja podatke o podešavanju sistema. Zlonamerne aplikacije mogu da oštete konfiguraciju sistema."</string>
+    <string name="permlab_receiveBootCompleted" msgid="6643339400247325379">"pokretanje pri pokretanju sistema"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="5565659082718177484">"Omogućava da se aplikacija pokrene odmah nakon pokretanja sistema. To može da uspori pokretanje tableta, pri čemu ova aplikacija može da uspori funkcionisanje celog tableta time što će uvek biti aktivna."</string>
+    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"Dozvoljava aplikaciji da se pokrene odmah po uključivanju sistema. To može da uspori pokretanje Android TV uređaja i aplikacija može da uspori funkcionisanje uređaja u celini tako što će uvek biti aktivna."</string>
+    <string name="permdesc_receiveBootCompleted" product="default" msgid="7912677044558690092">"Omogućava da se aplikacija pokrene čim se sistem pokrene. To može da uspori pokretanje telefona, pri čemu ova aplikacija može da uspori funkcionisanje celog telefona time što će uvek biti aktivna."</string>
+    <string name="permlab_broadcastSticky" msgid="4552241916400572230">"slanje prijemčivih emitovanja"</string>
+    <string name="permdesc_broadcastSticky" product="tablet" msgid="5058486069846384013">"Dozvoljava aplikaciji da šalje prijemčiva emitovanja, koja ostaju po završetku emitovanja. Prekomerna upotreba može da uspori ili destabilizuje tablet tako što će ga primorati da troši previše memorije."</string>
+    <string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Dozvoljava aplikaciji da šalje lepljiva emitovanja koja ostaju po završetku emitovanja. Prekomerna upotreba može da uspori ili destabilizuje Android TV uređaj tako što će ga primorati da troši previše memorije."</string>
+    <string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Dozvoljava aplikaciji da šalje prijemčiva emitovanja, koja ostaju po završetku emitovanja. Prekomerna upotreba može da uspori ili destabilizuje telefon tako što će ga primorati da troši previše memorije."</string>
+    <string name="permlab_readContacts" msgid="8776395111787429099">"čitanje kontakata"</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Dozvoljava aplikaciji da čita podatke o kontaktima koje čuvate na tabletu. Aplikacije će imati pristup i nalozima na vašem tabletu na kojima su napravljeni kontakti. Tu mogu da spadaju nalozi koje su otvorile aplikacije koje ste instalirali. Ova dozvola omogućava aplikacijama da čuvaju podatke o kontaktima i zlonamerne aplikacije mogu da dele podatke o kontaktima bez vašeg znanja."</string>
+    <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Dozvoljava aplikaciji da čita podatke o kontaktima koje čuvate na Android TV uređaju. Aplikacije će imati pristup i nalozima na vašem Android TV uređaju na kojima su napravljeni kontakti. Tu mogu da spadaju nalozi koje su otvorile aplikacije koje ste instalirali. Ova dozvola omogućava aplikacijama da čuvaju podatke o kontaktima i zlonamerne aplikacije mogu da dele podatke o kontaktima bez vašeg znanja."</string>
+    <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Dozvoljava aplikaciji da čita podatke o kontaktima koje čuvate na telefonu. Aplikacije će imati pristup i nalozima na vašem telefonu na kojima su napravljeni kontakti. Tu mogu da spadaju nalozi koje su otvorile aplikacije koje ste instalirali. Ova dozvola omogućava aplikacijama da čuvaju podatke o kontaktima i zlonamerne aplikacije mogu da dele podatke o kontaktima bez vašeg znanja."</string>
+    <string name="permlab_writeContacts" msgid="8919430536404830430">"izmena kontakata"</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Dozvoljava aplikaciji da menja podatke o kontaktima koje čuvate na tabletu. Ova dozvola omogućava aplikacijama da brišu podatke o kontaktima."</string>
+    <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Dozvoljava aplikaciji da menja podatke o kontaktima koje čuvate na Android TV uređaju. Ova dozvola omogućava aplikacijama da brišu podatke o kontaktima."</string>
+    <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Dozvoljava aplikaciji da menja podatke o kontaktima koje čuvate na telefonu. Ova dozvola omogućava aplikacijama da brišu podatke o kontaktima."</string>
+    <string name="permlab_readCallLog" msgid="1739990210293505948">"čitanje evidencije poziva"</string>
+    <string name="permdesc_readCallLog" msgid="8964770895425873433">"Ova aplikacija može da čita istoriju poziva."</string>
+    <string name="permlab_writeCallLog" msgid="670292975137658895">"pisanje evidencije poziva"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Dozvoljava aplikaciji da menja evidenciju poziva na tabletu, uključujući podatke o dolaznim i odlaznim pozivima. Zlonamerne aplikacije mogu ovo da koriste da bi brisale ili menjale evidenciju poziva."</string>
+    <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Dozvoljava aplikaciji da menja evidenciju poziva na Android TV uređaju, uključujući podatke o dolaznim i odlaznim pozivima. Zlonamerne aplikacije mogu ovo da koriste za brisanje ili menjanje evidencije poziva."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Dozvoljava aplikaciji da menja evidenciju poziva na telefonu, uključujući podatke o dolaznim i odlaznim pozivima. Zlonamerne aplikacije mogu ovo da koriste da bi brisale ili menjale evidenciju poziva."</string>
+    <string name="permlab_bodySensors" msgid="662918578601619569">"Pristup podacima senzora za telo, kao što je puls, u toku korišćenja"</string>
+    <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Dozvoljava aplikaciji da pristupa podacima senzora za telo, kao što su puls, temperatura i procenat kiseonika u krvi dok se aplikacija koristi."</string>
+    <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Pristup podacima senzora za telo, kao što je puls, u pozadini"</string>
+    <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Dozvoljava aplikaciji da pristupa podacima senzora za telo, kao što su puls, temperatura i procenat kiseonika u krvi dok je aplikacija u pozadini."</string>
+    <string name="permlab_readCalendar" msgid="6408654259475396200">"Čitanje događaja i podataka iz kalendara"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ova aplikacija može da čita sve događaje iz kalendara koje čuvate na tabletu, kao i da deli ili čuva podatke iz kalendara."</string>
+    <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ova aplikacija može da čita sve događaje iz kalendara koje čuvate na Android TV uređaju, kao i da deli ili čuva podatke iz kalendara."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="9118823807655829957">"Ova aplikacija može da čita sve događaje iz kalendara koje čuvate na telefonu, kao i da deli ili čuva podatke iz kalendara."</string>
+    <string name="permlab_writeCalendar" msgid="6422137308329578076">"dodavanje ili izmena kalendarskih događaja i slanje poruka e-pošte gostima bez znanja vlasnika"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="8722230940717092850">"Ova aplikaciji može da dodaje, uklanja ili menja događaje iz kalendara na tabletu. Ova aplikacija može da šalje poruke koje izgledaju kao da ih šalju vlasnici kalendara ili da menja događaje bez znanja vlasnika."</string>
+    <string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"Ova aplikacija može da dodaje, uklanja ili menja događaje iz kalendara na Android TV uređaju. Ova aplikacija može da šalje poruke koje izgledaju kao da ih šalju vlasnici kalendara ili da menja događaje bez znanja vlasnika."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Ova aplikaciji može da dodaje, uklanja ili menja događaje iz kalendara na telefonu. Ova aplikacija može da šalje poruke koje izgledaju kao da ih šalju vlasnici kalendara ili da menja događaje bez znanja vlasnika."</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"pristup dodatnim komandama dobavljača lokacije"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Omogućava aplikaciji da pristupa dodatnim komandama davaoca usluga lokacije. To može da omogući aplikaciji da utiče na rad GPS-a ili drugih izvora lokacije."</string>
+    <string name="permlab_accessFineLocation" msgid="6426318438195622966">"pristup preciznoj lokaciji samo u prvom planu"</string>
+    <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Ova aplikacija može da odredi vašu tačnu lokaciju na osnovu usluga lokacije dok se aplikacija koristi. Usluge lokacije za uređaj moraju da budu uključene da bi aplikacija odredila lokaciju. To može da poveća potrošnju baterije."</string>
+    <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"pristup približnoj lokaciji samo u prvom planu"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Ova aplikacija može da odredi vašu približnu lokaciju na osnovu usluga lokacije dok se aplikacija koristi. Usluge lokacije za uređaj moraju da budu uključene da bi aplikacija odredila lokaciju."</string>
+    <string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"pristup lokaciji u pozadini"</string>
+    <string name="permdesc_accessBackgroundLocation" msgid="8264885066095638105">"Ova aplikacija može da pristupa lokaciji u bilo kom trenutku, čak i dok se aplikacija ne koristi."</string>
+    <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"promena audio podešavanja"</string>
+    <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Dozvoljava aplikaciji da menja globalna audio podešavanja kao što su jačina zvuka i izbor zvučnika koji se koristi kao izlaz."</string>
+    <string name="permlab_recordAudio" msgid="1208457423054219147">"snimanje audio zapisa"</string>
+    <string name="permdesc_recordAudio" msgid="5857246765327514062">"Ova aplikacija može da snima zvuk pomoću mikrofona dok se aplikacija koristi."</string>
+    <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"da snima zvuk u pozadini"</string>
+    <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Ova aplikacija može da snima zvuk pomoću mikrofona u bilo kom trenutku."</string>
+    <string name="permlab_sim_communication" msgid="176788115994050692">"slanje komandi na SIM"</string>
+    <string name="permdesc_sim_communication" msgid="4179799296415957960">"Omogućava aplikaciji da šalje komande SIM kartici. To je veoma opasno."</string>
+    <string name="permlab_activityRecognition" msgid="1782303296053990884">"prepoznavanje fizičkih aktivnosti"</string>
+    <string name="permdesc_activityRecognition" msgid="8667484762991357519">"Ova aplikacija može da prepozna fizičke aktivnosti."</string>
+    <string name="permlab_camera" msgid="6320282492904119413">"snimanje fotografija i video snimaka"</string>
+    <string name="permdesc_camera" msgid="5240801376168647151">"Ova aplikacija može da snima slike i video snimke pomoću kamere dok se aplikacija koristi."</string>
+    <string name="permlab_backgroundCamera" msgid="7549917926079731681">"da snima slike i video snimke u pozadini"</string>
+    <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"Ova aplikacija može da snima fotografije i video snimke pomoću kamere u bilo kom trenutku."</string>
+    <string name="permlab_systemCamera" msgid="3642917457796210580">"Dozvolite nekoj aplikaciji ili usluzi da pristupa kamerama sistema da bi snimala slike i video snimke"</string>
+    <string name="permdesc_systemCamera" msgid="5938360914419175986">"Ova privilegovana sistemska aplikacija može da snima slike i video snimke pomoću kamere sistema u bilo kom trenutku. Aplikacija treba da ima i dozvolu android.permission.CAMERA"</string>
+    <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Dozvolite aplikaciji ili usluzi da dobija povratne pozive o otvaranju ili zatvaranju uređaja sa kamerom."</string>
+    <string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"Ova aplikacija može da dobija povratne pozive kada se bilo koji uređaj sa kamerom otvara ili zatvara (pomoću neke aplikacije)."</string>
+    <string name="permlab_vibrate" msgid="8596800035791962017">"kontrola vibracije"</string>
+    <string name="permdesc_vibrate" msgid="8733343234582083721">"Dozvoljava aplikaciji da kontroliše vibraciju."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Dozvoljava aplikaciji da pristupa stanju vibriranja."</string>
+    <string name="permlab_callPhone" msgid="1798582257194643320">"direktno pozivanje brojeva telefona"</string>
+    <string name="permdesc_callPhone" msgid="5439809516131609109">"Dozvoljava aplikaciji da poziva brojeve telefona bez vaše dozvole. Ovo može da dovede do neočekivanih troškova ili poziva. Imajte na umu da ovo ne dozvoljava aplikaciji da poziva brojeve za hitne slučajeve. Zlonamerne aplikacije mogu da pozivaju bez vaše potvrde, što može da dovede do troškova."</string>
+    <string name="permlab_accessImsCallService" msgid="442192920714863782">"pristup usluzi poziva pomoću razmene trenutnih poruka"</string>
+    <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Dozvoljava aplikaciji da koristi uslugu razmene trenutnih poruka da bi upućivala pozive bez vaše intervencije."</string>
+    <string name="permlab_readPhoneState" msgid="8138526903259297969">"čitanje statusa i identiteta telefona"</string>
+    <string name="permdesc_readPhoneState" msgid="7229063553502788058">"Dozvoljava aplikaciji da pristupa funkcijama telefona na uređaju. Ova dozvola omogućava aplikaciji da utvrdi broj telefona i ID-ove uređaja, zatim da li je poziv aktivan, kao i broj daljinskog uređaja sa kojim je uspostavljen poziv."</string>
+    <string name="permlab_readBasicPhoneState" msgid="3214853233263871347">"očitavanje osnovnog telefonskog statusa i identiteta"</string>
+    <string name="permdesc_readBasicPhoneState" msgid="828185691675460520">"Omogućava aplikaciji da pristupa osnovnim telefonskim funkcijama uređaja."</string>
+    <string name="permlab_manageOwnCalls" msgid="9033349060307561370">"preusmeravanje poziva preko sistema"</string>
+    <string name="permdesc_manageOwnCalls" msgid="4431178362202142574">"Dozvoljava aplikaciji da preusmerava pozive preko sistema da bi poboljšala doživljaj pozivanja."</string>
+    <string name="permlab_callCompanionApp" msgid="3654373653014126884">"pregled i kontrola poziva preko sistema."</string>
+    <string name="permdesc_callCompanionApp" msgid="8474168926184156261">"Dozvoljava aplikaciji da pregleda i kontroliše trenutne pozive na uređaju. To obuhvata informacije poput brojeva telefona i statusa poziva."</string>
+    <string name="permlab_exemptFromAudioRecordRestrictions" msgid="1164725468350759486">"izuzimanje iz ograničenja za snimanje zvuka"</string>
+    <string name="permdesc_exemptFromAudioRecordRestrictions" msgid="2425117015896871976">"Izuzmite aplikaciju iz ograničenja za snimanje zvuka."</string>
+    <string name="permlab_acceptHandover" msgid="2925523073573116523">"nastavi poziv u drugoj aplikaciji"</string>
+    <string name="permdesc_acceptHandovers" msgid="7129026180128626870">"Dozvoljava aplikaciji da nastavi poziv koji je započet u drugoj aplikaciji."</string>
+    <string name="permlab_readPhoneNumbers" msgid="5668704794723365628">"čitanje brojeva telefona"</string>
+    <string name="permdesc_readPhoneNumbers" msgid="7368652482818338871">"Dozvoljava aplikaciji da pristupa brojevima telefona na uređaju."</string>
+    <string name="permlab_wakeLock" product="automotive" msgid="1904736682319375676">"ne isključuj ekran u automobilu"</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1527660973931694000">"sprečavanje prelaska tableta u stanje spavanja"</string>
+    <string name="permlab_wakeLock" product="tv" msgid="2856941418123343518">"sprečava Android TV uređaj da pređe u stanje spavanja"</string>
+    <string name="permlab_wakeLock" product="default" msgid="569409726861695115">"sprečavanje prelaska telefona u stanje spavanja"</string>
+    <string name="permdesc_wakeLock" product="automotive" msgid="5995045369683254571">"Dozvoljava aplikaciji da ne isključuje ekran u automobilu."</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="2441742939101526277">"Dozvoljava aplikaciji da spreči tablet da pređe u stanje spavanja."</string>
+    <string name="permdesc_wakeLock" product="tv" msgid="2329298966735118796">"Dozvoljava aplikaciji da spreči Android TV uređaj da pređe u stanje spavanja."</string>
+    <string name="permdesc_wakeLock" product="default" msgid="3689523792074007163">"Dozvoljava aplikaciji da spreči telefon da pređe u stanje spavanja."</string>
+    <string name="permlab_transmitIr" msgid="8077196086358004010">"prenos infracrvenih zraka"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5884738958581810253">"Dozvoljava aplikaciji da koristi odašiljač infracrvenih zraka tableta."</string>
+    <string name="permdesc_transmitIr" product="tv" msgid="3278506969529173281">"Dozvoljava da aplikacija koristi odašiljač infracrvenih zraka na Android TV uređaju."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="8484193849295581808">"Dozvoljava aplikaciji da koristi odašiljač infracrvenih zraka telefona."</string>
+    <string name="permlab_setWallpaper" msgid="6959514622698794511">"podešavanje pozadine"</string>
+    <string name="permdesc_setWallpaper" msgid="2973996714129021397">"Dozvoljava aplikaciji da postavlja pozadinu sistema."</string>
+    <string name="permlab_setWallpaperHints" msgid="1153485176642032714">"prilagođavanje veličine pozadine"</string>
+    <string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"Dozvoljava aplikaciji da podesi savete za sistemsku veličinu pozadine."</string>
+    <string name="permlab_setTimeZone" msgid="7922618798611542432">"podešavanje vremenske zone"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1788868809638682503">"Dozvoljava aplikaciji da promeni vremensku zonu tableta."</string>
+    <string name="permdesc_setTimeZone" product="tv" msgid="9069045914174455938">"Dozvoljava aplikaciji da menja vremensku zonu Android TV uređaja."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4611828585759488256">"Dozvoljava aplikaciji da promeni vremensku zonu telefona."</string>
+    <string name="permlab_getAccounts" msgid="5304317160463582791">"pronalaženje naloga na uređaju"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="1784452755887604512">"Dozvoljava aplikaciji da preuzima listu naloga poznatih tabletu. Ovo može da obuhvata bilo koje naloge koje prave aplikacije koje instalirate."</string>
+    <string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"Dozvoljava aplikaciji da dođe do liste naloga poznatih Android TV uređaju. Ovo može da obuhvata sve naloge koje otvaraju aplikacije koje ste instalirali."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"Dozvoljava aplikaciji da preuzima listu naloga poznatih telefonu. Ovo može da obuhvata bilo koje naloge koje prave aplikacije koje instalirate."</string>
+    <string name="permlab_accessNetworkState" msgid="2349126720783633918">"pregled mrežnih veza"</string>
+    <string name="permdesc_accessNetworkState" msgid="4394564702881662849">"Dozvoljava aplikaciji da pregleda informacije o mrežnim vezama kao što su informacije o tome koje mreže postoje i koje mreže su povezane."</string>
+    <string name="permlab_createNetworkSockets" msgid="3224420491603590541">"ima pun mrežni pristup"</string>
+    <string name="permdesc_createNetworkSockets" msgid="7722020828749535988">"Dozvoljava aplikaciji da pravi mrežne priključke i koristi prilagođene mrežne protokole. Pregledač i druge aplikacije omogućavaju slanje podataka na Internet, pa ova dozvola nije potrebna za slanje podataka na Internet."</string>
+    <string name="permlab_changeNetworkState" msgid="8945711637530425586">"promena veze sa mrežom"</string>
+    <string name="permdesc_changeNetworkState" msgid="649341947816898736">"Dozvoljava aplikaciji da menja status povezivanja sa mrežom."</string>
+    <string name="permlab_changeTetherState" msgid="9079611809931863861">"promena povezivanja privezivanjem"</string>
+    <string name="permdesc_changeTetherState" msgid="3025129606422533085">"Dozvoljava aplikaciji da menja status veze sa privezanom mrežom."</string>
+    <string name="permlab_accessWifiState" msgid="5552488500317911052">"pregled WiFi veza"</string>
+    <string name="permdesc_accessWifiState" msgid="6913641669259483363">"Dozvoljava aplikaciji da pregleda informacije o WiFi umrežavanju, kao što su informacije o tome da li je WiFi omogućen i nazivi povezanih WiFi uređaja."</string>
+    <string name="permlab_changeWifiState" msgid="7947824109713181554">"povezivanje i prekid veze sa WiFi mrežom"</string>
+    <string name="permdesc_changeWifiState" msgid="7170350070554505384">"Dozvoljava aplikaciji da se povezuje sa pristupnim tačkama za WiFi i prekida vezu sa njima, kao i da unosi promene u konfiguraciju uređaja za WiFi mreže."</string>
+    <string name="permlab_changeWifiMulticastState" msgid="285626875870754696">"omogućavanje prijema višesmernog WiFi saobraćaja"</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="191079868596433554">"Dozvoljava aplikaciji da prima pakete koji se šalju na sve uređaje na WiFi mreži pomoću višesmernih adresa, a ne samo na tablet. Koristi više napajanja od režima jednosmernog saobraćaja."</string>
+    <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"Dozvoljava aplikaciji da prima pakete koji se šalju na sve uređaje na WiFi mreži pomoću višesmernih adresa, a ne samo na Android TV uređaj. Koristi više energije od režima bez višesmernog slanja."</string>
+    <string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"Dozvoljava aplikaciji da prima pakete koji se šalju na sve uređaje na WiFi mreži pomoću višesmernih adresa, a ne samo na telefon. Koristi više napajanja od režima jednosmernog saobraćaja."</string>
+    <string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"pristup Bluetooth podešavanjima"</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"Dozvoljava aplikaciji da konfiguriše lokalni Bluetooth tablet, kao i da otkrije daljinske uređaje i upari se sa njima."</string>
+    <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"Dozvoljava aplikaciji da konfiguriše Bluetooth na Android TV uređaju i da otkrije udaljene uređaje i upari se sa njima."</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"Dozvoljava aplikaciji da konfiguriše lokalni Bluetooth telefon, kao i da otkrije daljinske uređaje i upari se sa njima."</string>
+    <string name="permlab_accessWimaxState" msgid="7029563339012437434">"povezivanje i prekid veze sa WiMAX-om"</string>
+    <string name="permdesc_accessWimaxState" msgid="5372734776802067708">"Dozvoljava aplikaciji da utvrdi da li je WiMAX omogućen, kao i informacije o bilo kojim povezanim WiMAX mrežama."</string>
+    <string name="permlab_changeWimaxState" msgid="6223305780806267462">"promeni WiMAX statusa"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="4011097664859480108">"Dozvoljava aplikaciji da povezuje tablet sa WiMAX mrežama i prekida veze sa njima."</string>
+    <string name="permdesc_changeWimaxState" product="tv" msgid="5373274458799425276">"Dozvoljava aplikaciji da povezuje Android TV uređaj sa WiMAX mrežama i da prekida tu vezu."</string>
+    <string name="permdesc_changeWimaxState" product="default" msgid="1551666203780202101">"Dozvoljava aplikaciji da povezuje telefon sa WiMAX mrežama i prekida veze sa njima."</string>
+    <string name="permlab_bluetooth" msgid="586333280736937209">"uparivanje sa Bluetooth uređajima"</string>
+    <string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Dozvoljava aplikaciji da pregleda konfiguraciju Bluetooth-a na tabletu, kao i da uspostavlja i prihvata veze sa uparenim uređajima."</string>
+    <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Dozvoljava aplikaciji da pregleda konfiguraciju Bluetooth-a na Android TV uređaju i da uspostavlja i prihvata veze sa uparenim uređajima."</string>
+    <string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Dozvoljava aplikaciji da pregleda konfiguraciju Bluetooth-a na telefonu, kao i da uspostavlja i prihvata veze sa uparenim uređajima."</string>
+    <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"otkrivanje i uparivanje sa obližnjim Bluetooth uređ."</string>
+    <string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Dozvoljava aplikaciji da otkriva Bluetooth uređaje u blizini i uparuje se sa njima"</string>
+    <string name="permlab_bluetooth_connect" msgid="6657463246355003528">"povezivanje sa uparenim Bluetooth uređajima"</string>
+    <string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Dozvoljava aplikaciji da se povezuje sa uparenim Bluetooth uređajima"</string>
+    <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"oglašavanje na Bluetooth uređajima u blizini"</string>
+    <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Dozvoljava aplikaciji da se oglašava na Bluetooth uređajima u blizini"</string>
+    <string name="permlab_uwb_ranging" msgid="8141915781475770665">"određivanje razdaljine između uređaja ultra-širokog pojasa u blizini"</string>
+    <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Dozvoljava aplikaciji da određuje relativnu razdaljinu između uređaja ultra-širokog pojasa u blizini"</string>
+    <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interakcija sa WiFi uređajima u blizini"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Dozvoljava aplikaciji da se oglašava, povezuje i utvrđuje relativnu poziciju WiFi uređaja u blizini"</string>
+    <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacije o željenoj NFC usluzi za plaćanje"</string>
+    <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Dozvoljava aplikaciji da preuzima informacije o željenoj NFC usluzi za plaćanje, poput registrovanih identifikatora aplikacija i odredišta preusmeravanja."</string>
+    <string name="permlab_nfc" msgid="1904455246837674977">"kontrola komunikacije u užem polju (Near Field Communication)"</string>
+    <string name="permdesc_nfc" msgid="8352737680695296741">"Dozvoljava aplikaciji da komunicira sa oznakama, karticama i čitačima komunikacije kratkog dometa (NFC)."</string>
+    <string name="permlab_disableKeyguard" msgid="3605253559020928505">"onemogućavanje zaključavanja ekrana"</string>
+    <string name="permdesc_disableKeyguard" msgid="3223710003098573038">"Dozvoljava aplikaciji da onemogući zaključavanje tastature i sve povezane bezbednosne mere sa lozinkama. Na primer, telefon onemogućava zaključavanje tastature pri prijemu dolaznog telefonskog poziva, a zatim ga ponovo omogućava po završetku poziva."</string>
+    <string name="permlab_requestPasswordComplexity" msgid="1808977190557794109">"traženje složenosti zaključavanja ekrana"</string>
+    <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Dozvoljava aplikaciji da sazna nivo složenosti zaključavanja ekrana (visoka, srednja, niska ili nijedna), što ukazuje na mogući opseg trajanja i tip zaključavanja ekrana. Aplikacija može i da predlaže korisnicima da ažuriraju zaključavanje ekrana na određeni nivo, ali korisnici slobodno mogu da zanemare to i da idu na druge stranice. Imajte na umu da se podaci za zaključavanje ekrana ne čuvaju kao običan tekst, pa aplikacija ne zna tačnu lozinku."</string>
+    <string name="permlab_postNotification" msgid="4875401198597803658">"prikazivanje obaveštenja"</string>
+    <string name="permdesc_postNotification" msgid="5974977162462877075">"Dozvoljava aplikaciji da prikazuje obaveštenja"</string>
+    <string name="permlab_useBiometric" msgid="6314741124749633786">"koristi biometrijski hardver"</string>
+    <string name="permdesc_useBiometric" msgid="7502858732677143410">"Dozvoljava aplikaciji da koristi biometrijski hardver za potvrdu identiteta"</string>
+    <string name="permlab_manageFingerprint" msgid="7432667156322821178">"upravljaj hardverom za otiske prstiju"</string>
+    <string name="permdesc_manageFingerprint" msgid="2025616816437339865">"Dozvoljava aplikaciji da aktivira metode za dodavanje i brisanje šablona otisaka prstiju koji će se koristiti."</string>
+    <string name="permlab_useFingerprint" msgid="1001421069766751922">"koristi hardver za otiske prstiju"</string>
+    <string name="permdesc_useFingerprint" msgid="412463055059323742">"Dozvoljava aplikaciji da koristi hardver za otiske prstiju radi potvrde identiteta"</string>
+    <string name="permlab_audioWrite" msgid="8501705294265669405">"izmena muzičke kolekcije"</string>
+    <string name="permdesc_audioWrite" msgid="8057399517013412431">"Dozvoljava aplikaciji da menja muzičku kolekciju."</string>
+    <string name="permlab_videoWrite" msgid="5940738769586451318">"izmena video kolekcije"</string>
+    <string name="permdesc_videoWrite" msgid="6124731210613317051">"Dozvoljava aplikaciji da menja video kolekciju."</string>
+    <string name="permlab_imagesWrite" msgid="1774555086984985578">"izmena kolekcije slika"</string>
+    <string name="permdesc_imagesWrite" msgid="5195054463269193317">"Dozvoljava aplikaciji da menja kolekciju slika."</string>
+    <string name="permlab_mediaLocation" msgid="7368098373378598066">"čitanje lokacija iz medijske kolekcije"</string>
+    <string name="permdesc_mediaLocation" msgid="597912899423578138">"Dozvoljava aplikaciji da čita lokacije iz medijske kolekcije."</string>
+    <string name="biometric_app_setting_name" msgid="3339209978734534457">"Koristite biometriju"</string>
+    <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Koristite biometriju ili zaključavanje ekrana"</string>
+    <string name="biometric_dialog_default_title" msgid="55026799173208210">"Potvrdite svoj identitet"</string>
+    <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Koristite biometrijski podatak da biste nastavili"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Koristite biometrijski podatak ili zaključavanje ekrana da biste nastavili"</string>
+    <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrijski hardver nije dostupan"</string>
+    <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Potvrda identiteta je otkazana"</string>
+    <string name="biometric_not_recognized" msgid="5106687642694635888">"Nije prepoznato"</string>
+    <string name="biometric_error_canceled" msgid="8266582404844179778">"Potvrda identiteta je otkazana"</string>
+    <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Niste podesili ni PIN, ni šablon, ni lozinku"</string>
+    <string name="biometric_error_generic" msgid="6784371929985434439">"Greška pri potvrdi identiteta"</string>
+    <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Koristite zaključavanje ekrana"</string>
+    <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Upotrebite zaključavanje ekrana da biste nastavili"</string>
+    <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Jako pritisnite senzor"</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Prepoznavanje otiska prsta nije uspelo. Probajte ponovo."</string>
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Obrišite senzor za otisak prsta i probajte ponovo"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Obrišite senzor i probajte ponovo"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Jako pritisnite senzor"</string>
+    <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Previše sporo ste pomerili prst. Probajte ponovo."</string>
+    <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Probajte sa drugim otiskom prsta"</string>
+    <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Previše je svetlo"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Otkriven je pritisak dugmeta za uključivanje"</string>
+    <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Probajte da prilagodite"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Svaki put pomalo promenite položaj prsta"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Отисак прста није препознат"</string>
-    <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Отисак прста није препознат"</string>
-    <string name="fingerprint_authenticated" msgid="2024862866860283100">"Отисак прста је потврђен"</string>
-    <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Лице је потврђено"</string>
-    <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Лице је потврђено. Притисните Потврди"</string>
-    <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Хардвер за отиске прстију није доступан."</string>
-    <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Подешавање отиска прста није успело"</string>
-    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Време за подешавање отиска прста је истекло. Пробајте поново."</string>
-    <string name="fingerprint_error_canceled" msgid="540026881380070750">"Радња са отиском прста је отказана."</string>
-    <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Корисник је отказао радњу са отиском прста."</string>
-    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Превише покушаја. Користите закључавање екрана уместо тога."</string>
-    <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Превише покушаја. Користите закључавање екрана уместо тога."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Обрађивање отиска прста није успело. Пробајте поново."</string>
-    <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Није регистрован ниједан отисак прста."</string>
-    <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Овај уређај нема сензор за отисак прста."</string>
-    <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензор је привремено онемогућен."</string>
-    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Не можете да користите сензор за отисак прста. Посетите добављача за поправке"</string>
-    <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Притиснуто је дугме за укључивање"</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>
-    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Користите отисак прста или закључавање екрана да бисте наставили"</string>
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Otisak prsta nije prepoznat"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Otisak prsta nije prepoznat"</string>
+    <string name="fingerprint_authenticated" msgid="2024862866860283100">"Otisak prsta je potvrđen"</string>
+    <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Lice je potvrđeno"</string>
+    <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Lice je potvrđeno. Pritisnite Potvrdi"</string>
+    <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardver za otiske prstiju nije dostupan."</string>
+    <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Podešavanje otiska prsta nije uspelo"</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Vreme za podešavanje otiska prsta je isteklo. Probajte ponovo."</string>
+    <string name="fingerprint_error_canceled" msgid="540026881380070750">"Radnja sa otiskom prsta je otkazana."</string>
+    <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Korisnik je otkazao radnju sa otiskom prsta."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Previše pokušaja. Koristite zaključavanje ekrana umesto toga."</string>
+    <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Previše pokušaja. Koristite zaključavanje ekrana umesto toga."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Obrađivanje otiska prsta nije uspelo. Probajte ponovo."</string>
+    <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nije registrovan nijedan otisak prsta."</string>
+    <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor za otisak prsta."</string>
+    <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
+    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Ne možete da koristite senzor za otisak prsta. Posetite dobavljača za popravke"</string>
+    <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Pritisnuto je dugme za uključivanje"</string>
+    <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
+    <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Koristite otisak prsta"</string>
+    <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Koristite otisak prsta ili zaključavanje ekrana"</string>
+    <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Nastavite pomoću otiska prsta"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Koristite otisak prsta ili zaključavanje ekrana da biste nastavili"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
-    <string name="fingerprint_error_vendor_unknown" msgid="4170002184907291065">"Дошло је до проблема. Пробајте поново."</string>
-    <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Икона отиска прста"</string>
-    <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Откључавање лицем"</string>
-    <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Проблем са откључавање лицем"</string>
-    <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Додирните да бисте избрисали модел лица, па поново додајте своје лице"</string>
-    <string name="face_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="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>
-    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Не можете да користите сензор за отисак прста"</string>
-    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Посетите добављача за поправке."</string>
-    <string name="face_acquired_insufficient" msgid="6889245852748492218">"Прављење модела лица није успело. Пробајте поново."</string>
-    <string name="face_acquired_too_bright" msgid="8070756048978079164">"Превише је светло. Пробајте са слабијим осветљењем."</string>
-    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Нема довољно светла"</string>
-    <string name="face_acquired_too_close" msgid="4453646176196302462">"Удаљите телефон"</string>
-    <string name="face_acquired_too_far" msgid="2922278214231064859">"Приближите телефон"</string>
-    <string name="face_acquired_too_high" msgid="8278815780046368576">"Померите телефон нагоре"</string>
-    <string name="face_acquired_too_low" msgid="4075391872960840081">"Померите телефон надоле"</string>
-    <string name="face_acquired_too_right" msgid="6245286514593540859">"Померите телефон улево"</string>
-    <string name="face_acquired_too_left" msgid="9201762240918405486">"Померите телефон удесно"</string>
-    <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Гледајте право у уређај."</string>
-    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Не види се лице. Држите телефон у висини очију."</string>
-    <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Много се померате. Држите телефон мирно."</string>
-    <string name="face_acquired_recalibrate" msgid="8724013080976469746">"Поново региструјте лице."</string>
-    <string name="face_acquired_too_different" msgid="2520389515612972889">"Лице није препознато. Пробајте поново."</string>
-    <string name="face_acquired_too_similar" msgid="8882920552674125694">"Мало померите главу"</string>
-    <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Гледајте право у телефон"</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Гледајте право у телефон"</string>
-    <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Гледајте право у телефон"</string>
-    <string name="face_acquired_obscured" msgid="4917643294953326639">"Уклоните све што вам заклања лице."</string>
-    <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Очистите горњи део екрана, укључујући црну траку"</string>
+    <string name="fingerprint_error_vendor_unknown" msgid="4170002184907291065">"Došlo je do problema. Probajte ponovo."</string>
+    <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona otiska prsta"</string>
+    <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Otključavanje licem"</string>
+    <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problem sa otključavanje licem"</string>
+    <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Dodirnite da biste izbrisali model lica, pa ponovo dodajte svoje lice"</string>
+    <string name="face_setup_notification_title" msgid="8843461561970741790">"Podesite otključavanje licem"</string>
+    <string name="face_setup_notification_content" msgid="5463999831057751676">"Otključajte telefon tako što ćete ga pogledati"</string>
+    <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Da biste koristili otključavanje licem, uključite "<b>"pristup kameri"</b>" u odeljku Podešavanja &gt; Privatnost"</string>
+    <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Podesite još načina za otključavanje"</string>
+    <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Dodirnite da biste dodali otisak prsta"</string>
+    <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Otključavanje otiskom prsta"</string>
+    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Ne možete da koristite senzor za otisak prsta"</string>
+    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Posetite dobavljača za popravke."</string>
+    <string name="face_acquired_insufficient" msgid="6889245852748492218">"Pravljenje modela lica nije uspelo. Probajte ponovo."</string>
+    <string name="face_acquired_too_bright" msgid="8070756048978079164">"Previše je svetlo. Probajte sa slabijim osvetljenjem."</string>
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Nema dovoljno svetla"</string>
+    <string name="face_acquired_too_close" msgid="4453646176196302462">"Udaljite telefon"</string>
+    <string name="face_acquired_too_far" msgid="2922278214231064859">"Približite telefon"</string>
+    <string name="face_acquired_too_high" msgid="8278815780046368576">"Pomerite telefon nagore"</string>
+    <string name="face_acquired_too_low" msgid="4075391872960840081">"Pomerite telefon nadole"</string>
+    <string name="face_acquired_too_right" msgid="6245286514593540859">"Pomerite telefon ulevo"</string>
+    <string name="face_acquired_too_left" msgid="9201762240918405486">"Pomerite telefon udesno"</string>
+    <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Gledajte pravo u uređaj."</string>
+    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Ne vidi se lice. Držite telefon u visini očiju."</string>
+    <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Mnogo se pomerate. Držite telefon mirno."</string>
+    <string name="face_acquired_recalibrate" msgid="8724013080976469746">"Ponovo registrujte lice."</string>
+    <string name="face_acquired_too_different" msgid="2520389515612972889">"Lice nije prepoznato. Probajte ponovo."</string>
+    <string name="face_acquired_too_similar" msgid="8882920552674125694">"Malo pomerite glavu"</string>
+    <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Gledajte pravo u telefon"</string>
+    <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Gledajte pravo u telefon"</string>
+    <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Gledajte pravo u telefon"</string>
+    <string name="face_acquired_obscured" msgid="4917643294953326639">"Uklonite sve što vam zaklanja lice."</string>
+    <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Očistite gornji deo ekrana, uključujući crnu traku"</string>
     <!-- no translation found for face_acquired_dark_glasses_detected (5643703296620631986) -->
     <skip />
     <!-- no translation found for face_acquired_mouth_covering_detected (8219428572168642593) -->
     <skip />
-    <string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Прављење модела лица није успело. Пробајте поново."</string>
-    <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Откривене су тамне наочари. Лице мора да буде потпуно видљиво."</string>
-    <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Откривено је прекривање лица. Лице мора да буде потпуно видљиво."</string>
+    <string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Pravljenje modela lica nije uspelo. Probajte ponovo."</string>
+    <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Otkrivene su tamne naočari. Lice mora da bude potpuno vidljivo."</string>
+    <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Otkriveno je prekrivanje lica. Lice mora da bude potpuno vidljivo."</string>
   <string-array name="face_acquired_vendor">
   </string-array>
-    <string name="face_error_hw_not_available" msgid="5085202213036026288">"Провера лица није успела. Хардвер није доступан."</string>
-    <string name="face_error_timeout" msgid="2598544068593889762">"Пробајте поново откључавање лицем"</string>
-    <string name="face_error_no_space" msgid="5649264057026021723">"Нови подаци о лицу нису сачувани. Прво избришете претходне."</string>
-    <string name="face_error_canceled" msgid="2164434737103802131">"Обрада лица је отказана."</string>
-    <string name="face_error_user_canceled" msgid="5766472033202928373">"Корисник је отказао откључавање лицем"</string>
-    <string name="face_error_lockout" msgid="7864408714994529437">"Превише покушаја. Пробајте поново касније."</string>
-    <string name="face_error_lockout_permanent" msgid="3277134834042995260">"Превише покушаја. Откључавање лицем је онемогућено."</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_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_dialog_default_subtitle" msgid="6620492813371195429">"Потврдите идентитет лицем да бисте наставили"</string>
-    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Користите лице или закључавање екрана да бисте наставили"</string>
+    <string name="face_error_hw_not_available" msgid="5085202213036026288">"Provera lica nije uspela. Hardver nije dostupan."</string>
+    <string name="face_error_timeout" msgid="2598544068593889762">"Probajte ponovo otključavanje licem"</string>
+    <string name="face_error_no_space" msgid="5649264057026021723">"Novi podaci o licu nisu sačuvani. Prvo izbrišete prethodne."</string>
+    <string name="face_error_canceled" msgid="2164434737103802131">"Obrada lica je otkazana."</string>
+    <string name="face_error_user_canceled" msgid="5766472033202928373">"Korisnik je otkazao otključavanje licem"</string>
+    <string name="face_error_lockout" msgid="7864408714994529437">"Previše pokušaja. Probajte ponovo kasnije."</string>
+    <string name="face_error_lockout_permanent" msgid="3277134834042995260">"Previše pokušaja. Otključavanje licem je onemogućeno."</string>
+    <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Previše pokušaja. Koristite zaključavanje ekrana za to."</string>
+    <string name="face_error_unable_to_process" msgid="5723292697366130070">"Provera lica nije uspela. Probajte ponovo."</string>
+    <string name="face_error_not_enrolled" msgid="1134739108536328412">"Niste podesili otključavanje licem"</string>
+    <string name="face_error_hw_not_present" msgid="7940978724978763011">"Otključavanje licem nije podržano na ovom uređaju"</string>
+    <string name="face_error_security_update_required" msgid="5076017208528750161">"Senzor je privremeno onemogućen."</string>
+    <string name="face_name_template" msgid="3877037340223318119">"Lice <xliff:g id="FACEID">%d</xliff:g>"</string>
+    <string name="face_app_setting_name" msgid="5854024256907828015">"Koristite otključavanje licem"</string>
+    <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Koristite zaključavanje licem ili zaključavanje ekrana"</string>
+    <string name="face_dialog_default_subtitle" msgid="6620492813371195429">"Potvrdite identitet licem da biste nastavili"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Koristite lice ili zaključavanje ekrana da biste nastavili"</string>
   <string-array name="face_error_vendor">
   </string-array>
-    <string name="face_error_vendor_unknown" msgid="7387005932083302070">"Дошло је до проблема. Пробајте поново."</string>
-    <string name="face_icon_content_description" msgid="465030547475916280">"Икона лица"</string>
-    <string name="permlab_readSyncSettings" msgid="6250532864893156277">"читање подешавања синхронизације"</string>
-    <string name="permdesc_readSyncSettings" msgid="1325658466358779298">"Дозвољава апликацији да чита подешавања синхронизације за налог. На пример, овако може да се утврди да ли је апликација Људи синхронизована са налогом."</string>
-    <string name="permlab_writeSyncSettings" msgid="6583154300780427399">"укључивање и искључивање синхронизације"</string>
-    <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"Дозвољава апликацији да мења подешавања синхронизације за налог. На пример, овако може да се омогући синхронизација апликације Људи са налогом."</string>
-    <string name="permlab_readSyncStats" msgid="3747407238320105332">"читање статистике о синхронизацији"</string>
-    <string name="permdesc_readSyncStats" msgid="3867809926567379434">"Дозвољава апликацији да чита статистику синхронизације за налог, укључујући историју синхронизованих догађаја и количину података који се синхронизују."</string>
-    <string name="permlab_sdcardRead" msgid="5791467020950064920">"читање садржаја дељеног меморијског простора"</string>
-    <string name="permdesc_sdcardRead" msgid="6872973242228240382">"Дозвољава апликацији да чита садржај дељеног меморијског простора."</string>
-    <string name="permlab_readMediaAudio" msgid="8723513075731763810">"читање аудио фајлова из дељеног меморијског простора"</string>
-    <string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Омогућава апликацији да чита аудио фајлове из дељеног меморијског простора."</string>
-    <string name="permlab_readMediaVideo" msgid="7768003311260655007">"читање видео фајлова из дељеног меморијског простора"</string>
-    <string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Омогућава апликацији да чита видео фајлове из дељеног меморијског простора."</string>
-    <string name="permlab_readMediaImages" msgid="4057590631020986789">"читање фајлова слика из дељеног меморијског простора"</string>
-    <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Омогућава апликацији да чита фајлове слика из дељеног меморијског простора."</string>
-    <string name="permlab_sdcardWrite" msgid="4863021819671416668">"мењање или брисање садржаја дељеног меморијског простора"</string>
-    <string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Дозвољава апликацији да уписује садржај дељеног меморијског простора."</string>
-    <string name="permlab_use_sip" msgid="8250774565189337477">"упућивање/пријем SIP позива"</string>
-    <string name="permdesc_use_sip" msgid="3590270893253204451">"Омогућава апликацији да упућује и прима SIP позиве."</string>
-    <string name="permlab_register_sim_subscription" msgid="1653054249287576161">"региструје нове везе са телекомуникационим мрежама преко SIM картице"</string>
-    <string name="permdesc_register_sim_subscription" msgid="4183858662792232464">"Дозвољава апликацији да региструје нове везе са телекомуникационим мрежама преко SIM картице."</string>
-    <string name="permlab_register_call_provider" msgid="6135073566140050702">"региструје нове везе са телекомуникационим мрежама"</string>
-    <string name="permdesc_register_call_provider" msgid="4201429251459068613">"Дозвољава апликацији да региструје нове везе са телекомуникационим мрежама."</string>
-    <string name="permlab_connection_manager" msgid="3179365584691166915">"управљање везама са телекомуникационим мрежама"</string>
-    <string name="permdesc_connection_manager" msgid="1426093604238937733">"Дозвољава апликацији да управља везама са телекомуникационим мрежама."</string>
-    <string name="permlab_bind_incall_service" msgid="5990625112603493016">"комуницирај са екраном током позива"</string>
-    <string name="permdesc_bind_incall_service" msgid="4124917526967765162">"Дозвољава апликацији да контролише када и како се кориснику приказује екран током позива."</string>
-    <string name="permlab_bind_connection_service" msgid="5409268245525024736">"да ступа у интеракцију са телефонским услугама"</string>
-    <string name="permdesc_bind_connection_service" msgid="6261796725253264518">"Дозвољава интеракцију апликације са телефонским услугама ради упућивања/примања позива."</string>
-    <string name="permlab_control_incall_experience" msgid="6436863486094352987">"пружај кориснички доживљај током позива"</string>
-    <string name="permdesc_control_incall_experience" msgid="5896723643771737534">"Дозвољава апликацији да пружа кориснички доживљај током позива."</string>
-    <string name="permlab_readNetworkUsageHistory" msgid="8470402862501573795">"чита историју коришћења мреже"</string>
-    <string name="permdesc_readNetworkUsageHistory" msgid="1112962304941637102">"Дозвољава апликацији да чита историју коришћења мреже за посебне мреже и апликације."</string>
-    <string name="permlab_manageNetworkPolicy" msgid="6872549423152175378">"управљање смерницама за мрежу"</string>
-    <string name="permdesc_manageNetworkPolicy" msgid="1865663268764673296">"Дозвољава апликацији да управља смерницама за мрежу и одређује посебна правила за апликацију."</string>
-    <string name="permlab_modifyNetworkAccounting" msgid="7448790834938749041">"измените обрачунавање коришћења мреже"</string>
-    <string name="permdesc_modifyNetworkAccounting" msgid="5076042642247205390">"Дозвољава апликацији да измени начин на који апликације користе мрежу. Не користе је уобичајене апликације."</string>
-    <string name="permlab_accessNotifications" msgid="7130360248191984741">"приступ обавештењима"</string>
-    <string name="permdesc_accessNotifications" msgid="761730149268789668">"Дозвољава апликацији да преузима, испитује и брише обавештења, укључујући она која постављају друге апликације."</string>
-    <string name="permlab_bindNotificationListenerService" msgid="5848096702733262458">"повезивање са услугом монитора обавештења"</string>
-    <string name="permdesc_bindNotificationListenerService" msgid="4970553694467137126">"Дозвољава власнику да се повеже са интерфејсом услуге монитора обавештења највишег нивоа. Уобичајене апликације никада не би требало да је користе."</string>
-    <string name="permlab_bindConditionProviderService" msgid="5245421224814878483">"повежи са услугом добављача услова"</string>
-    <string name="permdesc_bindConditionProviderService" msgid="6106018791256120258">"Дозвољава власнику да се повеже са интерфејсом највишег нивоа услуге добављача услова. Не би требало никада да буде потребно за уобичајене апликације."</string>
-    <string name="permlab_bindDreamService" msgid="4776175992848982706">"повезивање са услугом сањарења"</string>
-    <string name="permdesc_bindDreamService" msgid="9129615743300572973">"Дозвољава власнику да се повеже са интерфејсом услуге сањарења највишег нивоа. Уобичајене апликације никада не би требало да је користе."</string>
-    <string name="permlab_invokeCarrierSetup" msgid="5098810760209818140">"позивање апликације са конфигурацијом коју одређује оператер"</string>
-    <string name="permdesc_invokeCarrierSetup" msgid="4790845896063237887">"Дозвољава власнику да позива апликацију са конфигурацијом коју одређује оператер. Уобичајене апликације никада не би требало да је користе."</string>
-    <string name="permlab_accessNetworkConditions" msgid="1270732533356286514">"праћење података о условима на мрежи"</string>
-    <string name="permdesc_accessNetworkConditions" msgid="2959269186741956109">"Дозвољава апликацији да прати податке о условима на мрежи. Не би никада требало да буде потребно за нормалне апликације."</string>
-    <string name="permlab_setInputCalibration" msgid="932069700285223434">"промени калибрацију улазног уређаја"</string>
-    <string name="permdesc_setInputCalibration" msgid="2937872391426631726">"Дозвољава апликацији да модификује параметре калибрације додирног екрана. Не би требало да буде потребно за нормалне апликације."</string>
-    <string name="permlab_accessDrmCertificates" msgid="6473765454472436597">"приступ DRM сертификатима"</string>
-    <string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"Дозвољава апликацији да додељује и користи DRM сертификате. Никада не би требало да се користи за уобичајене апликације."</string>
-    <string name="permlab_handoverStatus" msgid="7620438488137057281">"пријем статуса пребацивања помоћу Android пребацивања"</string>
-    <string name="permdesc_handoverStatus" msgid="3842269451732571070">"Дозвољава овој апликацији да прима информације о актуелним пребацивањима помоћу Android пребацивања"</string>
-    <string name="permlab_removeDrmCertificates" msgid="710576248717404416">"уклањај DRM сертификате"</string>
-    <string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"Дозвољава апликацији да уклања DRM сертификате. Никада не би требало да се користи за обичне апликације."</string>
-    <string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"повезивање са услугом за размену порука мобилног оператера"</string>
-    <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Дозвољава власнику да се повеже са интерфејсом највишег нивоа за услугу за размену порука мобилног оператера. Никада не би требало да буде потребно за стандардне апликације."</string>
-    <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"повезивање са услугама оператера"</string>
-    <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Дозвољава власнику да се повеже са услугама оператера. Никада не би требало да буде потребно за обичне апликације."</string>
-    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"приступај подешавању Не узнемиравај"</string>
-    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Дозвољава апликацији да чита и уписује конфигурацију подешавања Не узнемиравај."</string>
-    <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"почетак коришћења дозволе за преглед"</string>
-    <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Дозвољава власнику да започне коришћење дозволе за апликацију. Никада не би требало да буде потребна за уобичајене апликације."</string>
-    <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"покретање прегледа одлука о дозволама"</string>
-    <string name="permdesc_startReviewPermissionDecisions" msgid="2775556853503004236">"Дозвољава власнику да покрене екран за проверу одлука о дозволама. Никада не би требало да буде потребно за обичне апликације."</string>
-    <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"покретање приказа функција апликације"</string>
-    <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Дозвољава носиоцу дозволе да започне прегледање информација о функцијама апликације."</string>
-    <string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"приступ подацима сензора при великој брзини узорковања"</string>
-    <string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Дозвољава апликацији да узима узорак података сензора при брзини већој од 200 Hz"</string>
-    <string name="policylab_limitPassword" msgid="4851829918814422199">"Подешавање правила за лозинку"</string>
-    <string name="policydesc_limitPassword" msgid="4105491021115793793">"Контролише дужину и знакове дозвољене у лозинкама и PIN-овима за закључавање екрана."</string>
-    <string name="policylab_watchLogin" msgid="7599669460083719504">"Надгледајте покушаје откључавања екрана"</string>
-    <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Прати број нетачно унетих лозинки приликом откључавања екрана и закључава таблет или брише податке са таблета ако је нетачна лозинка унета превише пута."</string>
-    <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Надгледа број нетачних лозинки унетих при откључавању екрана и закључава Android TV уређај или брише све податке са Android TV уређаја ако се унесе превише нетачних лозинки."</string>
-    <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Прати број нетачно унетих лозинки при откључавању екрана и закључава систем за инфо-забаву или брише све податке са система за инфо-забаву ако је нетачна лозинка унета превише пута."</string>
-    <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Прати број нетачно унетих лозинки при откључавању екрана и закључава телефон или брише све податке са телефона ако је нетачна лозинка унета превише пута."</string>
-    <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Надгледа број нетачних лозинки унетих при откључавању екрана и закључава таблет или брише све податке овог корисника ако се унесе превише нетачних лозинки."</string>
-    <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Надгледа број нетачних лозинки унетих при откључавању екрана и закључава Android TV уређај или брише све податке овог корисника ако се унесе превише нетачних лозинки."</string>
-    <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Надгледа број нетачних лозинки унетих при откључавању екрана и закључава систем за инфо-забаву или брише све податке овог профила ако се унесе превише нетачних лозинки."</string>
-    <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"Надгледа број нетачних лозинки унетих при откључавању екрана и закључава телефон или брише све податке овог корисника ако се унесе превише нетачних лозинки."</string>
-    <string name="policylab_resetPassword" msgid="214556238645096520">"Промена закључавања екрана"</string>
-    <string name="policydesc_resetPassword" msgid="4626419138439341851">"Мења закључавање екрана."</string>
-    <string name="policylab_forceLock" msgid="7360335502968476434">"Закључавање екрана"</string>
-    <string name="policydesc_forceLock" msgid="1008844760853899693">"Контрола начина и времена закључавања екрана."</string>
-    <string name="policylab_wipeData" msgid="1359485247727537311">"Брисање свих података"</string>
-    <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Брисање података на таблету без упозорења ресетовањем на фабричка подешавања."</string>
-    <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Брише податке Android TV уређаја без упозорења помоћу ресетовања на фабричка подешавања."</string>
-    <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Брише податке на систему за инфо-забаву без упозорења ресетовањем на фабричка подешавања."</string>
-    <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Брисање података на телефону без упозорења ресетовањем на фабричка подешавања."</string>
-    <string name="policylab_wipeData_secondaryUser" product="automotive" msgid="115034358520328373">"Брисање података профила"</string>
-    <string name="policylab_wipeData_secondaryUser" product="default" msgid="413813645323433166">"Обриши податке корисника"</string>
-    <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"Брише податке овог корисника на овом таблету без упозорења."</string>
-    <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"Брише податке овог корисника на овом Android TV уређају без упозорења."</string>
-    <string name="policydesc_wipeData_secondaryUser" product="automotive" msgid="4658832487305780879">"Брише податке овог профила на овом систему за инфо-забаву без упозорења."</string>
-    <string name="policydesc_wipeData_secondaryUser" product="default" msgid="2788325512167208654">"Брише податке овог корисника на овом телефону без упозорења."</string>
-    <string name="policylab_setGlobalProxy" msgid="215332221188670221">"Подесите глобални прокси сервер уређаја"</string>
-    <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"Подешава глобални прокси уређаја који ће се користити док су смернице омогућене. Само власник уређаја може да подеси глобални прокси."</string>
-    <string name="policylab_expirePassword" msgid="6015404400532459169">"Подеси истек. лозин. за закљ. екр."</string>
-    <string name="policydesc_expirePassword" msgid="9136524319325960675">"Мења колико често лозинка, PIN или шаблон за закључавање екрана мора да се мења."</string>
-    <string name="policylab_encryptedStorage" msgid="9012936958126670110">"Подешавање шифровања складишта"</string>
-    <string name="policydesc_encryptedStorage" msgid="1102516950740375617">"Захтева да сачувани подаци апликације буду шифровани."</string>
-    <string name="policylab_disableCamera" msgid="5749486347810162018">"Онемогућавање камера"</string>
-    <string name="policydesc_disableCamera" msgid="3204405908799676104">"Спречите коришћење свих камера уређаја."</string>
-    <string name="policylab_disableKeyguardFeatures" msgid="5071855750149949741">"Онемогућавање функција закљ. екрана"</string>
-    <string name="policydesc_disableKeyguardFeatures" msgid="6641673177041195957">"Спречава коришћење неких функција закључавања екрана."</string>
+    <string name="face_error_vendor_unknown" msgid="7387005932083302070">"Došlo je do problema. Probajte ponovo."</string>
+    <string name="face_icon_content_description" msgid="465030547475916280">"Ikona lica"</string>
+    <string name="permlab_readSyncSettings" msgid="6250532864893156277">"čitanje podešavanja sinhronizacije"</string>
+    <string name="permdesc_readSyncSettings" msgid="1325658466358779298">"Dozvoljava aplikaciji da čita podešavanja sinhronizacije za nalog. Na primer, ovako može da se utvrdi da li je aplikacija Ljudi sinhronizovana sa nalogom."</string>
+    <string name="permlab_writeSyncSettings" msgid="6583154300780427399">"uključivanje i isključivanje sinhronizacije"</string>
+    <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"Dozvoljava aplikaciji da menja podešavanja sinhronizacije za nalog. Na primer, ovako može da se omogući sinhronizacija aplikacije Ljudi sa nalogom."</string>
+    <string name="permlab_readSyncStats" msgid="3747407238320105332">"čitanje statistike o sinhronizaciji"</string>
+    <string name="permdesc_readSyncStats" msgid="3867809926567379434">"Dozvoljava aplikaciji da čita statistiku sinhronizacije za nalog, uključujući istoriju sinhronizovanih događaja i količinu podataka koji se sinhronizuju."</string>
+    <string name="permlab_sdcardRead" msgid="5791467020950064920">"čitanje sadržaja deljenog memorijskog prostora"</string>
+    <string name="permdesc_sdcardRead" msgid="6872973242228240382">"Dozvoljava aplikaciji da čita sadržaj deljenog memorijskog prostora."</string>
+    <string name="permlab_readMediaAudio" msgid="8723513075731763810">"čitanje audio fajlova iz deljenog memorijskog prostora"</string>
+    <string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Omogućava aplikaciji da čita audio fajlove iz deljenog memorijskog prostora."</string>
+    <string name="permlab_readMediaVideo" msgid="7768003311260655007">"čitanje video fajlova iz deljenog memorijskog prostora"</string>
+    <string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Omogućava aplikaciji da čita video fajlove iz deljenog memorijskog prostora."</string>
+    <string name="permlab_readMediaImages" msgid="4057590631020986789">"čitanje fajlova slika iz deljenog memorijskog prostora"</string>
+    <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Omogućava aplikaciji da čita fajlove slika iz deljenog memorijskog prostora."</string>
+    <string name="permlab_sdcardWrite" msgid="4863021819671416668">"menjanje ili brisanje sadržaja deljenog memorijskog prostora"</string>
+    <string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Dozvoljava aplikaciji da upisuje sadržaj deljenog memorijskog prostora."</string>
+    <string name="permlab_use_sip" msgid="8250774565189337477">"upućivanje/prijem SIP poziva"</string>
+    <string name="permdesc_use_sip" msgid="3590270893253204451">"Omogućava aplikaciji da upućuje i prima SIP pozive."</string>
+    <string name="permlab_register_sim_subscription" msgid="1653054249287576161">"registruje nove veze sa telekomunikacionim mrežama preko SIM kartice"</string>
+    <string name="permdesc_register_sim_subscription" msgid="4183858662792232464">"Dozvoljava aplikaciji da registruje nove veze sa telekomunikacionim mrežama preko SIM kartice."</string>
+    <string name="permlab_register_call_provider" msgid="6135073566140050702">"registruje nove veze sa telekomunikacionim mrežama"</string>
+    <string name="permdesc_register_call_provider" msgid="4201429251459068613">"Dozvoljava aplikaciji da registruje nove veze sa telekomunikacionim mrežama."</string>
+    <string name="permlab_connection_manager" msgid="3179365584691166915">"upravljanje vezama sa telekomunikacionim mrežama"</string>
+    <string name="permdesc_connection_manager" msgid="1426093604238937733">"Dozvoljava aplikaciji da upravlja vezama sa telekomunikacionim mrežama."</string>
+    <string name="permlab_bind_incall_service" msgid="5990625112603493016">"komuniciraj sa ekranom tokom poziva"</string>
+    <string name="permdesc_bind_incall_service" msgid="4124917526967765162">"Dozvoljava aplikaciji da kontroliše kada i kako se korisniku prikazuje ekran tokom poziva."</string>
+    <string name="permlab_bind_connection_service" msgid="5409268245525024736">"da stupa u interakciju sa telefonskim uslugama"</string>
+    <string name="permdesc_bind_connection_service" msgid="6261796725253264518">"Dozvoljava interakciju aplikacije sa telefonskim uslugama radi upućivanja/primanja poziva."</string>
+    <string name="permlab_control_incall_experience" msgid="6436863486094352987">"pružaj korisnički doživljaj tokom poziva"</string>
+    <string name="permdesc_control_incall_experience" msgid="5896723643771737534">"Dozvoljava aplikaciji da pruža korisnički doživljaj tokom poziva."</string>
+    <string name="permlab_readNetworkUsageHistory" msgid="8470402862501573795">"čita istoriju korišćenja mreže"</string>
+    <string name="permdesc_readNetworkUsageHistory" msgid="1112962304941637102">"Dozvoljava aplikaciji da čita istoriju korišćenja mreže za posebne mreže i aplikacije."</string>
+    <string name="permlab_manageNetworkPolicy" msgid="6872549423152175378">"upravljanje smernicama za mrežu"</string>
+    <string name="permdesc_manageNetworkPolicy" msgid="1865663268764673296">"Dozvoljava aplikaciji da upravlja smernicama za mrežu i određuje posebna pravila za aplikaciju."</string>
+    <string name="permlab_modifyNetworkAccounting" msgid="7448790834938749041">"izmenite obračunavanje korišćenja mreže"</string>
+    <string name="permdesc_modifyNetworkAccounting" msgid="5076042642247205390">"Dozvoljava aplikaciji da izmeni način na koji aplikacije koriste mrežu. Ne koriste je uobičajene aplikacije."</string>
+    <string name="permlab_accessNotifications" msgid="7130360248191984741">"pristup obaveštenjima"</string>
+    <string name="permdesc_accessNotifications" msgid="761730149268789668">"Dozvoljava aplikaciji da preuzima, ispituje i briše obaveštenja, uključujući ona koja postavljaju druge aplikacije."</string>
+    <string name="permlab_bindNotificationListenerService" msgid="5848096702733262458">"povezivanje sa uslugom monitora obaveštenja"</string>
+    <string name="permdesc_bindNotificationListenerService" msgid="4970553694467137126">"Dozvoljava vlasniku da se poveže sa interfejsom usluge monitora obaveštenja najvišeg nivoa. Uobičajene aplikacije nikada ne bi trebalo da je koriste."</string>
+    <string name="permlab_bindConditionProviderService" msgid="5245421224814878483">"poveži sa uslugom dobavljača uslova"</string>
+    <string name="permdesc_bindConditionProviderService" msgid="6106018791256120258">"Dozvoljava vlasniku da se poveže sa interfejsom najvišeg nivoa usluge dobavljača uslova. Ne bi trebalo nikada da bude potrebno za uobičajene aplikacije."</string>
+    <string name="permlab_bindDreamService" msgid="4776175992848982706">"povezivanje sa uslugom sanjarenja"</string>
+    <string name="permdesc_bindDreamService" msgid="9129615743300572973">"Dozvoljava vlasniku da se poveže sa interfejsom usluge sanjarenja najvišeg nivoa. Uobičajene aplikacije nikada ne bi trebalo da je koriste."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="5098810760209818140">"pozivanje aplikacije sa konfiguracijom koju određuje operater"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4790845896063237887">"Dozvoljava vlasniku da poziva aplikaciju sa konfiguracijom koju određuje operater. Uobičajene aplikacije nikada ne bi trebalo da je koriste."</string>
+    <string name="permlab_accessNetworkConditions" msgid="1270732533356286514">"praćenje podataka o uslovima na mreži"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="2959269186741956109">"Dozvoljava aplikaciji da prati podatke o uslovima na mreži. Ne bi nikada trebalo da bude potrebno za normalne aplikacije."</string>
+    <string name="permlab_setInputCalibration" msgid="932069700285223434">"promeni kalibraciju ulaznog uređaja"</string>
+    <string name="permdesc_setInputCalibration" msgid="2937872391426631726">"Dozvoljava aplikaciji da modifikuje parametre kalibracije dodirnog ekrana. Ne bi trebalo da bude potrebno za normalne aplikacije."</string>
+    <string name="permlab_accessDrmCertificates" msgid="6473765454472436597">"pristup DRM sertifikatima"</string>
+    <string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"Dozvoljava aplikaciji da dodeljuje i koristi DRM sertifikate. Nikada ne bi trebalo da se koristi za uobičajene aplikacije."</string>
+    <string name="permlab_handoverStatus" msgid="7620438488137057281">"prijem statusa prebacivanja pomoću Android prebacivanja"</string>
+    <string name="permdesc_handoverStatus" msgid="3842269451732571070">"Dozvoljava ovoj aplikaciji da prima informacije o aktuelnim prebacivanjima pomoću Android prebacivanja"</string>
+    <string name="permlab_removeDrmCertificates" msgid="710576248717404416">"uklanjaj DRM sertifikate"</string>
+    <string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"Dozvoljava aplikaciji da uklanja DRM sertifikate. Nikada ne bi trebalo da se koristi za obične aplikacije."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"povezivanje sa uslugom za razmenu poruka mobilnog operatera"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Dozvoljava vlasniku da se poveže sa interfejsom najvišeg nivoa za uslugu za razmenu poruka mobilnog operatera. Nikada ne bi trebalo da bude potrebno za standardne aplikacije."</string>
+    <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"povezivanje sa uslugama operatera"</string>
+    <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Dozvoljava vlasniku da se poveže sa uslugama operatera. Nikada ne bi trebalo da bude potrebno za obične aplikacije."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"pristupaj podešavanju Ne uznemiravaj"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Dozvoljava aplikaciji da čita i upisuje konfiguraciju podešavanja Ne uznemiravaj."</string>
+    <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"početak korišćenja dozvole za pregled"</string>
+    <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Dozvoljava vlasniku da započne korišćenje dozvole za aplikaciju. Nikada ne bi trebalo da bude potrebna za uobičajene aplikacije."</string>
+    <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"pokretanje pregleda odluka o dozvolama"</string>
+    <string name="permdesc_startReviewPermissionDecisions" msgid="2775556853503004236">"Dozvoljava vlasniku da pokrene ekran za proveru odluka o dozvolama. Nikada ne bi trebalo da bude potrebno za obične aplikacije."</string>
+    <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"pokretanje prikaza funkcija aplikacije"</string>
+    <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Dozvoljava nosiocu dozvole da započne pregledanje informacija o funkcijama aplikacije."</string>
+    <string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"pristup podacima senzora pri velikoj brzini uzorkovanja"</string>
+    <string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Dozvoljava aplikaciji da uzima uzorak podataka senzora pri brzini većoj od 200 Hz"</string>
+    <string name="policylab_limitPassword" msgid="4851829918814422199">"Podešavanje pravila za lozinku"</string>
+    <string name="policydesc_limitPassword" msgid="4105491021115793793">"Kontroliše dužinu i znakove dozvoljene u lozinkama i PIN-ovima za zaključavanje ekrana."</string>
+    <string name="policylab_watchLogin" msgid="7599669460083719504">"Nadgledajte pokušaje otključavanja ekrana"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Prati broj netačno unetih lozinki prilikom otključavanja ekrana i zaključava tablet ili briše podatke sa tableta ako je netačna lozinka uneta previše puta."</string>
+    <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Nadgleda broj netačnih lozinki unetih pri otključavanju ekrana i zaključava Android TV uređaj ili briše sve podatke sa Android TV uređaja ako se unese previše netačnih lozinki."</string>
+    <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Prati broj netačno unetih lozinki pri otključavanju ekrana i zaključava sistem za info-zabavu ili briše sve podatke sa sistema za info-zabavu ako je netačna lozinka uneta previše puta."</string>
+    <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Prati broj netačno unetih lozinki pri otključavanju ekrana i zaključava telefon ili briše sve podatke sa telefona ako je netačna lozinka uneta previše puta."</string>
+    <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Nadgleda broj netačnih lozinki unetih pri otključavanju ekrana i zaključava tablet ili briše sve podatke ovog korisnika ako se unese previše netačnih lozinki."</string>
+    <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Nadgleda broj netačnih lozinki unetih pri otključavanju ekrana i zaključava Android TV uređaj ili briše sve podatke ovog korisnika ako se unese previše netačnih lozinki."</string>
+    <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Nadgleda broj netačnih lozinki unetih pri otključavanju ekrana i zaključava sistem za info-zabavu ili briše sve podatke ovog profila ako se unese previše netačnih lozinki."</string>
+    <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"Nadgleda broj netačnih lozinki unetih pri otključavanju ekrana i zaključava telefon ili briše sve podatke ovog korisnika ako se unese previše netačnih lozinki."</string>
+    <string name="policylab_resetPassword" msgid="214556238645096520">"Promena zaključavanja ekrana"</string>
+    <string name="policydesc_resetPassword" msgid="4626419138439341851">"Menja zaključavanje ekrana."</string>
+    <string name="policylab_forceLock" msgid="7360335502968476434">"Zaključavanje ekrana"</string>
+    <string name="policydesc_forceLock" msgid="1008844760853899693">"Kontrola načina i vremena zaključavanja ekrana."</string>
+    <string name="policylab_wipeData" msgid="1359485247727537311">"Brisanje svih podataka"</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Brisanje podataka na tabletu bez upozorenja resetovanjem na fabrička podešavanja."</string>
+    <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Briše podatke Android TV uređaja bez upozorenja pomoću resetovanja na fabrička podešavanja."</string>
+    <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Briše podatke na sistemu za info-zabavu bez upozorenja resetovanjem na fabrička podešavanja."</string>
+    <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Brisanje podataka na telefonu bez upozorenja resetovanjem na fabrička podešavanja."</string>
+    <string name="policylab_wipeData_secondaryUser" product="automotive" msgid="115034358520328373">"Brisanje podataka profila"</string>
+    <string name="policylab_wipeData_secondaryUser" product="default" msgid="413813645323433166">"Obriši podatke korisnika"</string>
+    <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"Briše podatke ovog korisnika na ovom tabletu bez upozorenja."</string>
+    <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"Briše podatke ovog korisnika na ovom Android TV uređaju bez upozorenja."</string>
+    <string name="policydesc_wipeData_secondaryUser" product="automotive" msgid="4658832487305780879">"Briše podatke ovog profila na ovom sistemu za info-zabavu bez upozorenja."</string>
+    <string name="policydesc_wipeData_secondaryUser" product="default" msgid="2788325512167208654">"Briše podatke ovog korisnika na ovom telefonu bez upozorenja."</string>
+    <string name="policylab_setGlobalProxy" msgid="215332221188670221">"Podesite globalni proksi server uređaja"</string>
+    <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"Podešava globalni proksi uređaja koji će se koristiti dok su smernice omogućene. Samo vlasnik uređaja može da podesi globalni proksi."</string>
+    <string name="policylab_expirePassword" msgid="6015404400532459169">"Podesi istek. lozin. za zaklj. ekr."</string>
+    <string name="policydesc_expirePassword" msgid="9136524319325960675">"Menja koliko često lozinka, PIN ili šablon za zaključavanje ekrana mora da se menja."</string>
+    <string name="policylab_encryptedStorage" msgid="9012936958126670110">"Podešavanje šifrovanja skladišta"</string>
+    <string name="policydesc_encryptedStorage" msgid="1102516950740375617">"Zahteva da sačuvani podaci aplikacije budu šifrovani."</string>
+    <string name="policylab_disableCamera" msgid="5749486347810162018">"Onemogućavanje kamera"</string>
+    <string name="policydesc_disableCamera" msgid="3204405908799676104">"Sprečite korišćenje svih kamera uređaja."</string>
+    <string name="policylab_disableKeyguardFeatures" msgid="5071855750149949741">"Onemogućavanje funkcija zaklj. ekrana"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="6641673177041195957">"Sprečava korišćenje nekih funkcija zaključavanja ekrana."</string>
   <string-array name="phoneTypes">
-    <item msgid="8996339953292723951">"Кућа"</item>
-    <item msgid="7740243458912727194">"Мобилни"</item>
-    <item msgid="8526146065496663766">"Посао"</item>
-    <item msgid="8150904584178569699">"Факс на послу"</item>
-    <item msgid="4537253139152229577">"Факс код куће"</item>
-    <item msgid="6751245029698664340">"Пејџер"</item>
-    <item msgid="1692790665884224905">"Друго"</item>
-    <item msgid="6216981255272016212">"Прилагођено"</item>
+    <item msgid="8996339953292723951">"Kuća"</item>
+    <item msgid="7740243458912727194">"Mobilni"</item>
+    <item msgid="8526146065496663766">"Posao"</item>
+    <item msgid="8150904584178569699">"Faks na poslu"</item>
+    <item msgid="4537253139152229577">"Faks kod kuće"</item>
+    <item msgid="6751245029698664340">"Pejdžer"</item>
+    <item msgid="1692790665884224905">"Drugo"</item>
+    <item msgid="6216981255272016212">"Prilagođeno"</item>
   </string-array>
   <string-array name="emailAddressTypes">
-    <item msgid="7786349763648997741">"Кућа"</item>
-    <item msgid="435564470865989199">"Посао"</item>
-    <item msgid="4199433197875490373">"Друго"</item>
-    <item msgid="3233938986670468328">"Прилагођено"</item>
+    <item msgid="7786349763648997741">"Kuća"</item>
+    <item msgid="435564470865989199">"Posao"</item>
+    <item msgid="4199433197875490373">"Drugo"</item>
+    <item msgid="3233938986670468328">"Prilagođeno"</item>
   </string-array>
   <string-array name="postalAddressTypes">
-    <item msgid="3861463339764243038">"Кућа"</item>
-    <item msgid="5472578890164979109">"Посао"</item>
-    <item msgid="5718921296646594739">"Друго"</item>
-    <item msgid="5523122236731783179">"Прилагођено"</item>
+    <item msgid="3861463339764243038">"Kuća"</item>
+    <item msgid="5472578890164979109">"Posao"</item>
+    <item msgid="5718921296646594739">"Drugo"</item>
+    <item msgid="5523122236731783179">"Prilagođeno"</item>
   </string-array>
   <string-array name="imAddressTypes">
-    <item msgid="588088543406993772">"Кућа"</item>
-    <item msgid="5503060422020476757">"Посао"</item>
-    <item msgid="2530391194653760297">"Друго"</item>
-    <item msgid="7640927178025203330">"Прилагођено"</item>
+    <item msgid="588088543406993772">"Kuća"</item>
+    <item msgid="5503060422020476757">"Posao"</item>
+    <item msgid="2530391194653760297">"Drugo"</item>
+    <item msgid="7640927178025203330">"Prilagođeno"</item>
   </string-array>
   <string-array name="organizationTypes">
-    <item msgid="6144047813304847762">"Посао"</item>
-    <item msgid="7402720230065674193">"Друго"</item>
-    <item msgid="808230403067569648">"Прилагођено"</item>
+    <item msgid="6144047813304847762">"Posao"</item>
+    <item msgid="7402720230065674193">"Drugo"</item>
+    <item msgid="808230403067569648">"Prilagođeno"</item>
   </string-array>
   <string-array name="imProtocols">
     <item msgid="7535761744432206400">"AIM"</item>
@@ -837,45 +837,45 @@
     <item msgid="4717545739447438044">"ICQ"</item>
     <item msgid="8293711853624033835">"Jabber"</item>
   </string-array>
-    <string name="phoneTypeCustom" msgid="5120365721260686814">"Прилагођено"</string>
-    <string name="phoneTypeHome" msgid="3880132427643623588">"Кућа"</string>
-    <string name="phoneTypeMobile" msgid="1178852541462086735">"Мобилни"</string>
-    <string name="phoneTypeWork" msgid="6604967163358864607">"Посао"</string>
-    <string name="phoneTypeFaxWork" msgid="6757519896109439123">"Факс на послу"</string>
-    <string name="phoneTypeFaxHome" msgid="6678559953115904345">"Факс код куће"</string>
-    <string name="phoneTypePager" msgid="576402072263522767">"Пејџер"</string>
-    <string name="phoneTypeOther" msgid="6918196243648754715">"Друго"</string>
-    <string name="phoneTypeCallback" msgid="3455781500844157767">"Повратни позив"</string>
-    <string name="phoneTypeCar" msgid="4604775148963129195">"Аутомобил"</string>
-    <string name="phoneTypeCompanyMain" msgid="4482773154536455441">"Пословни главни"</string>
+    <string name="phoneTypeCustom" msgid="5120365721260686814">"Prilagođeno"</string>
+    <string name="phoneTypeHome" msgid="3880132427643623588">"Kuća"</string>
+    <string name="phoneTypeMobile" msgid="1178852541462086735">"Mobilni"</string>
+    <string name="phoneTypeWork" msgid="6604967163358864607">"Posao"</string>
+    <string name="phoneTypeFaxWork" msgid="6757519896109439123">"Faks na poslu"</string>
+    <string name="phoneTypeFaxHome" msgid="6678559953115904345">"Faks kod kuće"</string>
+    <string name="phoneTypePager" msgid="576402072263522767">"Pejdžer"</string>
+    <string name="phoneTypeOther" msgid="6918196243648754715">"Drugo"</string>
+    <string name="phoneTypeCallback" msgid="3455781500844157767">"Povratni poziv"</string>
+    <string name="phoneTypeCar" msgid="4604775148963129195">"Automobil"</string>
+    <string name="phoneTypeCompanyMain" msgid="4482773154536455441">"Poslovni glavni"</string>
     <string name="phoneTypeIsdn" msgid="2496238954533998512">"ISDN"</string>
-    <string name="phoneTypeMain" msgid="5199722006991000111">"Главни"</string>
-    <string name="phoneTypeOtherFax" msgid="3037145630364770357">"Други факс"</string>
-    <string name="phoneTypeRadio" msgid="2637819130239264771">"Радио"</string>
-    <string name="phoneTypeTelex" msgid="2558783611711876562">"Телекс"</string>
+    <string name="phoneTypeMain" msgid="5199722006991000111">"Glavni"</string>
+    <string name="phoneTypeOtherFax" msgid="3037145630364770357">"Drugi faks"</string>
+    <string name="phoneTypeRadio" msgid="2637819130239264771">"Radio"</string>
+    <string name="phoneTypeTelex" msgid="2558783611711876562">"Teleks"</string>
     <string name="phoneTypeTtyTdd" msgid="532038552105328779">"TTY TDD"</string>
-    <string name="phoneTypeWorkMobile" msgid="7522314392003565121">"Пословни мобилни"</string>
-    <string name="phoneTypeWorkPager" msgid="3748332310638505234">"Пословни пејџер"</string>
-    <string name="phoneTypeAssistant" msgid="757550783842231039">"Помоћник"</string>
+    <string name="phoneTypeWorkMobile" msgid="7522314392003565121">"Poslovni mobilni"</string>
+    <string name="phoneTypeWorkPager" msgid="3748332310638505234">"Poslovni pejdžer"</string>
+    <string name="phoneTypeAssistant" msgid="757550783842231039">"Pomoćnik"</string>
     <string name="phoneTypeMms" msgid="1799747455131365989">"MMS"</string>
-    <string name="eventTypeCustom" msgid="3257367158986466481">"Прилагођено"</string>
-    <string name="eventTypeBirthday" msgid="7770026752793912283">"Рођендан"</string>
-    <string name="eventTypeAnniversary" msgid="4684702412407916888">"Годишњица"</string>
-    <string name="eventTypeOther" msgid="530671238533887997">"Други"</string>
-    <string name="emailTypeCustom" msgid="1809435350482181786">"Прилагођено"</string>
-    <string name="emailTypeHome" msgid="1597116303154775999">"Кућа"</string>
-    <string name="emailTypeWork" msgid="2020095414401882111">"Посао"</string>
-    <string name="emailTypeOther" msgid="5131130857030897465">"Друго"</string>
-    <string name="emailTypeMobile" msgid="787155077375364230">"Мобилни"</string>
-    <string name="postalTypeCustom" msgid="5645590470242939129">"Прилагођено"</string>
-    <string name="postalTypeHome" msgid="7562272480949727912">"Кућа"</string>
-    <string name="postalTypeWork" msgid="8553425424652012826">"Посао"</string>
-    <string name="postalTypeOther" msgid="7094245413678857420">"Друго"</string>
-    <string name="imTypeCustom" msgid="5653384545085765570">"Прилагођено"</string>
-    <string name="imTypeHome" msgid="6996507981044278216">"Кућа"</string>
-    <string name="imTypeWork" msgid="2099668940169903123">"Посао"</string>
-    <string name="imTypeOther" msgid="8068447383276219810">"Друго"</string>
-    <string name="imProtocolCustom" msgid="4437878287653764692">"Прилагођено"</string>
+    <string name="eventTypeCustom" msgid="3257367158986466481">"Prilagođeno"</string>
+    <string name="eventTypeBirthday" msgid="7770026752793912283">"Rođendan"</string>
+    <string name="eventTypeAnniversary" msgid="4684702412407916888">"Godišnjica"</string>
+    <string name="eventTypeOther" msgid="530671238533887997">"Drugi"</string>
+    <string name="emailTypeCustom" msgid="1809435350482181786">"Prilagođeno"</string>
+    <string name="emailTypeHome" msgid="1597116303154775999">"Kuća"</string>
+    <string name="emailTypeWork" msgid="2020095414401882111">"Posao"</string>
+    <string name="emailTypeOther" msgid="5131130857030897465">"Drugo"</string>
+    <string name="emailTypeMobile" msgid="787155077375364230">"Mobilni"</string>
+    <string name="postalTypeCustom" msgid="5645590470242939129">"Prilagođeno"</string>
+    <string name="postalTypeHome" msgid="7562272480949727912">"Kuća"</string>
+    <string name="postalTypeWork" msgid="8553425424652012826">"Posao"</string>
+    <string name="postalTypeOther" msgid="7094245413678857420">"Drugo"</string>
+    <string name="imTypeCustom" msgid="5653384545085765570">"Prilagođeno"</string>
+    <string name="imTypeHome" msgid="6996507981044278216">"Kuća"</string>
+    <string name="imTypeWork" msgid="2099668940169903123">"Posao"</string>
+    <string name="imTypeOther" msgid="8068447383276219810">"Drugo"</string>
+    <string name="imProtocolCustom" msgid="4437878287653764692">"Prilagođeno"</string>
     <string name="imProtocolAim" msgid="4050198236506604378">"AIM"</string>
     <string name="imProtocolMsn" msgid="2257148557766499232">"Windows Live"</string>
     <string name="imProtocolYahoo" msgid="5373338758093392231">"Yahoo"</string>
@@ -885,848 +885,848 @@
     <string name="imProtocolIcq" msgid="2410325380427389521">"ICQ"</string>
     <string name="imProtocolJabber" msgid="7919269388889582015">"Jabber"</string>
     <string name="imProtocolNetMeeting" msgid="4985002408136148256">"NetMeeting"</string>
-    <string name="orgTypeWork" msgid="8684458700669564172">"Посао"</string>
-    <string name="orgTypeOther" msgid="5450675258408005553">"Друго"</string>
-    <string name="orgTypeCustom" msgid="1126322047677329218">"Прилагођено"</string>
-    <string name="relationTypeCustom" msgid="282938315217441351">"Прилагођено"</string>
-    <string name="relationTypeAssistant" msgid="4057605157116589315">"Помоћник"</string>
-    <string name="relationTypeBrother" msgid="7141662427379247820">"Брат"</string>
-    <string name="relationTypeChild" msgid="9076258911292693601">"Дете"</string>
-    <string name="relationTypeDomesticPartner" msgid="7825306887697559238">"Невенчани партнер"</string>
-    <string name="relationTypeFather" msgid="3856225062864790596">"Отац"</string>
-    <string name="relationTypeFriend" msgid="3192092625893980574">"Пријатељ"</string>
-    <string name="relationTypeManager" msgid="2272860813153171857">"Менаџер"</string>
-    <string name="relationTypeMother" msgid="2331762740982699460">"Мајка"</string>
-    <string name="relationTypeParent" msgid="4177920938333039882">"Родитељ"</string>
-    <string name="relationTypePartner" msgid="4018017075116766194">"Партнер"</string>
-    <string name="relationTypeReferredBy" msgid="5285082289602849400">"Упутио/ла"</string>
-    <string name="relationTypeRelative" msgid="3396498519818009134">"Рођак"</string>
-    <string name="relationTypeSister" msgid="3721676005094140671">"Сестра"</string>
-    <string name="relationTypeSpouse" msgid="6916682664436031703">"Супруг/а"</string>
-    <string name="sipAddressTypeCustom" msgid="6283889809842649336">"Прилагођено"</string>
-    <string name="sipAddressTypeHome" msgid="5918441930656878367">"Почетна"</string>
-    <string name="sipAddressTypeWork" msgid="7873967986701216770">"Посао"</string>
-    <string name="sipAddressTypeOther" msgid="6317012577345187275">"Други"</string>
-    <string name="quick_contacts_not_available" msgid="1262709196045052223">"Није пронађена ниједна апликација за приказ овог контакта."</string>
-    <string name="keyguard_password_enter_pin_code" msgid="6401406801060956153">"Унесите PIN кôд"</string>
-    <string name="keyguard_password_enter_puk_code" msgid="3112256684547584093">"Унесите PUK и нови PIN кôд"</string>
-    <string name="keyguard_password_enter_puk_prompt" msgid="2825313071899938305">"PUK кôд"</string>
-    <string name="keyguard_password_enter_pin_prompt" msgid="5505434724229581207">"Нови PIN кôд"</string>
-    <string name="keyguard_password_entry_touch_hint" msgid="4032288032993261520"><font size="17">"Додирните за унос лозинке"</font></string>
-    <string name="keyguard_password_enter_password_code" msgid="2751130557661643482">"Откуцајте лозинку да бисте откључали"</string>
-    <string name="keyguard_password_enter_pin_password_code" msgid="7792964196473964340">"Унесите PIN за откључавање"</string>
-    <string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"PIN кôд је нетачан."</string>
-    <string name="keyguard_label_text" msgid="3841953694564168384">"Да бисте откључали, притисните „Мени“, а затим 0."</string>
-    <string name="emergency_call_dialog_number_for_display" msgid="2978165477085612673">"Број за хитне случајеве"</string>
-    <string name="lockscreen_carrier_default" msgid="6192313772955399160">"Мобилна мрежа није доступна"</string>
-    <string name="lockscreen_screen_locked" msgid="7364905540516041817">"Екран је закључан."</string>
-    <string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Притисните „Мени“ да бисте откључали телефон или упутите хитан позив."</string>
-    <string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Притисните „Мени“ за откључавање."</string>
-    <string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Унесите шаблон за откључавање"</string>
-    <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Хитне службе"</string>
-    <string name="lockscreen_return_to_call" msgid="3156883574692006382">"Назад на позив"</string>
-    <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Тачно!"</string>
-    <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="lockscreen_missing_sim_message_short" msgid="1248431165144893792">"Нема SIM картице"</string>
-    <string name="lockscreen_missing_sim_message" product="tablet" msgid="8596805728510570760">"У таблету нема SIM картице."</string>
-    <string name="lockscreen_missing_sim_message" product="tv" msgid="2582768023352171073">"Нема SIM картице у Android TV уређају."</string>
-    <string name="lockscreen_missing_sim_message" product="default" msgid="1408695081255172556">"У телефон није уметнута SIM картица."</string>
-    <string name="lockscreen_missing_sim_instructions" msgid="8473601862688263903">"Уметните SIM картицу."</string>
-    <string name="lockscreen_missing_sim_instructions_long" msgid="3664999892038416334">"SIM недостаје или не може да се прочита. Уметните SIM картицу."</string>
-    <string name="lockscreen_permanent_disabled_sim_message_short" msgid="3812893366715730539">"SIM картица је неупотребљива."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="4358929052509450807">"SIM картица је трајно онемогућена.\n Обратите се добављачу услуге бежичне мреже да бисте добили другу SIM картицу."</string>
-    <string name="lockscreen_transport_prev_description" msgid="2879469521751181478">"Претходна песма"</string>
-    <string name="lockscreen_transport_next_description" msgid="2931509904881099919">"Следећа песма"</string>
-    <string name="lockscreen_transport_pause_description" msgid="6705284702135372494">"Пауза"</string>
-    <string name="lockscreen_transport_play_description" msgid="106868788691652733">"Пусти"</string>
-    <string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"Заустави"</string>
-    <string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"Премотај уназад"</string>
-    <string name="lockscreen_transport_ffw_description" msgid="4763794746640196772">"Премотај унапред"</string>
-    <string name="emergency_calls_only" msgid="3057351206678279851">"Само хитни позиви"</string>
-    <string name="lockscreen_network_locked_message" msgid="2814046965899249635">"Мрежа је закључана"</string>
-    <string name="lockscreen_sim_puk_locked_message" msgid="6618356415831082174">"SIM картица је закључана PUK кодом."</string>
-    <string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"Погледајте Кориснички водич или контактирајте Корисничку подршку."</string>
-    <string name="lockscreen_sim_locked_message" msgid="3160196135801185938">"SIM картица је закључана."</string>
-    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="2286497117428409709">"Откључавање SIM картице…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"<xliff:g id="NUMBER_0">%1$d</xliff:g> пута сте неправилно нацртали шаблон за откључавање. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунде/и."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"<xliff:g id="NUMBER_0">%1$d</xliff:g> пута сте погрешно унели лозинку. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунде/и."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"<xliff:g id="NUMBER_0">%1$d</xliff:g> пута сте погрешно унели PIN. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунде/и."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"<xliff:g id="NUMBER_0">%1$d</xliff:g> пута сте нетачно унели шаблон за откључавање. Након још <xliff:g id="NUMBER_1">%2$d</xliff:g> несупешна(их) покушаја, од вас ће бити затражено да откључате таблет помоћу података за пријављивање на Google.\n\n Пробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> секунде/и."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"Нетачно сте нацртали шаблон за откључавање <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још пута (<xliff:g id="NUMBER_1">%2$d</xliff:g>), затражићемо да откључате телефон помоћу Android TV уређаја.\n\n Пробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> сек."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"<xliff:g id="NUMBER_0">%1$d</xliff:g> пута сте нетачно унели шаблон за откључавање. Након још <xliff:g id="NUMBER_1">%2$d</xliff:g> несупешна(их) покушаја, од вас ће бити затражено да откључате телефон помоћу података за пријављивање на Google.\n\n Пробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> секунде/и."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"Неправилно сте покушали да откључате таблет <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Након још неуспешних покушаја (<xliff:g id="NUMBER_1">%2$d</xliff:g>) таблет ће бити ресетован на фабричка подешавања и сви кориснички подаци ће бити изгубљени."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"Број ваших неуспешних покушаја да откључате Android TV уређај: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Број преосталих неуспешних покушаја после којих ће се Android TV ресетовати на фабричка подешавања и сви подаци корисника ће бити изгубљени: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"Неисправно сте покушали да откључате телефон <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Након још неуспешних покушаја (<xliff:g id="NUMBER_1">%2$d</xliff:g>) телефон ће бити ресетован на фабричка подешавања и сви кориснички подаци ће бити изгубљени."</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"Неисправно сте покушали да откључате таблет <xliff:g id="NUMBER">%d</xliff:g> пута. Таблет ће сада бити враћен на подразумевана фабричка подешавања."</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"Број ваших неуспешних покушаја да откључате Android TV уређај: <xliff:g id="NUMBER">%d</xliff:g>. Android TV уређај ће се сада ресетовати на фабричка подешавања."</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"Неисправно сте покушали да откључате телефон <xliff:g id="NUMBER">%d</xliff:g> пута. Телефон ће сада бити враћен на подразумевана фабричка подешавања."</string>
-    <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"Пробајте поново за <xliff:g id="NUMBER">%d</xliff:g> секунде/и."</string>
-    <string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"Заборавили сте шаблон?"</string>
-    <string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"Откључавање налога"</string>
-    <string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"Превише покушаја уноса шаблона"</string>
-    <string name="lockscreen_glogin_instructions" msgid="4695162942525531700">"Да бисте откључали, пријавите се помоћу Google налога."</string>
-    <string name="lockscreen_glogin_username_hint" msgid="6916101478673157045">"Корисничко име (имејл адреса)"</string>
-    <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_checking_password" msgid="2607271802803381645">"Проверавање..."</string>
-    <string name="lockscreen_unlock_label" msgid="4648257878373307582">"Откључај"</string>
-    <string name="lockscreen_sound_on_label" msgid="1660281470535492430">"Укључи звук"</string>
-    <string name="lockscreen_sound_off_label" msgid="2331496559245450053">"Искључи звук"</string>
-    <string name="lockscreen_access_pattern_start" msgid="3778502525702613399">"Образац је започет"</string>
-    <string name="lockscreen_access_pattern_cleared" msgid="7493849102641167049">"Образац је обрисан"</string>
-    <string name="lockscreen_access_pattern_cell_added" msgid="6746676335293144163">"Ћелија је додата"</string>
-    <string name="lockscreen_access_pattern_cell_added_verbose" msgid="2931364927622563465">"Ћелија <xliff:g id="CELL_INDEX">%1$s</xliff:g> је додата"</string>
-    <string name="lockscreen_access_pattern_detected" msgid="3931150554035194012">"Образац је довршен"</string>
-    <string name="lockscreen_access_pattern_area" msgid="1288780416685002841">"Област шаблона."</string>
-    <string name="keyguard_accessibility_widget_changed" msgid="7298011259508200234">"%1$s. Виџет %2$d од %3$d."</string>
-    <string name="keyguard_accessibility_add_widget" msgid="8245795023551343672">"Додај виџет."</string>
-    <string name="keyguard_accessibility_widget_empty_slot" msgid="544239307077644480">"Празно"</string>
-    <string name="keyguard_accessibility_unlock_area_expanded" msgid="7768634718706488951">"Област откључавања је проширена."</string>
-    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="4729922043778400434">"Област откључавања је скупљена."</string>
-    <string name="keyguard_accessibility_widget" msgid="6776892679715699875">"Виџет <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
-    <string name="keyguard_accessibility_user_selector" msgid="1466067610235696600">"Избор корисника"</string>
-    <string name="keyguard_accessibility_status" msgid="6792745049712397237">"Статус"</string>
-    <string name="keyguard_accessibility_camera" msgid="7862557559464986528">"Камера"</string>
-    <string name="keygaurd_accessibility_media_controls" msgid="2267379779900620614">"Контроле за медије"</string>
-    <string name="keyguard_accessibility_widget_reorder_start" msgid="7066213328912939191">"Започела је промена редоследа виџета."</string>
-    <string name="keyguard_accessibility_widget_reorder_end" msgid="1083806817600593490">"Промена редоследа виџета је завршена."</string>
-    <string name="keyguard_accessibility_widget_deleted" msgid="1509738950119878705">"Виџет <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> је избрисан."</string>
-    <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_pin_unlock" msgid="4020864007967340068">"Откључавање PIN-ом."</string>
-    <string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"Откључава SIM картицу PIN-ом."</string>
-    <string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"Откључава SIM картицу PUK-ом."</string>
-    <string name="keyguard_accessibility_password_unlock" msgid="6130186108581153265">"Откључавање лозинком."</string>
-    <string name="keyguard_accessibility_pattern_area" msgid="1419570880512350689">"Област шаблона."</string>
-    <string name="keyguard_accessibility_slide_area" msgid="4331399051142520176">"Област превлачења."</string>
+    <string name="orgTypeWork" msgid="8684458700669564172">"Posao"</string>
+    <string name="orgTypeOther" msgid="5450675258408005553">"Drugo"</string>
+    <string name="orgTypeCustom" msgid="1126322047677329218">"Prilagođeno"</string>
+    <string name="relationTypeCustom" msgid="282938315217441351">"Prilagođeno"</string>
+    <string name="relationTypeAssistant" msgid="4057605157116589315">"Pomoćnik"</string>
+    <string name="relationTypeBrother" msgid="7141662427379247820">"Brat"</string>
+    <string name="relationTypeChild" msgid="9076258911292693601">"Dete"</string>
+    <string name="relationTypeDomesticPartner" msgid="7825306887697559238">"Nevenčani partner"</string>
+    <string name="relationTypeFather" msgid="3856225062864790596">"Otac"</string>
+    <string name="relationTypeFriend" msgid="3192092625893980574">"Prijatelj"</string>
+    <string name="relationTypeManager" msgid="2272860813153171857">"Menadžer"</string>
+    <string name="relationTypeMother" msgid="2331762740982699460">"Majka"</string>
+    <string name="relationTypeParent" msgid="4177920938333039882">"Roditelj"</string>
+    <string name="relationTypePartner" msgid="4018017075116766194">"Partner"</string>
+    <string name="relationTypeReferredBy" msgid="5285082289602849400">"Uputio/la"</string>
+    <string name="relationTypeRelative" msgid="3396498519818009134">"Rođak"</string>
+    <string name="relationTypeSister" msgid="3721676005094140671">"Sestra"</string>
+    <string name="relationTypeSpouse" msgid="6916682664436031703">"Suprug/a"</string>
+    <string name="sipAddressTypeCustom" msgid="6283889809842649336">"Prilagođeno"</string>
+    <string name="sipAddressTypeHome" msgid="5918441930656878367">"Početna"</string>
+    <string name="sipAddressTypeWork" msgid="7873967986701216770">"Posao"</string>
+    <string name="sipAddressTypeOther" msgid="6317012577345187275">"Drugi"</string>
+    <string name="quick_contacts_not_available" msgid="1262709196045052223">"Nije pronađena nijedna aplikacija za prikaz ovog kontakta."</string>
+    <string name="keyguard_password_enter_pin_code" msgid="6401406801060956153">"Unesite PIN kôd"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="3112256684547584093">"Unesite PUK i novi PIN kôd"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="2825313071899938305">"PUK kôd"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="5505434724229581207">"Novi PIN kôd"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="4032288032993261520"><font size="17">"Dodirnite za unos lozinke"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="2751130557661643482">"Otkucajte lozinku da biste otključali"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="7792964196473964340">"Unesite PIN za otključavanje"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"PIN kôd je netačan."</string>
+    <string name="keyguard_label_text" msgid="3841953694564168384">"Da biste otključali, pritisnite „Meni“, a zatim 0."</string>
+    <string name="emergency_call_dialog_number_for_display" msgid="2978165477085612673">"Broj za hitne slučajeve"</string>
+    <string name="lockscreen_carrier_default" msgid="6192313772955399160">"Mobilna mreža nije dostupna"</string>
+    <string name="lockscreen_screen_locked" msgid="7364905540516041817">"Ekran je zaključan."</string>
+    <string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Pritisnite „Meni“ da biste otključali telefon ili uputite hitan poziv."</string>
+    <string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Pritisnite „Meni“ za otključavanje."</string>
+    <string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Unesite šablon za otključavanje"</string>
+    <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Hitne službe"</string>
+    <string name="lockscreen_return_to_call" msgid="3156883574692006382">"Nazad na poziv"</string>
+    <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Tačno!"</string>
+    <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Probajte ponovo"</string>
+    <string name="lockscreen_password_wrong" msgid="8605355913868947490">"Probajte ponovo"</string>
+    <string name="lockscreen_storage_locked" msgid="634993789186443380">"Otključaj za sve funkcije i podatke"</string>
+    <string name="faceunlock_multiple_failures" msgid="681991538434031708">"Premašen je najveći dozvoljeni broj pokušaja Otključavanja licem"</string>
+    <string name="lockscreen_missing_sim_message_short" msgid="1248431165144893792">"Nema SIM kartice"</string>
+    <string name="lockscreen_missing_sim_message" product="tablet" msgid="8596805728510570760">"U tabletu nema SIM kartice."</string>
+    <string name="lockscreen_missing_sim_message" product="tv" msgid="2582768023352171073">"Nema SIM kartice u Android TV uređaju."</string>
+    <string name="lockscreen_missing_sim_message" product="default" msgid="1408695081255172556">"U telefon nije umetnuta SIM kartica."</string>
+    <string name="lockscreen_missing_sim_instructions" msgid="8473601862688263903">"Umetnite SIM karticu."</string>
+    <string name="lockscreen_missing_sim_instructions_long" msgid="3664999892038416334">"SIM nedostaje ili ne može da se pročita. Umetnite SIM karticu."</string>
+    <string name="lockscreen_permanent_disabled_sim_message_short" msgid="3812893366715730539">"SIM kartica je neupotrebljiva."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="4358929052509450807">"SIM kartica je trajno onemogućena.\n Obratite se dobavljaču usluge bežične mreže da biste dobili drugu SIM karticu."</string>
+    <string name="lockscreen_transport_prev_description" msgid="2879469521751181478">"Prethodna pesma"</string>
+    <string name="lockscreen_transport_next_description" msgid="2931509904881099919">"Sledeća pesma"</string>
+    <string name="lockscreen_transport_pause_description" msgid="6705284702135372494">"Pauza"</string>
+    <string name="lockscreen_transport_play_description" msgid="106868788691652733">"Pusti"</string>
+    <string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"Zaustavi"</string>
+    <string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"Premotaj unazad"</string>
+    <string name="lockscreen_transport_ffw_description" msgid="4763794746640196772">"Premotaj unapred"</string>
+    <string name="emergency_calls_only" msgid="3057351206678279851">"Samo hitni pozivi"</string>
+    <string name="lockscreen_network_locked_message" msgid="2814046965899249635">"Mreža je zaključana"</string>
+    <string name="lockscreen_sim_puk_locked_message" msgid="6618356415831082174">"SIM kartica je zaključana PUK kodom."</string>
+    <string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"Pogledajte Korisnički vodič ili kontaktirajte Korisničku podršku."</string>
+    <string name="lockscreen_sim_locked_message" msgid="3160196135801185938">"SIM kartica je zaključana."</string>
+    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="2286497117428409709">"Otključavanje SIM kartice…"</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"<xliff:g id="NUMBER_0">%1$d</xliff:g> puta ste nepravilno nacrtali šablon za otključavanje. \n\nProbajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunde/i."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"<xliff:g id="NUMBER_0">%1$d</xliff:g> puta ste pogrešno uneli lozinku. \n\nProbajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunde/i."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"<xliff:g id="NUMBER_0">%1$d</xliff:g> puta ste pogrešno uneli PIN. \n\nProbajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunde/i."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"<xliff:g id="NUMBER_0">%1$d</xliff:g> puta ste netačno uneli šablon za otključavanje. Nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> nesupešna(ih) pokušaja, od vas će biti zatraženo da otključate tablet pomoću podataka za prijavljivanje na Google.\n\n Probajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunde/i."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"Netačno ste nacrtali šablon za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još puta (<xliff:g id="NUMBER_1">%2$d</xliff:g>), zatražićemo da otključate telefon pomoću Android TV uređaja.\n\n Probajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"<xliff:g id="NUMBER_0">%1$d</xliff:g> puta ste netačno uneli šablon za otključavanje. Nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> nesupešna(ih) pokušaja, od vas će biti zatraženo da otključate telefon pomoću podataka za prijavljivanje na Google.\n\n Probajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunde/i."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"Nepravilno ste pokušali da otključate tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Nakon još neuspešnih pokušaja (<xliff:g id="NUMBER_1">%2$d</xliff:g>) tablet će biti resetovan na fabrička podešavanja i svi korisnički podaci će biti izgubljeni."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"Broj vaših neuspešnih pokušaja da otključate Android TV uređaj: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Broj preostalih neuspešnih pokušaja posle kojih će se Android TV resetovati na fabrička podešavanja i svi podaci korisnika će biti izgubljeni: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"Neispravno ste pokušali da otključate telefon <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Nakon još neuspešnih pokušaja (<xliff:g id="NUMBER_1">%2$d</xliff:g>) telefon će biti resetovan na fabrička podešavanja i svi korisnički podaci će biti izgubljeni."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"Neispravno ste pokušali da otključate tablet <xliff:g id="NUMBER">%d</xliff:g> puta. Tablet će sada biti vraćen na podrazumevana fabrička podešavanja."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"Broj vaših neuspešnih pokušaja da otključate Android TV uređaj: <xliff:g id="NUMBER">%d</xliff:g>. Android TV uređaj će se sada resetovati na fabrička podešavanja."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"Neispravno ste pokušali da otključate telefon <xliff:g id="NUMBER">%d</xliff:g> puta. Telefon će sada biti vraćen na podrazumevana fabrička podešavanja."</string>
+    <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"Probajte ponovo za <xliff:g id="NUMBER">%d</xliff:g> sekunde/i."</string>
+    <string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"Zaboravili ste šablon?"</string>
+    <string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"Otključavanje naloga"</string>
+    <string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"Previše pokušaja unosa šablona"</string>
+    <string name="lockscreen_glogin_instructions" msgid="4695162942525531700">"Da biste otključali, prijavite se pomoću Google naloga."</string>
+    <string name="lockscreen_glogin_username_hint" msgid="6916101478673157045">"Korisničko ime (imejl adresa)"</string>
+    <string name="lockscreen_glogin_password_hint" msgid="3031027901286812848">"Lozinka"</string>
+    <string name="lockscreen_glogin_submit_button" msgid="3590556636347843733">"Prijavi me"</string>
+    <string name="lockscreen_glogin_invalid_input" msgid="4369219936865697679">"Nevažeće korisničko ime ili lozinka."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1683405808525090649">"Zaboravili ste korisničko ime ili lozinku?\nPosetite adresu "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_checking_password" msgid="2607271802803381645">"Proveravanje..."</string>
+    <string name="lockscreen_unlock_label" msgid="4648257878373307582">"Otključaj"</string>
+    <string name="lockscreen_sound_on_label" msgid="1660281470535492430">"Uključi zvuk"</string>
+    <string name="lockscreen_sound_off_label" msgid="2331496559245450053">"Isključi zvuk"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3778502525702613399">"Obrazac je započet"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="7493849102641167049">"Obrazac je obrisan"</string>
+    <string name="lockscreen_access_pattern_cell_added" msgid="6746676335293144163">"Ćelija je dodata"</string>
+    <string name="lockscreen_access_pattern_cell_added_verbose" msgid="2931364927622563465">"Ćelija <xliff:g id="CELL_INDEX">%1$s</xliff:g> je dodata"</string>
+    <string name="lockscreen_access_pattern_detected" msgid="3931150554035194012">"Obrazac je dovršen"</string>
+    <string name="lockscreen_access_pattern_area" msgid="1288780416685002841">"Oblast šablona."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="7298011259508200234">"%1$s. Vidžet %2$d od %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8245795023551343672">"Dodaj vidžet."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="544239307077644480">"Prazno"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="7768634718706488951">"Oblast otključavanja je proširena."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="4729922043778400434">"Oblast otključavanja je skupljena."</string>
+    <string name="keyguard_accessibility_widget" msgid="6776892679715699875">"Vidžet <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1466067610235696600">"Izbor korisnika"</string>
+    <string name="keyguard_accessibility_status" msgid="6792745049712397237">"Status"</string>
+    <string name="keyguard_accessibility_camera" msgid="7862557559464986528">"Kamera"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="2267379779900620614">"Kontrole za medije"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="7066213328912939191">"Započela je promena redosleda vidžeta."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="1083806817600593490">"Promena redosleda vidžeta je završena."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="1509738950119878705">"Vidžet <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> je izbrisan."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="4215280881346033434">"Proširi oblast otključavanja."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2968195219692413046">"Otključavanje prevlačenjem."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"Otključavanje šablonom."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"Otključavanje licem."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="4020864007967340068">"Otključavanje PIN-om."</string>
+    <string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"Otključava SIM karticu PIN-om."</string>
+    <string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"Otključava SIM karticu PUK-om."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="6130186108581153265">"Otključavanje lozinkom."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="1419570880512350689">"Oblast šablona."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="4331399051142520176">"Oblast prevlačenja."</string>
     <string name="password_keyboard_label_symbol_key" msgid="2716255580853511949">"?123"</string>
     <string name="password_keyboard_label_alpha_key" msgid="5294837425652726684">"ABC"</string>
     <string name="password_keyboard_label_alt_key" msgid="8528261816395508841">"ALT"</string>
-    <string name="granularity_label_character" msgid="8903387663153706317">"знак"</string>
-    <string name="granularity_label_word" msgid="3686589158760620518">"реч"</string>
-    <string name="granularity_label_link" msgid="9007852307112046526">"линк"</string>
-    <string name="granularity_label_line" msgid="376204904280620221">"ред"</string>
-    <string name="factorytest_failed" msgid="3190979160945298006">"Фабричко тестирање није успело"</string>
-    <string name="factorytest_not_system" msgid="5658160199925519869">"Радња FACTORY_TEST је подржана само за пакете инсталиране у фолдеру /system/app."</string>
-    <string name="factorytest_no_action" msgid="339252838115675515">"Није пронађен ниједан пакет који обезбеђује радњу FACTORY_TEST."</string>
-    <string name="factorytest_reboot" msgid="2050147445567257365">"Рестартуј"</string>
-    <string name="js_dialog_title" msgid="7464775045615023241">"На страници на адреси „<xliff:g id="TITLE">%s</xliff:g>“ пише:"</string>
+    <string name="granularity_label_character" msgid="8903387663153706317">"znak"</string>
+    <string name="granularity_label_word" msgid="3686589158760620518">"reč"</string>
+    <string name="granularity_label_link" msgid="9007852307112046526">"link"</string>
+    <string name="granularity_label_line" msgid="376204904280620221">"red"</string>
+    <string name="factorytest_failed" msgid="3190979160945298006">"Fabričko testiranje nije uspelo"</string>
+    <string name="factorytest_not_system" msgid="5658160199925519869">"Radnja FACTORY_TEST je podržana samo za pakete instalirane u folderu /system/app."</string>
+    <string name="factorytest_no_action" msgid="339252838115675515">"Nije pronađen nijedan paket koji obezbeđuje radnju FACTORY_TEST."</string>
+    <string name="factorytest_reboot" msgid="2050147445567257365">"Restartuj"</string>
+    <string name="js_dialog_title" msgid="7464775045615023241">"Na stranici na adresi „<xliff:g id="TITLE">%s</xliff:g>“ piše:"</string>
     <string name="js_dialog_title_default" msgid="3769524569903332476">"JavaScript"</string>
-    <string name="js_dialog_before_unload_title" msgid="7012587995876771246">"Потврда навигације"</string>
-    <string name="js_dialog_before_unload_positive_button" msgid="4274257182303565509">"Затвори ову страницу"</string>
-    <string name="js_dialog_before_unload_negative_button" msgid="3873765747622415310">"Остани на овој страници"</string>
-    <string name="js_dialog_before_unload" msgid="7213364985774778744">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nДа ли стварно желите да напустите ову страницу?"</string>
-    <string name="save_password_label" msgid="9161712335355510035">"Потврда"</string>
-    <string name="double_tap_toast" msgid="7065519579174882778">"Савет: Додирните двапут да бисте увећали и умањили приказ."</string>
-    <string name="autofill_this_form" msgid="3187132440451621492">"Аутом. поп."</string>
-    <string name="setup_autofill" msgid="5431369130866618567">"Подеш. аут. поп."</string>
-    <string name="autofill_window_title" msgid="4379134104008111961">"Аутоматски попуњава <xliff:g id="SERVICENAME">%1$s</xliff:g>"</string>
+    <string name="js_dialog_before_unload_title" msgid="7012587995876771246">"Potvrda navigacije"</string>
+    <string name="js_dialog_before_unload_positive_button" msgid="4274257182303565509">"Zatvori ovu stranicu"</string>
+    <string name="js_dialog_before_unload_negative_button" msgid="3873765747622415310">"Ostani na ovoj stranici"</string>
+    <string name="js_dialog_before_unload" msgid="7213364985774778744">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nDa li stvarno želite da napustite ovu stranicu?"</string>
+    <string name="save_password_label" msgid="9161712335355510035">"Potvrda"</string>
+    <string name="double_tap_toast" msgid="7065519579174882778">"Savet: Dodirnite dvaput da biste uvećali i umanjili prikaz."</string>
+    <string name="autofill_this_form" msgid="3187132440451621492">"Autom. pop."</string>
+    <string name="setup_autofill" msgid="5431369130866618567">"Podeš. aut. pop."</string>
+    <string name="autofill_window_title" msgid="4379134104008111961">"Automatski popunjava <xliff:g id="SERVICENAME">%1$s</xliff:g>"</string>
     <string name="autofill_address_name_separator" msgid="8190155636149596125">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3402882515222673691">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="760522655085707045">", "</string>
     <string name="autofill_address_summary_format" msgid="8417010069362125194">"$1$2$3"</string>
-    <string name="autofill_province" msgid="3676846437741893159">"Покрајина"</string>
-    <string name="autofill_postal_code" msgid="7034789388968295591">"Поштански број"</string>
-    <string name="autofill_state" msgid="3341725337190434069">"Држава"</string>
-    <string name="autofill_zip_code" msgid="1315503730274962450">"Поштански број"</string>
-    <string name="autofill_county" msgid="7781382735643492173">"Округ"</string>
-    <string name="autofill_island" msgid="5367139008536593734">"Острво"</string>
-    <string name="autofill_district" msgid="6428712062213557327">"Дистрикт"</string>
-    <string name="autofill_department" msgid="9047276226873531529">"Одељење"</string>
-    <string name="autofill_prefecture" msgid="7267397763720241872">"Префектура"</string>
-    <string name="autofill_parish" msgid="6847960518334530198">"Парохија"</string>
-    <string name="autofill_area" msgid="8289022370678448983">"Област"</string>
-    <string name="autofill_emirate" msgid="2544082046790551168">"Емират"</string>
-    <string name="permlab_readHistoryBookmarks" msgid="9102293913842539697">"читање веб обележивача и историје"</string>
-    <string name="permdesc_readHistoryBookmarks" msgid="2323799501008967852">"Дозвољава апликацији да чита историју свих URL адреса које су посећене помоћу Прегледача, као и све обележиваче у Прегледачу. Напомена: Ова дозвола се можда на примењује на прегледаче треће стране и друге апликације са могућношћу веб прегледања."</string>
-    <string name="permlab_writeHistoryBookmarks" msgid="6090259925187986937">"писање веб обележивача и историје"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="573341025292489065">"Дозвољава апликацији да мења историју Прегледача или обележиваче ускладиштене на таблету. Ово може да омогући апликацији да брише или мења податке Прегледача. Напомена: Ова дозвола се можда на примењује на прегледаче треће стране и друге апликације са могућношћу веб прегледања."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"Дозвољава апликацији да мења историју прегледача или обележиваче који се чувају на Android TV уређају. Ово може да омогући апликацији да брише или мења податке прегледача. Напомена: ова дозвола се можда не примењује на прегледаче треће стране ни друге апликације са могућностима веб-прегледања."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="2245203087160913652">"Дозвољава апликацији да мења историју Прегледача или обележиваче ускладиштене на телефону. Ово може да омогући апликацији да брише или мења податке Прегледача. Напомена: Ова дозвола се можда на примењује на прегледаче треће стране и друге апликације са могућношћу веб прегледања."</string>
-    <string name="permlab_setAlarm" msgid="1158001610254173567">"подешавање аларма"</string>
-    <string name="permdesc_setAlarm" msgid="2185033720060109640">"Дозвољава апликацији да подеси аларм у инсталираној апликацији будилника. Неке апликације будилника можда не примењују ову функцију."</string>
-    <string name="permlab_addVoicemail" msgid="4770245808840814471">"додавање говорне поште"</string>
-    <string name="permdesc_addVoicemail" msgid="5470312139820074324">"Дозвољава апликацији да додаје поруке у пријемно сандуче говорне поште."</string>
-    <string name="permlab_writeGeolocationPermissions" msgid="8605631647492879449">"измена дозвола за географске локације Прегледача"</string>
-    <string name="permdesc_writeGeolocationPermissions" msgid="5817346421222227772">"Дозвољава апликацији да измени дозволе Прегледача за утврђивање географске локације. Злонамерне апликације то могу да злоупотребе и искористе за слање информација о локацији насумичним веб-сајтовима."</string>
-    <string name="save_password_message" msgid="2146409467245462965">"Желите ли да прегледач запамти ову лозинку?"</string>
-    <string name="save_password_notnow" msgid="2878327088951240061">"Не сада"</string>
-    <string name="save_password_remember" msgid="6490888932657708341">"Запамти"</string>
-    <string name="save_password_never" msgid="6776808375903410659">"Никад"</string>
-    <string name="open_permission_deny" msgid="5136793905306987251">"Немате дозволу да отворите ову страницу."</string>
-    <string name="text_copied" msgid="2531420577879738860">"Текст је копиран у привремену меморију."</string>
-    <string name="pasted_from_app" msgid="5627698450808256545">"Апликација<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> је налепила податке из апликације <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
-    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> је прелепио/ла из привремене меморије"</string>
-    <string name="pasted_text" msgid="4298871641549173733">"Апликација<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> је налепила текст који сте копирали"</string>
-    <string name="pasted_image" msgid="4729097394781491022">"Апликација<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> је налепила слику коју сте копирали"</string>
-    <string name="pasted_content" msgid="646276353060777131">"Апликација<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> је налепила садржај који сте копирали"</string>
-    <string name="more_item_label" msgid="7419249600215749115">"Још"</string>
-    <string name="prepend_shortcut_label" msgid="1743716737502867951">"Мени+"</string>
+    <string name="autofill_province" msgid="3676846437741893159">"Pokrajina"</string>
+    <string name="autofill_postal_code" msgid="7034789388968295591">"Poštanski broj"</string>
+    <string name="autofill_state" msgid="3341725337190434069">"Država"</string>
+    <string name="autofill_zip_code" msgid="1315503730274962450">"Poštanski broj"</string>
+    <string name="autofill_county" msgid="7781382735643492173">"Okrug"</string>
+    <string name="autofill_island" msgid="5367139008536593734">"Ostrvo"</string>
+    <string name="autofill_district" msgid="6428712062213557327">"Distrikt"</string>
+    <string name="autofill_department" msgid="9047276226873531529">"Odeljenje"</string>
+    <string name="autofill_prefecture" msgid="7267397763720241872">"Prefektura"</string>
+    <string name="autofill_parish" msgid="6847960518334530198">"Parohija"</string>
+    <string name="autofill_area" msgid="8289022370678448983">"Oblast"</string>
+    <string name="autofill_emirate" msgid="2544082046790551168">"Emirat"</string>
+    <string name="permlab_readHistoryBookmarks" msgid="9102293913842539697">"čitanje veb obeleživača i istorije"</string>
+    <string name="permdesc_readHistoryBookmarks" msgid="2323799501008967852">"Dozvoljava aplikaciji da čita istoriju svih URL adresa koje su posećene pomoću Pregledača, kao i sve obeleživače u Pregledaču. Napomena: Ova dozvola se možda na primenjuje na pregledače treće strane i druge aplikacije sa mogućnošću veb pregledanja."</string>
+    <string name="permlab_writeHistoryBookmarks" msgid="6090259925187986937">"pisanje veb obeleživača i istorije"</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="573341025292489065">"Dozvoljava aplikaciji da menja istoriju Pregledača ili obeleživače uskladištene na tabletu. Ovo može da omogući aplikaciji da briše ili menja podatke Pregledača. Napomena: Ova dozvola se možda na primenjuje na pregledače treće strane i druge aplikacije sa mogućnošću veb pregledanja."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"Dozvoljava aplikaciji da menja istoriju pregledača ili obeleživače koji se čuvaju na Android TV uređaju. Ovo može da omogući aplikaciji da briše ili menja podatke pregledača. Napomena: ova dozvola se možda ne primenjuje na pregledače treće strane ni druge aplikacije sa mogućnostima veb-pregledanja."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="2245203087160913652">"Dozvoljava aplikaciji da menja istoriju Pregledača ili obeleživače uskladištene na telefonu. Ovo može da omogući aplikaciji da briše ili menja podatke Pregledača. Napomena: Ova dozvola se možda na primenjuje na pregledače treće strane i druge aplikacije sa mogućnošću veb pregledanja."</string>
+    <string name="permlab_setAlarm" msgid="1158001610254173567">"podešavanje alarma"</string>
+    <string name="permdesc_setAlarm" msgid="2185033720060109640">"Dozvoljava aplikaciji da podesi alarm u instaliranoj aplikaciji budilnika. Neke aplikacije budilnika možda ne primenjuju ovu funkciju."</string>
+    <string name="permlab_addVoicemail" msgid="4770245808840814471">"dodavanje govorne pošte"</string>
+    <string name="permdesc_addVoicemail" msgid="5470312139820074324">"Dozvoljava aplikaciji da dodaje poruke u prijemno sanduče govorne pošte."</string>
+    <string name="permlab_writeGeolocationPermissions" msgid="8605631647492879449">"izmena dozvola za geografske lokacije Pregledača"</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="5817346421222227772">"Dozvoljava aplikaciji da izmeni dozvole Pregledača za utvrđivanje geografske lokacije. Zlonamerne aplikacije to mogu da zloupotrebe i iskoriste za slanje informacija o lokaciji nasumičnim veb-sajtovima."</string>
+    <string name="save_password_message" msgid="2146409467245462965">"Želite li da pregledač zapamti ovu lozinku?"</string>
+    <string name="save_password_notnow" msgid="2878327088951240061">"Ne sada"</string>
+    <string name="save_password_remember" msgid="6490888932657708341">"Zapamti"</string>
+    <string name="save_password_never" msgid="6776808375903410659">"Nikad"</string>
+    <string name="open_permission_deny" msgid="5136793905306987251">"Nemate dozvolu da otvorite ovu stranicu."</string>
+    <string name="text_copied" msgid="2531420577879738860">"Tekst je kopiran u privremenu memoriju."</string>
+    <string name="pasted_from_app" msgid="5627698450808256545">"Aplikacija<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je nalepila podatke iz aplikacije <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je prelepio/la iz privremene memorije"</string>
+    <string name="pasted_text" msgid="4298871641549173733">"Aplikacija<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je nalepila tekst koji ste kopirali"</string>
+    <string name="pasted_image" msgid="4729097394781491022">"Aplikacija<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je nalepila sliku koju ste kopirali"</string>
+    <string name="pasted_content" msgid="646276353060777131">"Aplikacija<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je nalepila sadržaj koji ste kopirali"</string>
+    <string name="more_item_label" msgid="7419249600215749115">"Još"</string>
+    <string name="prepend_shortcut_label" msgid="1743716737502867951">"Meni+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
     <string name="menu_ctrl_shortcut_label" msgid="131911133027196485">"Ctrl+"</string>
     <string name="menu_alt_shortcut_label" msgid="343761069945250991">"Alt+"</string>
     <string name="menu_shift_shortcut_label" msgid="5443936876111232346">"Shift+"</string>
     <string name="menu_sym_shortcut_label" msgid="4037566049061218776">"Sym+"</string>
     <string name="menu_function_shortcut_label" msgid="2367112760987662566">"Function+"</string>
-    <string name="menu_space_shortcut_label" msgid="5949311515646872071">"размак"</string>
+    <string name="menu_space_shortcut_label" msgid="5949311515646872071">"razmak"</string>
     <string name="menu_enter_shortcut_label" msgid="6709499510082897320">"enter"</string>
-    <string name="menu_delete_shortcut_label" msgid="4365787714477739080">"избриши"</string>
-    <string name="search_go" msgid="2141477624421347086">"Претражи"</string>
-    <string name="search_hint" msgid="455364685740251925">"Претражите…"</string>
-    <string name="searchview_description_search" msgid="1045552007537359343">"Претражи"</string>
-    <string name="searchview_description_query" msgid="7430242366971716338">"Упит за претрагу"</string>
-    <string name="searchview_description_clear" msgid="1989371719192982900">"Обриши упит"</string>
-    <string name="searchview_description_submit" msgid="6771060386117334686">"Пошаљи упит"</string>
-    <string name="searchview_description_voice" msgid="42360159504884679">"Гласовна претрага"</string>
-    <string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"Oмогућити Истраживање додиром?"</string>
-    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> жели да омогући Истраживање додиром. Када је Истраживање додиром укључено, можете да чујете или видите описе ставке на коју сте ставили прст или да комуницирате са таблетом помоћу покрета."</string>
-    <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> жели да омогући Истраживање додиром. Када је Истраживање додиром укључено, можете да чујете или видите описе ставке на коју сте ставили прст или да комуницирате са телефоном помоћу покрета."</string>
-    <string name="oneMonthDurationPast" msgid="4538030857114635777">"Пре месец дана"</string>
-    <string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"Пре месец дана"</string>
-    <string name="last_num_days" msgid="2393660431490280537">"{count,plural, =1{Последњи # дан}one{Последњи # дан}few{Последња # дана}other{Последњих # дана}}"</string>
-    <string name="last_month" msgid="1528906781083518683">"Прошлог месеца"</string>
-    <string name="older" msgid="1645159827884647400">"Старије"</string>
+    <string name="menu_delete_shortcut_label" msgid="4365787714477739080">"izbriši"</string>
+    <string name="search_go" msgid="2141477624421347086">"Pretraži"</string>
+    <string name="search_hint" msgid="455364685740251925">"Pretražite…"</string>
+    <string name="searchview_description_search" msgid="1045552007537359343">"Pretraži"</string>
+    <string name="searchview_description_query" msgid="7430242366971716338">"Upit za pretragu"</string>
+    <string name="searchview_description_clear" msgid="1989371719192982900">"Obriši upit"</string>
+    <string name="searchview_description_submit" msgid="6771060386117334686">"Pošalji upit"</string>
+    <string name="searchview_description_voice" msgid="42360159504884679">"Glasovna pretraga"</string>
+    <string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"Omogućiti Istraživanje dodirom?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> želi da omogući Istraživanje dodirom. Kada je Istraživanje dodirom uključeno, možete da čujete ili vidite opise stavke na koju ste stavili prst ili da komunicirate sa tabletom pomoću pokreta."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> želi da omogući Istraživanje dodirom. Kada je Istraživanje dodirom uključeno, možete da čujete ili vidite opise stavke na koju ste stavili prst ili da komunicirate sa telefonom pomoću pokreta."</string>
+    <string name="oneMonthDurationPast" msgid="4538030857114635777">"Pre mesec dana"</string>
+    <string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"Pre mesec dana"</string>
+    <string name="last_num_days" msgid="2393660431490280537">"{count,plural, =1{Poslednji # dan}one{Poslednji # dan}few{Poslednja # dana}other{Poslednjih # dana}}"</string>
+    <string name="last_month" msgid="1528906781083518683">"Prošlog meseca"</string>
+    <string name="older" msgid="1645159827884647400">"Starije"</string>
     <string name="preposition_for_date" msgid="2780767868832729599">"<xliff:g id="DATE">%s</xliff:g>"</string>
-    <string name="preposition_for_time" msgid="4336835286453822053">"у <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="preposition_for_year" msgid="3149809685340130039">"у <xliff:g id="YEAR">%s</xliff:g>."</string>
-    <string name="day" msgid="8394717255950176156">"дан"</string>
-    <string name="days" msgid="4570879797423034973">"дана"</string>
-    <string name="hour" msgid="7796325297097314653">"сат"</string>
-    <string name="hours" msgid="8517014849629200683">"сата"</string>
-    <string name="minute" msgid="8369209540986467610">"мин"</string>
-    <string name="minutes" msgid="3456532942641808971">"мин"</string>
-    <string name="second" msgid="9210875257112211713">"сек"</string>
-    <string name="seconds" msgid="2175052687727971048">"сек"</string>
-    <string name="week" msgid="907127093960923779">"недеља"</string>
-    <string name="weeks" msgid="3516247214269821391">"недеље/а"</string>
-    <string name="year" msgid="5182610307741238982">"година"</string>
-    <string name="years" msgid="5797714729103773425">"годинe(а)"</string>
-    <string name="now_string_shortest" msgid="3684914126941650330">"сада"</string>
-    <string name="duration_minutes_shortest" msgid="5744379079540806690">"<xliff:g id="COUNT">%d</xliff:g> мин"</string>
-    <string name="duration_hours_shortest" msgid="1477752094141971675">"<xliff:g id="COUNT">%d</xliff:g> с"</string>
-    <string name="duration_days_shortest" msgid="4083124701676227233">"<xliff:g id="COUNT">%d</xliff:g> д"</string>
-    <string name="duration_years_shortest" msgid="483982719231145618">"<xliff:g id="COUNT">%d</xliff:g> год"</string>
-    <string name="duration_minutes_shortest_future" msgid="5260857299282734759">"за <xliff:g id="COUNT">%d</xliff:g> мин"</string>
-    <string name="duration_hours_shortest_future" msgid="2979276794547981674">"за <xliff:g id="COUNT">%d</xliff:g> с"</string>
-    <string name="duration_days_shortest_future" msgid="3392722163935571543">"за <xliff:g id="COUNT">%d</xliff:g> д"</string>
-    <string name="duration_years_shortest_future" msgid="5537464088352970388">"за <xliff:g id="COUNT">%d</xliff:g> год"</string>
-    <string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{Пре # минут}one{Пре # минут}few{Пре # минута}other{Пре # минута}}"</string>
-    <string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{Пре # сат}one{Пре # сат}few{Пре # сата}other{Пре # сати}}"</string>
-    <string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{Пре # дан}one{Пре # дан}few{Пре # дана}other{Пре # дана}}"</string>
-    <string name="duration_years_relative" msgid="8731202348869424370">"{count,plural, =1{Пре # годину}one{Пре # годину}few{Пре # године}other{Пре # година}}"</string>
-    <string name="duration_minutes_relative_future" msgid="5259574171747708115">"{count,plural, =1{# минут}one{# минут}few{# минута}other{# минута}}"</string>
-    <string name="duration_hours_relative_future" msgid="6670440478481140565">"{count,plural, =1{# сат}one{# сат}few{# сата}other{# сати}}"</string>
-    <string name="duration_days_relative_future" msgid="8870658635774250746">"{count,plural, =1{# дан}one{# дан}few{# дана}other{# дана}}"</string>
-    <string name="duration_years_relative_future" msgid="8855853883925918380">"{count,plural, =1{# година}one{# година}few{# године}other{# година}}"</string>
-    <string name="VideoView_error_title" msgid="5750686717225068016">"Проблем са видео снимком"</string>
-    <string name="VideoView_error_text_invalid_progressive_playback" msgid="3782449246085134720">"Овај видео не може да се стримује на овом уређају."</string>
-    <string name="VideoView_error_text_unknown" msgid="7658683339707607138">"Не можете да пустите овај видео."</string>
-    <string name="VideoView_error_button" msgid="5138809446603764272">"Потврди"</string>
+    <string name="preposition_for_time" msgid="4336835286453822053">"u <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="3149809685340130039">"u <xliff:g id="YEAR">%s</xliff:g>."</string>
+    <string name="day" msgid="8394717255950176156">"dan"</string>
+    <string name="days" msgid="4570879797423034973">"dana"</string>
+    <string name="hour" msgid="7796325297097314653">"sat"</string>
+    <string name="hours" msgid="8517014849629200683">"sata"</string>
+    <string name="minute" msgid="8369209540986467610">"min"</string>
+    <string name="minutes" msgid="3456532942641808971">"min"</string>
+    <string name="second" msgid="9210875257112211713">"sek"</string>
+    <string name="seconds" msgid="2175052687727971048">"sek"</string>
+    <string name="week" msgid="907127093960923779">"nedelja"</string>
+    <string name="weeks" msgid="3516247214269821391">"nedelje/a"</string>
+    <string name="year" msgid="5182610307741238982">"godina"</string>
+    <string name="years" msgid="5797714729103773425">"godine(a)"</string>
+    <string name="now_string_shortest" msgid="3684914126941650330">"sada"</string>
+    <string name="duration_minutes_shortest" msgid="5744379079540806690">"<xliff:g id="COUNT">%d</xliff:g> min"</string>
+    <string name="duration_hours_shortest" msgid="1477752094141971675">"<xliff:g id="COUNT">%d</xliff:g> s"</string>
+    <string name="duration_days_shortest" msgid="4083124701676227233">"<xliff:g id="COUNT">%d</xliff:g> d"</string>
+    <string name="duration_years_shortest" msgid="483982719231145618">"<xliff:g id="COUNT">%d</xliff:g> god"</string>
+    <string name="duration_minutes_shortest_future" msgid="5260857299282734759">"za <xliff:g id="COUNT">%d</xliff:g> min"</string>
+    <string name="duration_hours_shortest_future" msgid="2979276794547981674">"za <xliff:g id="COUNT">%d</xliff:g> s"</string>
+    <string name="duration_days_shortest_future" msgid="3392722163935571543">"za <xliff:g id="COUNT">%d</xliff:g> d"</string>
+    <string name="duration_years_shortest_future" msgid="5537464088352970388">"za <xliff:g id="COUNT">%d</xliff:g> god"</string>
+    <string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{Pre # minut}one{Pre # minut}few{Pre # minuta}other{Pre # minuta}}"</string>
+    <string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{Pre # sat}one{Pre # sat}few{Pre # sata}other{Pre # sati}}"</string>
+    <string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{Pre # dan}one{Pre # dan}few{Pre # dana}other{Pre # dana}}"</string>
+    <string name="duration_years_relative" msgid="8731202348869424370">"{count,plural, =1{Pre # godinu}one{Pre # godinu}few{Pre # godine}other{Pre # godina}}"</string>
+    <string name="duration_minutes_relative_future" msgid="5259574171747708115">"{count,plural, =1{# minut}one{# minut}few{# minuta}other{# minuta}}"</string>
+    <string name="duration_hours_relative_future" msgid="6670440478481140565">"{count,plural, =1{# sat}one{# sat}few{# sata}other{# sati}}"</string>
+    <string name="duration_days_relative_future" msgid="8870658635774250746">"{count,plural, =1{# dan}one{# dan}few{# dana}other{# dana}}"</string>
+    <string name="duration_years_relative_future" msgid="8855853883925918380">"{count,plural, =1{# godina}one{# godina}few{# godine}other{# godina}}"</string>
+    <string name="VideoView_error_title" msgid="5750686717225068016">"Problem sa video snimkom"</string>
+    <string name="VideoView_error_text_invalid_progressive_playback" msgid="3782449246085134720">"Ovaj video ne može da se strimuje na ovom uređaju."</string>
+    <string name="VideoView_error_text_unknown" msgid="7658683339707607138">"Ne možete da pustite ovaj video."</string>
+    <string name="VideoView_error_button" msgid="5138809446603764272">"Potvrdi"</string>
     <string name="relative_time" msgid="8572030016028033243">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="noon" msgid="8365974533050605886">"подне"</string>
-    <string name="Noon" msgid="6902418443846838189">"Подне"</string>
-    <string name="midnight" msgid="3646671134282785114">"поноћ"</string>
-    <string name="Midnight" msgid="8176019203622191377">"Поноћ"</string>
+    <string name="noon" msgid="8365974533050605886">"podne"</string>
+    <string name="Noon" msgid="6902418443846838189">"Podne"</string>
+    <string name="midnight" msgid="3646671134282785114">"ponoć"</string>
+    <string name="Midnight" msgid="8176019203622191377">"Ponoć"</string>
     <string name="elapsed_time_short_format_mm_ss" msgid="8689459651807876423">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="2302144714803345056">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
-    <string name="selectAll" msgid="1532369154488982046">"Изабери све"</string>
-    <string name="cut" msgid="2561199725874745819">"Исеци"</string>
-    <string name="copy" msgid="5472512047143665218">"Копирај"</string>
-    <string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"Копирање у привремену меморију није успело"</string>
-    <string name="paste" msgid="461843306215520225">"Налепи"</string>
-    <string name="paste_as_plain_text" msgid="7664800665823182587">"Налепи као обичан текст"</string>
-    <string name="replace" msgid="7842675434546657444">"Замени..."</string>
-    <string name="delete" msgid="1514113991712129054">"Избриши"</string>
-    <string name="copyUrl" msgid="6229645005987260230">"Копирај URL адресу"</string>
-    <string name="selectTextMode" msgid="3225108910999318778">"Изабери текст"</string>
-    <string name="undo" msgid="3175318090002654673">"Опозови"</string>
-    <string name="redo" msgid="7231448494008532233">"Понови"</string>
-    <string name="autofill" msgid="511224882647795296">"Аутоматско попуњавање"</string>
-    <string name="textSelectionCABTitle" msgid="5151441579532476940">"Избор текста"</string>
-    <string name="addToDictionary" msgid="8041821113480950096">"Додај у речник"</string>
-    <string name="deleteText" msgid="4200807474529938112">"Избриши"</string>
-    <string name="inputMethod" msgid="1784759500516314751">"Метод уноса"</string>
-    <string name="editTextMenuTitle" msgid="857666911134482176">"Радње у вези са текстом"</string>
-    <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Назад"</string>
-    <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Промените метод уноса"</string>
-    <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Меморијски простор је на измаку"</string>
-    <string name="low_internal_storage_view_text" msgid="8172166728369697835">"Неке системске функције можда не функционишу"</string>
-    <string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"Нема довољно меморијског простора за систем. Уверите се да имате 250 MB слободног простора и поново покрените."</string>
-    <string name="app_running_notification_title" msgid="8985999749231486569">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> је покренута"</string>
-    <string name="app_running_notification_text" msgid="5120815883400228566">"Додирните за више информација или заустављање апликације."</string>
-    <string name="ok" msgid="2646370155170753815">"Потврди"</string>
-    <string name="cancel" msgid="6908697720451760115">"Откажи"</string>
-    <string name="yes" msgid="9069828999585032361">"Потврди"</string>
-    <string name="no" msgid="5122037903299899715">"Откажи"</string>
-    <string name="dialog_alert_title" msgid="651856561974090712">"Пажња"</string>
-    <string name="loading" msgid="3138021523725055037">"Учитава се…"</string>
-    <string name="capital_on" msgid="2770685323900821829">"ДА"</string>
-    <string name="capital_off" msgid="7443704171014626777">"НЕ"</string>
-    <string name="checked" msgid="9179896827054513119">"означено је"</string>
-    <string name="not_checked" msgid="7972320087569023342">"није означено"</string>
-    <string name="selected" msgid="6614607926197755875">"изабрано"</string>
-    <string name="not_selected" msgid="410652016565864475">"није изабрано"</string>
-    <string name="in_progress" msgid="2149208189184319441">"у току"</string>
-    <string name="whichApplication" msgid="5432266899591255759">"Доврши радњу преко"</string>
-    <string name="whichApplicationNamed" msgid="6969946041713975681">"Завршите радњу помоћу апликације %1$s"</string>
-    <string name="whichApplicationLabel" msgid="7852182961472531728">"Заврши радњу"</string>
-    <string name="whichViewApplication" msgid="5733194231473132945">"Отворите помоћу"</string>
-    <string name="whichViewApplicationNamed" msgid="415164730629690105">"Отворите помоћу апликације %1$s"</string>
-    <string name="whichViewApplicationLabel" msgid="7367556735684742409">"Отвори"</string>
-    <string name="whichOpenHostLinksWith" msgid="7645631470199397485">"Отварајте <xliff:g id="HOST">%1$s</xliff:g> линкове помоћу"</string>
-    <string name="whichOpenLinksWith" msgid="1120936181362907258">"Отварај линкове помоћу"</string>
-    <string name="whichOpenLinksWithApp" msgid="6917864367861910086">"Отварајте линкове помоћу апликације <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
-    <string name="whichOpenHostLinksWithApp" msgid="2401668560768463004">"Отварајте <xliff:g id="HOST">%1$s</xliff:g> линкове помоћу апликације <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
-    <string name="whichGiveAccessToApplicationLabel" msgid="7805857277166106236">"Дозволи приступ"</string>
-    <string name="whichEditApplication" msgid="6191568491456092812">"Измените помоћу"</string>
-    <string name="whichEditApplicationNamed" msgid="8096494987978521514">"Измените помоћу апликације %1$s"</string>
-    <string name="whichEditApplicationLabel" msgid="1463288652070140285">"Измени"</string>
-    <string name="whichSendApplication" msgid="4143847974460792029">"Делите"</string>
-    <string name="whichSendApplicationNamed" msgid="4470386782693183461">"Делите помоћу апликације %1$s"</string>
-    <string name="whichSendApplicationLabel" msgid="7467813004769188515">"Дели"</string>
-    <string name="whichSendToApplication" msgid="77101541959464018">"Пошаљите помоћу:"</string>
-    <string name="whichSendToApplicationNamed" msgid="3385686512014670003">"Пошаљите помоћу: %1$s"</string>
-    <string name="whichSendToApplicationLabel" msgid="3543240188816513303">"Пошаљи"</string>
-    <string name="whichHomeApplication" msgid="8276350727038396616">"Изаберите апликацију за почетну страницу"</string>
-    <string name="whichHomeApplicationNamed" msgid="5855990024847433794">"Користите %1$s за почетну"</string>
-    <string name="whichHomeApplicationLabel" msgid="8907334282202933959">"Снимите слику"</string>
-    <string name="whichImageCaptureApplication" msgid="2737413019463215284">"Снимите слику помоћу апликације"</string>
-    <string name="whichImageCaptureApplicationNamed" msgid="8820702441847612202">"Снимите слику помоћу апликације %1$s"</string>
-    <string name="whichImageCaptureApplicationLabel" msgid="6505433734824988277">"Снимите слику"</string>
-    <string name="alwaysUse" msgid="3153558199076112903">"Подразумевано користи за ову радњу."</string>
-    <string name="use_a_different_app" msgid="4987790276170972776">"Користите другу апликацију"</string>
-    <string name="clearDefaultHintMsg" msgid="1325866337702524936">"Обришите подразумевано подешавање у менију Подешавања система &gt; Апликације &gt; Преузето."</string>
-    <string name="chooseActivity" msgid="8563390197659779956">"Изаберите радњу"</string>
-    <string name="chooseUsbActivity" msgid="2096269989990986612">"Избор апликације за USB уређај"</string>
-    <string name="noApplications" msgid="1186909265235544019">"Ниједна апликација не може да обавља ову радњу."</string>
-    <string name="aerr_application" msgid="4090916809370389109">"Апликација <xliff:g id="APPLICATION">%1$s</xliff:g> је заустављена"</string>
-    <string name="aerr_process" msgid="4268018696970966407">"Процес <xliff:g id="PROCESS">%1$s</xliff:g> је заустављен"</string>
-    <string name="aerr_application_repeated" msgid="7804378743218496566">"<xliff:g id="APPLICATION">%1$s</xliff:g> се стално зауставља"</string>
-    <string name="aerr_process_repeated" msgid="1153152413537954974">"Процес <xliff:g id="PROCESS">%1$s</xliff:g> се стално зауставља"</string>
-    <string name="aerr_restart" msgid="2789618625210505419">"Поново отвори апликацију"</string>
-    <string name="aerr_report" msgid="3095644466849299308">"Пошаљите повратне информације"</string>
-    <string name="aerr_close" msgid="3398336821267021852">"Затвори"</string>
-    <string name="aerr_mute" msgid="2304972923480211376">"Игнориши док се уређај не покрене поново"</string>
-    <string name="aerr_wait" msgid="3198677780474548217">"Чекај"</string>
-    <string name="aerr_close_app" msgid="8318883106083050970">"Затвори апликацију"</string>
+    <string name="selectAll" msgid="1532369154488982046">"Izaberi sve"</string>
+    <string name="cut" msgid="2561199725874745819">"Iseci"</string>
+    <string name="copy" msgid="5472512047143665218">"Kopiraj"</string>
+    <string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"Kopiranje u privremenu memoriju nije uspelo"</string>
+    <string name="paste" msgid="461843306215520225">"Nalepi"</string>
+    <string name="paste_as_plain_text" msgid="7664800665823182587">"Nalepi kao običan tekst"</string>
+    <string name="replace" msgid="7842675434546657444">"Zameni..."</string>
+    <string name="delete" msgid="1514113991712129054">"Izbriši"</string>
+    <string name="copyUrl" msgid="6229645005987260230">"Kopiraj URL adresu"</string>
+    <string name="selectTextMode" msgid="3225108910999318778">"Izaberi tekst"</string>
+    <string name="undo" msgid="3175318090002654673">"Opozovi"</string>
+    <string name="redo" msgid="7231448494008532233">"Ponovi"</string>
+    <string name="autofill" msgid="511224882647795296">"Automatsko popunjavanje"</string>
+    <string name="textSelectionCABTitle" msgid="5151441579532476940">"Izbor teksta"</string>
+    <string name="addToDictionary" msgid="8041821113480950096">"Dodaj u rečnik"</string>
+    <string name="deleteText" msgid="4200807474529938112">"Izbriši"</string>
+    <string name="inputMethod" msgid="1784759500516314751">"Metod unosa"</string>
+    <string name="editTextMenuTitle" msgid="857666911134482176">"Radnje u vezi sa tekstom"</string>
+    <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Nazad"</string>
+    <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Promenite metod unosa"</string>
+    <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Memorijski prostor je na izmaku"</string>
+    <string name="low_internal_storage_view_text" msgid="8172166728369697835">"Neke sistemske funkcije možda ne funkcionišu"</string>
+    <string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"Nema dovoljno memorijskog prostora za sistem. Uverite se da imate 250 MB slobodnog prostora i ponovo pokrenite."</string>
+    <string name="app_running_notification_title" msgid="8985999749231486569">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je pokrenuta"</string>
+    <string name="app_running_notification_text" msgid="5120815883400228566">"Dodirnite za više informacija ili zaustavljanje aplikacije."</string>
+    <string name="ok" msgid="2646370155170753815">"Potvrdi"</string>
+    <string name="cancel" msgid="6908697720451760115">"Otkaži"</string>
+    <string name="yes" msgid="9069828999585032361">"Potvrdi"</string>
+    <string name="no" msgid="5122037903299899715">"Otkaži"</string>
+    <string name="dialog_alert_title" msgid="651856561974090712">"Pažnja"</string>
+    <string name="loading" msgid="3138021523725055037">"Učitava se…"</string>
+    <string name="capital_on" msgid="2770685323900821829">"DA"</string>
+    <string name="capital_off" msgid="7443704171014626777">"NE"</string>
+    <string name="checked" msgid="9179896827054513119">"označeno je"</string>
+    <string name="not_checked" msgid="7972320087569023342">"nije označeno"</string>
+    <string name="selected" msgid="6614607926197755875">"izabrano"</string>
+    <string name="not_selected" msgid="410652016565864475">"nije izabrano"</string>
+    <string name="in_progress" msgid="2149208189184319441">"u toku"</string>
+    <string name="whichApplication" msgid="5432266899591255759">"Dovrši radnju preko"</string>
+    <string name="whichApplicationNamed" msgid="6969946041713975681">"Završite radnju pomoću aplikacije %1$s"</string>
+    <string name="whichApplicationLabel" msgid="7852182961472531728">"Završi radnju"</string>
+    <string name="whichViewApplication" msgid="5733194231473132945">"Otvorite pomoću"</string>
+    <string name="whichViewApplicationNamed" msgid="415164730629690105">"Otvorite pomoću aplikacije %1$s"</string>
+    <string name="whichViewApplicationLabel" msgid="7367556735684742409">"Otvori"</string>
+    <string name="whichOpenHostLinksWith" msgid="7645631470199397485">"Otvarajte <xliff:g id="HOST">%1$s</xliff:g> linkove pomoću"</string>
+    <string name="whichOpenLinksWith" msgid="1120936181362907258">"Otvaraj linkove pomoću"</string>
+    <string name="whichOpenLinksWithApp" msgid="6917864367861910086">"Otvarajte linkove pomoću aplikacije <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="2401668560768463004">"Otvarajte <xliff:g id="HOST">%1$s</xliff:g> linkove pomoću aplikacije <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichGiveAccessToApplicationLabel" msgid="7805857277166106236">"Dozvoli pristup"</string>
+    <string name="whichEditApplication" msgid="6191568491456092812">"Izmenite pomoću"</string>
+    <string name="whichEditApplicationNamed" msgid="8096494987978521514">"Izmenite pomoću aplikacije %1$s"</string>
+    <string name="whichEditApplicationLabel" msgid="1463288652070140285">"Izmeni"</string>
+    <string name="whichSendApplication" msgid="4143847974460792029">"Delite"</string>
+    <string name="whichSendApplicationNamed" msgid="4470386782693183461">"Delite pomoću aplikacije %1$s"</string>
+    <string name="whichSendApplicationLabel" msgid="7467813004769188515">"Deli"</string>
+    <string name="whichSendToApplication" msgid="77101541959464018">"Pošaljite pomoću:"</string>
+    <string name="whichSendToApplicationNamed" msgid="3385686512014670003">"Pošaljite pomoću: %1$s"</string>
+    <string name="whichSendToApplicationLabel" msgid="3543240188816513303">"Pošalji"</string>
+    <string name="whichHomeApplication" msgid="8276350727038396616">"Izaberite aplikaciju za početnu stranicu"</string>
+    <string name="whichHomeApplicationNamed" msgid="5855990024847433794">"Koristite %1$s za početnu"</string>
+    <string name="whichHomeApplicationLabel" msgid="8907334282202933959">"Snimite sliku"</string>
+    <string name="whichImageCaptureApplication" msgid="2737413019463215284">"Snimite sliku pomoću aplikacije"</string>
+    <string name="whichImageCaptureApplicationNamed" msgid="8820702441847612202">"Snimite sliku pomoću aplikacije %1$s"</string>
+    <string name="whichImageCaptureApplicationLabel" msgid="6505433734824988277">"Snimite sliku"</string>
+    <string name="alwaysUse" msgid="3153558199076112903">"Podrazumevano koristi za ovu radnju."</string>
+    <string name="use_a_different_app" msgid="4987790276170972776">"Koristite drugu aplikaciju"</string>
+    <string name="clearDefaultHintMsg" msgid="1325866337702524936">"Obrišite podrazumevano podešavanje u meniju Podešavanja sistema &gt; Aplikacije &gt; Preuzeto."</string>
+    <string name="chooseActivity" msgid="8563390197659779956">"Izaberite radnju"</string>
+    <string name="chooseUsbActivity" msgid="2096269989990986612">"Izbor aplikacije za USB uređaj"</string>
+    <string name="noApplications" msgid="1186909265235544019">"Nijedna aplikacija ne može da obavlja ovu radnju."</string>
+    <string name="aerr_application" msgid="4090916809370389109">"Aplikacija <xliff:g id="APPLICATION">%1$s</xliff:g> je zaustavljena"</string>
+    <string name="aerr_process" msgid="4268018696970966407">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> je zaustavljen"</string>
+    <string name="aerr_application_repeated" msgid="7804378743218496566">"<xliff:g id="APPLICATION">%1$s</xliff:g> se stalno zaustavlja"</string>
+    <string name="aerr_process_repeated" msgid="1153152413537954974">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> se stalno zaustavlja"</string>
+    <string name="aerr_restart" msgid="2789618625210505419">"Ponovo otvori aplikaciju"</string>
+    <string name="aerr_report" msgid="3095644466849299308">"Pošaljite povratne informacije"</string>
+    <string name="aerr_close" msgid="3398336821267021852">"Zatvori"</string>
+    <string name="aerr_mute" msgid="2304972923480211376">"Ignoriši dok se uređaj ne pokrene ponovo"</string>
+    <string name="aerr_wait" msgid="3198677780474548217">"Čekaj"</string>
+    <string name="aerr_close_app" msgid="8318883106083050970">"Zatvori aplikaciju"</string>
     <string name="anr_title" msgid="7290329487067300120"></string>
-    <string name="anr_activity_application" msgid="8121716632960340680">"<xliff:g id="APPLICATION">%2$s</xliff:g> не реагује"</string>
-    <string name="anr_activity_process" msgid="3477362583767128667">"<xliff:g id="ACTIVITY">%1$s</xliff:g> не реагује"</string>
-    <string name="anr_application_process" msgid="4978772139461676184">"<xliff:g id="APPLICATION">%1$s</xliff:g> не реагује"</string>
-    <string name="anr_process" msgid="1664277165911816067">"Процес <xliff:g id="PROCESS">%1$s</xliff:g> не реагује"</string>
-    <string name="force_close" msgid="9035203496368973803">"Потврди"</string>
-    <string name="report" msgid="2149194372340349521">"Пријави"</string>
-    <string name="wait" msgid="7765985809494033348">"Сачекај"</string>
-    <string name="webpage_unresponsive" msgid="7850879412195273433">"Страница је престала да се одазива.\n\n Да ли желите да је затворите?"</string>
-    <string name="launch_warning_title" msgid="6725456009564953595">"Апликација је преусмерена"</string>
-    <string name="launch_warning_replace" msgid="3073392976283203402">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> је сада покренута."</string>
-    <string name="launch_warning_original" msgid="3332206576800169626">"Првобитно је покренута апликација <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="screen_compat_mode_scale" msgid="8627359598437527726">"Размера"</string>
-    <string name="screen_compat_mode_show" msgid="5080361367584709857">"Увек приказуј"</string>
-    <string name="screen_compat_mode_hint" msgid="4032272159093750908">"Поново омогућите у менију Системска подешавања &gt; Апликације &gt; Преузето."</string>
-    <string name="unsupported_display_size_message" msgid="7265211375269394699">"<xliff:g id="APP_NAME">%1$s</xliff:g> не подржава тренутно подешавање величине приказа и може да се понаша неочекивано."</string>
-    <string name="unsupported_display_size_show" msgid="980129850974919375">"Увек приказуј"</string>
-    <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> је направљена за некомпатибилну верзију Android ОС-а и може да се понаша на неочекиван начин. Можда је доступна ажурирана верзија апликације."</string>
-    <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Увек прикажи"</string>
-    <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Потражи ажурирање"</string>
-    <string name="smv_application" msgid="3775183542777792638">"Апликација <xliff:g id="APPLICATION">%1$s</xliff:g> (процес <xliff:g id="PROCESS">%2$s</xliff:g>) је прекршила самонаметнуте StrictMode смернице."</string>
-    <string name="smv_process" msgid="1398801497130695446">"Процес <xliff:g id="PROCESS">%1$s</xliff:g> је прекршио самонаметнуте StrictMode смернице."</string>
-    <string name="android_upgrading_title" product="default" msgid="7279077384220829683">"Телефон се ажурира…"</string>
-    <string name="android_upgrading_title" product="tablet" msgid="4268417249079938805">"Таблет се ажурира…"</string>
-    <string name="android_upgrading_title" product="device" msgid="6774767702998149762">"Уређај се ажурира…"</string>
-    <string name="android_start_title" product="default" msgid="4036708252778757652">"Телефон се покреће…"</string>
-    <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android се покреће…"</string>
-    <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Таблет се покреће…"</string>
-    <string name="android_start_title" product="device" msgid="6967413819673299309">"Уређај се покреће…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Меморија се оптимизује."</string>
-    <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Ажурирање система се довршава…"</string>
-    <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> се надограђује…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Оптимизовање апликације <xliff:g id="NUMBER_0">%1$d</xliff:g> од <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
-    <string name="android_preparing_apk" msgid="589736917792300956">"Припрема се <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
-    <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Покретање апликација."</string>
-    <string name="android_upgrading_complete" msgid="409800058018374746">"Завршавање покретања."</string>
-    <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Притиснули сте дугме за укључивање – тиме обично искључујете екран.\n\nПробајте лагано да додирнете док подешавате отисак прста."</string>
-    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Завршите подешавање искључивањем екрана"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Искључи"</string>
-    <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Настављате верификацију отиска прста?"</string>
-    <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Притиснули сте дугме за укључивање – тиме обично искључујете екран.\n\nПробајте лагано да додирнете да бисте верификовали отисак прста."</string>
-    <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Искључи екран"</string>
-    <string name="fp_power_button_bp_negative_button" msgid="3971364246496775178">"Настави"</string>
-    <string name="heavy_weight_notification" msgid="8382784283600329576">"Апликација <xliff:g id="APP">%1$s</xliff:g> је покренута"</string>
-    <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Додирните да бисте се вратили у игру"</string>
-    <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Одаберите игру"</string>
-    <string name="heavy_weight_switcher_text" msgid="6814316627367160126">"Да би перформансе биле боље, може да буде отворена само једна од ових игара."</string>
-    <string name="old_app_action" msgid="725331621042848590">"Назад на <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_action" msgid="547772182913269801">"Отвори <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1958903080400806644">"<xliff:g id="OLD_APP">%1$s</xliff:g> ће се затворити без чувања"</string>
-    <string name="dump_heap_notification" msgid="5316644945404825032">"<xliff:g id="PROC">%1$s</xliff:g> премашује ограничење меморије"</string>
-    <string name="dump_heap_ready_notification" msgid="2302452262927390268">"Снимак динамичког дела меморије за процес <xliff:g id="PROC">%1$s</xliff:g> је спреман"</string>
-    <string name="dump_heap_notification_detail" msgid="8431586843001054050">"Снимак динамичког дела меморије је направљен. Додирните за дељење."</string>
-    <string name="dump_heap_title" msgid="4367128917229233901">"Желите ли да делите снимак динамичког дела меморије?"</string>
-    <string name="dump_heap_text" msgid="1692649033835719336">"Процес <xliff:g id="PROC">%1$s</xliff:g> је премашио ограничење меморије од <xliff:g id="SIZE">%2$s</xliff:g>. Снимак динамичког дела меморије је доступан и можете да га делите са програмером. Будите опрезни: овај снимак динамичког дела меморије може да садржи неке личне податке којима апликација може да приступа."</string>
-    <string name="dump_heap_system_text" msgid="6805155514925350849">"Процес <xliff:g id="PROC">%1$s</xliff:g> је премашио ограничење меморије од <xliff:g id="SIZE">%2$s</xliff:g>. Снимак динамичког дела меморије је доступан и можете да га делите. Будите опрезни: овај снимак динамичког дела меморије може да садржи осетљиве личне податке којима процес може да приступа, што може да обухвата текст који сте уносили."</string>
-    <string name="dump_heap_ready_text" msgid="5849618132123045516">"Снимак динамичког дела меморије за процес <xliff:g id="PROC">%1$s</xliff:g> је доступан и можете да га делите. Будите опрезни: овај снимак динамичког дела меморије може да садржи осетљиве личне податке којима процес може да приступа, што може да обухвата текст који сте уносили."</string>
-    <string name="sendText" msgid="493003724401350724">"Изаберите радњу за текст"</string>
-    <string name="volume_ringtone" msgid="134784084629229029">"Јачина звука звона"</string>
-    <string name="volume_music" msgid="7727274216734955095">"Јачина звука медија"</string>
-    <string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Играње преко Bluetooth-а"</string>
-    <string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Подешен је нечујни звук звона"</string>
-    <string name="volume_call" msgid="7625321655265747433">"Јачина звука долазног позива"</string>
-    <string name="volume_bluetooth_call" msgid="2930204618610115061">"Јачина звука долазећег позива преко Bluetooth-а"</string>
-    <string name="volume_alarm" msgid="4486241060751798448">"Јачина звука аларма"</string>
-    <string name="volume_notification" msgid="6864412249031660057">"Јачина звука за обавештења"</string>
-    <string name="volume_unknown" msgid="4041914008166576293">"Јачина звука"</string>
-    <string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"Јачина звука Bluetooth уређаја"</string>
-    <string name="volume_icon_description_ringer" msgid="2187800636867423459">"Јачина мелодије звона"</string>
-    <string name="volume_icon_description_incall" msgid="4491255105381227919">"Јачина звука позива"</string>
-    <string name="volume_icon_description_media" msgid="4997633254078171233">"Јачина звука медија"</string>
-    <string name="volume_icon_description_notification" msgid="579091344110747279">"Јачина звука обавештења"</string>
-    <string name="ringtone_default" msgid="9118299121288174597">"Подразумевани звук звона"</string>
-    <string name="ringtone_default_with_actual" msgid="2709686194556159773">"Подразумевано (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
-    <string name="ringtone_silent" msgid="397111123930141876">"Без звука"</string>
-    <string name="ringtone_picker_title" msgid="667342618626068253">"Звукови звона"</string>
-    <string name="ringtone_picker_title_alarm" msgid="7438934548339024767">"Звуци аларма"</string>
-    <string name="ringtone_picker_title_notification" msgid="6387191794719608122">"Звуци обавештења"</string>
-    <string name="ringtone_unknown" msgid="5059495249862816475">"Непознато"</string>
-    <string name="wifi_available_sign_in" msgid="381054692557675237">"Пријављивање на WiFi мрежу"</string>
-    <string name="network_available_sign_in" msgid="1520342291829283114">"Пријавите се на мрежу"</string>
+    <string name="anr_activity_application" msgid="8121716632960340680">"<xliff:g id="APPLICATION">%2$s</xliff:g> ne reaguje"</string>
+    <string name="anr_activity_process" msgid="3477362583767128667">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ne reaguje"</string>
+    <string name="anr_application_process" msgid="4978772139461676184">"<xliff:g id="APPLICATION">%1$s</xliff:g> ne reaguje"</string>
+    <string name="anr_process" msgid="1664277165911816067">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> ne reaguje"</string>
+    <string name="force_close" msgid="9035203496368973803">"Potvrdi"</string>
+    <string name="report" msgid="2149194372340349521">"Prijavi"</string>
+    <string name="wait" msgid="7765985809494033348">"Sačekaj"</string>
+    <string name="webpage_unresponsive" msgid="7850879412195273433">"Stranica je prestala da se odaziva.\n\n Da li želite da je zatvorite?"</string>
+    <string name="launch_warning_title" msgid="6725456009564953595">"Aplikacija je preusmerena"</string>
+    <string name="launch_warning_replace" msgid="3073392976283203402">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je sada pokrenuta."</string>
+    <string name="launch_warning_original" msgid="3332206576800169626">"Prvobitno je pokrenuta aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="screen_compat_mode_scale" msgid="8627359598437527726">"Razmera"</string>
+    <string name="screen_compat_mode_show" msgid="5080361367584709857">"Uvek prikazuj"</string>
+    <string name="screen_compat_mode_hint" msgid="4032272159093750908">"Ponovo omogućite u meniju Sistemska podešavanja &gt; Aplikacije &gt; Preuzeto."</string>
+    <string name="unsupported_display_size_message" msgid="7265211375269394699">"<xliff:g id="APP_NAME">%1$s</xliff:g> ne podržava trenutno podešavanje veličine prikaza i može da se ponaša neočekivano."</string>
+    <string name="unsupported_display_size_show" msgid="980129850974919375">"Uvek prikazuj"</string>
+    <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je napravljena za nekompatibilnu verziju Android OS-a i može da se ponaša na neočekivan način. Možda je dostupna ažurirana verzija aplikacije."</string>
+    <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Uvek prikaži"</string>
+    <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Potraži ažuriranje"</string>
+    <string name="smv_application" msgid="3775183542777792638">"Aplikacija <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) je prekršila samonametnute StrictMode smernice."</string>
+    <string name="smv_process" msgid="1398801497130695446">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> je prekršio samonametnute StrictMode smernice."</string>
+    <string name="android_upgrading_title" product="default" msgid="7279077384220829683">"Telefon se ažurira…"</string>
+    <string name="android_upgrading_title" product="tablet" msgid="4268417249079938805">"Tablet se ažurira…"</string>
+    <string name="android_upgrading_title" product="device" msgid="6774767702998149762">"Uređaj se ažurira…"</string>
+    <string name="android_start_title" product="default" msgid="4036708252778757652">"Telefon se pokreće…"</string>
+    <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android se pokreće…"</string>
+    <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Tablet se pokreće…"</string>
+    <string name="android_start_title" product="device" msgid="6967413819673299309">"Uređaj se pokreće…"</string>
+    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Memorija se optimizuje."</string>
+    <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Ažuriranje sistema se dovršava…"</string>
+    <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> se nadograđuje…"</string>
+    <string name="android_upgrading_apk" msgid="1339564803894466737">"Optimizovanje aplikacije <xliff:g id="NUMBER_0">%1$d</xliff:g> od <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+    <string name="android_preparing_apk" msgid="589736917792300956">"Priprema se <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
+    <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Pokretanje aplikacija."</string>
+    <string name="android_upgrading_complete" msgid="409800058018374746">"Završavanje pokretanja."</string>
+    <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Pritisnuli ste dugme za uključivanje – time obično isključujete ekran.\n\nProbajte lagano da dodirnete dok podešavate otisak prsta."</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Završite podešavanje isključivanjem ekrana"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Isključi"</string>
+    <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Nastavljate verifikaciju otiska prsta?"</string>
+    <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Pritisnuli ste dugme za uključivanje – time obično isključujete ekran.\n\nProbajte lagano da dodirnete da biste verifikovali otisak prsta."</string>
+    <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Isključi ekran"</string>
+    <string name="fp_power_button_bp_negative_button" msgid="3971364246496775178">"Nastavi"</string>
+    <string name="heavy_weight_notification" msgid="8382784283600329576">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> je pokrenuta"</string>
+    <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Dodirnite da biste se vratili u igru"</string>
+    <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Odaberite igru"</string>
+    <string name="heavy_weight_switcher_text" msgid="6814316627367160126">"Da bi performanse bile bolje, može da bude otvorena samo jedna od ovih igara."</string>
+    <string name="old_app_action" msgid="725331621042848590">"Nazad na <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
+    <string name="new_app_action" msgid="547772182913269801">"Otvori <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
+    <string name="new_app_description" msgid="1958903080400806644">"<xliff:g id="OLD_APP">%1$s</xliff:g> će se zatvoriti bez čuvanja"</string>
+    <string name="dump_heap_notification" msgid="5316644945404825032">"<xliff:g id="PROC">%1$s</xliff:g> premašuje ograničenje memorije"</string>
+    <string name="dump_heap_ready_notification" msgid="2302452262927390268">"Snimak dinamičkog dela memorije za proces <xliff:g id="PROC">%1$s</xliff:g> je spreman"</string>
+    <string name="dump_heap_notification_detail" msgid="8431586843001054050">"Snimak dinamičkog dela memorije je napravljen. Dodirnite za deljenje."</string>
+    <string name="dump_heap_title" msgid="4367128917229233901">"Želite li da delite snimak dinamičkog dela memorije?"</string>
+    <string name="dump_heap_text" msgid="1692649033835719336">"Proces <xliff:g id="PROC">%1$s</xliff:g> je premašio ograničenje memorije od <xliff:g id="SIZE">%2$s</xliff:g>. Snimak dinamičkog dela memorije je dostupan i možete da ga delite sa programerom. Budite oprezni: ovaj snimak dinamičkog dela memorije može da sadrži neke lične podatke kojima aplikacija može da pristupa."</string>
+    <string name="dump_heap_system_text" msgid="6805155514925350849">"Proces <xliff:g id="PROC">%1$s</xliff:g> je premašio ograničenje memorije od <xliff:g id="SIZE">%2$s</xliff:g>. Snimak dinamičkog dela memorije je dostupan i možete da ga delite. Budite oprezni: ovaj snimak dinamičkog dela memorije može da sadrži osetljive lične podatke kojima proces može da pristupa, što može da obuhvata tekst koji ste unosili."</string>
+    <string name="dump_heap_ready_text" msgid="5849618132123045516">"Snimak dinamičkog dela memorije za proces <xliff:g id="PROC">%1$s</xliff:g> je dostupan i možete da ga delite. Budite oprezni: ovaj snimak dinamičkog dela memorije može da sadrži osetljive lične podatke kojima proces može da pristupa, što može da obuhvata tekst koji ste unosili."</string>
+    <string name="sendText" msgid="493003724401350724">"Izaberite radnju za tekst"</string>
+    <string name="volume_ringtone" msgid="134784084629229029">"Jačina zvuka zvona"</string>
+    <string name="volume_music" msgid="7727274216734955095">"Jačina zvuka medija"</string>
+    <string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Igranje preko Bluetooth-a"</string>
+    <string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Podešen je nečujni zvuk zvona"</string>
+    <string name="volume_call" msgid="7625321655265747433">"Jačina zvuka dolaznog poziva"</string>
+    <string name="volume_bluetooth_call" msgid="2930204618610115061">"Jačina zvuka dolazećeg poziva preko Bluetooth-a"</string>
+    <string name="volume_alarm" msgid="4486241060751798448">"Jačina zvuka alarma"</string>
+    <string name="volume_notification" msgid="6864412249031660057">"Jačina zvuka za obaveštenja"</string>
+    <string name="volume_unknown" msgid="4041914008166576293">"Jačina zvuka"</string>
+    <string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"Jačina zvuka Bluetooth uređaja"</string>
+    <string name="volume_icon_description_ringer" msgid="2187800636867423459">"Jačina melodije zvona"</string>
+    <string name="volume_icon_description_incall" msgid="4491255105381227919">"Jačina zvuka poziva"</string>
+    <string name="volume_icon_description_media" msgid="4997633254078171233">"Jačina zvuka medija"</string>
+    <string name="volume_icon_description_notification" msgid="579091344110747279">"Jačina zvuka obaveštenja"</string>
+    <string name="ringtone_default" msgid="9118299121288174597">"Podrazumevani zvuk zvona"</string>
+    <string name="ringtone_default_with_actual" msgid="2709686194556159773">"Podrazumevano (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <string name="ringtone_silent" msgid="397111123930141876">"Bez zvuka"</string>
+    <string name="ringtone_picker_title" msgid="667342618626068253">"Zvukovi zvona"</string>
+    <string name="ringtone_picker_title_alarm" msgid="7438934548339024767">"Zvuci alarma"</string>
+    <string name="ringtone_picker_title_notification" msgid="6387191794719608122">"Zvuci obaveštenja"</string>
+    <string name="ringtone_unknown" msgid="5059495249862816475">"Nepoznato"</string>
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Prijavljivanje na WiFi mrežu"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Prijavite se na mrežu"</string>
     <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
     <skip />
-    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> нема приступ интернету"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Додирните за опције"</string>
-    <string name="mobile_no_internet" msgid="4014455157529909781">"Мобилна мрежа нема приступ интернету"</string>
-    <string name="other_networks_no_internet" msgid="6698711684200067033">"Мрежа нема приступ интернету"</string>
-    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Приступ приватном DNS серверу није успео"</string>
-    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> има ограничену везу"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Додирните да бисте се ипак повезали"</string>
-    <string name="network_switch_metered" msgid="1531869544142283384">"Прешли сте на тип мреже <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Уређај користи тип мреже <xliff:g id="NEW_NETWORK">%1$s</xliff:g> када тип мреже <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> нема приступ интернету. Можда ће се наплаћивати трошкови."</string>
-    <string name="network_switch_metered_toast" msgid="501662047275723743">"Прешли сте са типа мреже <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> на тип мреже <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nema pristup internetu"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Dodirnite za opcije"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobilna mreža nema pristup internetu"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Mreža nema pristup internetu"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Pristup privatnom DNS serveru nije uspeo"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ima ograničenu vezu"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Dodirnite da biste se ipak povezali"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Prešli ste na tip mreže <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Uređaj koristi tip mreže <xliff:g id="NEW_NETWORK">%1$s</xliff:g> kada tip mreže <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nema pristup internetu. Možda će se naplaćivati troškovi."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Prešli ste sa tipa mreže <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na tip mreže <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
-    <item msgid="2255670471736226365">"мобилни подаци"</item>
+    <item msgid="2255670471736226365">"mobilni podaci"</item>
     <item msgid="5520925862115353992">"WiFi"</item>
     <item msgid="1055487873974272842">"Bluetooth"</item>
-    <item msgid="1616528372438698248">"Етернет"</item>
+    <item msgid="1616528372438698248">"Eternet"</item>
     <item msgid="9177085807664964627">"VPN"</item>
   </string-array>
-    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"непознат тип мреже"</string>
-    <string name="accept" msgid="5447154347815825107">"Прихвати"</string>
-    <string name="decline" msgid="6490507610282145874">"Одбиј"</string>
-    <string name="select_character" msgid="3352797107930786979">"Уметање знака"</string>
-    <string name="sms_control_title" msgid="4748684259903148341">"Слање SMS порука"</string>
-    <string name="sms_control_message" msgid="6574313876316388239">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; шаље велики број SMS порука. Желите ли да дозволите овој апликацији да настави са слањем порука?"</string>
-    <string name="sms_control_yes" msgid="4858845109269524622">"Дозволи"</string>
-    <string name="sms_control_no" msgid="4845717880040355570">"Одбиј"</string>
-    <string name="sms_short_code_confirm_message" msgid="1385416688897538724">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; жели да пошаље поруку на адресу &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt;."</string>
-    <string name="sms_short_code_details" msgid="2723725738333388351">"Ово "<b>"може да проузрокује трошкове"</b>" на рачуну за мобилни уређај."</string>
-    <string name="sms_premium_short_code_details" msgid="1400296309866638111"><b>"Ово ће проузроковати трошкове на рачуну за мобилни уређај."</b></string>
-    <string name="sms_short_code_confirm_allow" msgid="920477594325526691">"Пошаљи"</string>
-    <string name="sms_short_code_confirm_deny" msgid="1356917469323768230">"Откажи"</string>
-    <string name="sms_short_code_remember_choice" msgid="1374526438647744862">"Запамти мој избор"</string>
-    <string name="sms_short_code_remember_undo_instruction" msgid="2620984439143080410">"Ово можете да промените касније у Подешавања &gt; Апликације"</string>
-    <string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"Увек дозволи"</string>
-    <string name="sms_short_code_confirm_never_allow" msgid="2688828813521652079">"Никада не дозволи"</string>
-    <string name="sim_removed_title" msgid="5387212933992546283">"SIM картица је уклоњена"</string>
-    <string name="sim_removed_message" msgid="9051174064474904617">"Мобилна мрежа неће бити доступна док не покренете систем поново уз уметање важеће SIM картице."</string>
-    <string name="sim_done_button" msgid="6464250841528410598">"Готово"</string>
-    <string name="sim_added_title" msgid="7930779986759414595">"SIM картица је додата"</string>
-    <string name="sim_added_message" msgid="6602906609509958680">"Рестартујте уређај да бисте могли да приступите мобилној мрежи."</string>
-    <string name="sim_restart_button" msgid="8481803851341190038">"Рестартуј"</string>
-    <string name="install_carrier_app_notification_title" msgid="5712723402213090102">"Активирајте мобилну услугу"</string>
-    <string name="install_carrier_app_notification_text" msgid="2781317581274192728">"Преузмите апликацију мобилног оператера да бисте активирали нови SIM"</string>
-    <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"Преузмите апликацију <xliff:g id="APP_NAME">%1$s</xliff:g> да бисте активирали нову SIM картицу"</string>
-    <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Преузмите апликацију"</string>
-    <string name="carrier_app_notification_title" msgid="5815477368072060250">"Нова SIM картица је уметнута"</string>
-    <string name="carrier_app_notification_text" msgid="6567057546341958637">"Додирните за подешавање"</string>
-    <string name="time_picker_dialog_title" msgid="9053376764985220821">"Подесите време"</string>
-    <string name="date_picker_dialog_title" msgid="5030520449243071926">"Подешавање датума"</string>
-    <string name="date_time_set" msgid="4603445265164486816">"Подеси"</string>
-    <string name="date_time_done" msgid="8363155889402873463">"Готово"</string>
-    <string name="perms_new_perm_prefix" msgid="6984556020395757087"><font size="12" fgcolor="#ff33b5e5">"НОВО: "</font></string>
-    <string name="perms_description_app" msgid="2747752389870161996">"Омогућава <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="no_permissions" msgid="5729199278862516390">"Није потребна ниједна дозвола"</string>
-    <string name="perm_costs_money" msgid="749054595022779685">"ово ће вам можда бити наплаћено"</string>
-    <string name="dlg_ok" msgid="5103447663504839312">"Потврди"</string>
-    <string name="usb_charging_notification_title" msgid="1674124518282666955">"Овај уређај се пуни преко USB-а"</string>
-    <string name="usb_supplying_notification_title" msgid="5378546632408101811">"Повезани уређај се пуни преко USB-а"</string>
-    <string name="usb_mtp_notification_title" msgid="1065989144124499810">"USB пренос датотека је укључен"</string>
-    <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Режим PTP преко USB-а је укључен"</string>
-    <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB привезивање је укључено"</string>
-    <string name="usb_midi_notification_title" msgid="7404506788950595557">"Режим MIDI преко USB-а је укључен"</string>
-    <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB додатак је повезан"</string>
-    <string name="usb_notification_message" msgid="4715163067192110676">"Додирните за још опција."</string>
-    <string name="usb_power_notification_message" msgid="7284765627437897702">"Повезани уређај се пуни. Додирните за још опција."</string>
-    <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Откривена је аналогна додатна опрема за аудио садржај"</string>
-    <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Прикључени уређај није компатибилан са овим телефоном. Додирните да бисте сазнали више."</string>
-    <string name="adb_active_notification_title" msgid="408390247354560331">"Повезано је отклањање грешака са USB-а"</string>
-    <string name="adb_active_notification_message" msgid="5617264033476778211">"Додирните да бисте га искључили"</string>
-    <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Изаберите да бисте онемогућили отклањања грешака са USB-а."</string>
-    <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Бежично отклањање грешака је повезано"</string>
-    <string name="adbwifi_active_notification_message" msgid="930987922852867972">"Додирните да бисте искључили бежично отклањање грешака"</string>
-    <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Изаберите да бисте онемогућили бежично отклањање грешака."</string>
-    <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Омогућен је режим пробног коришћења"</string>
-    <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Обавите ресетовање на фабричка подешавања да бисте онемогућили режим пробног коришћења."</string>
-    <string name="console_running_notification_title" msgid="6087888939261635904">"Серијска конзола је омогућена"</string>
-    <string name="console_running_notification_message" msgid="7892751888125174039">"Перформансе су смањене. Да бисте онемогући конзолу, проверите покретачки програм."</string>
-    <string name="mte_override_notification_title" msgid="4731115381962792944">"Експериментални MTE је омогућен"</string>
-    <string name="mte_override_notification_message" msgid="2441170442725738942">"Ово може да утиче на перформансе и стабилност. Рестартујте да бисте онемогућили. Ако је омогућено помоћу arm64.memtag.bootctl, прво подесите на Ништа."</string>
-    <string name="usb_contaminant_detected_title" msgid="4359048603069159678">"Течност или нечистоћа у USB порту"</string>
-    <string name="usb_contaminant_detected_message" msgid="7346100585390795743">"USB порт је аутоматски искључен. Додирните да бисте сазнали више."</string>
-    <string name="usb_contaminant_not_detected_title" msgid="2651167729563264053">"Коришћење USB порта је дозвољено"</string>
-    <string name="usb_contaminant_not_detected_message" msgid="892863190942660462">"Телефон више не открива течност или нечистоћу."</string>
-    <string name="taking_remote_bugreport_notification_title" msgid="1582531382166919850">"Извештај о грешци се генерише…"</string>
-    <string name="share_remote_bugreport_notification_title" msgid="6708897723753334999">"Желите ли да поделите извештај о грешци?"</string>
-    <string name="sharing_remote_bugreport_notification_title" msgid="3077385149217638550">"Дели се извештај о грешци…"</string>
-    <string name="share_remote_bugreport_notification_message_finished" msgid="7325635795739260135">"Администратор је затражио извештај о грешци ради лакшег решавања проблема у вези са овим уређајем. Апликације и подаци могу да се деле."</string>
-    <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="select_keyboard_layout_notification_title" msgid="4427643867639774118">"Конфигуришите физичку тастатуру"</string>
-    <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Додирните да бисте изабрали језик и распоред"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"nepoznat tip mreže"</string>
+    <string name="accept" msgid="5447154347815825107">"Prihvati"</string>
+    <string name="decline" msgid="6490507610282145874">"Odbij"</string>
+    <string name="select_character" msgid="3352797107930786979">"Umetanje znaka"</string>
+    <string name="sms_control_title" msgid="4748684259903148341">"Slanje SMS poruka"</string>
+    <string name="sms_control_message" msgid="6574313876316388239">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; šalje veliki broj SMS poruka. Želite li da dozvolite ovoj aplikaciji da nastavi sa slanjem poruka?"</string>
+    <string name="sms_control_yes" msgid="4858845109269524622">"Dozvoli"</string>
+    <string name="sms_control_no" msgid="4845717880040355570">"Odbij"</string>
+    <string name="sms_short_code_confirm_message" msgid="1385416688897538724">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; želi da pošalje poruku na adresu &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt;."</string>
+    <string name="sms_short_code_details" msgid="2723725738333388351">"Ovo "<b>"može da prouzrokuje troškove"</b>" na računu za mobilni uređaj."</string>
+    <string name="sms_premium_short_code_details" msgid="1400296309866638111"><b>"Ovo će prouzrokovati troškove na računu za mobilni uređaj."</b></string>
+    <string name="sms_short_code_confirm_allow" msgid="920477594325526691">"Pošalji"</string>
+    <string name="sms_short_code_confirm_deny" msgid="1356917469323768230">"Otkaži"</string>
+    <string name="sms_short_code_remember_choice" msgid="1374526438647744862">"Zapamti moj izbor"</string>
+    <string name="sms_short_code_remember_undo_instruction" msgid="2620984439143080410">"Ovo možete da promenite kasnije u Podešavanja &gt; Aplikacije"</string>
+    <string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"Uvek dozvoli"</string>
+    <string name="sms_short_code_confirm_never_allow" msgid="2688828813521652079">"Nikada ne dozvoli"</string>
+    <string name="sim_removed_title" msgid="5387212933992546283">"SIM kartica je uklonjena"</string>
+    <string name="sim_removed_message" msgid="9051174064474904617">"Mobilna mreža neće biti dostupna dok ne pokrenete sistem ponovo uz umetanje važeće SIM kartice."</string>
+    <string name="sim_done_button" msgid="6464250841528410598">"Gotovo"</string>
+    <string name="sim_added_title" msgid="7930779986759414595">"SIM kartica je dodata"</string>
+    <string name="sim_added_message" msgid="6602906609509958680">"Restartujte uređaj da biste mogli da pristupite mobilnoj mreži."</string>
+    <string name="sim_restart_button" msgid="8481803851341190038">"Restartuj"</string>
+    <string name="install_carrier_app_notification_title" msgid="5712723402213090102">"Aktivirajte mobilnu uslugu"</string>
+    <string name="install_carrier_app_notification_text" msgid="2781317581274192728">"Preuzmite aplikaciju mobilnog operatera da biste aktivirali novi SIM"</string>
+    <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"Preuzmite aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> da biste aktivirali novu SIM karticu"</string>
+    <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Preuzmite aplikaciju"</string>
+    <string name="carrier_app_notification_title" msgid="5815477368072060250">"Nova SIM kartica je umetnuta"</string>
+    <string name="carrier_app_notification_text" msgid="6567057546341958637">"Dodirnite za podešavanje"</string>
+    <string name="time_picker_dialog_title" msgid="9053376764985220821">"Podesite vreme"</string>
+    <string name="date_picker_dialog_title" msgid="5030520449243071926">"Podešavanje datuma"</string>
+    <string name="date_time_set" msgid="4603445265164486816">"Podesi"</string>
+    <string name="date_time_done" msgid="8363155889402873463">"Gotovo"</string>
+    <string name="perms_new_perm_prefix" msgid="6984556020395757087"><font size="12" fgcolor="#ff33b5e5">"NOVO: "</font></string>
+    <string name="perms_description_app" msgid="2747752389870161996">"Omogućava <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="no_permissions" msgid="5729199278862516390">"Nije potrebna nijedna dozvola"</string>
+    <string name="perm_costs_money" msgid="749054595022779685">"ovo će vam možda biti naplaćeno"</string>
+    <string name="dlg_ok" msgid="5103447663504839312">"Potvrdi"</string>
+    <string name="usb_charging_notification_title" msgid="1674124518282666955">"Ovaj uređaj se puni preko USB-a"</string>
+    <string name="usb_supplying_notification_title" msgid="5378546632408101811">"Povezani uređaj se puni preko USB-a"</string>
+    <string name="usb_mtp_notification_title" msgid="1065989144124499810">"USB prenos datoteka je uključen"</string>
+    <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Režim PTP preko USB-a je uključen"</string>
+    <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB privezivanje je uključeno"</string>
+    <string name="usb_midi_notification_title" msgid="7404506788950595557">"Režim MIDI preko USB-a je uključen"</string>
+    <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB dodatak je povezan"</string>
+    <string name="usb_notification_message" msgid="4715163067192110676">"Dodirnite za još opcija."</string>
+    <string name="usb_power_notification_message" msgid="7284765627437897702">"Povezani uređaj se puni. Dodirnite za još opcija."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Otkrivena je analogna dodatna oprema za audio sadržaj"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Priključeni uređaj nije kompatibilan sa ovim telefonom. Dodirnite da biste saznali više."</string>
+    <string name="adb_active_notification_title" msgid="408390247354560331">"Povezano je otklanjanje grešaka sa USB-a"</string>
+    <string name="adb_active_notification_message" msgid="5617264033476778211">"Dodirnite da biste ga isključili"</string>
+    <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Izaberite da biste onemogućili otklanjanja grešaka sa USB-a."</string>
+    <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Bežično otklanjanje grešaka je povezano"</string>
+    <string name="adbwifi_active_notification_message" msgid="930987922852867972">"Dodirnite da biste isključili bežično otklanjanje grešaka"</string>
+    <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Izaberite da biste onemogućili bežično otklanjanje grešaka."</string>
+    <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Omogućen je režim probnog korišćenja"</string>
+    <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Obavite resetovanje na fabrička podešavanja da biste onemogućili režim probnog korišćenja."</string>
+    <string name="console_running_notification_title" msgid="6087888939261635904">"Serijska konzola je omogućena"</string>
+    <string name="console_running_notification_message" msgid="7892751888125174039">"Performanse su smanjene. Da biste onemogući konzolu, proverite pokretački program."</string>
+    <string name="mte_override_notification_title" msgid="4731115381962792944">"Eksperimentalni MTE je omogućen"</string>
+    <string name="mte_override_notification_message" msgid="2441170442725738942">"Ovo može da utiče na performanse i stabilnost. Restartujte da biste onemogućili. Ako je omogućeno pomoću arm64.memtag.bootctl, prvo podesite na Ništa."</string>
+    <string name="usb_contaminant_detected_title" msgid="4359048603069159678">"Tečnost ili nečistoća u USB portu"</string>
+    <string name="usb_contaminant_detected_message" msgid="7346100585390795743">"USB port je automatski isključen. Dodirnite da biste saznali više."</string>
+    <string name="usb_contaminant_not_detected_title" msgid="2651167729563264053">"Korišćenje USB porta je dozvoljeno"</string>
+    <string name="usb_contaminant_not_detected_message" msgid="892863190942660462">"Telefon više ne otkriva tečnost ili nečistoću."</string>
+    <string name="taking_remote_bugreport_notification_title" msgid="1582531382166919850">"Izveštaj o grešci se generiše…"</string>
+    <string name="share_remote_bugreport_notification_title" msgid="6708897723753334999">"Želite li da podelite izveštaj o grešci?"</string>
+    <string name="sharing_remote_bugreport_notification_title" msgid="3077385149217638550">"Deli se izveštaj o grešci…"</string>
+    <string name="share_remote_bugreport_notification_message_finished" msgid="7325635795739260135">"Administrator je zatražio izveštaj o grešci radi lakšeg rešavanja problema u vezi sa ovim uređajem. Aplikacije i podaci mogu da se dele."</string>
+    <string name="share_remote_bugreport_action" msgid="7630880678785123682">"DELI"</string>
+    <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="select_keyboard_layout_notification_title" msgid="4427643867639774118">"Konfigurišite fizičku tastaturu"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Dodirnite da biste izabrali jezik i raspored"</string>
     <string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Приказ преко других апликација"</string>
-    <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"Апликација <xliff:g id="NAME">%s</xliff:g> се приказује преко других апликација"</string>
-    <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> се приказује преко других апл."</string>
-    <string name="alert_windows_notification_message" msgid="6538171456970725333">"Ако не желите ову функцију за <xliff:g id="NAME">%s</xliff:g>, додирните да бисте отворили подешавања и искључили је."</string>
-    <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Искључи"</string>
-    <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Проверава се <xliff:g id="NAME">%s</xliff:g>…"</string>
-    <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Прегледа се актуелни садржај"</string>
-    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Анализира се меморијски простор за медије"</string>
-    <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Нови/а <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> не ради"</string>
-    <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Додирните да бисте подесили"</string>
-    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Изаберите да бисте подесили"</string>
-    <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Можда морате да реформатирате уређај. Додирните да бисте избацили."</string>
-    <string name="ext_media_ready_notification_message" msgid="7509496364380197369">"За чување слика, видео снимака, музике и другог садржаја"</string>
-    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Прегледајте медијске фајлове"</string>
-    <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Проблем са: <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> не ради"</string>
-    <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Додирните да бисте исправили"</string>
-    <string name="ext_media_unmountable_notification_message" product="tv" msgid="3003611129979934633">"Медиј <xliff:g id="NAME">%s</xliff:g> је оштећен. Изаберите да га поправите."</string>
-    <string name="ext_media_unmountable_notification_message" product="automotive" msgid="2274596120715020680">"Можда морате да реформатирате уређај. Додирните да бисте избацили."</string>
-    <string name="ext_media_unsupported_notification_title" msgid="3487534182861251401">"Откривенo: <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> не ради"</string>
-    <string name="ext_media_unsupported_notification_message" msgid="8463636521459807981">"Додирните да бисте подесили."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Изаберите да бисте подесили уређај <xliff:g id="NAME">%s</xliff:g> у подржаном формату."</string>
-    <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Можда морате да реформатирате уређај"</string>
-    <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"Уређај <xliff:g id="NAME">%s</xliff:g> је неочекивано уклоњен"</string>
-    <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Избаците медијум пре него што га уклоните да не бисте изгубили садржај"</string>
-    <string name="ext_media_nomedia_notification_title" msgid="742671636376975890">"<xliff:g id="NAME">%s</xliff:g> је уклоњен/а"</string>
-    <string name="ext_media_nomedia_notification_message" msgid="2832724384636625852">"Неке функције можда неће исправно радити. Уметните нов меморијски уређај."</string>
-    <string name="ext_media_unmounting_notification_title" msgid="4147986383917892162">"Избацује се <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="ext_media_unmounting_notification_message" msgid="5717036261538754203">"Не уклањајте"</string>
-    <string name="ext_media_init_action" msgid="2312974060585056709">"Активирај"</string>
-    <string name="ext_media_unmount_action" msgid="966992232088442745">"Избаци"</string>
-    <string name="ext_media_browse_action" msgid="344865351947079139">"Истражи"</string>
-    <string name="ext_media_seamless_action" msgid="8837030226009268080">"Промените излаз"</string>
-    <string name="ext_media_missing_title" msgid="3209472091220515046">"<xliff:g id="NAME">%s</xliff:g> недостаје"</string>
-    <string name="ext_media_missing_message" msgid="4408988706227922909">"Поново уметните уређај"</string>
-    <string name="ext_media_move_specific_title" msgid="8492118544775964250">"Преноси се <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="ext_media_move_title" msgid="2682741525619033637">"Подаци се преносе"</string>
-    <string name="ext_media_move_success_title" msgid="4901763082647316767">"Пренос садржаја је готов"</string>
-    <string name="ext_media_move_success_message" msgid="9159542002276982979">"Садржај је премешен на: <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="ext_media_move_failure_title" msgid="3184577479181333665">"Премештање садржаја није успело"</string>
-    <string name="ext_media_move_failure_message" msgid="4197306718121869335">"Пробајте да поново преместите садржај"</string>
-    <string name="ext_media_status_removed" msgid="241223931135751691">"Уклоњен је"</string>
-    <string name="ext_media_status_unmounted" msgid="8145812017295835941">"Избачен је"</string>
-    <string name="ext_media_status_checking" msgid="159013362442090347">"Проверава се..."</string>
-    <string name="ext_media_status_mounted" msgid="3459448555811203459">"Спреман је"</string>
-    <string name="ext_media_status_mounted_ro" msgid="1974809199760086956">"Само за читање"</string>
-    <string name="ext_media_status_bad_removal" msgid="508448566481406245">"Уклоњен је на небезбедан начин"</string>
-    <string name="ext_media_status_unmountable" msgid="7043574843541087748">"Оштећен је"</string>
-    <string name="ext_media_status_unsupported" msgid="5460509911660539317">"Није подржан"</string>
-    <string name="ext_media_status_ejecting" msgid="7532403368044013797">"Избацује се..."</string>
-    <string name="ext_media_status_formatting" msgid="774148701503179906">"Форматира се..."</string>
-    <string name="ext_media_status_missing" msgid="6520746443048867314">"Није уметнут"</string>
-    <string name="activity_list_empty" msgid="4219430010716034252">"Није пронађена ниједна подударна активност."</string>
-    <string name="permlab_route_media_output" msgid="8048124531439513118">"усмеравање излаза медија"</string>
-    <string name="permdesc_route_media_output" msgid="1759683269387729675">"Дозвољава апликацији да усмерава излаз медија на друге спољне уређаје."</string>
-    <string name="permlab_readInstallSessions" msgid="7279049337895583621">"читање сесија инсталирања"</string>
-    <string name="permdesc_readInstallSessions" msgid="4012608316610763473">"Дозвољава апликацији да чита сесије инсталирања. То јој дозвољава да види детаље о активним инсталацијама пакета."</string>
-    <string name="permlab_requestInstallPackages" msgid="7600020863445351154">"захтевање пакета за инсталирање"</string>
-    <string name="permdesc_requestInstallPackages" msgid="3969369278325313067">"Омогућава да апликација захтева инсталацију пакета."</string>
-    <string name="permlab_requestDeletePackages" msgid="2541172829260106795">"захтевање брисања пакета"</string>
-    <string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Омогућава да апликација захтева брисање пакета."</string>
-    <string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"тражење дозволе за игнорисање оптимизација батерије"</string>
-    <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Дозвољава апликацији да тражи дозволу за игнорисање оптимизација батерије за ту апликацију."</string>
-    <string name="permlab_queryAllPackages" msgid="2928450604653281650">"слање упита за све пакете"</string>
-    <string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Дозвољава апликацији да види све инсталиране пакете."</string>
-    <string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Додирните двапут за контролу зумирања"</string>
-    <string name="gadget_host_error_inflating" msgid="2449961590495198720">"Није могуће додати виџет."</string>
-    <string name="ime_action_go" msgid="5536744546326495436">"Иди"</string>
-    <string name="ime_action_search" msgid="4501435960587287668">"Претражи"</string>
-    <string name="ime_action_send" msgid="8456843745664334138">"Пошаљи"</string>
-    <string name="ime_action_next" msgid="4169702997635728543">"Даље"</string>
-    <string name="ime_action_done" msgid="6299921014822891569">"Готово"</string>
-    <string name="ime_action_previous" msgid="6548799326860401611">"Претходно"</string>
-    <string name="ime_action_default" msgid="8265027027659800121">"Изврши"</string>
-    <string name="dial_number_using" msgid="6060769078933953531">"Бирај број\nкористећи <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="6200708808003692594">"Направите контакт\nкористећи <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"Следеће апликације захтевају дозволу за приступ налогу, како сада, тако и убудуће."</string>
-    <string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"Желите да одобрите овај захтев?"</string>
-    <string name="grant_permissions_header_text" msgid="3420736827804657201">"Захтев за приступ"</string>
-    <string name="allow" msgid="6195617008611933762">"Дозволи"</string>
-    <string name="deny" msgid="6632259981847676572">"Одбиј"</string>
-    <string name="permission_request_notification_title" msgid="1810025922441048273">"Затражена је дозвола"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="3743417870360129298">"Затражена је дозвола\nза налог <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
-    <string name="permission_request_notification_for_app_with_subtitle" msgid="1298704005732851350">"<xliff:g id="APP">%1$s</xliff:g> тражи дозволу \nза налог <xliff:g id="ACCOUNT">%2$s</xliff:g>."</string>
-    <string name="forward_intent_to_owner" msgid="4620359037192871015">"Користите ову апликацију изван пословног профила"</string>
-    <string name="forward_intent_to_work" msgid="3620262405636021151">"Користите ову апликацију на пословном профилу"</string>
-    <string name="input_method_binding_label" msgid="1166731601721983656">"Метод уноса"</string>
-    <string name="sync_binding_label" msgid="469249309424662147">"Синхронизација"</string>
-    <string name="accessibility_binding_label" msgid="1974602776545801715">"Приступачност"</string>
-    <string name="wallpaper_binding_label" msgid="1197440498000786738">"Позадина"</string>
-    <string name="chooser_wallpaper" msgid="3082405680079923708">"Промена позадине"</string>
-    <string name="notification_listener_binding_label" msgid="2702165274471499713">"Монитор обавештења"</string>
-    <string name="vr_listener_binding_label" msgid="8013112996671206429">"Обрађивач за виртуелну реалност"</string>
-    <string name="condition_provider_service_binding_label" msgid="8490641013951857673">"Добављач услова"</string>
-    <string name="notification_ranker_binding_label" msgid="432708245635563763">"Услуга рангирања обавештења"</string>
-    <string name="vpn_title" msgid="5906991595291514182">"VPN је активиран"</string>
-    <string name="vpn_title_long" msgid="6834144390504619998">"Апликација <xliff:g id="APP">%s</xliff:g> је активирала VPN"</string>
-    <string name="vpn_text" msgid="2275388920267251078">"Додирните да бисте управљали мрежом."</string>
-    <string name="vpn_text_long" msgid="278540576806169831">"Повезано са сесијом <xliff:g id="SESSION">%s</xliff:g>. Додирните да бисте управљали мрежом."</string>
-    <string name="vpn_lockdown_connecting" msgid="6096725311950342607">"Повезивање стално укљученог VPN-а..."</string>
-    <string name="vpn_lockdown_connected" msgid="2853127976590658469">"Стално укључен VPN је повезан"</string>
-    <string name="vpn_lockdown_disconnected" msgid="5573611651300764955">"Веза са увек укљученим VPN-ом је прекинута"</string>
-    <string name="vpn_lockdown_error" msgid="4453048646854247947">"Повезивање на стално укључени VPN није успело"</string>
-    <string name="vpn_lockdown_config" msgid="8331697329868252169">"Промените подешавања VPN-а"</string>
-    <string name="upload_file" msgid="8651942222301634271">"Одабери фајл"</string>
-    <string name="no_file_chosen" msgid="4146295695162318057">"Није изабрана ниједна датотека"</string>
-    <string name="reset" msgid="3865826612628171429">"Ресетуј"</string>
-    <string name="submit" msgid="862795280643405865">"Пошаљи"</string>
-    <string name="car_mode_disable_notification_title" msgid="8450693275833142896">"Апликација за вожњу је покренута"</string>
-    <string name="car_mode_disable_notification_message" msgid="8954550232288567515">"Додирните да бисте изашли из апликације за вожњу."</string>
-    <string name="back_button_label" msgid="4078224038025043387">"Назад"</string>
+    <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Prikaz preko drugih aplikacija"</string>
+    <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"Aplikacija <xliff:g id="NAME">%s</xliff:g> se prikazuje preko drugih aplikacija"</string>
+    <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> se prikazuje preko drugih apl."</string>
+    <string name="alert_windows_notification_message" msgid="6538171456970725333">"Ako ne želite ovu funkciju za <xliff:g id="NAME">%s</xliff:g>, dodirnite da biste otvorili podešavanja i isključili je."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Isključi"</string>
+    <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Proverava se <xliff:g id="NAME">%s</xliff:g>…"</string>
+    <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Pregleda se aktuelni sadržaj"</string>
+    <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analizira se memorijski prostor za medije"</string>
+    <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Novi/a <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> ne radi"</string>
+    <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Dodirnite da biste podesili"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Izaberite da biste podesili"</string>
+    <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Možda morate da reformatirate uređaj. Dodirnite da biste izbacili."</string>
+    <string name="ext_media_ready_notification_message" msgid="7509496364380197369">"Za čuvanje slika, video snimaka, muzike i drugog sadržaja"</string>
+    <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Pregledajte medijske fajlove"</string>
+    <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Problem sa: <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> ne radi"</string>
+    <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Dodirnite da biste ispravili"</string>
+    <string name="ext_media_unmountable_notification_message" product="tv" msgid="3003611129979934633">"Medij <xliff:g id="NAME">%s</xliff:g> je oštećen. Izaberite da ga popravite."</string>
+    <string name="ext_media_unmountable_notification_message" product="automotive" msgid="2274596120715020680">"Možda morate da reformatirate uređaj. Dodirnite da biste izbacili."</string>
+    <string name="ext_media_unsupported_notification_title" msgid="3487534182861251401">"Otkriveno: <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> ne radi"</string>
+    <string name="ext_media_unsupported_notification_message" msgid="8463636521459807981">"Dodirnite da biste podesili."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Izaberite da biste podesili uređaj <xliff:g id="NAME">%s</xliff:g> u podržanom formatu."</string>
+    <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Možda morate da reformatirate uređaj"</string>
+    <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"Uređaj <xliff:g id="NAME">%s</xliff:g> je neočekivano uklonjen"</string>
+    <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Izbacite medijum pre nego što ga uklonite da ne biste izgubili sadržaj"</string>
+    <string name="ext_media_nomedia_notification_title" msgid="742671636376975890">"<xliff:g id="NAME">%s</xliff:g> je uklonjen/a"</string>
+    <string name="ext_media_nomedia_notification_message" msgid="2832724384636625852">"Neke funkcije možda neće ispravno raditi. Umetnite nov memorijski uređaj."</string>
+    <string name="ext_media_unmounting_notification_title" msgid="4147986383917892162">"Izbacuje se <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="ext_media_unmounting_notification_message" msgid="5717036261538754203">"Ne uklanjajte"</string>
+    <string name="ext_media_init_action" msgid="2312974060585056709">"Aktiviraj"</string>
+    <string name="ext_media_unmount_action" msgid="966992232088442745">"Izbaci"</string>
+    <string name="ext_media_browse_action" msgid="344865351947079139">"Istraži"</string>
+    <string name="ext_media_seamless_action" msgid="8837030226009268080">"Promenite izlaz"</string>
+    <string name="ext_media_missing_title" msgid="3209472091220515046">"<xliff:g id="NAME">%s</xliff:g> nedostaje"</string>
+    <string name="ext_media_missing_message" msgid="4408988706227922909">"Ponovo umetnite uređaj"</string>
+    <string name="ext_media_move_specific_title" msgid="8492118544775964250">"Prenosi se <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="ext_media_move_title" msgid="2682741525619033637">"Podaci se prenose"</string>
+    <string name="ext_media_move_success_title" msgid="4901763082647316767">"Prenos sadržaja je gotov"</string>
+    <string name="ext_media_move_success_message" msgid="9159542002276982979">"Sadržaj je premešen na: <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="ext_media_move_failure_title" msgid="3184577479181333665">"Premeštanje sadržaja nije uspelo"</string>
+    <string name="ext_media_move_failure_message" msgid="4197306718121869335">"Probajte da ponovo premestite sadržaj"</string>
+    <string name="ext_media_status_removed" msgid="241223931135751691">"Uklonjen je"</string>
+    <string name="ext_media_status_unmounted" msgid="8145812017295835941">"Izbačen je"</string>
+    <string name="ext_media_status_checking" msgid="159013362442090347">"Proverava se..."</string>
+    <string name="ext_media_status_mounted" msgid="3459448555811203459">"Spreman je"</string>
+    <string name="ext_media_status_mounted_ro" msgid="1974809199760086956">"Samo za čitanje"</string>
+    <string name="ext_media_status_bad_removal" msgid="508448566481406245">"Uklonjen je na nebezbedan način"</string>
+    <string name="ext_media_status_unmountable" msgid="7043574843541087748">"Oštećen je"</string>
+    <string name="ext_media_status_unsupported" msgid="5460509911660539317">"Nije podržan"</string>
+    <string name="ext_media_status_ejecting" msgid="7532403368044013797">"Izbacuje se..."</string>
+    <string name="ext_media_status_formatting" msgid="774148701503179906">"Formatira se..."</string>
+    <string name="ext_media_status_missing" msgid="6520746443048867314">"Nije umetnut"</string>
+    <string name="activity_list_empty" msgid="4219430010716034252">"Nije pronađena nijedna podudarna aktivnost."</string>
+    <string name="permlab_route_media_output" msgid="8048124531439513118">"usmeravanje izlaza medija"</string>
+    <string name="permdesc_route_media_output" msgid="1759683269387729675">"Dozvoljava aplikaciji da usmerava izlaz medija na druge spoljne uređaje."</string>
+    <string name="permlab_readInstallSessions" msgid="7279049337895583621">"čitanje sesija instaliranja"</string>
+    <string name="permdesc_readInstallSessions" msgid="4012608316610763473">"Dozvoljava aplikaciji da čita sesije instaliranja. To joj dozvoljava da vidi detalje o aktivnim instalacijama paketa."</string>
+    <string name="permlab_requestInstallPackages" msgid="7600020863445351154">"zahtevanje paketa za instaliranje"</string>
+    <string name="permdesc_requestInstallPackages" msgid="3969369278325313067">"Omogućava da aplikacija zahteva instalaciju paketa."</string>
+    <string name="permlab_requestDeletePackages" msgid="2541172829260106795">"zahtevanje brisanja paketa"</string>
+    <string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Omogućava da aplikacija zahteva brisanje paketa."</string>
+    <string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"traženje dozvole za ignorisanje optimizacija baterije"</string>
+    <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Dozvoljava aplikaciji da traži dozvolu za ignorisanje optimizacija baterije za tu aplikaciju."</string>
+    <string name="permlab_queryAllPackages" msgid="2928450604653281650">"slanje upita za sve pakete"</string>
+    <string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Dozvoljava aplikaciji da vidi sve instalirane pakete."</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Dodirnite dvaput za kontrolu zumiranja"</string>
+    <string name="gadget_host_error_inflating" msgid="2449961590495198720">"Nije moguće dodati vidžet."</string>
+    <string name="ime_action_go" msgid="5536744546326495436">"Idi"</string>
+    <string name="ime_action_search" msgid="4501435960587287668">"Pretraži"</string>
+    <string name="ime_action_send" msgid="8456843745664334138">"Pošalji"</string>
+    <string name="ime_action_next" msgid="4169702997635728543">"Dalje"</string>
+    <string name="ime_action_done" msgid="6299921014822891569">"Gotovo"</string>
+    <string name="ime_action_previous" msgid="6548799326860401611">"Prethodno"</string>
+    <string name="ime_action_default" msgid="8265027027659800121">"Izvrši"</string>
+    <string name="dial_number_using" msgid="6060769078933953531">"Biraj broj\nkoristeći <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="6200708808003692594">"Napravite kontakt\nkoristeći <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"Sledeće aplikacije zahtevaju dozvolu za pristup nalogu, kako sada, tako i ubuduće."</string>
+    <string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"Želite da odobrite ovaj zahtev?"</string>
+    <string name="grant_permissions_header_text" msgid="3420736827804657201">"Zahtev za pristup"</string>
+    <string name="allow" msgid="6195617008611933762">"Dozvoli"</string>
+    <string name="deny" msgid="6632259981847676572">"Odbij"</string>
+    <string name="permission_request_notification_title" msgid="1810025922441048273">"Zatražena je dozvola"</string>
+    <string name="permission_request_notification_with_subtitle" msgid="3743417870360129298">"Zatražena je dozvola\nza nalog <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
+    <string name="permission_request_notification_for_app_with_subtitle" msgid="1298704005732851350">"<xliff:g id="APP">%1$s</xliff:g> traži dozvolu \nza nalog <xliff:g id="ACCOUNT">%2$s</xliff:g>."</string>
+    <string name="forward_intent_to_owner" msgid="4620359037192871015">"Koristite ovu aplikaciju izvan poslovnog profila"</string>
+    <string name="forward_intent_to_work" msgid="3620262405636021151">"Koristite ovu aplikaciju na poslovnom profilu"</string>
+    <string name="input_method_binding_label" msgid="1166731601721983656">"Metod unosa"</string>
+    <string name="sync_binding_label" msgid="469249309424662147">"Sinhronizacija"</string>
+    <string name="accessibility_binding_label" msgid="1974602776545801715">"Pristupačnost"</string>
+    <string name="wallpaper_binding_label" msgid="1197440498000786738">"Pozadina"</string>
+    <string name="chooser_wallpaper" msgid="3082405680079923708">"Promena pozadine"</string>
+    <string name="notification_listener_binding_label" msgid="2702165274471499713">"Monitor obaveštenja"</string>
+    <string name="vr_listener_binding_label" msgid="8013112996671206429">"Obrađivač za virtuelnu realnost"</string>
+    <string name="condition_provider_service_binding_label" msgid="8490641013951857673">"Dobavljač uslova"</string>
+    <string name="notification_ranker_binding_label" msgid="432708245635563763">"Usluga rangiranja obaveštenja"</string>
+    <string name="vpn_title" msgid="5906991595291514182">"VPN je aktiviran"</string>
+    <string name="vpn_title_long" msgid="6834144390504619998">"Aplikacija <xliff:g id="APP">%s</xliff:g> je aktivirala VPN"</string>
+    <string name="vpn_text" msgid="2275388920267251078">"Dodirnite da biste upravljali mrežom."</string>
+    <string name="vpn_text_long" msgid="278540576806169831">"Povezano sa sesijom <xliff:g id="SESSION">%s</xliff:g>. Dodirnite da biste upravljali mrežom."</string>
+    <string name="vpn_lockdown_connecting" msgid="6096725311950342607">"Povezivanje stalno uključenog VPN-a..."</string>
+    <string name="vpn_lockdown_connected" msgid="2853127976590658469">"Stalno uključen VPN je povezan"</string>
+    <string name="vpn_lockdown_disconnected" msgid="5573611651300764955">"Veza sa uvek uključenim VPN-om je prekinuta"</string>
+    <string name="vpn_lockdown_error" msgid="4453048646854247947">"Povezivanje na stalno uključeni VPN nije uspelo"</string>
+    <string name="vpn_lockdown_config" msgid="8331697329868252169">"Promenite podešavanja VPN-a"</string>
+    <string name="upload_file" msgid="8651942222301634271">"Odaberi fajl"</string>
+    <string name="no_file_chosen" msgid="4146295695162318057">"Nije izabrana nijedna datoteka"</string>
+    <string name="reset" msgid="3865826612628171429">"Resetuj"</string>
+    <string name="submit" msgid="862795280643405865">"Pošalji"</string>
+    <string name="car_mode_disable_notification_title" msgid="8450693275833142896">"Aplikacija za vožnju je pokrenuta"</string>
+    <string name="car_mode_disable_notification_message" msgid="8954550232288567515">"Dodirnite da biste izašli iz aplikacije za vožnju."</string>
+    <string name="back_button_label" msgid="4078224038025043387">"Nazad"</string>
     <string name="next_button_label" msgid="6040209156399907780">"Next"</string>
-    <string name="skip_button_label" msgid="3566599811326688389">"Прескочи"</string>
-    <string name="no_matches" msgid="6472699895759164599">"Нема подударања"</string>
-    <string name="find_on_page" msgid="5400537367077438198">"Пронађи на страници"</string>
-    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# подударање}one{# од {total}}few{# од {total}}other{# од {total}}}"</string>
-    <string name="action_mode_done" msgid="2536182504764803222">"Готово"</string>
-    <string name="progress_erasing" msgid="6891435992721028004">"Брише се дељени меморијски простор…"</string>
-    <string name="share" msgid="4157615043345227321">"Дели"</string>
-    <string name="find" msgid="5015737188624767706">"Пронађи"</string>
-    <string name="websearch" msgid="5624340204512793290">"Веб-претрага"</string>
-    <string name="find_next" msgid="5341217051549648153">"Пронађи следеће"</string>
-    <string name="find_previous" msgid="4405898398141275532">"Пронађи претходно"</string>
-    <string name="gpsNotifTicker" msgid="3207361857637620780">"Захтев за локацију од корисника <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="1590033371665669570">"Захтев за локацију"</string>
-    <string name="gpsNotifMessage" msgid="7346649122793758032">"Захтева <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
-    <string name="gpsVerifYes" msgid="3719843080744112940">"Да"</string>
-    <string name="gpsVerifNo" msgid="1671201856091564741">"Не"</string>
-    <string name="sync_too_many_deletes" msgid="6999440774578705300">"Премашено је ограничење за брисање"</string>
-    <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Постоје избрисане ставке (<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>) за <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, налог <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Шта желите да урадите?"</string>
-    <string name="sync_really_delete" msgid="5657871730315579051">"Избриши ставке"</string>
-    <string name="sync_undo_deletes" msgid="5786033331266418896">"Опозови брисања"</string>
-    <string name="sync_do_nothing" msgid="4528734662446469646">"Не ради ништа за сада"</string>
-    <string name="choose_account_label" msgid="5557833752759831548">"Изаберите налог"</string>
-    <string name="add_account_label" msgid="4067610644298737417">"Додај налог"</string>
-    <string name="add_account_button_label" msgid="322390749416414097">"Додај налог"</string>
-    <string name="number_picker_increment_button" msgid="7621013714795186298">"Повећавање"</string>
-    <string name="number_picker_decrement_button" msgid="5116948444762708204">"Смањивање"</string>
-    <string name="number_picker_increment_scroll_mode" msgid="8403893549806805985">"<xliff:g id="VALUE">%s</xliff:g> додирните и задржите."</string>
-    <string name="number_picker_increment_scroll_action" msgid="8310191318914268271">"Превуците нагоре да бисте повећали, а надоле да бисте смањили."</string>
-    <string name="time_picker_increment_minute_button" msgid="7195870222945784300">"Повећавање минута"</string>
-    <string name="time_picker_decrement_minute_button" msgid="230925389943411490">"Смањивање минута"</string>
-    <string name="time_picker_increment_hour_button" msgid="3063572723197178242">"Повећавање сати"</string>
-    <string name="time_picker_decrement_hour_button" msgid="584101766855054412">"Смањивање сати"</string>
-    <string name="time_picker_increment_set_pm_button" msgid="5889149366900376419">"Подеси по подне"</string>
-    <string name="time_picker_decrement_set_am_button" msgid="1422608001541064087">"Подеси пре подне"</string>
-    <string name="date_picker_increment_month_button" msgid="3447263316096060309">"Повећавање месеца"</string>
-    <string name="date_picker_decrement_month_button" msgid="6531888937036883014">"Смањивање месеца"</string>
-    <string name="date_picker_increment_day_button" msgid="4349336637188534259">"Повећавање дана"</string>
-    <string name="date_picker_decrement_day_button" msgid="6840253837656637248">"Смањивање дана"</string>
-    <string name="date_picker_increment_year_button" msgid="7608128783435372594">"Повећавање године"</string>
-    <string name="date_picker_decrement_year_button" msgid="4102586521754172684">"Смањивање године"</string>
-    <string name="date_picker_prev_month_button" msgid="3418694374017868369">"Претходни месец"</string>
-    <string name="date_picker_next_month_button" msgid="4858207337779144840">"Следећи месец"</string>
+    <string name="skip_button_label" msgid="3566599811326688389">"Preskoči"</string>
+    <string name="no_matches" msgid="6472699895759164599">"Nema podudaranja"</string>
+    <string name="find_on_page" msgid="5400537367077438198">"Pronađi na stranici"</string>
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# podudaranje}one{# od {total}}few{# od {total}}other{# od {total}}}"</string>
+    <string name="action_mode_done" msgid="2536182504764803222">"Gotovo"</string>
+    <string name="progress_erasing" msgid="6891435992721028004">"Briše se deljeni memorijski prostor…"</string>
+    <string name="share" msgid="4157615043345227321">"Deli"</string>
+    <string name="find" msgid="5015737188624767706">"Pronađi"</string>
+    <string name="websearch" msgid="5624340204512793290">"Veb-pretraga"</string>
+    <string name="find_next" msgid="5341217051549648153">"Pronađi sledeće"</string>
+    <string name="find_previous" msgid="4405898398141275532">"Pronađi prethodno"</string>
+    <string name="gpsNotifTicker" msgid="3207361857637620780">"Zahtev za lokaciju od korisnika <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="gpsNotifTitle" msgid="1590033371665669570">"Zahtev za lokaciju"</string>
+    <string name="gpsNotifMessage" msgid="7346649122793758032">"Zahteva <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+    <string name="gpsVerifYes" msgid="3719843080744112940">"Da"</string>
+    <string name="gpsVerifNo" msgid="1671201856091564741">"Ne"</string>
+    <string name="sync_too_many_deletes" msgid="6999440774578705300">"Premašeno je ograničenje za brisanje"</string>
+    <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Postoje izbrisane stavke (<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>) za <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, nalog <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Šta želite da uradite?"</string>
+    <string name="sync_really_delete" msgid="5657871730315579051">"Izbriši stavke"</string>
+    <string name="sync_undo_deletes" msgid="5786033331266418896">"Opozovi brisanja"</string>
+    <string name="sync_do_nothing" msgid="4528734662446469646">"Ne radi ništa za sada"</string>
+    <string name="choose_account_label" msgid="5557833752759831548">"Izaberite nalog"</string>
+    <string name="add_account_label" msgid="4067610644298737417">"Dodaj nalog"</string>
+    <string name="add_account_button_label" msgid="322390749416414097">"Dodaj nalog"</string>
+    <string name="number_picker_increment_button" msgid="7621013714795186298">"Povećavanje"</string>
+    <string name="number_picker_decrement_button" msgid="5116948444762708204">"Smanjivanje"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="8403893549806805985">"<xliff:g id="VALUE">%s</xliff:g> dodirnite i zadržite."</string>
+    <string name="number_picker_increment_scroll_action" msgid="8310191318914268271">"Prevucite nagore da biste povećali, a nadole da biste smanjili."</string>
+    <string name="time_picker_increment_minute_button" msgid="7195870222945784300">"Povećavanje minuta"</string>
+    <string name="time_picker_decrement_minute_button" msgid="230925389943411490">"Smanjivanje minuta"</string>
+    <string name="time_picker_increment_hour_button" msgid="3063572723197178242">"Povećavanje sati"</string>
+    <string name="time_picker_decrement_hour_button" msgid="584101766855054412">"Smanjivanje sati"</string>
+    <string name="time_picker_increment_set_pm_button" msgid="5889149366900376419">"Podesi po podne"</string>
+    <string name="time_picker_decrement_set_am_button" msgid="1422608001541064087">"Podesi pre podne"</string>
+    <string name="date_picker_increment_month_button" msgid="3447263316096060309">"Povećavanje meseca"</string>
+    <string name="date_picker_decrement_month_button" msgid="6531888937036883014">"Smanjivanje meseca"</string>
+    <string name="date_picker_increment_day_button" msgid="4349336637188534259">"Povećavanje dana"</string>
+    <string name="date_picker_decrement_day_button" msgid="6840253837656637248">"Smanjivanje dana"</string>
+    <string name="date_picker_increment_year_button" msgid="7608128783435372594">"Povećavanje godine"</string>
+    <string name="date_picker_decrement_year_button" msgid="4102586521754172684">"Smanjivanje godine"</string>
+    <string name="date_picker_prev_month_button" msgid="3418694374017868369">"Prethodni mesec"</string>
+    <string name="date_picker_next_month_button" msgid="4858207337779144840">"Sledeći mesec"</string>
     <string name="keyboardview_keycode_alt" msgid="8997420058584292385">"Alt"</string>
-    <string name="keyboardview_keycode_cancel" msgid="2134624484115716975">"Откажи"</string>
-    <string name="keyboardview_keycode_delete" msgid="2661117313730098650">"Избриши"</string>
-    <string name="keyboardview_keycode_done" msgid="2524518019001653851">"Готово"</string>
-    <string name="keyboardview_keycode_mode_change" msgid="2743735349997999020">"Промена режима"</string>
+    <string name="keyboardview_keycode_cancel" msgid="2134624484115716975">"Otkaži"</string>
+    <string name="keyboardview_keycode_delete" msgid="2661117313730098650">"Izbriši"</string>
+    <string name="keyboardview_keycode_done" msgid="2524518019001653851">"Gotovo"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="2743735349997999020">"Promena režima"</string>
     <string name="keyboardview_keycode_shift" msgid="3026509237043975573">"Shift"</string>
     <string name="keyboardview_keycode_enter" msgid="168054869339091055">"Enter"</string>
-    <string name="activitychooserview_choose_application" msgid="3500574466367891463">"Изаберите апликацију"</string>
-    <string name="activitychooserview_choose_application_error" msgid="6937782107559241734">"Није могуће покренути <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
-    <string name="shareactionprovider_share_with" msgid="2753089758467748982">"Дели са"</string>
-    <string name="shareactionprovider_share_with_application" msgid="4902832247173666973">"Дели са апликацијом <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
-    <string name="content_description_sliding_handle" msgid="982510275422590757">"Клизна ручица. Додирните и задржите."</string>
-    <string name="description_target_unlock_tablet" msgid="7431571180065859551">"Превуците да бисте откључали."</string>
-    <string name="action_bar_home_description" msgid="1501655419158631974">"Кретање до Почетне"</string>
-    <string name="action_bar_up_description" msgid="6611579697195026932">"Кретање нагоре"</string>
-    <string name="action_menu_overflow_description" msgid="4579536843510088170">"Још опција"</string>
+    <string name="activitychooserview_choose_application" msgid="3500574466367891463">"Izaberite aplikaciju"</string>
+    <string name="activitychooserview_choose_application_error" msgid="6937782107559241734">"Nije moguće pokrenuti <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+    <string name="shareactionprovider_share_with" msgid="2753089758467748982">"Deli sa"</string>
+    <string name="shareactionprovider_share_with_application" msgid="4902832247173666973">"Deli sa aplikacijom <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+    <string name="content_description_sliding_handle" msgid="982510275422590757">"Klizna ručica. Dodirnite i zadržite."</string>
+    <string name="description_target_unlock_tablet" msgid="7431571180065859551">"Prevucite da biste otključali."</string>
+    <string name="action_bar_home_description" msgid="1501655419158631974">"Kretanje do Početne"</string>
+    <string name="action_bar_up_description" msgid="6611579697195026932">"Kretanje nagore"</string>
+    <string name="action_menu_overflow_description" msgid="4579536843510088170">"Još opcija"</string>
     <string name="action_bar_home_description_format" msgid="5087107531331621803">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="4346835454749569826">"%1$s, %2$s, %3$s"</string>
-    <string name="storage_internal" msgid="8490227947584914460">"Унутрашњи дељени меморијски простор"</string>
-    <string name="storage_sd_card" msgid="3404740277075331881">"SD картица"</string>
-    <string name="storage_sd_card_label" msgid="7526153141147470509">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD картица"</string>
-    <string name="storage_usb_drive" msgid="448030813201444573">"USB диск"</string>
-    <string name="storage_usb_drive_label" msgid="6631740655876540521">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB диск"</string>
-    <string name="storage_usb" msgid="2391213347883616886">"USB меморија"</string>
-    <string name="extract_edit_menu_button" msgid="63954536535863040">"Измени"</string>
-    <string name="data_usage_warning_title" msgid="9034893717078325845">"Упозорење на потрошњу података"</string>
-    <string name="data_usage_warning_body" msgid="1669325367188029454">"Потрошили сте <xliff:g id="APP">%s</xliff:g> података"</string>
-    <string name="data_usage_mobile_limit_title" msgid="3911447354393775241">"Достигли сте ограничење података"</string>
-    <string name="data_usage_wifi_limit_title" msgid="2069698056520812232">"Нема више WiFi података"</string>
-    <string name="data_usage_limit_body" msgid="3567699582000085710">"Подаци су паузирани током остатка циклуса"</string>
-    <string name="data_usage_mobile_limit_snoozed_title" msgid="101888478915677895">"Потрошили сте мобилне податке"</string>
-    <string name="data_usage_wifi_limit_snoozed_title" msgid="1622359254521960508">"Потрошили сте WiFi податке"</string>
-    <string name="data_usage_limit_snoozed_body" msgid="545146591766765678">"Прекорачили сте <xliff:g id="SIZE">%s</xliff:g> од подешеног ограничења"</string>
-    <string name="data_usage_restricted_title" msgid="126711424380051268">"Позадински подаци су ограничени"</string>
-    <string name="data_usage_restricted_body" msgid="5338694433686077733">"Додирните за уклањање ограничења."</string>
-    <string name="data_usage_rapid_title" msgid="2950192123248740375">"Велика потрошња моб. података"</string>
-    <string name="data_usage_rapid_body" msgid="3886676853263693432">"Апликације су потрошиле више података него обично"</string>
-    <string name="data_usage_rapid_app_body" msgid="5425779218506513861">"Апликација <xliff:g id="APP">%s</xliff:g> је потрошила више података него обично"</string>
-    <string name="ssl_certificate" msgid="5690020361307261997">"Безбедносни сертификат"</string>
-    <string name="ssl_certificate_is_valid" msgid="7293675884598527081">"Овај сертификат је важећи."</string>
-    <string name="issued_to" msgid="5975877665505297662">"Издато за:"</string>
-    <string name="common_name" msgid="1486334593631798443">"Уобичајени назив:"</string>
-    <string name="org_name" msgid="7526331696464255245">"Организација:"</string>
-    <string name="org_unit" msgid="995934486977223076">"Организациона јединица:"</string>
-    <string name="issued_by" msgid="7872459822431585684">"Издао/ла:"</string>
-    <string name="validity_period" msgid="1717724283033175968">"Важност:"</string>
-    <string name="issued_on" msgid="5855489688152497307">"Издато:"</string>
-    <string name="expires_on" msgid="1623640879705103121">"Истиче:"</string>
-    <string name="serial_number" msgid="3479576915806623429">"Серијски број:"</string>
-    <string name="fingerprints" msgid="148690767172613723">"Дигитални отисци:"</string>
-    <string name="sha256_fingerprint" msgid="7103976380961964600">"SHA-256 отисак прста:"</string>
-    <string name="sha1_fingerprint" msgid="2339915142825390774">"SHA-1 отисак прста:"</string>
-    <string name="activity_chooser_view_see_all" msgid="3917045206812726099">"Прикажи све"</string>
-    <string name="activity_chooser_view_dialog_title_default" msgid="8880731437191978314">"Избор активности"</string>
-    <string name="share_action_provider_share_with" msgid="1904096863622941880">"Дели са"</string>
-    <string name="sending" msgid="206925243621664438">"Слање..."</string>
-    <string name="launchBrowserDefault" msgid="6328349989932924119">"Желите ли да покренете прегледач?"</string>
-    <string name="SetupCallDefault" msgid="5581740063237175247">"Желите ли да прихватите позив?"</string>
-    <string name="activity_resolver_use_always" msgid="5575222334666843269">"Увек"</string>
-    <string name="activity_resolver_use_once" msgid="948462794469672658">"Само једном"</string>
-    <string name="activity_resolver_work_profiles_support" msgid="4071345609235361269">"%1$s не подржава пословни профил"</string>
-    <string name="default_audio_route_name" product="tablet" msgid="367936735632195517">"Таблет"</string>
-    <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"ТВ"</string>
-    <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Телефон"</string>
-    <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Звучници базне станице"</string>
+    <string name="storage_internal" msgid="8490227947584914460">"Unutrašnji deljeni memorijski prostor"</string>
+    <string name="storage_sd_card" msgid="3404740277075331881">"SD kartica"</string>
+    <string name="storage_sd_card_label" msgid="7526153141147470509">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD kartica"</string>
+    <string name="storage_usb_drive" msgid="448030813201444573">"USB disk"</string>
+    <string name="storage_usb_drive_label" msgid="6631740655876540521">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB disk"</string>
+    <string name="storage_usb" msgid="2391213347883616886">"USB memorija"</string>
+    <string name="extract_edit_menu_button" msgid="63954536535863040">"Izmeni"</string>
+    <string name="data_usage_warning_title" msgid="9034893717078325845">"Upozorenje na potrošnju podataka"</string>
+    <string name="data_usage_warning_body" msgid="1669325367188029454">"Potrošili ste <xliff:g id="APP">%s</xliff:g> podataka"</string>
+    <string name="data_usage_mobile_limit_title" msgid="3911447354393775241">"Dostigli ste ograničenje podataka"</string>
+    <string name="data_usage_wifi_limit_title" msgid="2069698056520812232">"Nema više WiFi podataka"</string>
+    <string name="data_usage_limit_body" msgid="3567699582000085710">"Podaci su pauzirani tokom ostatka ciklusa"</string>
+    <string name="data_usage_mobile_limit_snoozed_title" msgid="101888478915677895">"Potrošili ste mobilne podatke"</string>
+    <string name="data_usage_wifi_limit_snoozed_title" msgid="1622359254521960508">"Potrošili ste WiFi podatke"</string>
+    <string name="data_usage_limit_snoozed_body" msgid="545146591766765678">"Prekoračili ste <xliff:g id="SIZE">%s</xliff:g> od podešenog ograničenja"</string>
+    <string name="data_usage_restricted_title" msgid="126711424380051268">"Pozadinski podaci su ograničeni"</string>
+    <string name="data_usage_restricted_body" msgid="5338694433686077733">"Dodirnite za uklanjanje ograničenja."</string>
+    <string name="data_usage_rapid_title" msgid="2950192123248740375">"Velika potrošnja mob. podataka"</string>
+    <string name="data_usage_rapid_body" msgid="3886676853263693432">"Aplikacije su potrošile više podataka nego obično"</string>
+    <string name="data_usage_rapid_app_body" msgid="5425779218506513861">"Aplikacija <xliff:g id="APP">%s</xliff:g> je potrošila više podataka nego obično"</string>
+    <string name="ssl_certificate" msgid="5690020361307261997">"Bezbednosni sertifikat"</string>
+    <string name="ssl_certificate_is_valid" msgid="7293675884598527081">"Ovaj sertifikat je važeći."</string>
+    <string name="issued_to" msgid="5975877665505297662">"Izdato za:"</string>
+    <string name="common_name" msgid="1486334593631798443">"Uobičajeni naziv:"</string>
+    <string name="org_name" msgid="7526331696464255245">"Organizacija:"</string>
+    <string name="org_unit" msgid="995934486977223076">"Organizaciona jedinica:"</string>
+    <string name="issued_by" msgid="7872459822431585684">"Izdao/la:"</string>
+    <string name="validity_period" msgid="1717724283033175968">"Važnost:"</string>
+    <string name="issued_on" msgid="5855489688152497307">"Izdato:"</string>
+    <string name="expires_on" msgid="1623640879705103121">"Ističe:"</string>
+    <string name="serial_number" msgid="3479576915806623429">"Serijski broj:"</string>
+    <string name="fingerprints" msgid="148690767172613723">"Digitalni otisci:"</string>
+    <string name="sha256_fingerprint" msgid="7103976380961964600">"SHA-256 otisak prsta:"</string>
+    <string name="sha1_fingerprint" msgid="2339915142825390774">"SHA-1 otisak prsta:"</string>
+    <string name="activity_chooser_view_see_all" msgid="3917045206812726099">"Prikaži sve"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="8880731437191978314">"Izbor aktivnosti"</string>
+    <string name="share_action_provider_share_with" msgid="1904096863622941880">"Deli sa"</string>
+    <string name="sending" msgid="206925243621664438">"Slanje..."</string>
+    <string name="launchBrowserDefault" msgid="6328349989932924119">"Želite li da pokrenete pregledač?"</string>
+    <string name="SetupCallDefault" msgid="5581740063237175247">"Želite li da prihvatite poziv?"</string>
+    <string name="activity_resolver_use_always" msgid="5575222334666843269">"Uvek"</string>
+    <string name="activity_resolver_use_once" msgid="948462794469672658">"Samo jednom"</string>
+    <string name="activity_resolver_work_profiles_support" msgid="4071345609235361269">"%1$s ne podržava poslovni profil"</string>
+    <string name="default_audio_route_name" product="tablet" msgid="367936735632195517">"Tablet"</string>
+    <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
+    <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefon"</string>
+    <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Zvučnici bazne stanice"</string>
     <string name="default_audio_route_name_hdmi" msgid="5474470558160717850">"HDMI"</string>
-    <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Слушалице"</string>
+    <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Slušalice"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
-    <string name="default_audio_route_category_name" msgid="5241740395748134483">"Систем"</string>
-    <string name="bluetooth_a2dp_audio_route_name" msgid="4214648773120426288">"Bluetooth аудио"</string>
-    <string name="wireless_display_route_description" msgid="8297563323032966831">"Бежични екран"</string>
-    <string name="media_route_button_content_description" msgid="2299223698196869956">"Пребацуј"</string>
-    <string name="media_route_chooser_title" msgid="6646594924991269208">"Повежите са уређајем"</string>
-    <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Пребаците екран на уређај"</string>
-    <string name="media_route_chooser_searching" msgid="6119673534251329535">"Тражење уређаја…"</string>
-    <string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"Подешавања"</string>
-    <string name="media_route_controller_disconnect" msgid="7362617572732576959">"Прекини везу"</string>
-    <string name="media_route_status_scanning" msgid="8045156315309594482">"Скенирање..."</string>
-    <string name="media_route_status_connecting" msgid="5845597961412010540">"Повезује се..."</string>
-    <string name="media_route_status_available" msgid="1477537663492007608">"Доступна"</string>
-    <string name="media_route_status_not_available" msgid="480912417977515261">"Нису доступне"</string>
-    <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="default_audio_route_category_name" msgid="5241740395748134483">"Sistem"</string>
+    <string name="bluetooth_a2dp_audio_route_name" msgid="4214648773120426288">"Bluetooth audio"</string>
+    <string name="wireless_display_route_description" msgid="8297563323032966831">"Bežični ekran"</string>
+    <string name="media_route_button_content_description" msgid="2299223698196869956">"Prebacuj"</string>
+    <string name="media_route_chooser_title" msgid="6646594924991269208">"Povežite sa uređajem"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Prebacite ekran na uređaj"</string>
+    <string name="media_route_chooser_searching" msgid="6119673534251329535">"Traženje uređaja…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"Podešavanja"</string>
+    <string name="media_route_controller_disconnect" msgid="7362617572732576959">"Prekini vezu"</string>
+    <string name="media_route_status_scanning" msgid="8045156315309594482">"Skeniranje..."</string>
+    <string name="media_route_status_connecting" msgid="5845597961412010540">"Povezuje se..."</string>
+    <string name="media_route_status_available" msgid="1477537663492007608">"Dostupna"</string>
+    <string name="media_route_status_not_available" msgid="480912417977515261">"Nisu dostupne"</string>
+    <string name="media_route_status_in_use" msgid="6684112905244944724">"U upotrebi"</string>
+    <string name="display_manager_built_in_display_name" msgid="1015775198829722440">"Ugrađeni ekran"</string>
+    <string name="display_manager_hdmi_display_name" msgid="1022758026251534975">"HDMI ekran"</string>
+    <string name="display_manager_overlay_display_name" msgid="5306088205181005861">"Postavljeni element br. <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>×<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>
-    <string name="kg_wrong_pattern" msgid="1342812634464179931">"Погрешан шаблон"</string>
-    <string name="kg_wrong_password" msgid="2384677900494439426">"Погрешна лозинка"</string>
-    <string name="kg_wrong_pin" msgid="3680925703673166482">"Погрешан PIN"</string>
-    <string name="kg_pattern_instructions" msgid="8366024510502517748">"Нацртајте шаблон"</string>
-    <string name="kg_sim_pin_instructions" msgid="6479401489471690359">"Унесите PIN SIM картице"</string>
-    <string name="kg_pin_instructions" msgid="7355933174673539021">"Унесите PIN"</string>
-    <string name="kg_password_instructions" msgid="7179782578809398050">"Унесите лозинку"</string>
-    <string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"SIM картица је сада онемогућена. Унесите PUK кôд да бисте наставили. За детаље контактирајте оператера."</string>
-    <string name="kg_puk_enter_pin_hint" msgid="8190982314659429770">"Унесите жељени PIN кôд"</string>
-    <string name="kg_enter_confirm_pin_hint" msgid="6372557107414074580">"Потврдите жељени PIN кôд"</string>
-    <string name="kg_sim_unlock_progress_dialog_message" msgid="8871937892678885545">"Откључавање SIM картице…"</string>
-    <string name="kg_password_wrong_pin_code" msgid="9013856346870572451">"PIN кôд је нетачан."</string>
-    <string name="kg_invalid_sim_pin_hint" msgid="4821601451222564077">"Унесите PIN који има од 4 до 8 бројева."</string>
-    <string name="kg_invalid_sim_puk_hint" msgid="2539364558870734339">"PUK кôд треба да има 8 бројева."</string>
-    <string name="kg_invalid_puk" msgid="4809502818518963344">"Поново унесите исправни PUK кôд. Поновљени покушаји ће трајно онемогућити SIM."</string>
-    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"PIN кодови се не подударају"</string>
-    <string name="kg_login_too_many_attempts" msgid="699292728290654121">"Превише покушаја уноса шаблона"</string>
-    <string name="kg_login_instructions" msgid="3619844310339066827">"Да бисте откључали, пријавите се помоћу Google налога."</string>
-    <string name="kg_login_username_hint" msgid="1765453775467133251">"Корисничко име (имејл адреса)"</string>
-    <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_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>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"Нацртали сте шаблон за откључавање нетачно <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунде/и."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"Покушали сте да откључате таблет нетачно <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Након још <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешна(их) покушаја таблет ће бити ресетован на фабричка подешавања и сви кориснички подаци ће бити изгубљени."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"Број ваших неуспешних покушаја да откључате Android TV уређај: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Број преосталих неуспешних покушаја после којих ће се Android TV ресетовати на фабричка подешавања и сви подаци корисника ће бити изгубљени: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"Покушали сте да откључате телефон нетачно <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешна(их) покушаја телефон ће бити ресетован на фабричка подешавања и сви кориснички подаци ће бити изгубљени."</string>
-    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"Покушали сте да откључате таблет нетачно <xliff:g id="NUMBER">%d</xliff:g> пута. Таблет ће сада бити враћен на подразумевана фабричка подешавања."</string>
-    <string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"Број ваших неуспешних покушаја да откључате Android TV уређај: <xliff:g id="NUMBER">%d</xliff:g>. Android TV уређај ће се сада ресетовати на фабричка подешавања."</string>
-    <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"Покушали сте да откључате телефон нетачно <xliff:g id="NUMBER">%d</xliff:g> пута. Телефон ће сада бити враћен на подразумевана фабричка подешавања."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"Нацртали сте шаблон за откључавање нетачно <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешна(их) покушаја, од вас ће бити затражено да откључате таблет помоћу налога е-поште.\n\nПробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> секунде/и."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"Нетачно сте нацртали шаблон за откључавање <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још пута (<xliff:g id="NUMBER_1">%2$d</xliff:g>), затражићемо да откључате телефон помоћу Android TV уређаја.\n\n Пробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> сек."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Нацртали сте шаблон за откључавање нетачно <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешна(их) покушаја, од вас ће бити затражено да откључате телефон помоћу налога е-поште.\n\nПробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> секунде/и."</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="2810034719482834679">", bezbedno"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="406145459223122537">"Zaboravljeni šablon"</string>
+    <string name="kg_wrong_pattern" msgid="1342812634464179931">"Pogrešan šablon"</string>
+    <string name="kg_wrong_password" msgid="2384677900494439426">"Pogrešna lozinka"</string>
+    <string name="kg_wrong_pin" msgid="3680925703673166482">"Pogrešan PIN"</string>
+    <string name="kg_pattern_instructions" msgid="8366024510502517748">"Nacrtajte šablon"</string>
+    <string name="kg_sim_pin_instructions" msgid="6479401489471690359">"Unesite PIN SIM kartice"</string>
+    <string name="kg_pin_instructions" msgid="7355933174673539021">"Unesite PIN"</string>
+    <string name="kg_password_instructions" msgid="7179782578809398050">"Unesite lozinku"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"SIM kartica je sada onemogućena. Unesite PUK kôd da biste nastavili. Za detalje kontaktirajte operatera."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="8190982314659429770">"Unesite željeni PIN kôd"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="6372557107414074580">"Potvrdite željeni PIN kôd"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8871937892678885545">"Otključavanje SIM kartice…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="9013856346870572451">"PIN kôd je netačan."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="4821601451222564077">"Unesite PIN koji ima od 4 do 8 brojeva."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="2539364558870734339">"PUK kôd treba da ima 8 brojeva."</string>
+    <string name="kg_invalid_puk" msgid="4809502818518963344">"Ponovo unesite ispravni PUK kôd. Ponovljeni pokušaji će trajno onemogućiti SIM."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"PIN kodovi se ne podudaraju"</string>
+    <string name="kg_login_too_many_attempts" msgid="699292728290654121">"Previše pokušaja unosa šablona"</string>
+    <string name="kg_login_instructions" msgid="3619844310339066827">"Da biste otključali, prijavite se pomoću Google naloga."</string>
+    <string name="kg_login_username_hint" msgid="1765453775467133251">"Korisničko ime (imejl adresa)"</string>
+    <string name="kg_login_password_hint" msgid="3330530727273164402">"Lozinka"</string>
+    <string name="kg_login_submit_button" msgid="893611277617096870">"Prijavi me"</string>
+    <string name="kg_login_invalid_input" msgid="8292367491901220210">"Nevažeće korisničko ime ili lozinka."</string>
+    <string name="kg_login_account_recovery_hint" msgid="4892466171043541248">"Zaboravili ste korisničko ime ili lozinku?\nPosetite adresu "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="4676010303243317253">"Provera naloga…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Uneli ste netačni PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nProbajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunde/i."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"Uneli ste netačnu lozinku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nProbajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunde/i."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"Nacrtali ste šablon za otključavanje netačno <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nProbajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunde/i."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"Pokušali ste da otključate tablet netačno <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> neuspešna(ih) pokušaja tablet će biti resetovan na fabrička podešavanja i svi korisnički podaci će biti izgubljeni."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"Broj vaših neuspešnih pokušaja da otključate Android TV uređaj: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Broj preostalih neuspešnih pokušaja posle kojih će se Android TV resetovati na fabrička podešavanja i svi podaci korisnika će biti izgubljeni: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"Pokušali ste da otključate telefon netačno <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Posle još <xliff:g id="NUMBER_1">%2$d</xliff:g> neuspešna(ih) pokušaja telefon će biti resetovan na fabrička podešavanja i svi korisnički podaci će biti izgubljeni."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"Pokušali ste da otključate tablet netačno <xliff:g id="NUMBER">%d</xliff:g> puta. Tablet će sada biti vraćen na podrazumevana fabrička podešavanja."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"Broj vaših neuspešnih pokušaja da otključate Android TV uređaj: <xliff:g id="NUMBER">%d</xliff:g>. Android TV uređaj će se sada resetovati na fabrička podešavanja."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"Pokušali ste da otključate telefon netačno <xliff:g id="NUMBER">%d</xliff:g> puta. Telefon će sada biti vraćen na podrazumevana fabrička podešavanja."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"Nacrtali ste šablon za otključavanje netačno <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Posle još <xliff:g id="NUMBER_1">%2$d</xliff:g> neuspešna(ih) pokušaja, od vas će biti zatraženo da otključate tablet pomoću naloga e-pošte.\n\nProbajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunde/i."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"Netačno ste nacrtali šablon za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još puta (<xliff:g id="NUMBER_1">%2$d</xliff:g>), zatražićemo da otključate telefon pomoću Android TV uređaja.\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="5270861875006378092">"Nacrtali ste šablon za otključavanje netačno <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Posle još <xliff:g id="NUMBER_1">%2$d</xliff:g> neuspešna(ih) pokušaja, od vas će biti zatraženo da otključate telefon pomoću naloga e-pošte.\n\nProbajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunde/i."</string>
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
-    <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Уклони"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Желите да појачате звук изнад препорученог нивоа?\n\nСлушање гласне музике дуже време може да вам оштети слух."</string>
-    <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Желите ли да користите пречицу за приступачност?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Када је пречица укључена, притисните оба дугмета за јачину звука да бисте покренули функцију приступачности."</string>
-    <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Желите да укључите пречицу за функције приступачности?"</string>
-    <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Ако задржите оба тастера за јачину звука пар секунди, укључиће се функције приступачности. То може да промени начин рада уређаја.\n\nПостојеће функције:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nМожете да промените изабране функције у одељку Подешавања &gt; Приступачност."</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Ukloni"</string>
+    <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Želite da pojačate zvuk iznad preporučenog nivoa?\n\nSlušanje glasne muzike duže vreme može da vam ošteti sluh."</string>
+    <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Želite li da koristite prečicu za pristupačnost?"</string>
+    <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kada je prečica uključena, pritisnite oba dugmeta za jačinu zvuka da biste pokrenuli funkciju pristupačnosti."</string>
+    <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Želite da uključite prečicu za funkcije pristupačnosti?"</string>
+    <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Ako zadržite oba tastera za jačinu zvuka par sekundi, uključiće se funkcije pristupačnosti. To može da promeni način rada uređaja.\n\nPostojeće funkcije:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nMožete da promenite izabrane funkcije u odeljku Podešavanja &gt; Pristupačnost."</string>
     <string name="accessibility_shortcut_multiple_service_list" msgid="2128323171922023762">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
-    <string name="accessibility_shortcut_single_service_warning_title" msgid="1909518473488345266">"Желите да укључите пречицу за услугу <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
-    <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Ако задржите оба тастера за јачину звука пар секунди, укључује се <xliff:g id="SERVICE">%1$s</xliff:g>, функција приступачности. То може да промени начин рада уређаја.\n\nМожете да промените функцију на коју се односи ова пречица у одељку Подешавања &gt; Приступачност."</string>
-    <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Укључи"</string>
-    <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Не укључуј"</string>
-    <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"УКЉУЧЕНО"</string>
-    <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ИСКЉУЧЕНО"</string>
-    <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Желите ли да дозволите да услуга <xliff:g id="SERVICE">%1$s</xliff:g> има потпуну контролу над уређајем?"</string>
-    <string name="accessibility_service_warning_description" msgid="291674995220940133">"Потпуна контрола је примерена за апликације које вам помажу код услуга приступачности, али не и за већину апликација."</string>
-    <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Прегледај и контролиши екран"</string>
-    <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Може да чита сав садржај на екрану и приказује га у другим апликацијама."</string>
-    <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Прегледај и обављај радње"</string>
-    <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Може да прати интеракције са апликацијом или сензором хардвера и користи апликације уместо вас."</string>
-    <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Дозволи"</string>
-    <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Одбиј"</string>
-    <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Додирните неку функцију да бисте почели да је користите:"</string>
-    <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Одаберите функције које ћете користити са дугметом Приступачност"</string>
-    <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Одаберите функције за пречицу тастером јачине звука"</string>
-    <string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"Услуга <xliff:g id="SERVICE_NAME">%s</xliff:g> је искључена"</string>
-    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Измените пречице"</string>
-    <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Готово"</string>
-    <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Искључи пречицу"</string>
-    <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Користи пречицу"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Инверзија боја"</string>
-    <string name="color_correction_feature_name" msgid="3655077237805422597">"Корекција боја"</string>
-    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Режим једном руком"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Додатно затамњено"</string>
-    <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Држали сте тастере за јачину звука. Услуга <xliff:g id="SERVICE_NAME">%1$s</xliff:g> је укључена."</string>
-    <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Држали сте тастере за јачину звука. Услуга <xliff:g id="SERVICE_NAME">%1$s</xliff:g> је искључена."</string>
-    <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Притисните и задржите оба тастера за јачину звука три секунде да бисте користили <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Изаберите функцију која ће се користити када додирнете дугме Приступачност:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Одаберите функцију која ће се користити помоћу покрета за приступачност (помоћу два прста превуците нагоре од дна екрана):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Одаберите функцију која ће се користити помоћу покрета за приступачност (помоћу три прста превуците нагоре од дна екрана):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Да бисте прелазили са једне функције на другу, додирните и задржите дугме Приступачност."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Да бисте прелазили са једне функције на другу, превуците нагоре помоћу два прста и задржите."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Да бисте прелазили са једне функције на другу, превуците нагоре помоћу три прста и задржите."</string>
-    <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Увећање"</string>
-    <string name="user_switched" msgid="7249833311585228097">"Актуелни корисник <xliff:g id="NAME">%1$s</xliff:g>."</string>
-    <string name="user_switching_message" msgid="1912993630661332336">"Пребацивање на <xliff:g id="NAME">%1$s</xliff:g>…"</string>
-    <string name="user_logging_out_message" msgid="7216437629179710359">"Одјављује се <xliff:g id="NAME">%1$s</xliff:g>…"</string>
-    <string name="owner_name" msgid="8713560351570795743">"Власник"</string>
-    <string name="guest_name" msgid="8502103277839834324">"Гост"</string>
-    <string name="error_message_title" msgid="4082495589294631966">"Грешка"</string>
-    <string name="error_message_change_not_allowed" msgid="843159705042381454">"Администратор није дозволио ову промену"</string>
-    <string name="app_not_found" msgid="3429506115332341800">"Није пронађена ниједна апликација која би могла да обави ову радњу"</string>
-    <string name="revoke" msgid="5526857743819590458">"Опозови"</string>
+    <string name="accessibility_shortcut_single_service_warning_title" msgid="1909518473488345266">"Želite da uključite prečicu za uslugu <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Ako zadržite oba tastera za jačinu zvuka par sekundi, uključuje se <xliff:g id="SERVICE">%1$s</xliff:g>, funkcija pristupačnosti. To može da promeni način rada uređaja.\n\nMožete da promenite funkciju na koju se odnosi ova prečica u odeljku Podešavanja &gt; Pristupačnost."</string>
+    <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Uključi"</string>
+    <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Ne uključuj"</string>
+    <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"UKLJUČENO"</string>
+    <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ISKLJUČENO"</string>
+    <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Želite li da dozvolite da usluga <xliff:g id="SERVICE">%1$s</xliff:g> ima potpunu kontrolu nad uređajem?"</string>
+    <string name="accessibility_service_warning_description" msgid="291674995220940133">"Potpuna kontrola je primerena za aplikacije koje vam pomažu kod usluga pristupačnosti, ali ne i za većinu aplikacija."</string>
+    <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Pregledaj i kontroliši ekran"</string>
+    <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Može da čita sav sadržaj na ekranu i prikazuje ga u drugim aplikacijama."</string>
+    <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Pregledaj i obavljaj radnje"</string>
+    <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Može da prati interakcije sa aplikacijom ili senzorom hardvera i koristi aplikacije umesto vas."</string>
+    <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Dozvoli"</string>
+    <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Odbij"</string>
+    <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Dodirnite neku funkciju da biste počeli da je koristite:"</string>
+    <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Odaberite funkcije koje ćete koristiti sa dugmetom Pristupačnost"</string>
+    <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Odaberite funkcije za prečicu tasterom jačine zvuka"</string>
+    <string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"Usluga <xliff:g id="SERVICE_NAME">%s</xliff:g> je isključena"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Izmenite prečice"</string>
+    <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Gotovo"</string>
+    <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Isključi prečicu"</string>
+    <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Koristi prečicu"</string>
+    <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija boja"</string>
+    <string name="color_correction_feature_name" msgid="3655077237805422597">"Korekcija boja"</string>
+    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Režim jednom rukom"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Dodatno zatamnjeno"</string>
+    <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je uključena."</string>
+    <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je isključena."</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Pritisnite i zadržite oba tastera za jačinu zvuka tri sekunde da biste koristili <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Izaberite funkciju koja će se koristiti kada dodirnete dugme Pristupačnost:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Odaberite funkciju koja će se koristiti pomoću pokreta za pristupačnost (pomoću dva prsta prevucite nagore od dna ekrana):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Odaberite funkciju koja će se koristiti pomoću pokreta za pristupačnost (pomoću tri prsta prevucite nagore od dna ekrana):"</string>
+    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Da biste prelazili sa jedne funkcije na drugu, dodirnite i zadržite dugme Pristupačnost."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Da biste prelazili sa jedne funkcije na drugu, prevucite nagore pomoću dva prsta i zadržite."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Da biste prelazili sa jedne funkcije na drugu, prevucite nagore pomoću tri prsta i zadržite."</string>
+    <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Uvećanje"</string>
+    <string name="user_switched" msgid="7249833311585228097">"Aktuelni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="user_switching_message" msgid="1912993630661332336">"Prebacivanje na <xliff:g id="NAME">%1$s</xliff:g>…"</string>
+    <string name="user_logging_out_message" msgid="7216437629179710359">"Odjavljuje se <xliff:g id="NAME">%1$s</xliff:g>…"</string>
+    <string name="owner_name" msgid="8713560351570795743">"Vlasnik"</string>
+    <string name="guest_name" msgid="8502103277839834324">"Gost"</string>
+    <string name="error_message_title" msgid="4082495589294631966">"Greška"</string>
+    <string name="error_message_change_not_allowed" msgid="843159705042381454">"Administrator nije dozvolio ovu promenu"</string>
+    <string name="app_not_found" msgid="3429506115332341800">"Nije pronađena nijedna aplikacija koja bi mogla da obavi ovu radnju"</string>
+    <string name="revoke" msgid="5526857743819590458">"Opozovi"</string>
     <string name="mediasize_iso_a0" msgid="7039061159929977973">"ISO A0"</string>
     <string name="mediasize_iso_a1" msgid="4063589931031977223">"ISO A1"</string>
     <string name="mediasize_iso_a2" msgid="2779860175680233980">"ISO A2"</string>
@@ -1820,480 +1820,480 @@
     <string name="mediasize_japanese_kaku2" msgid="7477551750461028312">"Kaku2"</string>
     <string name="mediasize_japanese_you4" msgid="5552111912684384833">"You4"</string>
     <string name="mediasize_japanese_l" msgid="1326765321473431817">"L"</string>
-    <string name="mediasize_unknown_portrait" msgid="3817016220446495613">"Непозната величина, усправно"</string>
-    <string name="mediasize_unknown_landscape" msgid="1584741567225095325">"Непозната величина, водоравно"</string>
-    <string name="write_fail_reason_cancelled" msgid="2344081488493969190">"Отказано је"</string>
-    <string name="write_fail_reason_cannot_write" msgid="432118118378451508">"Грешка при исписивању садржаја"</string>
-    <string name="reason_unknown" msgid="5599739807581133337">"непознато"</string>
-    <string name="reason_service_unavailable" msgid="5288405248063804713">"Услуга штампања није омогућена"</string>
-    <string name="print_service_installed_title" msgid="6134880817336942482">"Услуга <xliff:g id="NAME">%s</xliff:g> је инсталирана"</string>
-    <string name="print_service_installed_message" msgid="7005672469916968131">"Додирните да бисте омогућили"</string>
-    <string name="restr_pin_enter_admin_pin" msgid="1199419462726962697">"Унесите PIN администратора"</string>
-    <string name="restr_pin_enter_pin" msgid="373139384161304555">"Унесите PIN"</string>
-    <string name="restr_pin_incorrect" msgid="3861383632940852496">"Нетачно"</string>
-    <string name="restr_pin_enter_old_pin" msgid="7537079094090650967">"Актуелни PIN"</string>
-    <string name="restr_pin_enter_new_pin" msgid="3267614461844565431">"Нови PIN"</string>
-    <string name="restr_pin_confirm_pin" msgid="7143161971614944989">"Потврдите нови PIN"</string>
-    <string name="restr_pin_create_pin" msgid="917067613896366033">"Направите PIN за измену ограничења"</string>
-    <string name="restr_pin_error_doesnt_match" msgid="7063392698489280556">"PIN-ови се не подударају. Пробајте поново."</string>
-    <string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN је прекратак. Мора да садржи најмање 4 цифре."</string>
-    <string name="restr_pin_try_later" msgid="5897719962541636727">"Пробајте поново касније"</string>
-    <string name="immersive_cling_title" msgid="2307034298721541791">"Приказује се цео екран"</string>
-    <string name="immersive_cling_description" msgid="7092737175345204832">"Да бисте изашли, превуците надоле одозго."</string>
-    <string name="immersive_cling_positive" msgid="7047498036346489883">"Важи"</string>
-    <string name="done_label" msgid="7283767013231718521">"Готово"</string>
-    <string name="hour_picker_description" msgid="5153757582093524635">"Кружни клизач за сате"</string>
-    <string name="minute_picker_description" msgid="9029797023621927294">"Кружни клизач за минуте"</string>
-    <string name="select_hours" msgid="5982889657313147347">"Изаберите сате"</string>
-    <string name="select_minutes" msgid="9157401137441014032">"Изаберите минуте"</string>
-    <string name="select_day" msgid="2060371240117403147">"Изаберите месец и дан"</string>
-    <string name="select_year" msgid="1868350712095595393">"Изаберите годину"</string>
-    <string name="deleted_key" msgid="9130083334943364001">"Избрисали сте <xliff:g id="KEY">%1$s</xliff:g>"</string>
-    <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> на послу"</string>
-    <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. пословни <xliff:g id="LABEL">%1$s</xliff:g>"</string>
-    <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. пословни имејл <xliff:g id="LABEL">%1$s</xliff:g>"</string>
-    <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Тражи PIN пре откачињања"</string>
-    <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Тражи шаблон за откључавање пре откачињања"</string>
-    <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Тражи лозинку пре откачињања"</string>
-    <string name="package_installed_device_owner" msgid="7035926868974878525">"Инсталирао је администратор"</string>
-    <string name="package_updated_device_owner" msgid="7560272363805506941">"Ажурирао је администратор"</string>
-    <string name="package_deleted_device_owner" msgid="2292335928930293023">"Избрисао је администратор"</string>
-    <string name="confirm_battery_saver" msgid="5247976246208245754">"Потврди"</string>
-    <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Уштеда батерије укључује тамну тему и ограничава или искључује активности у позадини, неке визуелне ефекте, одређене функције и неке мрежне везе."</string>
-    <string name="battery_saver_description" msgid="8518809702138617167">"Уштеда батерије укључује тамну тему и ограничава или искључује активности у позадини, неке визуелне ефекте, одређене функције и неке мрежне везе."</string>
-    <string name="data_saver_description" msgid="4995164271550590517">"Да би се смањила потрошња података, Уштеда података спречава неке апликације да шаљу или примају податке у позадини. Апликација коју тренутно користите може да приступа подацима, али ће то чинити ређе. На пример, слике се неће приказивати док их не додирнете."</string>
-    <string name="data_saver_enable_title" msgid="7080620065745260137">"Желите да укључите Уштеду података?"</string>
-    <string name="data_saver_enable_button" msgid="4399405762586419726">"Укључи"</string>
-    <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{Један минут (до {formattedTime})}one{# минут (до {formattedTime})}few{# минута (до {formattedTime})}other{# минута (до {formattedTime})}}"</string>
-    <string name="zen_mode_duration_minutes_summary_short" msgid="1187553788355486950">"{count,plural, =1{1 мин (до {formattedTime})}one{# мин (до {formattedTime})}few{# мин (до {formattedTime})}other{# мин (до {formattedTime})}}"</string>
-    <string name="zen_mode_duration_hours_summary" msgid="3866333100793277211">"{count,plural, =1{1 сат (до {formattedTime})}one{# сат (до {formattedTime})}few{# сата (до {formattedTime})}other{# сати (до {formattedTime})}}"</string>
-    <string name="zen_mode_duration_hours_summary_short" msgid="687919813833347945">"{count,plural, =1{1 с (до {formattedTime})}one{# с (до {formattedTime})}few{# с (до {formattedTime})}other{# с (до {formattedTime})}}"</string>
-    <string name="zen_mode_duration_minutes" msgid="2340007982276569054">"{count,plural, =1{Један минут}one{# минут}few{# минута}other{# минута}}"</string>
-    <string name="zen_mode_duration_minutes_short" msgid="2435756450204526554">"{count,plural, =1{1 мин}one{# мин}few{# мин}other{# мин}}"</string>
-    <string name="zen_mode_duration_hours" msgid="7841806065034711849">"{count,plural, =1{1 сат}one{# сат}few{# сата}other{# сати}}"</string>
-    <string name="zen_mode_duration_hours_short" msgid="3666949653933099065">"{count,plural, =1{1 с}one{# с}few{# с}other{# с}}"</string>
-    <string name="zen_mode_until_next_day" msgid="1403042784161725038">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
-    <string name="zen_mode_until" msgid="2250286190237669079">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
-    <string name="zen_mode_alarm" msgid="7046911727540499275">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (следећи аларм)"</string>
-    <string name="zen_mode_forever" msgid="740585666364912448">"Док не искључите"</string>
-    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Док не искључите режим Не узнемиравај"</string>
+    <string name="mediasize_unknown_portrait" msgid="3817016220446495613">"Nepoznata veličina, uspravno"</string>
+    <string name="mediasize_unknown_landscape" msgid="1584741567225095325">"Nepoznata veličina, vodoravno"</string>
+    <string name="write_fail_reason_cancelled" msgid="2344081488493969190">"Otkazano je"</string>
+    <string name="write_fail_reason_cannot_write" msgid="432118118378451508">"Greška pri ispisivanju sadržaja"</string>
+    <string name="reason_unknown" msgid="5599739807581133337">"nepoznato"</string>
+    <string name="reason_service_unavailable" msgid="5288405248063804713">"Usluga štampanja nije omogućena"</string>
+    <string name="print_service_installed_title" msgid="6134880817336942482">"Usluga <xliff:g id="NAME">%s</xliff:g> je instalirana"</string>
+    <string name="print_service_installed_message" msgid="7005672469916968131">"Dodirnite da biste omogućili"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="1199419462726962697">"Unesite PIN administratora"</string>
+    <string name="restr_pin_enter_pin" msgid="373139384161304555">"Unesite PIN"</string>
+    <string name="restr_pin_incorrect" msgid="3861383632940852496">"Netačno"</string>
+    <string name="restr_pin_enter_old_pin" msgid="7537079094090650967">"Aktuelni PIN"</string>
+    <string name="restr_pin_enter_new_pin" msgid="3267614461844565431">"Novi PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="7143161971614944989">"Potvrdite novi PIN"</string>
+    <string name="restr_pin_create_pin" msgid="917067613896366033">"Napravite PIN za izmenu ograničenja"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="7063392698489280556">"PIN-ovi se ne podudaraju. Probajte ponovo."</string>
+    <string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN je prekratak. Mora da sadrži najmanje 4 cifre."</string>
+    <string name="restr_pin_try_later" msgid="5897719962541636727">"Probajte ponovo kasnije"</string>
+    <string name="immersive_cling_title" msgid="2307034298721541791">"Prikazuje se ceo ekran"</string>
+    <string name="immersive_cling_description" msgid="7092737175345204832">"Da biste izašli, prevucite nadole odozgo."</string>
+    <string name="immersive_cling_positive" msgid="7047498036346489883">"Važi"</string>
+    <string name="done_label" msgid="7283767013231718521">"Gotovo"</string>
+    <string name="hour_picker_description" msgid="5153757582093524635">"Kružni klizač za sate"</string>
+    <string name="minute_picker_description" msgid="9029797023621927294">"Kružni klizač za minute"</string>
+    <string name="select_hours" msgid="5982889657313147347">"Izaberite sate"</string>
+    <string name="select_minutes" msgid="9157401137441014032">"Izaberite minute"</string>
+    <string name="select_day" msgid="2060371240117403147">"Izaberite mesec i dan"</string>
+    <string name="select_year" msgid="1868350712095595393">"Izaberite godinu"</string>
+    <string name="deleted_key" msgid="9130083334943364001">"Izbrisali ste <xliff:g id="KEY">%1$s</xliff:g>"</string>
+    <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> na poslu"</string>
+    <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. poslovni <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. poslovni imejl <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Traži PIN pre otkačinjanja"</string>
+    <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Traži šablon za otključavanje pre otkačinjanja"</string>
+    <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Traži lozinku pre otkačinjanja"</string>
+    <string name="package_installed_device_owner" msgid="7035926868974878525">"Instalirao je administrator"</string>
+    <string name="package_updated_device_owner" msgid="7560272363805506941">"Ažurirao je administrator"</string>
+    <string name="package_deleted_device_owner" msgid="2292335928930293023">"Izbrisao je administrator"</string>
+    <string name="confirm_battery_saver" msgid="5247976246208245754">"Potvrdi"</string>
+    <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Ušteda baterije uključuje tamnu temu i ograničava ili isključuje aktivnosti u pozadini, neke vizuelne efekte, određene funkcije i neke mrežne veze."</string>
+    <string name="battery_saver_description" msgid="8518809702138617167">"Ušteda baterije uključuje tamnu temu i ograničava ili isključuje aktivnosti u pozadini, neke vizuelne efekte, određene funkcije i neke mrežne veze."</string>
+    <string name="data_saver_description" msgid="4995164271550590517">"Da bi se smanjila potrošnja podataka, Ušteda podataka sprečava neke aplikacije da šalju ili primaju podatke u pozadini. Aplikacija koju trenutno koristite može da pristupa podacima, ali će to činiti ređe. Na primer, slike se neće prikazivati dok ih ne dodirnete."</string>
+    <string name="data_saver_enable_title" msgid="7080620065745260137">"Želite da uključite Uštedu podataka?"</string>
+    <string name="data_saver_enable_button" msgid="4399405762586419726">"Uključi"</string>
+    <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{Jedan minut (do {formattedTime})}one{# minut (do {formattedTime})}few{# minuta (do {formattedTime})}other{# minuta (do {formattedTime})}}"</string>
+    <string name="zen_mode_duration_minutes_summary_short" msgid="1187553788355486950">"{count,plural, =1{1 min (do {formattedTime})}one{# min (do {formattedTime})}few{# min (do {formattedTime})}other{# min (do {formattedTime})}}"</string>
+    <string name="zen_mode_duration_hours_summary" msgid="3866333100793277211">"{count,plural, =1{1 sat (do {formattedTime})}one{# sat (do {formattedTime})}few{# sata (do {formattedTime})}other{# sati (do {formattedTime})}}"</string>
+    <string name="zen_mode_duration_hours_summary_short" msgid="687919813833347945">"{count,plural, =1{1 s (do {formattedTime})}one{# s (do {formattedTime})}few{# s (do {formattedTime})}other{# s (do {formattedTime})}}"</string>
+    <string name="zen_mode_duration_minutes" msgid="2340007982276569054">"{count,plural, =1{Jedan minut}one{# minut}few{# minuta}other{# minuta}}"</string>
+    <string name="zen_mode_duration_minutes_short" msgid="2435756450204526554">"{count,plural, =1{1 min}one{# min}few{# min}other{# min}}"</string>
+    <string name="zen_mode_duration_hours" msgid="7841806065034711849">"{count,plural, =1{1 sat}one{# sat}few{# sata}other{# sati}}"</string>
+    <string name="zen_mode_duration_hours_short" msgid="3666949653933099065">"{count,plural, =1{1 s}one{# s}few{# s}other{# s}}"</string>
+    <string name="zen_mode_until_next_day" msgid="1403042784161725038">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+    <string name="zen_mode_until" msgid="2250286190237669079">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+    <string name="zen_mode_alarm" msgid="7046911727540499275">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (sledeći alarm)"</string>
+    <string name="zen_mode_forever" msgid="740585666364912448">"Dok ne isključite"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Dok ne isključite režim Ne uznemiravaj"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
-    <string name="toolbar_collapse_description" msgid="8009920446193610996">"Скупи"</string>
-    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Не узнемиравај"</string>
-    <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Одмор"</string>
-    <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Радни дан увече"</string>
-    <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Викенд"</string>
-    <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Догађај"</string>
-    <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Спавање"</string>
-    <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> искључује неке звуке"</string>
-    <string name="system_error_wipe_data" msgid="5910572292172208493">"Дошло је до интерног проблема у вези са уређајем и можда ће бити нестабилан док не обавите ресетовање на фабричка подешавања."</string>
-    <string name="system_error_manufacturer" msgid="703545241070116315">"Дошло је до интерног проблема у вези са уређајем. Потражите детаље од произвођача."</string>
-    <string name="stk_cc_ussd_to_dial" msgid="3139884150741157610">"USSD захтев је промењен у обичан позив"</string>
-    <string name="stk_cc_ussd_to_ss" msgid="4826846653052609738">"USSD захтев је промењен у SS захтев"</string>
-    <string name="stk_cc_ussd_to_ussd" msgid="8343001461299302472">"Промењено је у нови USSD захтев"</string>
-    <string name="stk_cc_ussd_to_dial_video" msgid="429118590323618623">"USSD захтев је промењен у видео позив"</string>
-    <string name="stk_cc_ss_to_dial" msgid="4087396658768717077">"SS захтев је промењен у обичан позив"</string>
-    <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS захтев је промењен у видео позив"</string>
-    <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS захтев је промењен у USSD захтев"</string>
-    <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Промењено је у нови SS захтев"</string>
-    <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Упозорење о „пецању“"</string>
-    <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Пословни профил"</string>
-    <string name="notification_alerted_content_description" msgid="6139691253611265992">"Обавештено"</string>
-    <string name="notification_verified_content_description" msgid="6401483602782359391">"Верификовано"</string>
-    <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Прошири"</string>
-    <string name="expand_button_content_description_expanded" msgid="7484217944948667489">"Скупи"</string>
-    <string name="expand_action_accessibility" msgid="1947657036871746627">"укључите/искључите проширење"</string>
-    <string name="usb_midi_peripheral_name" msgid="490523464968655741">"Android USB порт за периферијске уређаје"</string>
+    <string name="toolbar_collapse_description" msgid="8009920446193610996">"Skupi"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Ne uznemiravaj"</string>
+    <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Odmor"</string>
+    <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Radni dan uveče"</string>
+    <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Vikend"</string>
+    <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Događaj"</string>
+    <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Spavanje"</string>
+    <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> isključuje neke zvuke"</string>
+    <string name="system_error_wipe_data" msgid="5910572292172208493">"Došlo je do internog problema u vezi sa uređajem i možda će biti nestabilan dok ne obavite resetovanje na fabrička podešavanja."</string>
+    <string name="system_error_manufacturer" msgid="703545241070116315">"Došlo je do internog problema u vezi sa uređajem. Potražite detalje od proizvođača."</string>
+    <string name="stk_cc_ussd_to_dial" msgid="3139884150741157610">"USSD zahtev je promenjen u običan poziv"</string>
+    <string name="stk_cc_ussd_to_ss" msgid="4826846653052609738">"USSD zahtev je promenjen u SS zahtev"</string>
+    <string name="stk_cc_ussd_to_ussd" msgid="8343001461299302472">"Promenjeno je u novi USSD zahtev"</string>
+    <string name="stk_cc_ussd_to_dial_video" msgid="429118590323618623">"USSD zahtev je promenjen u video poziv"</string>
+    <string name="stk_cc_ss_to_dial" msgid="4087396658768717077">"SS zahtev je promenjen u običan poziv"</string>
+    <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS zahtev je promenjen u video poziv"</string>
+    <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS zahtev je promenjen u USSD zahtev"</string>
+    <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Promenjeno je u novi SS zahtev"</string>
+    <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Upozorenje o „pecanju“"</string>
+    <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Poslovni profil"</string>
+    <string name="notification_alerted_content_description" msgid="6139691253611265992">"Obavešteno"</string>
+    <string name="notification_verified_content_description" msgid="6401483602782359391">"Verifikovano"</string>
+    <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Proširi"</string>
+    <string name="expand_button_content_description_expanded" msgid="7484217944948667489">"Skupi"</string>
+    <string name="expand_action_accessibility" msgid="1947657036871746627">"uključite/isključite proširenje"</string>
+    <string name="usb_midi_peripheral_name" msgid="490523464968655741">"Android USB port za periferijske uređaje"</string>
     <string name="usb_midi_peripheral_manufacturer_name" msgid="7557148557088787741">"Android"</string>
-    <string name="usb_midi_peripheral_product_name" msgid="2836276258480904434">"USB порт за периферијске уређаје"</string>
-    <string name="floating_toolbar_open_overflow_description" msgid="2260297653578167367">"Још опција"</string>
-    <string name="floating_toolbar_close_overflow_description" msgid="3949818077708138098">"Затвори преклопни мени"</string>
-    <string name="maximize_button_text" msgid="4258922519914732645">"Увећај"</string>
-    <string name="close_button_text" msgid="10603510034455258">"Затвори"</string>
+    <string name="usb_midi_peripheral_product_name" msgid="2836276258480904434">"USB port za periferijske uređaje"</string>
+    <string name="floating_toolbar_open_overflow_description" msgid="2260297653578167367">"Još opcija"</string>
+    <string name="floating_toolbar_close_overflow_description" msgid="3949818077708138098">"Zatvori preklopni meni"</string>
+    <string name="maximize_button_text" msgid="4258922519914732645">"Uvećaj"</string>
+    <string name="close_button_text" msgid="10603510034455258">"Zatvori"</string>
     <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
-    <string name="call_notification_answer_action" msgid="5999246836247132937">"Одговори"</string>
-    <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Видео"</string>
-    <string name="call_notification_decline_action" msgid="3700345945214000726">"Одбиј"</string>
-    <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Прекини везу"</string>
-    <string name="call_notification_incoming_text" msgid="6143109825406638201">"Долазни позив"</string>
-    <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Позив је у току"</string>
-    <string name="call_notification_screening_text" msgid="8396931408268940208">"Проверава се долазни позив"</string>
-    <string name="default_notification_channel_label" msgid="3697928973567217330">"Некатегоризовано"</string>
-    <string name="importance_from_user" msgid="2782756722448800447">"Ви подешавате важност ових обавештења."</string>
-    <string name="importance_from_person" msgid="4235804979664465383">"Ово је важно због људи који учествују."</string>
-    <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Прилагођено обавештење о апликацији"</string>
-    <string name="user_creation_account_exists" msgid="2239146360099708035">"Желите ли да дозволите да <xliff:g id="APP">%1$s</xliff:g> направи новог корисника са налогом <xliff:g id="ACCOUNT">%2$s</xliff:g> (корисник са тим налогом већ постоји)?"</string>
-    <string name="user_creation_adding" msgid="7305185499667958364">"Желите ли да дозволите да <xliff:g id="APP">%1$s</xliff:g> направи новог корисника са налогом <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="supervised_user_creation_label" msgid="6884904353827427515">"Додајте корисника под надзором"</string>
-    <string name="language_selection_title" msgid="52674936078683285">"Додајте језик"</string>
-    <string name="country_selection_title" msgid="5221495687299014379">"Подешавање региона"</string>
-    <string name="search_language_hint" msgid="7004225294308793583">"Унесите назив језика"</string>
-    <string name="language_picker_section_suggested" msgid="6556199184638990447">"Предложени"</string>
-    <string name="language_picker_regions_section_suggested" msgid="6080131515268225316">"Предложено"</string>
-    <string name="language_picker_section_all" msgid="1985809075777564284">"Сви језици"</string>
-    <string name="region_picker_section_all" msgid="756441309928774155">"Сви региони"</string>
-    <string name="locale_search_menu" msgid="6258090710176422934">"Претражи"</string>
-    <string name="app_suspended_title" msgid="888873445010322650">"Апликација није доступна"</string>
-    <string name="app_suspended_default_message" msgid="6451215678552004172">"Апликација <xliff:g id="APP_NAME_0">%1$s</xliff:g> тренутно није доступна. <xliff:g id="APP_NAME_1">%2$s</xliff:g> управља доступношћу."</string>
-    <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="961171256005852058">"Укључујете пословне апликације?"</string>
-    <string name="work_mode_off_message" msgid="7319580997683623309">"Приступајте пословним апликацијама и обавештењима"</string>
-    <string name="work_mode_turn_on" msgid="3662561662475962285">"Укључи"</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>
-    <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> – није доступно"</string>
-    <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Потребна је дозвола"</string>
-    <string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Камера није доступна"</string>
-    <string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Наставите на телефону"</string>
-    <string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Микрофон је недоступан"</string>
-    <string name="app_streaming_blocked_title_for_playstore_dialog" msgid="8149823099822897538">"Play продавница није доступна"</string>
-    <string name="app_streaming_blocked_title_for_settings_dialog" product="tv" msgid="196994247017450357">"Подешавања Android TV-а су недоступна"</string>
-    <string name="app_streaming_blocked_title_for_settings_dialog" product="tablet" msgid="8222710146267948647">"Подешавања таблета су недоступна"</string>
-    <string name="app_streaming_blocked_title_for_settings_dialog" product="default" msgid="6895719984375299791">"Подешавања телефона су недоступна"</string>
-    <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Овој апликацији тренутно не може да се приступи са уређаја <xliff:g id="DEVICE">%1$s</xliff:g>. Пробајте на Android TV уређају."</string>
-    <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Овој апликацији тренутно не може да се приступи са уређаја <xliff:g id="DEVICE">%1$s</xliff:g>. Пробајте на таблету."</string>
-    <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Овој апликацији тренутно не може да се приступи са уређаја <xliff:g id="DEVICE">%1$s</xliff:g>. Пробајте на телефону."</string>
-    <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Ова апликација захтева додатну безбедност. Пробајте на Android TV уређају."</string>
-    <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Ова апликација захтева додатну безбедност. Пробајте на таблету."</string>
-    <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Ова апликација захтева додатну безбедност. Пробајте на телефону."</string>
-    <string name="app_streaming_blocked_message_for_settings_dialog" product="tv" msgid="820334666354451145">"Овој апликацији не може да се приступи са уређаја <xliff:g id="DEVICE">%1$s</xliff:g>. Пробајте на Android TV уређају."</string>
-    <string name="app_streaming_blocked_message_for_settings_dialog" product="tablet" msgid="3286849551133045896">"Овој апликацији не може да се приступи са уређаја <xliff:g id="DEVICE">%1$s</xliff:g>. Пробајте на таблету."</string>
-    <string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Овој апликацији не може да се приступи са уређаја <xliff:g id="DEVICE">%1$s</xliff:g>. Пробајте на телефону."</string>
-    <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ова апликација је направљена за старију верзију Android-а, па можда неће радити исправно. Потражите ажурирања или контактирајте програмера."</string>
-    <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Потражи ажурирање"</string>
-    <string name="new_sms_notification_title" msgid="6528758221319927107">"Имате нове поруке"</string>
-    <string name="new_sms_notification_content" msgid="3197949934153460639">"Отворите апликацију за SMS да бисте прегледали"</string>
-    <string name="profile_encrypted_title" msgid="9001208667521266472">"Неке функције су можда ограничене"</string>
-    <string name="profile_encrypted_detail" msgid="5279730442756849055">"Пословни профил је закључан"</string>
-    <string name="profile_encrypted_message" msgid="1128512616293157802">"Додиром откљ. пословни профил"</string>
-    <string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Повезано је са производом <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
-    <string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Додирните за преглед датотека"</string>
-    <string name="pin_target" msgid="8036028973110156895">"Закачи"</string>
-    <string name="pin_specific_target" msgid="7824671240625957415">"Закачи апликацију <xliff:g id="LABEL">%1$s</xliff:g>"</string>
-    <string name="unpin_target" msgid="3963318576590204447">"Откачи"</string>
-    <string name="unpin_specific_target" msgid="3859828252160908146">"Откачи апликацију <xliff:g id="LABEL">%1$s</xliff:g>"</string>
-    <string name="app_info" msgid="6113278084877079851">"Информације о апликацији"</string>
+    <string name="call_notification_answer_action" msgid="5999246836247132937">"Odgovori"</string>
+    <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Video"</string>
+    <string name="call_notification_decline_action" msgid="3700345945214000726">"Odbij"</string>
+    <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Prekini vezu"</string>
+    <string name="call_notification_incoming_text" msgid="6143109825406638201">"Dolazni poziv"</string>
+    <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Poziv je u toku"</string>
+    <string name="call_notification_screening_text" msgid="8396931408268940208">"Proverava se dolazni poziv"</string>
+    <string name="default_notification_channel_label" msgid="3697928973567217330">"Nekategorizovano"</string>
+    <string name="importance_from_user" msgid="2782756722448800447">"Vi podešavate važnost ovih obaveštenja."</string>
+    <string name="importance_from_person" msgid="4235804979664465383">"Ovo je važno zbog ljudi koji učestvuju."</string>
+    <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Prilagođeno obaveštenje o aplikaciji"</string>
+    <string name="user_creation_account_exists" msgid="2239146360099708035">"Želite li da dozvolite da <xliff:g id="APP">%1$s</xliff:g> napravi novog korisnika sa nalogom <xliff:g id="ACCOUNT">%2$s</xliff:g> (korisnik sa tim nalogom već postoji)?"</string>
+    <string name="user_creation_adding" msgid="7305185499667958364">"Želite li da dozvolite da <xliff:g id="APP">%1$s</xliff:g> napravi novog korisnika sa nalogom <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
+    <string name="supervised_user_creation_label" msgid="6884904353827427515">"Dodajte korisnika pod nadzorom"</string>
+    <string name="language_selection_title" msgid="52674936078683285">"Dodajte jezik"</string>
+    <string name="country_selection_title" msgid="5221495687299014379">"Podešavanje regiona"</string>
+    <string name="search_language_hint" msgid="7004225294308793583">"Unesite naziv jezika"</string>
+    <string name="language_picker_section_suggested" msgid="6556199184638990447">"Predloženi"</string>
+    <string name="language_picker_regions_section_suggested" msgid="6080131515268225316">"Predloženo"</string>
+    <string name="language_picker_section_all" msgid="1985809075777564284">"Svi jezici"</string>
+    <string name="region_picker_section_all" msgid="756441309928774155">"Svi regioni"</string>
+    <string name="locale_search_menu" msgid="6258090710176422934">"Pretraži"</string>
+    <string name="app_suspended_title" msgid="888873445010322650">"Aplikacija nije dostupna"</string>
+    <string name="app_suspended_default_message" msgid="6451215678552004172">"Aplikacija <xliff:g id="APP_NAME_0">%1$s</xliff:g> trenutno nije dostupna. <xliff:g id="APP_NAME_1">%2$s</xliff:g> upravlja dostupnošću."</string>
+    <string name="app_suspended_more_details" msgid="211260942831587014">"Saznajte više"</string>
+    <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Opozovi pauziranje aplikacije"</string>
+    <string name="work_mode_off_title" msgid="961171256005852058">"Uključujete poslovne aplikacije?"</string>
+    <string name="work_mode_off_message" msgid="7319580997683623309">"Pristupajte poslovnim aplikacijama i obaveštenjima"</string>
+    <string name="work_mode_turn_on" msgid="3662561662475962285">"Uključi"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija nije dostupna"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutno nije dostupna."</string>
+    <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> – nije dostupno"</string>
+    <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Potrebna je dozvola"</string>
+    <string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kamera nije dostupna"</string>
+    <string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Nastavite na telefonu"</string>
+    <string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofon je nedostupan"</string>
+    <string name="app_streaming_blocked_title_for_playstore_dialog" msgid="8149823099822897538">"Play prodavnica nije dostupna"</string>
+    <string name="app_streaming_blocked_title_for_settings_dialog" product="tv" msgid="196994247017450357">"Podešavanja Android TV-a su nedostupna"</string>
+    <string name="app_streaming_blocked_title_for_settings_dialog" product="tablet" msgid="8222710146267948647">"Podešavanja tableta su nedostupna"</string>
+    <string name="app_streaming_blocked_title_for_settings_dialog" product="default" msgid="6895719984375299791">"Podešavanja telefona su nedostupna"</string>
+    <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Ovoj aplikaciji trenutno ne može da se pristupi sa uređaja <xliff:g id="DEVICE">%1$s</xliff:g>. Probajte na Android TV uređaju."</string>
+    <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Ovoj aplikaciji trenutno ne može da se pristupi sa uređaja <xliff:g id="DEVICE">%1$s</xliff:g>. Probajte na tabletu."</string>
+    <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Ovoj aplikaciji trenutno ne može da se pristupi sa uređaja <xliff:g id="DEVICE">%1$s</xliff:g>. Probajte na telefonu."</string>
+    <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Ova aplikacija zahteva dodatnu bezbednost. Probajte na Android TV uređaju."</string>
+    <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Ova aplikacija zahteva dodatnu bezbednost. Probajte na tabletu."</string>
+    <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Ova aplikacija zahteva dodatnu bezbednost. Probajte na telefonu."</string>
+    <string name="app_streaming_blocked_message_for_settings_dialog" product="tv" msgid="820334666354451145">"Ovoj aplikaciji ne može da se pristupi sa uređaja <xliff:g id="DEVICE">%1$s</xliff:g>. Probajte na Android TV uređaju."</string>
+    <string name="app_streaming_blocked_message_for_settings_dialog" product="tablet" msgid="3286849551133045896">"Ovoj aplikaciji ne može da se pristupi sa uređaja <xliff:g id="DEVICE">%1$s</xliff:g>. Probajte na tabletu."</string>
+    <string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Ovoj aplikaciji ne može da se pristupi sa uređaja <xliff:g id="DEVICE">%1$s</xliff:g>. Probajte na telefonu."</string>
+    <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ova aplikacija je napravljena za stariju verziju Android-a, pa možda neće raditi ispravno. Potražite ažuriranja ili kontaktirajte programera."</string>
+    <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Potraži ažuriranje"</string>
+    <string name="new_sms_notification_title" msgid="6528758221319927107">"Imate nove poruke"</string>
+    <string name="new_sms_notification_content" msgid="3197949934153460639">"Otvorite aplikaciju za SMS da biste pregledali"</string>
+    <string name="profile_encrypted_title" msgid="9001208667521266472">"Neke funkcije su možda ograničene"</string>
+    <string name="profile_encrypted_detail" msgid="5279730442756849055">"Poslovni profil je zaključan"</string>
+    <string name="profile_encrypted_message" msgid="1128512616293157802">"Dodirom otklj. poslovni profil"</string>
+    <string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Povezano je sa proizvodom <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
+    <string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Dodirnite za pregled datoteka"</string>
+    <string name="pin_target" msgid="8036028973110156895">"Zakači"</string>
+    <string name="pin_specific_target" msgid="7824671240625957415">"Zakači aplikaciju <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="unpin_target" msgid="3963318576590204447">"Otkači"</string>
+    <string name="unpin_specific_target" msgid="3859828252160908146">"Otkači aplikaciju <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="app_info" msgid="6113278084877079851">"Informacije o aplikaciji"</string>
     <string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="demo_starting_message" msgid="6577581216125805905">"Покрећемо демонстрацију..."</string>
-    <string name="demo_restarting_message" msgid="1160053183701746766">"Ресетујемо уређај..."</string>
-    <string name="suspended_widget_accessibility" msgid="6331451091851326101">"Виџет <xliff:g id="LABEL">%1$s</xliff:g> је онемогућен"</string>
-    <string name="conference_call" msgid="5731633152336490471">"Конференцијски позив"</string>
-    <string name="tooltip_popup_title" msgid="7863719020269945722">"Објашњење"</string>
-    <string name="app_category_game" msgid="4534216074910244790">"Игре"</string>
-    <string name="app_category_audio" msgid="8296029904794676222">"Музика и аудио"</string>
-    <string name="app_category_video" msgid="2590183854839565814">"Филмови и видео"</string>
-    <string name="app_category_image" msgid="7307840291864213007">"Слике"</string>
-    <string name="app_category_social" msgid="2278269325488344054">"Друштвене мреже и комуникација"</string>
-    <string name="app_category_news" msgid="1172762719574964544">"Новости и часописи"</string>
-    <string name="app_category_maps" msgid="6395725487922533156">"Мапе и навигација"</string>
-    <string name="app_category_productivity" msgid="1844422703029557883">"Продуктивност"</string>
-    <string name="app_category_accessibility" msgid="6643521607848547683">"Приступачност"</string>
-    <string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Меморијски простор уређаја"</string>
-    <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Отклањање грешака са USB-а"</string>
-    <string name="time_picker_hour_label" msgid="4208590187662336864">"сат"</string>
-    <string name="time_picker_minute_label" msgid="8307452311269824553">"минут"</string>
-    <string name="time_picker_header_text" msgid="9073802285051516688">"Подесите време"</string>
-    <string name="time_picker_input_error" msgid="8386271930742451034">"Унесите важеће време"</string>
-    <string name="time_picker_prompt_label" msgid="303588544656363889">"Унесите време"</string>
-    <string name="time_picker_text_input_mode_description" msgid="4761160667516611576">"Пређите у режим уноса текста ради уноса времена."</string>
-    <string name="time_picker_radial_mode_description" msgid="1222342577115016953">"Пређите у режим сата ради уноса времена."</string>
-    <string name="autofill_picker_accessibility_title" msgid="4425806874792196599">"Опције аутоматског попуњавања"</string>
-    <string name="autofill_save_accessibility_title" msgid="1523225776218450005">"Сачувајте за аутоматско попуњавање"</string>
-    <string name="autofill_error_cannot_autofill" msgid="6528827648643138596">"Садржај не може аутоматски да се попуни"</string>
-    <string name="autofill_picker_no_suggestions" msgid="1076022650427481509">"Нема аутоматски попуњених предлога"</string>
-    <string name="autofill_picker_some_suggestions" msgid="5560549696296202701">"{count,plural, =1{Један аутоматски попуњен предлог}one{# аутоматски попуњен предлог}few{# аутоматски попуњена предлога}other{# аутоматски попуњених предлога}}"</string>
-    <string name="autofill_save_title" msgid="7719802414283739775">"Желите ли да сачувате у услузи "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
-    <string name="autofill_save_title_with_type" msgid="3002460014579799605">"Желите ли да сачувате ставку <xliff:g id="TYPE">%1$s</xliff:g> у услузи "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
-    <string name="autofill_save_title_with_2types" msgid="3783270967447869241">"Желите ли да сачувате ставке <xliff:g id="TYPE_0">%1$s</xliff:g> и <xliff:g id="TYPE_1">%2$s</xliff:g> у услузи "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string>
-    <string name="autofill_save_title_with_3types" msgid="6598228952100102578">"Желите ли да сачувате ставке <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> и <xliff:g id="TYPE_2">%3$s</xliff:g> у услузи "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"?"</string>
-    <string name="autofill_update_title" msgid="3630695947047069136">"Желите ли да ажурирате у услузи "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
-    <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Желите ли да ажурирате ставку <xliff:g id="TYPE">%1$s</xliff:g> у услузи "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
-    <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Желите ли да ажурирате ставке <xliff:g id="TYPE_0">%1$s</xliff:g> и <xliff:g id="TYPE_1">%2$s</xliff:g> у услузи "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string>
-    <string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Желите ли да ажурирате ове ставке у услузи "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> и <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
-    <string name="autofill_save_yes" msgid="8035743017382012850">"Сачувај"</string>
-    <string name="autofill_save_no" msgid="9212826374207023544">"Не, хвала"</string>
-    <string name="autofill_save_notnow" msgid="2853932672029024195">"Не сада"</string>
-    <string name="autofill_save_never" msgid="6821841919831402526">"Никада"</string>
-    <string name="autofill_update_yes" msgid="4608662968996874445">"Ажурирај"</string>
-    <string name="autofill_continue_yes" msgid="7914985605534510385">"Настави"</string>
-    <string name="autofill_save_type_password" msgid="5624528786144539944">"лозинка"</string>
-    <string name="autofill_save_type_address" msgid="3111006395818252885">"адреса"</string>
-    <string name="autofill_save_type_credit_card" msgid="3583795235862046693">"кредитна картица"</string>
-    <string name="autofill_save_type_debit_card" msgid="3169397504133097468">"дебитна картица"</string>
-    <string name="autofill_save_type_payment_card" msgid="6555012156728690856">"платна картица"</string>
-    <string name="autofill_save_type_generic_card" msgid="1019367283921448608">"картица"</string>
-    <string name="autofill_save_type_username" msgid="1018816929884640882">"корисничко име"</string>
-    <string name="autofill_save_type_email_address" msgid="1303262336895591924">"имејл адреса"</string>
-    <string name="etws_primary_default_message_earthquake" msgid="8401079517718280669">"Останите мирни и потражите склониште у околини."</string>
-    <string name="etws_primary_default_message_tsunami" msgid="5828171463387976279">"Одмах се склоните из приобалних региона и области поред река на неко безбедније место, на пример, на неко узвишење."</string>
-    <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="4888224011071875068">"Останите мирни и потражите склониште у околини."</string>
-    <string name="etws_primary_default_message_test" msgid="4583367373909549421">"Тестирање порука у хитним случајевима"</string>
-    <string name="notification_reply_button_accessibility" msgid="5235776156579456126">"Одговори"</string>
+    <string name="demo_starting_message" msgid="6577581216125805905">"Pokrećemo demonstraciju..."</string>
+    <string name="demo_restarting_message" msgid="1160053183701746766">"Resetujemo uređaj..."</string>
+    <string name="suspended_widget_accessibility" msgid="6331451091851326101">"Vidžet <xliff:g id="LABEL">%1$s</xliff:g> je onemogućen"</string>
+    <string name="conference_call" msgid="5731633152336490471">"Konferencijski poziv"</string>
+    <string name="tooltip_popup_title" msgid="7863719020269945722">"Objašnjenje"</string>
+    <string name="app_category_game" msgid="4534216074910244790">"Igre"</string>
+    <string name="app_category_audio" msgid="8296029904794676222">"Muzika i audio"</string>
+    <string name="app_category_video" msgid="2590183854839565814">"Filmovi i video"</string>
+    <string name="app_category_image" msgid="7307840291864213007">"Slike"</string>
+    <string name="app_category_social" msgid="2278269325488344054">"Društvene mreže i komunikacija"</string>
+    <string name="app_category_news" msgid="1172762719574964544">"Novosti i časopisi"</string>
+    <string name="app_category_maps" msgid="6395725487922533156">"Mape i navigacija"</string>
+    <string name="app_category_productivity" msgid="1844422703029557883">"Produktivnost"</string>
+    <string name="app_category_accessibility" msgid="6643521607848547683">"Pristupačnost"</string>
+    <string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Memorijski prostor uređaja"</string>
+    <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Otklanjanje grešaka sa USB-a"</string>
+    <string name="time_picker_hour_label" msgid="4208590187662336864">"sat"</string>
+    <string name="time_picker_minute_label" msgid="8307452311269824553">"minut"</string>
+    <string name="time_picker_header_text" msgid="9073802285051516688">"Podesite vreme"</string>
+    <string name="time_picker_input_error" msgid="8386271930742451034">"Unesite važeće vreme"</string>
+    <string name="time_picker_prompt_label" msgid="303588544656363889">"Unesite vreme"</string>
+    <string name="time_picker_text_input_mode_description" msgid="4761160667516611576">"Pređite u režim unosa teksta radi unosa vremena."</string>
+    <string name="time_picker_radial_mode_description" msgid="1222342577115016953">"Pređite u režim sata radi unosa vremena."</string>
+    <string name="autofill_picker_accessibility_title" msgid="4425806874792196599">"Opcije automatskog popunjavanja"</string>
+    <string name="autofill_save_accessibility_title" msgid="1523225776218450005">"Sačuvajte za automatsko popunjavanje"</string>
+    <string name="autofill_error_cannot_autofill" msgid="6528827648643138596">"Sadržaj ne može automatski da se popuni"</string>
+    <string name="autofill_picker_no_suggestions" msgid="1076022650427481509">"Nema automatski popunjenih predloga"</string>
+    <string name="autofill_picker_some_suggestions" msgid="5560549696296202701">"{count,plural, =1{Jedan automatski popunjen predlog}one{# automatski popunjen predlog}few{# automatski popunjena predloga}other{# automatski popunjenih predloga}}"</string>
+    <string name="autofill_save_title" msgid="7719802414283739775">"Želite li da sačuvate u usluzi "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
+    <string name="autofill_save_title_with_type" msgid="3002460014579799605">"Želite li da sačuvate stavku <xliff:g id="TYPE">%1$s</xliff:g> u usluzi "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
+    <string name="autofill_save_title_with_2types" msgid="3783270967447869241">"Želite li da sačuvate stavke <xliff:g id="TYPE_0">%1$s</xliff:g> i <xliff:g id="TYPE_1">%2$s</xliff:g> u usluzi "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string>
+    <string name="autofill_save_title_with_3types" msgid="6598228952100102578">"Želite li da sačuvate stavke <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> i <xliff:g id="TYPE_2">%3$s</xliff:g> u usluzi "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"?"</string>
+    <string name="autofill_update_title" msgid="3630695947047069136">"Želite li da ažurirate u usluzi "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
+    <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Želite li da ažurirate stavku <xliff:g id="TYPE">%1$s</xliff:g> u usluzi "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
+    <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Želite li da ažurirate stavke <xliff:g id="TYPE_0">%1$s</xliff:g> i <xliff:g id="TYPE_1">%2$s</xliff:g> u usluzi "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string>
+    <string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Želite li da ažurirate ove stavke u usluzi "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> i <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
+    <string name="autofill_save_yes" msgid="8035743017382012850">"Sačuvaj"</string>
+    <string name="autofill_save_no" msgid="9212826374207023544">"Ne, hvala"</string>
+    <string name="autofill_save_notnow" msgid="2853932672029024195">"Ne sada"</string>
+    <string name="autofill_save_never" msgid="6821841919831402526">"Nikada"</string>
+    <string name="autofill_update_yes" msgid="4608662968996874445">"Ažuriraj"</string>
+    <string name="autofill_continue_yes" msgid="7914985605534510385">"Nastavi"</string>
+    <string name="autofill_save_type_password" msgid="5624528786144539944">"lozinka"</string>
+    <string name="autofill_save_type_address" msgid="3111006395818252885">"adresa"</string>
+    <string name="autofill_save_type_credit_card" msgid="3583795235862046693">"kreditna kartica"</string>
+    <string name="autofill_save_type_debit_card" msgid="3169397504133097468">"debitna kartica"</string>
+    <string name="autofill_save_type_payment_card" msgid="6555012156728690856">"platna kartica"</string>
+    <string name="autofill_save_type_generic_card" msgid="1019367283921448608">"kartica"</string>
+    <string name="autofill_save_type_username" msgid="1018816929884640882">"korisničko ime"</string>
+    <string name="autofill_save_type_email_address" msgid="1303262336895591924">"imejl adresa"</string>
+    <string name="etws_primary_default_message_earthquake" msgid="8401079517718280669">"Ostanite mirni i potražite sklonište u okolini."</string>
+    <string name="etws_primary_default_message_tsunami" msgid="5828171463387976279">"Odmah se sklonite iz priobalnih regiona i oblasti pored reka na neko bezbednije mesto, na primer, na neko uzvišenje."</string>
+    <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="4888224011071875068">"Ostanite mirni i potražite sklonište u okolini."</string>
+    <string name="etws_primary_default_message_test" msgid="4583367373909549421">"Testiranje poruka u hitnim slučajevima"</string>
+    <string name="notification_reply_button_accessibility" msgid="5235776156579456126">"Odgovori"</string>
     <string name="etws_primary_default_message_others" msgid="7958161706019130739"></string>
-    <string name="mmcc_authentication_reject" msgid="4891965994643876369">"SIM картица није прилагођена за гласовне услуге"</string>
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="227760698553988751">"SIM картица није подешена за гласовне услуге"</string>
-    <string name="mmcc_illegal_ms" msgid="7509650265233909445">"SIM картица није прилагођена за гласовне услуге"</string>
-    <string name="mmcc_illegal_me" msgid="6505557881889904915">"Телефон није прилагођен за гласовне услуге"</string>
-    <string name="mmcc_authentication_reject_msim_template" msgid="4480853038909922153">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> није дозвољен"</string>
-    <string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="3688508325248599657">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> није подешен"</string>
-    <string name="mmcc_illegal_ms_msim_template" msgid="832644375774599327">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> није дозвољен"</string>
-    <string name="mmcc_illegal_me_msim_template" msgid="4802735138861422802">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> није дозвољен"</string>
-    <string name="popup_window_default_title" msgid="6907717596694826919">"Искачући прозор"</string>
-    <string name="slice_more_content" msgid="3377367737876888459">"и још <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
-    <string name="shortcut_restored_on_lower_version" msgid="9206301954024286063">"Апликација је враћена на старију верзију или није компатибилна са овом пречицом"</string>
-    <string name="shortcut_restore_not_supported" msgid="4763198938588468400">"Враћање пречице није успело јер апликација не подржава прављење резервне копије и враћање"</string>
-    <string name="shortcut_restore_signature_mismatch" msgid="579345304221605479">"Враћање пречице није успело јер се потписи апликација не подударају"</string>
-    <string name="shortcut_restore_unknown_issue" msgid="2478146134395982154">"Враћање пречице није успело"</string>
-    <string name="shortcut_disabled_reason_unknown" msgid="753074793553599166">"Пречица је онемогућена"</string>
-    <string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ДЕИНСТАЛИРАЈ"</string>
-    <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ИПАК ОТВОРИ"</string>
-    <string name="harmful_app_warning_title" msgid="8794823880881113856">"Откривена је штетна апликација"</string>
-    <string name="log_access_confirmation_title" msgid="2343578467290592708">"Желите да дозволите апликацији <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> да приступа свим евиденцијама уређаја?"</string>
-    <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Дозволи једнократан приступ"</string>
-    <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Не дозволи"</string>
-    <string name="log_access_confirmation_body" product="default" msgid="1806692062668620735">"Евиденције уређаја региструју шта се дешава на уређају. Апликације могу да користе те евиденције да би пронашле и решиле проблеме.\n\nНеке евиденције могу да садрже осетљиве информације, па приступ свим евиденцијама уређаја треба да дозвољавате само апликацијама у које имате поверења. \n\nАко не дозволите овој апликацији да приступа свим евиденцијама уређаја, она и даље може да приступа сопственим евиденцијама. Произвођач уређаја ће можда и даље моћи да приступа неким евиденцијама или информацијама на уређају."</string>
-    <string name="log_access_confirmation_body" product="tv" msgid="7379536536425265262">"Евиденције уређаја региструју шта се дешава на уређају. Апликације могу да користе те евиденције да би пронашле и решиле проблеме.\n\nНеке евиденције могу да садрже осетљиве информације, па приступ свим евиденцијама уређаја треба да дозвољавате само апликацијама у које имате поверења. \n\nАко не дозволите овој апликацији да приступа свим евиденцијама уређаја, она и даље може да приступа сопственим евиденцијама. Произвођач уређаја ће можда и даље моћи да приступа неким евиденцијама или информацијама на уређају.\n\nСазнајте више на g.co/android/devicelogs."</string>
-    <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Не приказуј поново"</string>
-    <string name="slices_permission_request" msgid="3677129866636153406">"Апликација <xliff:g id="APP_0">%1$s</xliff:g> жели да приказује исечке из апликације <xliff:g id="APP_2">%2$s</xliff:g>"</string>
-    <string name="screenshot_edit" msgid="7408934887203689207">"Измени"</string>
-    <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Вибрација за позиве и обавештења је укључена"</string>
-    <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Мелодија звона за позиве и обавештење је искључена"</string>
-    <string name="notification_channel_system_changes" msgid="2462010596920209678">"Системске промене"</string>
-    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Не узнемиравај"</string>
-    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Ново: Режим Не узнемиравај крије обавештења"</string>
-    <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Додирните да бисте сазнали више и променили подешавање."</string>
-    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Режим Не узнемиравај је промењен"</string>
-    <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Додирните да бисте проверили шта је блокирано."</string>
-    <string name="review_notification_settings_title" msgid="5102557424459810820">"Прегледајте подешавања обавештења"</string>
-    <string name="review_notification_settings_text" msgid="5916244866751849279">"Од Android-а 13 апликације које инсталирате морају да имају дозволу за слање обавештења. Додирните да бисте променили ову дозволу за постојеће апликације."</string>
-    <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Подсети ме касније"</string>
-    <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Одбаци"</string>
-    <string name="notification_app_name_system" msgid="3045196791746735601">"Систем"</string>
-    <string name="notification_app_name_settings" msgid="9088548800899952531">"Подешавања"</string>
-    <string name="notification_appops_camera_active" msgid="8177643089272352083">"Камера"</string>
-    <string name="notification_appops_microphone_active" msgid="581333393214739332">"Микрофон"</string>
-    <string name="notification_appops_overlay_active" msgid="5571732753262836481">"приказује се на екрану док користите друге апликације"</string>
-    <string name="notification_feedback_indicator" msgid="663476517711323016">"Пошаљите повратне информације"</string>
-    <string name="notification_feedback_indicator_alerted" msgid="6552871804121942099">"Ово обавештење је унапређено у Подразумевано. Додирните да бисте навели повратне информације."</string>
-    <string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Ово обавештење је деградирано у Нечујно. Додирните да бисте навели повратне информације."</string>
-    <string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Ово обавештење је рангирано више. Додирните да бисте навели повратне информације."</string>
-    <string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Ово обавештење је рангирано ниже. Додирните да бисте навели повратне информације."</string>
-    <string name="nas_upgrade_notification_title" msgid="8436359459300146555">"Побољшана обавештења"</string>
-    <string name="nas_upgrade_notification_content" msgid="5157550369837103337">"Предложене радње и одговоре сада добијате помоћу побољшаних обавештења. Прилагодљива обавештења за Android више нису подржана."</string>
-    <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Потврди"</string>
-    <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Искључи"</string>
-    <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Сазнајте више"</string>
-    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Побољшана обавештења су заменила Android прилагодљива обавештења у Android-у 12. Ова функција показује предложене радње и одговоре, и организује обавештења.\n\nПобољшана обавештења могу да приступају садржају обавештења, укључујући личне податке попут имена контаката и порука. Ова функција може и да одбацује обавештења или да одговара на њих, на пример, да се јавља на телефонске позиве и контролише режим Не узнемиравај."</string>
-    <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Обавештење о информацијама Рутинског режима"</string>
-    <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батерија ће се можда испразнити пре уобичајеног пуњења"</string>
-    <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Уштеда батерије је активирана да би се продужило трајање батерије"</string>
-    <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Уштеда батерије"</string>
-    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Уштеда батерије је искључена"</string>
-    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Батерија телефона је довољно напуњена. Функције више нису ограничене."</string>
-    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Батерија таблета је довољно напуњена. Функције више нису ограничене."</string>
-    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Батерија уређаја је довољно напуњена. Функције више нису ограничене."</string>
-    <string name="mime_type_folder" msgid="2203536499348787650">"Фолдер"</string>
-    <string name="mime_type_apk" msgid="3168784749499623902">"Android апликација"</string>
-    <string name="mime_type_generic" msgid="4606589110116560228">"Датотека"</string>
-    <string name="mime_type_generic_ext" msgid="9220220924380909486">"<xliff:g id="EXTENSION">%1$s</xliff:g> датотека"</string>
-    <string name="mime_type_audio" msgid="4933450584432509875">"Аудио датотека"</string>
-    <string name="mime_type_audio_ext" msgid="2615491023840514797">"<xliff:g id="EXTENSION">%1$s</xliff:g> аудио датотека"</string>
-    <string name="mime_type_video" msgid="7071965726609428150">"Видео"</string>
-    <string name="mime_type_video_ext" msgid="185438149044230136">"<xliff:g id="EXTENSION">%1$s</xliff:g> видео"</string>
-    <string name="mime_type_image" msgid="2134307276151645257">"Слика"</string>
-    <string name="mime_type_image_ext" msgid="5743552697560999471">"<xliff:g id="EXTENSION">%1$s</xliff:g> слика"</string>
-    <string name="mime_type_compressed" msgid="8737300936080662063">"Архива"</string>
-    <string name="mime_type_compressed_ext" msgid="4775627287994475737">"<xliff:g id="EXTENSION">%1$s</xliff:g> архива"</string>
-    <string name="mime_type_document" msgid="3737256839487088554">"Документ"</string>
-    <string name="mime_type_document_ext" msgid="2398002765046677311">"<xliff:g id="EXTENSION">%1$s</xliff:g> документ"</string>
-    <string name="mime_type_spreadsheet" msgid="8188407519131275838">"Табела"</string>
-    <string name="mime_type_spreadsheet_ext" msgid="8720173181137254414">"<xliff:g id="EXTENSION">%1$s</xliff:g> табела"</string>
-    <string name="mime_type_presentation" msgid="1145384236788242075">"Презентација"</string>
-    <string name="mime_type_presentation_ext" msgid="8761049335564371468">"<xliff:g id="EXTENSION">%1$s</xliff:g> презентација"</string>
-    <string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"Bluetooth остаје укључен током режима рада у авиону"</string>
-    <string name="car_loading_profile" msgid="8219978381196748070">"Учитава се"</string>
-    <string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + # фајл}one{{file_name} + # фајл}few{{file_name} + # фајла}other{{file_name} + # фајлова}}"</string>
-    <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Нема препоручених људи за дељење"</string>
-    <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Листа апликација"</string>
-    <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Ова апликација нема дозволу за снимање, али би могла да снима звук помоћу овог USB уређаја."</string>
-    <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Почетак"</string>
-    <string name="accessibility_system_action_back_label" msgid="4205361367345537608">"Назад"</string>
-    <string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"Недавне апликације"</string>
-    <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Обавештења"</string>
-    <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Брза подешавања"</string>
-    <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Дијалог напајања"</string>
-    <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Закључавање екрана"</string>
-    <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Снимак екрана"</string>
-    <string name="accessibility_system_action_headset_hook_label" msgid="8524691721287425468">"Кука за слушалице"</string>
-    <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Пречица за приступачност на екрану"</string>
-    <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Алатка за бирање пречица за приступачност на екрану"</string>
-    <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Пречица за приступачност"</string>
-    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Одбаци траку са обавештењима"</string>
-    <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"нагоре на D-pad-у"</string>
-    <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"надоле на D-pad-у"</string>
-    <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"налево на D-pad-у"</string>
-    <string name="accessibility_system_action_dpad_right_label" msgid="9180196950365804081">"надесно на D-pad-у"</string>
-    <string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"центар на D-pad-у"</string>
-    <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Трака са насловима апликације <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Пакет <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> је додат у сегмент ОГРАНИЧЕНО"</string>
+    <string name="mmcc_authentication_reject" msgid="4891965994643876369">"SIM kartica nije prilagođena za glasovne usluge"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="227760698553988751">"SIM kartica nije podešena za glasovne usluge"</string>
+    <string name="mmcc_illegal_ms" msgid="7509650265233909445">"SIM kartica nije prilagođena za glasovne usluge"</string>
+    <string name="mmcc_illegal_me" msgid="6505557881889904915">"Telefon nije prilagođen za glasovne usluge"</string>
+    <string name="mmcc_authentication_reject_msim_template" msgid="4480853038909922153">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> nije dozvoljen"</string>
+    <string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="3688508325248599657">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> nije podešen"</string>
+    <string name="mmcc_illegal_ms_msim_template" msgid="832644375774599327">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> nije dozvoljen"</string>
+    <string name="mmcc_illegal_me_msim_template" msgid="4802735138861422802">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> nije dozvoljen"</string>
+    <string name="popup_window_default_title" msgid="6907717596694826919">"Iskačući prozor"</string>
+    <string name="slice_more_content" msgid="3377367737876888459">"i još <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <string name="shortcut_restored_on_lower_version" msgid="9206301954024286063">"Aplikacija je vraćena na stariju verziju ili nije kompatibilna sa ovom prečicom"</string>
+    <string name="shortcut_restore_not_supported" msgid="4763198938588468400">"Vraćanje prečice nije uspelo jer aplikacija ne podržava pravljenje rezervne kopije i vraćanje"</string>
+    <string name="shortcut_restore_signature_mismatch" msgid="579345304221605479">"Vraćanje prečice nije uspelo jer se potpisi aplikacija ne podudaraju"</string>
+    <string name="shortcut_restore_unknown_issue" msgid="2478146134395982154">"Vraćanje prečice nije uspelo"</string>
+    <string name="shortcut_disabled_reason_unknown" msgid="753074793553599166">"Prečica je onemogućena"</string>
+    <string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"DEINSTALIRAJ"</string>
+    <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"IPAK OTVORI"</string>
+    <string name="harmful_app_warning_title" msgid="8794823880881113856">"Otkrivena je štetna aplikacija"</string>
+    <string name="log_access_confirmation_title" msgid="2343578467290592708">"Želite da dozvolite aplikaciji <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> da pristupa svim evidencijama uređaja?"</string>
+    <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Dozvoli jednokratan pristup"</string>
+    <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Ne dozvoli"</string>
+    <string name="log_access_confirmation_body" product="default" msgid="1806692062668620735">"Evidencije uređaja registruju šta se dešava na uređaju. Aplikacije mogu da koriste te evidencije da bi pronašle i rešile probleme.\n\nNeke evidencije mogu da sadrže osetljive informacije, pa pristup svim evidencijama uređaja treba da dozvoljavate samo aplikacijama u koje imate poverenja. \n\nAko ne dozvolite ovoj aplikaciji da pristupa svim evidencijama uređaja, ona i dalje može da pristupa sopstvenim evidencijama. Proizvođač uređaja će možda i dalje moći da pristupa nekim evidencijama ili informacijama na uređaju."</string>
+    <string name="log_access_confirmation_body" product="tv" msgid="7379536536425265262">"Evidencije uređaja registruju šta se dešava na uređaju. Aplikacije mogu da koriste te evidencije da bi pronašle i rešile probleme.\n\nNeke evidencije mogu da sadrže osetljive informacije, pa pristup svim evidencijama uređaja treba da dozvoljavate samo aplikacijama u koje imate poverenja. \n\nAko ne dozvolite ovoj aplikaciji da pristupa svim evidencijama uređaja, ona i dalje može da pristupa sopstvenim evidencijama. Proizvođač uređaja će možda i dalje moći da pristupa nekim evidencijama ili informacijama na uređaju.\n\nSaznajte više na g.co/android/devicelogs."</string>
+    <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ne prikazuj ponovo"</string>
+    <string name="slices_permission_request" msgid="3677129866636153406">"Aplikacija <xliff:g id="APP_0">%1$s</xliff:g> želi da prikazuje isečke iz aplikacije <xliff:g id="APP_2">%2$s</xliff:g>"</string>
+    <string name="screenshot_edit" msgid="7408934887203689207">"Izmeni"</string>
+    <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Vibracija za pozive i obaveštenja je uključena"</string>
+    <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Melodija zvona za pozive i obaveštenje je isključena"</string>
+    <string name="notification_channel_system_changes" msgid="2462010596920209678">"Sistemske promene"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Ne uznemiravaj"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Novo: Režim Ne uznemiravaj krije obaveštenja"</string>
+    <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Dodirnite da biste saznali više i promenili podešavanje."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Režim Ne uznemiravaj je promenjen"</string>
+    <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Dodirnite da biste proverili šta je blokirano."</string>
+    <string name="review_notification_settings_title" msgid="5102557424459810820">"Pregledajte podešavanja obaveštenja"</string>
+    <string name="review_notification_settings_text" msgid="5916244866751849279">"Od Android-a 13 aplikacije koje instalirate moraju da imaju dozvolu za slanje obaveštenja. Dodirnite da biste promenili ovu dozvolu za postojeće aplikacije."</string>
+    <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Podseti me kasnije"</string>
+    <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Odbaci"</string>
+    <string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
+    <string name="notification_app_name_settings" msgid="9088548800899952531">"Podešavanja"</string>
+    <string name="notification_appops_camera_active" msgid="8177643089272352083">"Kamera"</string>
+    <string name="notification_appops_microphone_active" msgid="581333393214739332">"Mikrofon"</string>
+    <string name="notification_appops_overlay_active" msgid="5571732753262836481">"prikazuje se na ekranu dok koristite druge aplikacije"</string>
+    <string name="notification_feedback_indicator" msgid="663476517711323016">"Pošaljite povratne informacije"</string>
+    <string name="notification_feedback_indicator_alerted" msgid="6552871804121942099">"Ovo obaveštenje je unapređeno u Podrazumevano. Dodirnite da biste naveli povratne informacije."</string>
+    <string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Ovo obaveštenje je degradirano u Nečujno. Dodirnite da biste naveli povratne informacije."</string>
+    <string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Ovo obaveštenje je rangirano više. Dodirnite da biste naveli povratne informacije."</string>
+    <string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Ovo obaveštenje je rangirano niže. Dodirnite da biste naveli povratne informacije."</string>
+    <string name="nas_upgrade_notification_title" msgid="8436359459300146555">"Poboljšana obaveštenja"</string>
+    <string name="nas_upgrade_notification_content" msgid="5157550369837103337">"Predložene radnje i odgovore sada dobijate pomoću poboljšanih obaveštenja. Prilagodljiva obaveštenja za Android više nisu podržana."</string>
+    <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Potvrdi"</string>
+    <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Isključi"</string>
+    <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Saznajte više"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Poboljšana obaveštenja su zamenila Android prilagodljiva obaveštenja u Android-u 12. Ova funkcija pokazuje predložene radnje i odgovore, i organizuje obaveštenja.\n\nPoboljšana obaveštenja mogu da pristupaju sadržaju obaveštenja, uključujući lične podatke poput imena kontakata i poruka. Ova funkcija može i da odbacuje obaveštenja ili da odgovara na njih, na primer, da se javlja na telefonske pozive i kontroliše režim Ne uznemiravaj."</string>
+    <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Obaveštenje o informacijama Rutinskog režima"</string>
+    <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Baterija će se možda isprazniti pre uobičajenog punjenja"</string>
+    <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Ušteda baterije je aktivirana da bi se produžilo trajanje baterije"</string>
+    <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Ušteda baterije"</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Ušteda baterije je isključena"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Baterija telefona je dovoljno napunjena. Funkcije više nisu ograničene."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Baterija tableta je dovoljno napunjena. Funkcije više nisu ograničene."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Baterija uređaja je dovoljno napunjena. Funkcije više nisu ograničene."</string>
+    <string name="mime_type_folder" msgid="2203536499348787650">"Folder"</string>
+    <string name="mime_type_apk" msgid="3168784749499623902">"Android aplikacija"</string>
+    <string name="mime_type_generic" msgid="4606589110116560228">"Datoteka"</string>
+    <string name="mime_type_generic_ext" msgid="9220220924380909486">"<xliff:g id="EXTENSION">%1$s</xliff:g> datoteka"</string>
+    <string name="mime_type_audio" msgid="4933450584432509875">"Audio datoteka"</string>
+    <string name="mime_type_audio_ext" msgid="2615491023840514797">"<xliff:g id="EXTENSION">%1$s</xliff:g> audio datoteka"</string>
+    <string name="mime_type_video" msgid="7071965726609428150">"Video"</string>
+    <string name="mime_type_video_ext" msgid="185438149044230136">"<xliff:g id="EXTENSION">%1$s</xliff:g> video"</string>
+    <string name="mime_type_image" msgid="2134307276151645257">"Slika"</string>
+    <string name="mime_type_image_ext" msgid="5743552697560999471">"<xliff:g id="EXTENSION">%1$s</xliff:g> slika"</string>
+    <string name="mime_type_compressed" msgid="8737300936080662063">"Arhiva"</string>
+    <string name="mime_type_compressed_ext" msgid="4775627287994475737">"<xliff:g id="EXTENSION">%1$s</xliff:g> arhiva"</string>
+    <string name="mime_type_document" msgid="3737256839487088554">"Dokument"</string>
+    <string name="mime_type_document_ext" msgid="2398002765046677311">"<xliff:g id="EXTENSION">%1$s</xliff:g> dokument"</string>
+    <string name="mime_type_spreadsheet" msgid="8188407519131275838">"Tabela"</string>
+    <string name="mime_type_spreadsheet_ext" msgid="8720173181137254414">"<xliff:g id="EXTENSION">%1$s</xliff:g> tabela"</string>
+    <string name="mime_type_presentation" msgid="1145384236788242075">"Prezentacija"</string>
+    <string name="mime_type_presentation_ext" msgid="8761049335564371468">"<xliff:g id="EXTENSION">%1$s</xliff:g> prezentacija"</string>
+    <string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"Bluetooth ostaje uključen tokom režima rada u avionu"</string>
+    <string name="car_loading_profile" msgid="8219978381196748070">"Učitava se"</string>
+    <string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + # fajl}one{{file_name} + # fajl}few{{file_name} + # fajla}other{{file_name} + # fajlova}}"</string>
+    <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Nema preporučenih ljudi za deljenje"</string>
+    <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Lista aplikacija"</string>
+    <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Ova aplikacija nema dozvolu za snimanje, ali bi mogla da snima zvuk pomoću ovog USB uređaja."</string>
+    <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Početak"</string>
+    <string name="accessibility_system_action_back_label" msgid="4205361367345537608">"Nazad"</string>
+    <string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"Nedavne aplikacije"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Obaveštenja"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Brza podešavanja"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Dijalog napajanja"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Zaključavanje ekrana"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Snimak ekrana"</string>
+    <string name="accessibility_system_action_headset_hook_label" msgid="8524691721287425468">"Kuka za slušalice"</string>
+    <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Prečica za pristupačnost na ekranu"</string>
+    <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Alatka za biranje prečica za pristupačnost na ekranu"</string>
+    <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Prečica za pristupačnost"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Odbaci traku sa obaveštenjima"</string>
+    <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"nagore na D-pad-u"</string>
+    <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"nadole na D-pad-u"</string>
+    <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"nalevo na D-pad-u"</string>
+    <string name="accessibility_system_action_dpad_right_label" msgid="9180196950365804081">"nadesno na D-pad-u"</string>
+    <string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"centar na D-pad-u"</string>
+    <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Traka sa naslovima aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Paket <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> je dodat u segment OGRANIČENO"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
-    <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"је послао/ла слику"</string>
-    <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Конверзација"</string>
-    <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Групна конверзација"</string>
+    <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"je poslao/la sliku"</string>
+    <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Konverzacija"</string>
+    <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Grupna konverzacija"</string>
     <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string>
-    <string name="resolver_personal_tab" msgid="2051260504014442073">"Лично"</string>
-    <string name="resolver_work_tab" msgid="2690019516263167035">"Пословно"</string>
-    <string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Лични приказ"</string>
-    <string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Приказ за посао"</string>
-    <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Блокира ИТ администратор"</string>
-    <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Овај садржај не може да се дели помоћу пословних апликација"</string>
-    <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Овај садржај не може да се отвара помоћу пословних апликација"</string>
-    <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Овај садржај не може да се дели помоћу личних апликација"</string>
-    <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Овај садржај не може да се отвара помоћу личних апликација"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Пословни профил је паузиран"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Додирните да бисте укључили"</string>
-    <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Нема пословних апликација"</string>
-    <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Нема личних апликација"</string>
-    <string name="miniresolver_open_in_personal" msgid="3874522693661065566">"Желите да на личном профилу отворите: <xliff:g id="APP">%s</xliff:g>?"</string>
-    <string name="miniresolver_open_in_work" msgid="4415223793669536559">"Желите да на пословном профилу отворите: <xliff:g id="APP">%s</xliff:g>?"</string>
-    <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Користи лични прегледач"</string>
-    <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Користи пословни прегледач"</string>
-    <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN за откључавање SIM мреже"</string>
-    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN за откључавање подскупа SIM мреже"</string>
-    <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN за откључавање пословне SIM картице"</string>
-    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_ENTRY" msgid="973059024670737358">"PIN за откључавање добављача услуге SIM картице"</string>
-    <string name="PERSOSUBSTATE_SIM_SIM_ENTRY" msgid="4487435301206073787">"PIN за откључавање SIM картице"</string>
-    <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_ENTRY" msgid="768060297218652809">"Унесите PUK"</string>
-    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_ENTRY" msgid="7129527319490548930">"Унесите PUK"</string>
-    <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_ENTRY" msgid="2876126640607573252">"Унесите PUK"</string>
-    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_ENTRY" msgid="8952595089930109282">"Унесите PUK"</string>
-    <string name="PERSOSUBSTATE_SIM_SIM_PUK_ENTRY" msgid="3013902515773728996">"Унесите PUK"</string>
-    <string name="PERSOSUBSTATE_RUIM_NETWORK1_ENTRY" msgid="2974411408893410289">"PIN за откључавање RUIM мреже 1"</string>
-    <string name="PERSOSUBSTATE_RUIM_NETWORK2_ENTRY" msgid="687618528751880721">"PIN за откључавање RUIM мреже 2"</string>
-    <string name="PERSOSUBSTATE_RUIM_HRPD_ENTRY" msgid="6810596579655575381">"PIN за откључавање RUIM hrpd-а"</string>
-    <string name="PERSOSUBSTATE_RUIM_CORPORATE_ENTRY" msgid="2715929642540980259">"PIN за откључавање пословне RUIM картице"</string>
-    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_ENTRY" msgid="8557791623303951590">"PIN за откључавање RUIM картице добављача услуге"</string>
-    <string name="PERSOSUBSTATE_RUIM_RUIM_ENTRY" msgid="7382468767274580323">"PIN за откључавање RUIM картице"</string>
-    <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_ENTRY" msgid="6730880791104286987">"Унесите PUK"</string>
-    <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_ENTRY" msgid="6432126539782267026">"Унесите PUK"</string>
-    <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_ENTRY" msgid="1730510161529488920">"Унесите PUK"</string>
-    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_ENTRY" msgid="3369885925003346830">"Унесите PUK"</string>
-    <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_ENTRY" msgid="9129139686191167829">"Унесите PUK"</string>
-    <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_ENTRY" msgid="2869929685874615358">"Унесите PUK"</string>
-    <string name="PERSOSUBSTATE_SIM_SPN_ENTRY" msgid="1238663472392741771">"PIN за откључавање SPN-а"</string>
-    <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_ENTRY" msgid="3988705848553894358">"PIN за откључавање SP еквивалентног матичног PLMN-а"</string>
-    <string name="PERSOSUBSTATE_SIM_ICCID_ENTRY" msgid="6186770686690993200">"PIN за откључавање ICCID-а"</string>
-    <string name="PERSOSUBSTATE_SIM_IMPI_ENTRY" msgid="7043865376145617024">"PIN за откључавање IMPI-ја"</string>
-    <string name="PERSOSUBSTATE_SIM_NS_SP_ENTRY" msgid="6144227308185112176">"PIN за откључавање добављача услуге подскупа мреже"</string>
-    <string name="PERSOSUBSTATE_SIM_NETWORK_IN_PROGRESS" msgid="4233355366318061180">"Захтева се откључавање SIM мреже…"</string>
-    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_IN_PROGRESS" msgid="6742563947637715645">"Захтева се откључавање подскупа SIM мреже…"</string>
-    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_IN_PROGRESS" msgid="2033399698172403560">"Захтева се откључавање добављача услуге SIM картице…"</string>
-    <string name="PERSOSUBSTATE_SIM_CORPORATE_IN_PROGRESS" msgid="4795977251920732254">"Захтева се откључавање пословне SIM картице…"</string>
-    <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_IN_PROGRESS" msgid="1090425878157254446">"Захтева се откључавање помоћу PUK-а…"</string>
-    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_IN_PROGRESS" msgid="6476898876518094438">"Захтева се откључавање помоћу PUK-а…"</string>
-    <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_IN_PROGRESS" msgid="6006806734293747731">"Захтева се откључавање помоћу PUK-а…"</string>
-    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_IN_PROGRESS" msgid="6546680489620881893">"Захтева се откључавање помоћу PUK-а…"</string>
-    <string name="PERSOSUBSTATE_SIM_SIM_PUK_IN_PROGRESS" msgid="3506845511000727015">"Захтева се откључавање помоћу PUK-а…"</string>
-    <string name="PERSOSUBSTATE_SIM_SIM_IN_PROGRESS" msgid="6709169861932992750">"Захтева се откључавање SIM картице…"</string>
-    <string name="PERSOSUBSTATE_RUIM_NETWORK1_IN_PROGRESS" msgid="4013870911606478520">"Захтева се откључавање RUIM мреже 1…"</string>
-    <string name="PERSOSUBSTATE_RUIM_NETWORK2_IN_PROGRESS" msgid="9032651188219523434">"Захтева се откључавање RUIM мреже 2…"</string>
-    <string name="PERSOSUBSTATE_RUIM_HRPD_IN_PROGRESS" msgid="6584576506344491207">"Захтева се откључавање RUIM hrpd-а…"</string>
-    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_IN_PROGRESS" msgid="830981927724888114">"Захтева се откључавање RUIM картице добављача услуге…"</string>
-    <string name="PERSOSUBSTATE_RUIM_CORPORATE_IN_PROGRESS" msgid="7851790973098894802">"Захтева се откључавање пословне RUIM картице…"</string>
-    <string name="PERSOSUBSTATE_SIM_SPN_IN_PROGRESS" msgid="1149560739586960121">"Захтева се откључавање SPN-а…"</string>
-    <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_IN_PROGRESS" msgid="5708964693522116025">"Захтева се откључавање SP еквивалентног матичног PLMN-а…"</string>
-    <string name="PERSOSUBSTATE_SIM_ICCID_IN_PROGRESS" msgid="7288103122966483455">"Захтева се откључавање ICCID-а…"</string>
-    <string name="PERSOSUBSTATE_SIM_IMPI_IN_PROGRESS" msgid="4036752174056147753">"Захтева се откључавање IMPI-ја…"</string>
-    <string name="PERSOSUBSTATE_SIM_NS_SP_IN_PROGRESS" msgid="5089536274515338566">"Захтева се откључавање добављача услуге подскупа мреже…"</string>
-    <string name="PERSOSUBSTATE_RUIM_RUIM_IN_PROGRESS" msgid="6737197986936251958">"Захтева се откључавање RUIM картице…"</string>
-    <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_IN_PROGRESS" msgid="5658767775619998623">"Захтева се откључавање помоћу PUK-а…"</string>
-    <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_IN_PROGRESS" msgid="665978313257653727">"Захтева се откључавање помоћу PUK-а…"</string>
-    <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_IN_PROGRESS" msgid="3857142652251836850">"Захтева се откључавање помоћу PUK-а…"</string>
-    <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_IN_PROGRESS" msgid="2695664012344346788">"Захтева се откључавање помоћу PUK-а…"</string>
-    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_IN_PROGRESS" msgid="2695678959963807782">"Захтева се откључавање помоћу PUK-а…"</string>
-    <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_IN_PROGRESS" msgid="1230605365926493599">"Захтева се откључавање помоћу PUK-а…"</string>
-    <string name="PERSOSUBSTATE_SIM_NETWORK_ERROR" msgid="1924844017037151535">"Захтев за откључавање SIM мреже није успео."</string>
-    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ERROR" msgid="3372797822292089708">"Захтев за откључавање подскупа SIM мреже је успео."</string>
-    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_ERROR" msgid="1878443146720411381">"Захтев за откључавање добављача услуге SIM картице није успео."</string>
-    <string name="PERSOSUBSTATE_SIM_CORPORATE_ERROR" msgid="7664778312218023192">"Захтев за откључавање пословне SIM картице није успео."</string>
-    <string name="PERSOSUBSTATE_SIM_SIM_ERROR" msgid="2472944311643350302">"Захтев за откључавање SIM картице није успео."</string>
-    <string name="PERSOSUBSTATE_RUIM_NETWORK1_ERROR" msgid="828089694480999120">"Захтев за откључавање RUIM мреже 1 није успео."</string>
-    <string name="PERSOSUBSTATE_RUIM_NETWORK2_ERROR" msgid="17619001007092511">"Захтев за откључавање RUIM мреже 2 није успео."</string>
-    <string name="PERSOSUBSTATE_RUIM_HRPD_ERROR" msgid="807214229604353614">"Захтев за откључавање RUIM hrpd-а није успео."</string>
-    <string name="PERSOSUBSTATE_RUIM_CORPORATE_ERROR" msgid="8644184447744175747">"Захтев за откључавање пословне RUIM картице није успео."</string>
-    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_ERROR" msgid="3801002648649640407">"Захтев за откључавање RUIM картице добављача услуге није успео."</string>
-    <string name="PERSOSUBSTATE_RUIM_RUIM_ERROR" msgid="707397021218680753">"Захтев за откључавање RUIM картице није успео."</string>
-    <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_ERROR" msgid="894358680773257820">"Откључавање помоћу PUK-а није успело."</string>
-    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_ERROR" msgid="352466878146726991">"Откључавање помоћу PUK-а није успело."</string>
-    <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_ERROR" msgid="7353389721907138671">"Откључавање помоћу PUK-а није успело."</string>
-    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_ERROR" msgid="2655263155490857920">"Откључавање помоћу PUK-а није успело."</string>
-    <string name="PERSOSUBSTATE_SIM_SIM_PUK_ERROR" msgid="6903740900892931310">"Откључавање помоћу PUK-а није успело."</string>
-    <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_ERROR" msgid="5165901670447518687">"Откључавање помоћу PUK-а није успело."</string>
-    <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_ERROR" msgid="2856763216589267623">"Откључавање помоћу PUK-а није успело."</string>
-    <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_ERROR" msgid="817542684437829139">"Откључавање помоћу PUK-а није успело."</string>
-    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_ERROR" msgid="5178635064113393143">"Откључавање помоћу PUK-а није успело."</string>
-    <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_ERROR" msgid="5391587926974531008">"Откључавање помоћу PUK-а није успело."</string>
-    <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_ERROR" msgid="4895494864493315868">"Откључавање помоћу PUK-а није успело."</string>
-    <string name="PERSOSUBSTATE_SIM_SPN_ERROR" msgid="9017576601595353649">"Захтев за откључавање SPN-а није успео."</string>
-    <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_ERROR" msgid="1116993930995545742">"Захтев за откључавање SP еквивалентног матичног PLMN-а није успео."</string>
-    <string name="PERSOSUBSTATE_SIM_ICCID_ERROR" msgid="7559167306794441462">"Захтев за откључавање ICCID-а није успео."</string>
-    <string name="PERSOSUBSTATE_SIM_IMPI_ERROR" msgid="2782926139511136588">"Захтев за откључавање IMPI-ја није успео."</string>
-    <string name="PERSOSUBSTATE_SIM_NS_SP_ERROR" msgid="1890493954453456758">"Захтев за откључавање добављача услуге подскупа мреже није успео."</string>
-    <string name="PERSOSUBSTATE_SIM_NETWORK_SUCCESS" msgid="4886243367747126325">"Откључавање SIM мреже је успело."</string>
-    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_SUCCESS" msgid="4053809277733513987">"Откључавање подскупа SIM мреже је успело."</string>
-    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_SUCCESS" msgid="8249342930499801740">"Откључавање добављача услуге SIM картице је успело."</string>
-    <string name="PERSOSUBSTATE_SIM_CORPORATE_SUCCESS" msgid="2339794542560381270">"Откључавање пословне SIM картице је успело."</string>
-    <string name="PERSOSUBSTATE_SIM_SIM_SUCCESS" msgid="6975608174152828954">"Откључавање SIM картице је успело."</string>
-    <string name="PERSOSUBSTATE_RUIM_NETWORK1_SUCCESS" msgid="2846699261330463192">"Откључавање RUIM мреже 1 је успело."</string>
-    <string name="PERSOSUBSTATE_RUIM_NETWORK2_SUCCESS" msgid="5335414726057102801">"Откључавање RUIM мреже 2 је успело."</string>
-    <string name="PERSOSUBSTATE_RUIM_HRPD_SUCCESS" msgid="8868100318474971969">"Откључавање RUIM hrpd-а је успело."</string>
-    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_SUCCESS" msgid="6020936629725666932">"Захтев за откључавање RUIM картице добављача услуге је успео."</string>
-    <string name="PERSOSUBSTATE_RUIM_CORPORATE_SUCCESS" msgid="6944873647584595489">"Откључавање пословне RUIM картице је успело."</string>
-    <string name="PERSOSUBSTATE_RUIM_RUIM_SUCCESS" msgid="2526483514124121988">"Откључавање RUIM картице је успело."</string>
-    <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_SUCCESS" msgid="7662200333621664621">"Откључавање помоћу PUK-а је успело."</string>
-    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_SUCCESS" msgid="2861223407953766632">"Откључавање помоћу PUK-а је успело."</string>
-    <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_SUCCESS" msgid="5345648571175243272">"Откључавање помоћу PUK-а је успело."</string>
-    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_SUCCESS" msgid="3725278343103422466">"Откључавање помоћу PUK-а је успело."</string>
-    <string name="PERSOSUBSTATE_SIM_SIM_PUK_SUCCESS" msgid="6998502547560297983">"Откључавање помоћу PUK-а је успело."</string>
-    <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_SUCCESS" msgid="8555433771162560361">"Откључавање помоћу PUK-а је успело."</string>
-    <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_SUCCESS" msgid="3555767296933606232">"Откључавање помоћу PUK-а је успело."</string>
-    <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_SUCCESS" msgid="6778051818199974237">"Откључавање помоћу PUK-а је успело."</string>
-    <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_SUCCESS" msgid="4080108758498911429">"Откључавање помоћу PUK-а је успело."</string>
-    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_SUCCESS" msgid="7873675303000794343">"Откључавање помоћу PUK-а је успело."</string>
-    <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_SUCCESS" msgid="1763198215069819523">"Откључавање помоћу PUK-а је успело."</string>
-    <string name="PERSOSUBSTATE_SIM_SPN_SUCCESS" msgid="2053891977727320532">"Откључавање SPN-а је успело."</string>
-    <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_SUCCESS" msgid="8146602361895007345">"Откључавање SP еквивалентног матичног PLMN-а је успело."</string>
-    <string name="PERSOSUBSTATE_SIM_ICCID_SUCCESS" msgid="8058678548991999545">"Откључавање ICCID-а је успело."</string>
-    <string name="PERSOSUBSTATE_SIM_IMPI_SUCCESS" msgid="2545608067978550571">"Откључавање IMPI-ја је успело."</string>
-    <string name="PERSOSUBSTATE_SIM_NS_SP_SUCCESS" msgid="4352382949744625007">"Захтев за откључавање добављача услуге подскупа мреже је успео."</string>
+    <string name="resolver_personal_tab" msgid="2051260504014442073">"Lično"</string>
+    <string name="resolver_work_tab" msgid="2690019516263167035">"Poslovno"</string>
+    <string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Lični prikaz"</string>
+    <string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Prikaz za posao"</string>
+    <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Blokira IT administrator"</string>
+    <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Ovaj sadržaj ne može da se deli pomoću poslovnih aplikacija"</string>
+    <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Ovaj sadržaj ne može da se otvara pomoću poslovnih aplikacija"</string>
+    <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Ovaj sadržaj ne može da se deli pomoću ličnih aplikacija"</string>
+    <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Ovaj sadržaj ne može da se otvara pomoću ličnih aplikacija"</string>
+    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Poslovni profil je pauziran"</string>
+    <string name="resolver_switch_on_work" msgid="463709043650610420">"Dodirnite da biste uključili"</string>
+    <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nema poslovnih aplikacija"</string>
+    <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nema ličnih aplikacija"</string>
+    <string name="miniresolver_open_in_personal" msgid="3874522693661065566">"Želite da na ličnom profilu otvorite: <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_work" msgid="4415223793669536559">"Želite da na poslovnom profilu otvorite: <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Koristi lični pregledač"</string>
+    <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Koristi poslovni pregledač"</string>
+    <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN za otključavanje SIM mreže"</string>
+    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN za otključavanje podskupa SIM mreže"</string>
+    <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN za otključavanje poslovne SIM kartice"</string>
+    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_ENTRY" msgid="973059024670737358">"PIN za otključavanje dobavljača usluge SIM kartice"</string>
+    <string name="PERSOSUBSTATE_SIM_SIM_ENTRY" msgid="4487435301206073787">"PIN za otključavanje SIM kartice"</string>
+    <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_ENTRY" msgid="768060297218652809">"Unesite PUK"</string>
+    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_ENTRY" msgid="7129527319490548930">"Unesite PUK"</string>
+    <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_ENTRY" msgid="2876126640607573252">"Unesite PUK"</string>
+    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_ENTRY" msgid="8952595089930109282">"Unesite PUK"</string>
+    <string name="PERSOSUBSTATE_SIM_SIM_PUK_ENTRY" msgid="3013902515773728996">"Unesite PUK"</string>
+    <string name="PERSOSUBSTATE_RUIM_NETWORK1_ENTRY" msgid="2974411408893410289">"PIN za otključavanje RUIM mreže 1"</string>
+    <string name="PERSOSUBSTATE_RUIM_NETWORK2_ENTRY" msgid="687618528751880721">"PIN za otključavanje RUIM mreže 2"</string>
+    <string name="PERSOSUBSTATE_RUIM_HRPD_ENTRY" msgid="6810596579655575381">"PIN za otključavanje RUIM hrpd-a"</string>
+    <string name="PERSOSUBSTATE_RUIM_CORPORATE_ENTRY" msgid="2715929642540980259">"PIN za otključavanje poslovne RUIM kartice"</string>
+    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_ENTRY" msgid="8557791623303951590">"PIN za otključavanje RUIM kartice dobavljača usluge"</string>
+    <string name="PERSOSUBSTATE_RUIM_RUIM_ENTRY" msgid="7382468767274580323">"PIN za otključavanje RUIM kartice"</string>
+    <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_ENTRY" msgid="6730880791104286987">"Unesite PUK"</string>
+    <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_ENTRY" msgid="6432126539782267026">"Unesite PUK"</string>
+    <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_ENTRY" msgid="1730510161529488920">"Unesite PUK"</string>
+    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_ENTRY" msgid="3369885925003346830">"Unesite PUK"</string>
+    <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_ENTRY" msgid="9129139686191167829">"Unesite PUK"</string>
+    <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_ENTRY" msgid="2869929685874615358">"Unesite PUK"</string>
+    <string name="PERSOSUBSTATE_SIM_SPN_ENTRY" msgid="1238663472392741771">"PIN za otključavanje SPN-a"</string>
+    <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_ENTRY" msgid="3988705848553894358">"PIN za otključavanje SP ekvivalentnog matičnog PLMN-a"</string>
+    <string name="PERSOSUBSTATE_SIM_ICCID_ENTRY" msgid="6186770686690993200">"PIN za otključavanje ICCID-a"</string>
+    <string name="PERSOSUBSTATE_SIM_IMPI_ENTRY" msgid="7043865376145617024">"PIN za otključavanje IMPI-ja"</string>
+    <string name="PERSOSUBSTATE_SIM_NS_SP_ENTRY" msgid="6144227308185112176">"PIN za otključavanje dobavljača usluge podskupa mreže"</string>
+    <string name="PERSOSUBSTATE_SIM_NETWORK_IN_PROGRESS" msgid="4233355366318061180">"Zahteva se otključavanje SIM mreže…"</string>
+    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_IN_PROGRESS" msgid="6742563947637715645">"Zahteva se otključavanje podskupa SIM mreže…"</string>
+    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_IN_PROGRESS" msgid="2033399698172403560">"Zahteva se otključavanje dobavljača usluge SIM kartice…"</string>
+    <string name="PERSOSUBSTATE_SIM_CORPORATE_IN_PROGRESS" msgid="4795977251920732254">"Zahteva se otključavanje poslovne SIM kartice…"</string>
+    <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_IN_PROGRESS" msgid="1090425878157254446">"Zahteva se otključavanje pomoću PUK-a…"</string>
+    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_IN_PROGRESS" msgid="6476898876518094438">"Zahteva se otključavanje pomoću PUK-a…"</string>
+    <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_IN_PROGRESS" msgid="6006806734293747731">"Zahteva se otključavanje pomoću PUK-a…"</string>
+    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_IN_PROGRESS" msgid="6546680489620881893">"Zahteva se otključavanje pomoću PUK-a…"</string>
+    <string name="PERSOSUBSTATE_SIM_SIM_PUK_IN_PROGRESS" msgid="3506845511000727015">"Zahteva se otključavanje pomoću PUK-a…"</string>
+    <string name="PERSOSUBSTATE_SIM_SIM_IN_PROGRESS" msgid="6709169861932992750">"Zahteva se otključavanje SIM kartice…"</string>
+    <string name="PERSOSUBSTATE_RUIM_NETWORK1_IN_PROGRESS" msgid="4013870911606478520">"Zahteva se otključavanje RUIM mreže 1…"</string>
+    <string name="PERSOSUBSTATE_RUIM_NETWORK2_IN_PROGRESS" msgid="9032651188219523434">"Zahteva se otključavanje RUIM mreže 2…"</string>
+    <string name="PERSOSUBSTATE_RUIM_HRPD_IN_PROGRESS" msgid="6584576506344491207">"Zahteva se otključavanje RUIM hrpd-a…"</string>
+    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_IN_PROGRESS" msgid="830981927724888114">"Zahteva se otključavanje RUIM kartice dobavljača usluge…"</string>
+    <string name="PERSOSUBSTATE_RUIM_CORPORATE_IN_PROGRESS" msgid="7851790973098894802">"Zahteva se otključavanje poslovne RUIM kartice…"</string>
+    <string name="PERSOSUBSTATE_SIM_SPN_IN_PROGRESS" msgid="1149560739586960121">"Zahteva se otključavanje SPN-a…"</string>
+    <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_IN_PROGRESS" msgid="5708964693522116025">"Zahteva se otključavanje SP ekvivalentnog matičnog PLMN-a…"</string>
+    <string name="PERSOSUBSTATE_SIM_ICCID_IN_PROGRESS" msgid="7288103122966483455">"Zahteva se otključavanje ICCID-a…"</string>
+    <string name="PERSOSUBSTATE_SIM_IMPI_IN_PROGRESS" msgid="4036752174056147753">"Zahteva se otključavanje IMPI-ja…"</string>
+    <string name="PERSOSUBSTATE_SIM_NS_SP_IN_PROGRESS" msgid="5089536274515338566">"Zahteva se otključavanje dobavljača usluge podskupa mreže…"</string>
+    <string name="PERSOSUBSTATE_RUIM_RUIM_IN_PROGRESS" msgid="6737197986936251958">"Zahteva se otključavanje RUIM kartice…"</string>
+    <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_IN_PROGRESS" msgid="5658767775619998623">"Zahteva se otključavanje pomoću PUK-a…"</string>
+    <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_IN_PROGRESS" msgid="665978313257653727">"Zahteva se otključavanje pomoću PUK-a…"</string>
+    <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_IN_PROGRESS" msgid="3857142652251836850">"Zahteva se otključavanje pomoću PUK-a…"</string>
+    <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_IN_PROGRESS" msgid="2695664012344346788">"Zahteva se otključavanje pomoću PUK-a…"</string>
+    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_IN_PROGRESS" msgid="2695678959963807782">"Zahteva se otključavanje pomoću PUK-a…"</string>
+    <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_IN_PROGRESS" msgid="1230605365926493599">"Zahteva se otključavanje pomoću PUK-a…"</string>
+    <string name="PERSOSUBSTATE_SIM_NETWORK_ERROR" msgid="1924844017037151535">"Zahtev za otključavanje SIM mreže nije uspeo."</string>
+    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ERROR" msgid="3372797822292089708">"Zahtev za otključavanje podskupa SIM mreže je uspeo."</string>
+    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_ERROR" msgid="1878443146720411381">"Zahtev za otključavanje dobavljača usluge SIM kartice nije uspeo."</string>
+    <string name="PERSOSUBSTATE_SIM_CORPORATE_ERROR" msgid="7664778312218023192">"Zahtev za otključavanje poslovne SIM kartice nije uspeo."</string>
+    <string name="PERSOSUBSTATE_SIM_SIM_ERROR" msgid="2472944311643350302">"Zahtev za otključavanje SIM kartice nije uspeo."</string>
+    <string name="PERSOSUBSTATE_RUIM_NETWORK1_ERROR" msgid="828089694480999120">"Zahtev za otključavanje RUIM mreže 1 nije uspeo."</string>
+    <string name="PERSOSUBSTATE_RUIM_NETWORK2_ERROR" msgid="17619001007092511">"Zahtev za otključavanje RUIM mreže 2 nije uspeo."</string>
+    <string name="PERSOSUBSTATE_RUIM_HRPD_ERROR" msgid="807214229604353614">"Zahtev za otključavanje RUIM hrpd-a nije uspeo."</string>
+    <string name="PERSOSUBSTATE_RUIM_CORPORATE_ERROR" msgid="8644184447744175747">"Zahtev za otključavanje poslovne RUIM kartice nije uspeo."</string>
+    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_ERROR" msgid="3801002648649640407">"Zahtev za otključavanje RUIM kartice dobavljača usluge nije uspeo."</string>
+    <string name="PERSOSUBSTATE_RUIM_RUIM_ERROR" msgid="707397021218680753">"Zahtev za otključavanje RUIM kartice nije uspeo."</string>
+    <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_ERROR" msgid="894358680773257820">"Otključavanje pomoću PUK-a nije uspelo."</string>
+    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_ERROR" msgid="352466878146726991">"Otključavanje pomoću PUK-a nije uspelo."</string>
+    <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_ERROR" msgid="7353389721907138671">"Otključavanje pomoću PUK-a nije uspelo."</string>
+    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_ERROR" msgid="2655263155490857920">"Otključavanje pomoću PUK-a nije uspelo."</string>
+    <string name="PERSOSUBSTATE_SIM_SIM_PUK_ERROR" msgid="6903740900892931310">"Otključavanje pomoću PUK-a nije uspelo."</string>
+    <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_ERROR" msgid="5165901670447518687">"Otključavanje pomoću PUK-a nije uspelo."</string>
+    <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_ERROR" msgid="2856763216589267623">"Otključavanje pomoću PUK-a nije uspelo."</string>
+    <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_ERROR" msgid="817542684437829139">"Otključavanje pomoću PUK-a nije uspelo."</string>
+    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_ERROR" msgid="5178635064113393143">"Otključavanje pomoću PUK-a nije uspelo."</string>
+    <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_ERROR" msgid="5391587926974531008">"Otključavanje pomoću PUK-a nije uspelo."</string>
+    <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_ERROR" msgid="4895494864493315868">"Otključavanje pomoću PUK-a nije uspelo."</string>
+    <string name="PERSOSUBSTATE_SIM_SPN_ERROR" msgid="9017576601595353649">"Zahtev za otključavanje SPN-a nije uspeo."</string>
+    <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_ERROR" msgid="1116993930995545742">"Zahtev za otključavanje SP ekvivalentnog matičnog PLMN-a nije uspeo."</string>
+    <string name="PERSOSUBSTATE_SIM_ICCID_ERROR" msgid="7559167306794441462">"Zahtev za otključavanje ICCID-a nije uspeo."</string>
+    <string name="PERSOSUBSTATE_SIM_IMPI_ERROR" msgid="2782926139511136588">"Zahtev za otključavanje IMPI-ja nije uspeo."</string>
+    <string name="PERSOSUBSTATE_SIM_NS_SP_ERROR" msgid="1890493954453456758">"Zahtev za otključavanje dobavljača usluge podskupa mreže nije uspeo."</string>
+    <string name="PERSOSUBSTATE_SIM_NETWORK_SUCCESS" msgid="4886243367747126325">"Otključavanje SIM mreže je uspelo."</string>
+    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_SUCCESS" msgid="4053809277733513987">"Otključavanje podskupa SIM mreže je uspelo."</string>
+    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_SUCCESS" msgid="8249342930499801740">"Otključavanje dobavljača usluge SIM kartice je uspelo."</string>
+    <string name="PERSOSUBSTATE_SIM_CORPORATE_SUCCESS" msgid="2339794542560381270">"Otključavanje poslovne SIM kartice je uspelo."</string>
+    <string name="PERSOSUBSTATE_SIM_SIM_SUCCESS" msgid="6975608174152828954">"Otključavanje SIM kartice je uspelo."</string>
+    <string name="PERSOSUBSTATE_RUIM_NETWORK1_SUCCESS" msgid="2846699261330463192">"Otključavanje RUIM mreže 1 je uspelo."</string>
+    <string name="PERSOSUBSTATE_RUIM_NETWORK2_SUCCESS" msgid="5335414726057102801">"Otključavanje RUIM mreže 2 je uspelo."</string>
+    <string name="PERSOSUBSTATE_RUIM_HRPD_SUCCESS" msgid="8868100318474971969">"Otključavanje RUIM hrpd-a je uspelo."</string>
+    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_SUCCESS" msgid="6020936629725666932">"Zahtev za otključavanje RUIM kartice dobavljača usluge je uspeo."</string>
+    <string name="PERSOSUBSTATE_RUIM_CORPORATE_SUCCESS" msgid="6944873647584595489">"Otključavanje poslovne RUIM kartice je uspelo."</string>
+    <string name="PERSOSUBSTATE_RUIM_RUIM_SUCCESS" msgid="2526483514124121988">"Otključavanje RUIM kartice je uspelo."</string>
+    <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_SUCCESS" msgid="7662200333621664621">"Otključavanje pomoću PUK-a je uspelo."</string>
+    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_SUCCESS" msgid="2861223407953766632">"Otključavanje pomoću PUK-a je uspelo."</string>
+    <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_SUCCESS" msgid="5345648571175243272">"Otključavanje pomoću PUK-a je uspelo."</string>
+    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_SUCCESS" msgid="3725278343103422466">"Otključavanje pomoću PUK-a je uspelo."</string>
+    <string name="PERSOSUBSTATE_SIM_SIM_PUK_SUCCESS" msgid="6998502547560297983">"Otključavanje pomoću PUK-a je uspelo."</string>
+    <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_SUCCESS" msgid="8555433771162560361">"Otključavanje pomoću PUK-a je uspelo."</string>
+    <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_SUCCESS" msgid="3555767296933606232">"Otključavanje pomoću PUK-a je uspelo."</string>
+    <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_SUCCESS" msgid="6778051818199974237">"Otključavanje pomoću PUK-a je uspelo."</string>
+    <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_SUCCESS" msgid="4080108758498911429">"Otključavanje pomoću PUK-a je uspelo."</string>
+    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_SUCCESS" msgid="7873675303000794343">"Otključavanje pomoću PUK-a je uspelo."</string>
+    <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_SUCCESS" msgid="1763198215069819523">"Otključavanje pomoću PUK-a je uspelo."</string>
+    <string name="PERSOSUBSTATE_SIM_SPN_SUCCESS" msgid="2053891977727320532">"Otključavanje SPN-a je uspelo."</string>
+    <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_SUCCESS" msgid="8146602361895007345">"Otključavanje SP ekvivalentnog matičnog PLMN-a je uspelo."</string>
+    <string name="PERSOSUBSTATE_SIM_ICCID_SUCCESS" msgid="8058678548991999545">"Otključavanje ICCID-a je uspelo."</string>
+    <string name="PERSOSUBSTATE_SIM_IMPI_SUCCESS" msgid="2545608067978550571">"Otključavanje IMPI-ja je uspelo."</string>
+    <string name="PERSOSUBSTATE_SIM_NS_SP_SUCCESS" msgid="4352382949744625007">"Zahtev za otključavanje dobavljača usluge podskupa mreže je uspeo."</string>
     <string name="config_pdp_reject_dialog_title" msgid="4072057179246785727"></string>
     <string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
-    <string name="window_magnification_prompt_title" msgid="2876703640772778215">"Нова подешавања увећања"</string>
-    <string name="window_magnification_prompt_content" msgid="8159173903032344891">"Сада можете да увећате део екрана"</string>
-    <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Укључите у Подешавањима"</string>
-    <string name="dismiss_action" msgid="1728820550388704784">"Одбаци"</string>
-    <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Одблокирајте микрофон уређаја"</string>
-    <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Одблокирајте камеру уређаја"</string>
-    <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"За &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; и све апликације и услуге"</string>
-    <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Одблокирај"</string>
-    <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Приватност сензора"</string>
-    <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Икона апликације"</string>
-    <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Имиџ бренда апликације"</string>
-    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Проверите подешавања приступа"</string>
-    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> може да прегледа и контролише екран. Додирните да бисте прегледали."</string>
-    <string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> Преведено."</string>
-    <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Порука је преведена са језика <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> на <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
-    <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Активност у позадини"</string>
-    <string name="notification_title_abusive_bg_apps" msgid="994230770856147656">"Апликација вам празни батерију"</string>
-    <string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Апликација је и даље активна"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"Апликација <xliff:g id="APP">%1$s</xliff:g> ради у позадини. Додирните да бисте управљали потрошњом батерије."</string>
-    <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> може да утиче на трајање батерије. Додирните да бисте прегледали активне апликације."</string>
-    <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Проверите активне апликације"</string>
-    <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Не може да се приступи камери телефона са <xliff:g id="DEVICE">%1$s</xliff:g> уређаја"</string>
-    <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Не може да се приступи камери таблета са <xliff:g id="DEVICE">%1$s</xliff:g> уређаја"</string>
-    <string name="vdm_secure_window" msgid="161700398158812314">"Овом не можете да приступате током стримовања. Пробајте на телефону."</string>
-    <string name="system_locale_title" msgid="711882686834677268">"Подразумевани системски"</string>
+    <string name="window_magnification_prompt_title" msgid="2876703640772778215">"Nova podešavanja uvećanja"</string>
+    <string name="window_magnification_prompt_content" msgid="8159173903032344891">"Sada možete da uvećate deo ekrana"</string>
+    <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Uključite u Podešavanjima"</string>
+    <string name="dismiss_action" msgid="1728820550388704784">"Odbaci"</string>
+    <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Odblokirajte mikrofon uređaja"</string>
+    <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Odblokirajte kameru uređaja"</string>
+    <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Za &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; i sve aplikacije i usluge"</string>
+    <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Odblokiraj"</string>
+    <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privatnost senzora"</string>
+    <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikona aplikacije"</string>
+    <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imidž brenda aplikacije"</string>
+    <string name="view_and_control_notification_title" msgid="4300765399209912240">"Proverite podešavanja pristupa"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> može da pregleda i kontroliše ekran. Dodirnite da biste pregledali."</string>
+    <string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> Prevedeno."</string>
+    <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Poruka je prevedena sa jezika <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> na <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
+    <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Aktivnost u pozadini"</string>
+    <string name="notification_title_abusive_bg_apps" msgid="994230770856147656">"Aplikacija vam prazni bateriju"</string>
+    <string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Aplikacija je i dalje aktivna"</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> radi u pozadini. Dodirnite da biste upravljali potrošnjom baterije."</string>
+    <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> može da utiče na trajanje baterije. Dodirnite da biste pregledali aktivne aplikacije."</string>
+    <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Proverite aktivne aplikacije"</string>
+    <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ne može da se pristupi kameri telefona sa <xliff:g id="DEVICE">%1$s</xliff:g> uređaja"</string>
+    <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ne može da se pristupi kameri tableta sa <xliff:g id="DEVICE">%1$s</xliff:g> uređaja"</string>
+    <string name="vdm_secure_window" msgid="161700398158812314">"Ovom ne možete da pristupate tokom strimovanja. Probajte na telefonu."</string>
+    <string name="system_locale_title" msgid="711882686834677268">"Podrazumevani sistemski"</string>
 </resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 80384ad..35f08cc 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -1530,7 +1530,7 @@
     <string name="sync_undo_deletes" msgid="5786033331266418896">"Poništiti brisanje"</string>
     <string name="sync_do_nothing" msgid="4528734662446469646">"Ne radi ništa za sada"</string>
     <string name="choose_account_label" msgid="5557833752759831548">"Odaberite račun"</string>
-    <string name="add_account_label" msgid="4067610644298737417">"Dodaj račun"</string>
+    <string name="add_account_label" msgid="4067610644298737417">"Dodajte račun"</string>
     <string name="add_account_button_label" msgid="322390749416414097">"Dodajte račun"</string>
     <string name="number_picker_increment_button" msgid="7621013714795186298">"Povećaj"</string>
     <string name="number_picker_decrement_button" msgid="5116948444762708204">"Smanji"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index eece25d..ea61fea 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -327,7 +327,7 @@
     <string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string>
     <string name="permgroupdesc_phone" msgid="270048070781478204">"uskutečňování a spravování telefonních hovorů"</string>
     <string name="permgrouplab_sensors" msgid="9134046949784064495">"Tělesné senzory"</string>
-    <string name="permgroupdesc_sensors" msgid="2610631290633747752">"přístup k datům ze snímačů vašich životních funkcí"</string>
+    <string name="permgroupdesc_sensors" msgid="2610631290633747752">"přístup k datům ze senzorů vašich životních funkcí"</string>
     <string name="permgrouplab_notifications" msgid="5472972361980668884">"Oznámení"</string>
     <string name="permgroupdesc_notifications" msgid="4608679556801506580">"zobrazovat oznámení"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Načítat obsah oken"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 1fe2b99..ca619b3 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -586,11 +586,11 @@
     <string name="biometric_error_generic" msgid="6784371929985434439">"Der opstod fejl i forbindelse med godkendelse"</string>
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Brug skærmlås"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Angiv din skærmlås for at fortsætte"</string>
-    <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Hold fingeren nede på sensoren"</string>
+    <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Hold fingeren på sensoren"</string>
     <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Fingeraftrykket kan ikke genkendes. Prøv igen."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Rengør fingeraftrykssensoren, og prøv igen"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Rengør sensoren, og prøv igen"</string>
-    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Hold fingeren nede på sensoren"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Hold fingeren på sensoren"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Du bevægede fingeren for langsomt. Prøv igen."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prøv med et andet fingeraftryk"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Der er for lyst"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 64d390e..876d3a1 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1681,13 +1681,13 @@
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Verknüpfung für Bedienungshilfen aktivieren?"</string>
     <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Wenn du beide Lautstärketasten einige Sekunden lang gedrückt hältst, aktivierst du die Bedienungshilfen. Dadurch kann sich die Funktionsweise deines Geräts ändern.\n\nAktuelle Funktionen:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nDu kannst ausgewählte Funktionen unter \"Einstellungen\" &gt; \"Bedienungshilfen\" ändern."</string>
     <string name="accessibility_shortcut_multiple_service_list" msgid="2128323171922023762">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
-    <string name="accessibility_shortcut_single_service_warning_title" msgid="1909518473488345266">"Verknüpfung für <xliff:g id="SERVICE">%1$s</xliff:g> aktivieren?"</string>
+    <string name="accessibility_shortcut_single_service_warning_title" msgid="1909518473488345266">"Kurzbefehl für <xliff:g id="SERVICE">%1$s</xliff:g> aktivieren?"</string>
     <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Wenn du beide Lautstärketasten einige Sekunden lang gedrückt hältst, aktivierst du die Bedienungshilfe \"<xliff:g id="SERVICE">%1$s</xliff:g>\". Dadurch kann sich die Funktionsweise deines Geräts ändern.\n\nUnter \"Einstellungen &gt; \"Bedienungshilfen\" kannst du dieser Verknüpfung eine andere Funktion zuweisen."</string>
     <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Aktivieren"</string>
     <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Nicht aktivieren"</string>
     <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"AN"</string>
     <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"AUS"</string>
-    <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> die vollständige Kontrolle über dein Gerät geben?"</string>
+    <string name="accessibility_enable_service_title" msgid="3931558336268541484">"„<xliff:g id="SERVICE">%1$s</xliff:g>“ die vollständige Kontrolle über dein Gerät geben?"</string>
     <string name="accessibility_service_warning_description" msgid="291674995220940133">"Die vollständige Kontrolle sollte nur für Apps aktiviert werden, die dir Zugang zu App-Funktionen erleichtern. Das ist in der Regel nur ein kleiner Teil der Apps."</string>
     <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Bildschirm aufrufen und steuern"</string>
     <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Die Funktion kann alle Inhalte auf dem Bildschirm lesen und diese Inhalte über andere Apps anzeigen."</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index e60a96e..ce02af2 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -78,7 +78,7 @@
     <string name="CLIRDefaultOffNextCallOff" msgid="2491576172356463443">"Deitzailearen identitatea zerbitzuaren balio lehenetsiak ez du murriztapenik ezartzen. Hurrengo deia: murriztapenik gabe."</string>
     <string name="serviceNotProvisioned" msgid="8289333510236766193">"Zerbitzua ez da hornitu."</string>
     <string name="CLIRPermanent" msgid="166443681876381118">"Ezin duzu aldatu deitzailearen identitatearen ezarpena."</string>
-    <string name="RestrictedOnDataTitle" msgid="1500576417268169774">"Ez dago mugikorreko datu-zerbitzurik"</string>
+    <string name="RestrictedOnDataTitle" msgid="1500576417268169774">"Ez dago mugikorretarako datu-zerbitzurik"</string>
     <string name="RestrictedOnEmergencyTitle" msgid="2852916906106191866">"Ezin da egin larrialdi-deirik"</string>
     <string name="RestrictedOnNormalTitle" msgid="7009474589746551737">"Ez dago ahots-deien zerbitzurik"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="3982069078579103087">"Ez dago ahozko zerbitzurik eta ezin da egin larrialdi-deirik"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index c4fe972a..c81bf00 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -299,11 +299,11 @@
     <string name="user_owner_label" msgid="8628726904184471211">"Vaihda henkilökohtaiseen profiiliin"</string>
     <string name="managed_profile_label" msgid="7316778766973512382">"Vaihda työprofiiliin"</string>
     <string name="permgrouplab_contacts" msgid="4254143639307316920">"Yhteystiedot"</string>
-    <string name="permgroupdesc_contacts" msgid="9163927941244182567">"käyttää yhteystietoja"</string>
+    <string name="permgroupdesc_contacts" msgid="9163927941244182567">"pääsy yhteystietoihin"</string>
     <string name="permgrouplab_location" msgid="1858277002233964394">"Sijainti"</string>
-    <string name="permgroupdesc_location" msgid="1995955142118450685">"käyttää laitteen sijaintia"</string>
+    <string name="permgroupdesc_location" msgid="1995955142118450685">"pääsy laitteen sijaintiin"</string>
     <string name="permgrouplab_calendar" msgid="6426860926123033230">"Kalenteri"</string>
-    <string name="permgroupdesc_calendar" msgid="6762751063361489379">"käyttää kalenteria"</string>
+    <string name="permgroupdesc_calendar" msgid="6762751063361489379">"pääsy kalenteriin"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Tekstiviestit"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"lähettää ja tarkastella tekstiviestejä"</string>
     <string name="permgrouplab_storage" msgid="17339216290379241">"Tiedostot"</string>
@@ -313,7 +313,7 @@
     <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Valokuvat ja videot"</string>
     <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"pääsy laitteen kuviin ja videoihin"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofoni"</string>
-    <string name="permgroupdesc_microphone" msgid="1047786732792487722">"tallentaa ääntä"</string>
+    <string name="permgroupdesc_microphone" msgid="1047786732792487722">"tallentaa audiota"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Liikkuminen"</string>
     <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"nähdä liikkumistietosi"</string>
     <string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
@@ -325,7 +325,7 @@
     <string name="permgrouplab_phone" msgid="570318944091926620">"Puhelin"</string>
     <string name="permgroupdesc_phone" msgid="270048070781478204">"soittaa ja hallinnoida puheluita"</string>
     <string name="permgrouplab_sensors" msgid="9134046949784064495">"Kehon anturit"</string>
-    <string name="permgroupdesc_sensors" msgid="2610631290633747752">"käyttää anturitietoja elintoiminnoistasi"</string>
+    <string name="permgroupdesc_sensors" msgid="2610631290633747752">"pääsy anturidataan elintoiminnoistasi"</string>
     <string name="permgrouplab_notifications" msgid="5472972361980668884">"Ilmoitukset"</string>
     <string name="permgroupdesc_notifications" msgid="4608679556801506580">"näyttää ilmoituksia"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Noutaa ikkunan sisältöä"</string>
@@ -448,7 +448,7 @@
     <string name="permdesc_accessBackgroundLocation" msgid="8264885066095638105">"Tällä sovelluksella on pääsy sijaintitietoihin milloin tahansa, myös silloin kun sovellusta ei käytetä."</string>
     <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"muuta ääniasetuksia"</string>
     <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Antaa sovelluksen muokata yleisiä ääniasetuksia, kuten äänenvoimakkuutta ja käytettävää kaiutinta."</string>
-    <string name="permlab_recordAudio" msgid="1208457423054219147">"tallentaa ääntä"</string>
+    <string name="permlab_recordAudio" msgid="1208457423054219147">"tallentaa audiota"</string>
     <string name="permdesc_recordAudio" msgid="5857246765327514062">"Tämä sovellus voi tallentaa mikrofonilla audiota, kun sovellusta käytetään."</string>
     <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"tallentaa audiota taustalla"</string>
     <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Tämä sovellus voi tallentaa mikrofonilla audiota koska tahansa."</string>
@@ -1173,7 +1173,7 @@
     <string name="selected" msgid="6614607926197755875">"valittu"</string>
     <string name="not_selected" msgid="410652016565864475">"ei valittu"</string>
     <string name="in_progress" msgid="2149208189184319441">"käynnissä"</string>
-    <string name="whichApplication" msgid="5432266899591255759">"Tee toiminto käyttäen sovellusta"</string>
+    <string name="whichApplication" msgid="5432266899591255759">"Tee toiminto käyttäen:"</string>
     <string name="whichApplicationNamed" msgid="6969946041713975681">"Suorita sovelluksella %1$s"</string>
     <string name="whichApplicationLabel" msgid="7852182961472531728">"Suorita toiminto"</string>
     <string name="whichViewApplication" msgid="5733194231473132945">"Avaa sovelluksessa"</string>
@@ -1972,7 +1972,7 @@
     <string name="pin_specific_target" msgid="7824671240625957415">"Kiinnitä <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="unpin_target" msgid="3963318576590204447">"Irrota"</string>
     <string name="unpin_specific_target" msgid="3859828252160908146">"Irrota <xliff:g id="LABEL">%1$s</xliff:g>"</string>
-    <string name="app_info" msgid="6113278084877079851">"Sovelluksen tiedot"</string>
+    <string name="app_info" msgid="6113278084877079851">"Sovellustiedot"</string>
     <string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="6577581216125805905">"Aloitetaan esittelyä…"</string>
     <string name="demo_restarting_message" msgid="1160053183701746766">"Palautetaan asetuksia…"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index dcde676..2a472f8 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1630,7 +1630,7 @@
     <string name="media_route_status_connecting" msgid="5845597961412010540">"कनेक्ट हो रहा है..."</string>
     <string name="media_route_status_available" msgid="1477537663492007608">"मौजूद"</string>
     <string name="media_route_status_not_available" msgid="480912417977515261">"उपलब्‍ध नहीं"</string>
-    <string name="media_route_status_in_use" msgid="6684112905244944724">"उपयोग में"</string>
+    <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>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 7d24662..8b27a9e 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -176,7 +176,7 @@
     <string name="notification_title" msgid="5783748077084481121">"<xliff:g id="ACCOUNT">%1$s</xliff:g> үшін кіру қателігі"</string>
     <string name="contentServiceSync" msgid="2341041749565687871">"Синх"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="5766411446676388623">"Синхрондау мүмкін емес"</string>
-    <string name="contentServiceTooManyDeletesNotificationDesc" msgid="4562226280528716090">"Көптеген <xliff:g id="CONTENT_TYPE">%s</xliff:g> мазмұнын жоюға әрекет жасалды."</string>
+    <string name="contentServiceTooManyDeletesNotificationDesc" msgid="4562226280528716090">"Көптеген <xliff:g id="CONTENT_TYPE">%s</xliff:g> контентін жоюға әрекет жасалды."</string>
     <string name="low_memory" product="tablet" msgid="5557552311566179924">"Планшет жады толы. Орын босату үшін кейбір файлдарды жойыңыз."</string>
     <string name="low_memory" product="watch" msgid="3479447988234030194">"Сағат жады толы. Орын босату үшін кейбір файлдарды жойыңыз."</string>
     <string name="low_memory" product="tv" msgid="6663680413790323318">"Android TV құрылғысының жады толы. Орын босату үшін кейбір файлдарды өшіріп тастаңыз."</string>
@@ -328,8 +328,8 @@
     <string name="permgroupdesc_sensors" msgid="2610631290633747752">"ағза күйінің көрсеткіштері туралы сенсор деректеріне қатынасу"</string>
     <string name="permgrouplab_notifications" msgid="5472972361980668884">"Хабарландырулар"</string>
     <string name="permgroupdesc_notifications" msgid="4608679556801506580">"хабарландыруларды көрсету"</string>
-    <string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Терезе мазмұнын оқып отыру"</string>
-    <string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Ашық тұрған терезе мазмұнын тексеру."</string>
+    <string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Терезе контентін оқып отыру"</string>
+    <string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Ашық тұрған терезе контентін тексеру."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Түртілген элементтерді дыбыстау функциясын қосу"</string>
     <string name="capability_desc_canRequestTouchExploration" msgid="4394677060796752976">"Түртілген элементтер дауыстап айтылады және экранды қимылдар арқылы зерттеуге болады."</string>
     <string name="capability_title_canRequestFilterKeyEvents" msgid="2772371671541753254">"Терілген мәтінді тексеру"</string>
@@ -631,7 +631,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">"Face Unlock функциясын пайдалану үшін \"Параметрлер &gt; Құпиялылық\" бөлімінен "<b>"Камераны пайдалану рұқсатын"</b>" қосыңыз."</string>
+    <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Face Unlock функциясын пайдалану үшін \"Параметрлер &gt; Құпиялық\" бөлімінен "<b>"Камераны пайдалану рұқсатын"</b>" қосыңыз."</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>
@@ -1065,7 +1065,7 @@
     <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> қолданбасы буферіңізден алынған деректерді қойды."</string>
     <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> сіз көшірген мәтінді қойды."</string>
     <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> сіз көшірген суретті қойды."</string>
-    <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> сіз көшірген мазмұнды қойды."</string>
+    <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> сіз көшірген контентті қойды."</string>
     <string name="more_item_label" msgid="7419249600215749115">"Көбірек"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Mәзір+"</string>
     <string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
@@ -1399,14 +1399,14 @@
     <string name="alert_windows_notification_message" msgid="6538171456970725333">"<xliff:g id="NAME">%s</xliff:g> деген пайдаланушының бұл функцияны пайдалануына жол бермеу үшін параметрлерді түртіп ашыңыз да, оларды өшіріңіз."</string>
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Өшіру"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> тексеріліп жатыр…"</string>
-    <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Ағымдағы мазмұн тексерілуде"</string>
+    <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Ағымдағы контент тексерілуде"</string>
     <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Мультимедиа жады талдануда"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Жаңа <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> жұмыс істемейді"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Реттеу үшін түртіңіз"</string>
     <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Реттеу үшін таңдаңыз."</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Құрылғыны қайта форматтау қажет болуы мүмкін. Шығару үшін түртіңіз."</string>
-    <string name="ext_media_ready_notification_message" msgid="7509496364380197369">"Фотосуреттерді, бейнелерді, музыка мен басқа мазмұнды сақтау үшін"</string>
+    <string name="ext_media_ready_notification_message" msgid="7509496364380197369">"Фотосуреттерді, бейнелерді, музыка мен басқа контентті сақтау үшін"</string>
     <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Медиа файлдарды таңдаңыз."</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g> ақаулы"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> жұмыс істемейді"</string>
@@ -1419,7 +1419,7 @@
     <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"<xliff:g id="NAME">%s</xliff:g> құрылғысын қолдау көрсетілетін форматта реттеу үшін таңдаңыз."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Құрылғыны қайта форматтау қажет болуы мүмкін."</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> кенеттен шығарылды"</string>
-    <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Мазмұнды жоғалтып алмау үшін ақпарат тасығышты алдымен ажыратыңыз, содан кейін барып шығарыңыз."</string>
+    <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Контентті жоғалтып алмау үшін ақпарат тасығышты алдымен ажыратыңыз, содан кейін барып шығарыңыз."</string>
     <string name="ext_media_nomedia_notification_title" msgid="742671636376975890">"<xliff:g id="NAME">%s</xliff:g> жоқ"</string>
     <string name="ext_media_nomedia_notification_message" msgid="2832724384636625852">"Кейбір функциялар дұрыс жұмыс істемеуі мүмкін. Жаңа жад құрылғысын енгізіңіз."</string>
     <string name="ext_media_unmounting_notification_title" msgid="4147986383917892162">"<xliff:g id="NAME">%s</xliff:g> ажыратылуда"</string>
@@ -1432,10 +1432,10 @@
     <string name="ext_media_missing_message" msgid="4408988706227922909">"Құрылғыны қайта салыңыз"</string>
     <string name="ext_media_move_specific_title" msgid="8492118544775964250">"<xliff:g id="NAME">%s</xliff:g> тасымалдануда"</string>
     <string name="ext_media_move_title" msgid="2682741525619033637">"Деректер тасымалдануда"</string>
-    <string name="ext_media_move_success_title" msgid="4901763082647316767">"Мазмұн жіберілді"</string>
-    <string name="ext_media_move_success_message" msgid="9159542002276982979">"Мазмұн <xliff:g id="NAME">%s</xliff:g> жадына тасымалданды"</string>
-    <string name="ext_media_move_failure_title" msgid="3184577479181333665">"Мазмұн тасымалданбады"</string>
-    <string name="ext_media_move_failure_message" msgid="4197306718121869335">"Мазмұнды қайта тасымалдап көріңіз"</string>
+    <string name="ext_media_move_success_title" msgid="4901763082647316767">"Контент жіберілді"</string>
+    <string name="ext_media_move_success_message" msgid="9159542002276982979">"Контент <xliff:g id="NAME">%s</xliff:g> жадына тасымалданды"</string>
+    <string name="ext_media_move_failure_title" msgid="3184577479181333665">"Контент тасымалданбады"</string>
+    <string name="ext_media_move_failure_message" msgid="4197306718121869335">"Контентті қайта тасымалдап көріңіз"</string>
     <string name="ext_media_status_removed" msgid="241223931135751691">"Алынды"</string>
     <string name="ext_media_status_unmounted" msgid="8145812017295835941">"Ажыратылды"</string>
     <string name="ext_media_status_checking" msgid="159013362442090347">"Тексерілуде…"</string>
@@ -1690,7 +1690,7 @@
     <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> қызметіне құрылғыны толық басқаруға рұқсат етілсін бе?"</string>
     <string name="accessibility_service_warning_description" msgid="291674995220940133">"Арнайы мүмкіндіктер бойынша көмектесетін қолданбаларға ғана құрылғыны толық басқару рұқсатын берген дұрыс."</string>
     <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Экранды көру және басқару"</string>
-    <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Ол экрандағы мазмұнды толық оқиды және мазмұнды басқа қолданбалардың үстінен көрсете алады."</string>
+    <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Ол экрандағы контентті толық оқиды және контентті басқа қолданбалардың үстінен көрсете алады."</string>
     <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Әрекеттерді көру және орындау"</string>
     <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Ол қолданбамен немесе жабдық датчигімен істеген тапсырмаларыңызды бақылайды және қолданбаларды сіздің атыңыздан пайдаланады."</string>
     <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Рұқсат ету"</string>
@@ -1822,7 +1822,7 @@
     <string name="mediasize_unknown_portrait" msgid="3817016220446495613">"Белгісіз портреттік"</string>
     <string name="mediasize_unknown_landscape" msgid="1584741567225095325">"Белгісіз ландшафт"</string>
     <string name="write_fail_reason_cancelled" msgid="2344081488493969190">"Тоқтатылды"</string>
-    <string name="write_fail_reason_cannot_write" msgid="432118118378451508">"Мазмұн жазу қателігі"</string>
+    <string name="write_fail_reason_cannot_write" msgid="432118118378451508">"Контент жазу қателігі"</string>
     <string name="reason_unknown" msgid="5599739807581133337">"белгісіз"</string>
     <string name="reason_service_unavailable" msgid="5288405248063804713">"Принтер қызметі қосылмаған"</string>
     <string name="print_service_installed_title" msgid="6134880817336942482">"<xliff:g id="NAME">%s</xliff:g> қызметі орнатылды"</string>
@@ -1999,7 +1999,7 @@
     <string name="time_picker_radial_mode_description" msgid="1222342577115016953">"Уақытты енгізу үшін сағат режиміне өтіңіз."</string>
     <string name="autofill_picker_accessibility_title" msgid="4425806874792196599">"Автотолтыру опциялары"</string>
     <string name="autofill_save_accessibility_title" msgid="1523225776218450005">"Автотолтыру үшін сақтау"</string>
-    <string name="autofill_error_cannot_autofill" msgid="6528827648643138596">"Мазмұндар автотолтырылмайды"</string>
+    <string name="autofill_error_cannot_autofill" msgid="6528827648643138596">"Дерек автоматты толтырылмайды."</string>
     <string name="autofill_picker_no_suggestions" msgid="1076022650427481509">"Автотолтыру ұсыныстары жоқ"</string>
     <string name="autofill_picker_some_suggestions" msgid="5560549696296202701">"{count,plural, =1{Бір автотолтыру ұсынысы}other{# автотолтыру ұсынысы}}"</string>
     <string name="autofill_save_title" msgid="7719802414283739775"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" қызметіне сақталсын ба?"</string>
@@ -2083,7 +2083,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Жарайды"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Өшіру"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Толығырақ"</string>
-    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12 жүйесінде \"Бейімделетін хабарландырулар\" функциясын \"Кеңейтілген хабарландырулар\" алмастырды. Бұл функция ұсынылған әрекеттер мен жауаптарды көрсетіп, хабарландыруларыңызды ретке келтіреді.\n\nОл хабарландыру мазмұнын, соның ішінде жеке ақпаратыңызды (мысалы, контакт аттары мен хабарларды) пайдалана алады. Сондай-ақ бұл функция арқылы хабарландыруларды жабуға немесе оларға жауап беруге (мысалы, телефон қоңырауларына жауап беруге және Мазаламау режимін басқаруға) болады."</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12 жүйесінде \"Бейімделетін хабарландырулар\" функциясын \"Кеңейтілген хабарландырулар\" алмастырды. Бұл функция ұсынылған әрекеттер мен жауаптарды көрсетіп, хабарландыруларыңызды ретке келтіреді.\n\nОл хабарландыру контентін, соның ішінде жеке ақпаратыңызды (мысалы, контакт аттары мен хабарларды) пайдалана алады. Сондай-ақ бұл функция арқылы хабарландыруларды жабуға немесе оларға жауап беруге (мысалы, телефон қоңырауларына жауап беруге және Мазаламау режимін басқаруға) болады."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Режим туралы хабарландыру"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батарея заряды азаюы мүмкін"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Батарея ұзаққа жетуі үшін, Батареяны үнемдеу режимі іске қосылды"</string>
@@ -2146,10 +2146,10 @@
     <string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Жеке көру"</string>
     <string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Жұмыс деректерін көру"</string>
     <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Әкімшіңіз бөгеген"</string>
-    <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Бұл мазмұнды жұмыс қолданбаларымен бөлісу мүмкін емес."</string>
-    <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Бұл мазмұнды жұмыс қолданбаларымен ашу мүмкін емес."</string>
-    <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Бұл мазмұнды жеке қолданбалармен бөлісу мүмкін емес."</string>
-    <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Бұл мазмұнды жеке қолданбалармен ашу мүмкін емес."</string>
+    <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Бұл контентті жұмыс қолданбаларымен бөлісу мүмкін емес."</string>
+    <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Бұл контентті жұмыс қолданбаларымен ашу мүмкін емес."</string>
+    <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Бұл контентті жеке қолданбалармен бөлісу мүмкін емес."</string>
+    <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Бұл контентті жеке қолданбалармен ашу мүмкін емес."</string>
     <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Жұмыс профилі кідіртілді."</string>
     <string name="resolver_switch_on_work" msgid="463709043650610420">"Қосу үшін түртіңіз"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Жұмыс қолданбалары жоқ."</string>
@@ -2278,7 +2278,7 @@
     <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Құрылғы камерасының бөгеуін алыңыз"</string>
     <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; және барлық қолданбалар мен қызметтерге арналған."</string>
     <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Бөгеуді алу"</string>
-    <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Датчикке қатысты құпиялылық"</string>
+    <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Датчикке қатысты құпиялық"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Қолданба белгішесі"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Қолданба брендін ілгері жылжыту кескіні"</string>
     <string name="view_and_control_notification_title" msgid="4300765399209912240">"Пайдалану параметрлерін тексеріңіз"</string>
@@ -2293,6 +2293,6 @@
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Белсенді қолданбаларды тексеру"</string>
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> құрылғысынан телефон камерасын пайдалану мүмкін емес."</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> құрылғысынан планшет камерасын пайдалану мүмкін емес."</string>
-    <string name="vdm_secure_window" msgid="161700398158812314">"Трансляция кезінде мазмұнды көру мүмкін емес. Оның орнына телефоннан көріңіз."</string>
+    <string name="vdm_secure_window" msgid="161700398158812314">"Трансляция кезінде контентті көру мүмкін емес. Оның орнына телефоннан көріңіз."</string>
     <string name="system_locale_title" msgid="711882686834677268">"Жүйенің әдепкі параметрі"</string>
 </resources>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index fe1fa95..d923937 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -1178,7 +1178,7 @@
     <string name="whichApplicationLabel" msgid="7852182961472531728">"ಕ್ರಿಯೆಯನ್ನು ಪೂರ್ಣಗೊಳಿಸಿ"</string>
     <string name="whichViewApplication" msgid="5733194231473132945">"ಇದರ ಮೂಲಕ ತೆರೆಯಿರಿ"</string>
     <string name="whichViewApplicationNamed" msgid="415164730629690105">"%1$s ಜೊತೆಗೆ ತೆರೆಯಿರಿ"</string>
-    <string name="whichViewApplicationLabel" msgid="7367556735684742409">"ತೆರೆ"</string>
+    <string name="whichViewApplicationLabel" msgid="7367556735684742409">"ತೆರೆಯಿರಿ"</string>
     <string name="whichOpenHostLinksWith" msgid="7645631470199397485">"ಇವುಗಳ ಮೂಲಕ <xliff:g id="HOST">%1$s</xliff:g> ಲಿಂಕ್‌ಗಳನ್ನು ತೆರೆಯಿರಿ"</string>
     <string name="whichOpenLinksWith" msgid="1120936181362907258">"ಇವುಗಳ ಮೂಲಕ ಲಿಂಕ್‌ಗಳನ್ನು ತೆರೆಯಿರಿ"</string>
     <string name="whichOpenLinksWithApp" msgid="6917864367861910086">"<xliff:g id="APPLICATION">%1$s</xliff:g> ಮೂಲಕ ಲಿಂಕ್‌ಗಳನ್ನು ತೆರೆಯಿರಿ"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 3db4e9b..27d932a 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -264,7 +264,7 @@
     <string name="global_actions_toggle_airplane_mode" msgid="6911684460146916206">"Учак режими"</string>
     <string name="global_actions_airplane_mode_on_status" msgid="5508025516695361936">"Учак режими КҮЙҮК"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="8522219771500505475">"Учак режими ӨЧҮК"</string>
-    <string name="global_action_settings" msgid="4671878836947494217">"Жөндөөлөр"</string>
+    <string name="global_action_settings" msgid="4671878836947494217">"Параметрлер"</string>
     <string name="global_action_assist" msgid="2517047220311505805">"Жардам"</string>
     <string name="global_action_voice_assist" msgid="6655788068555086695">"Үн жардамчысы"</string>
     <string name="global_action_lockdown" msgid="2475471405907902963">"Бекем кулпулоо"</string>
@@ -631,7 +631,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">"Жүзүнөн таанып ачуу функциясын колдонуу үчүн Жөндөөлөр &gt; Купуялык бөлүмүнө өтүп, "<b>"Камераны колдонууну"</b>" күйгүзүңүз"</string>
+    <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Жүзүнөн таанып ачуу функциясын колдонуу үчүн Параметрлер &gt; Купуялык бөлүмүнө өтүп, "<b>"Камераны колдонууну"</b>" күйгүзүңүз"</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>
@@ -1624,7 +1624,7 @@
     <string name="media_route_chooser_title" msgid="6646594924991269208">"Түзмөккө туташуу"</string>
     <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Тышкы экранга чыгаруу"</string>
     <string name="media_route_chooser_searching" msgid="6119673534251329535">"Түзмөктөр изделүүдө..."</string>
-    <string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"Жөндөөлөр"</string>
+    <string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"Параметрлер"</string>
     <string name="media_route_controller_disconnect" msgid="7362617572732576959">"Ажыратуу"</string>
     <string name="media_route_status_scanning" msgid="8045156315309594482">"Скандоодо..."</string>
     <string name="media_route_status_connecting" msgid="5845597961412010540">"Туташууда..."</string>
@@ -1679,10 +1679,10 @@
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Ыкчам иштетесизби?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Атайын мүмкүнчүлүктөр функциясын пайдалануу үчүн ал күйгүзүлгөндө, үндү катуулатып/акырындаткан эки баскычты тең 3 секунддай коё бербей басып туруңуз."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Атайын мүмкүнчүлүктөрдүн ыкчам баскычын иштетесизби?"</string>
-    <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Атайын мүмкүнчүлүктөр функциясын иштетүү үчүн үндү катуулатуу/акырындатуу баскычтарын бир нече секунд коё бербей басып туруңуз. Ушуну менен, түзмөгүңүз бир аз башкача иштеп калышы мүмкүн.\n\nУчурдагы функциялар:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nТандалган функцияларды өзгөртүү үчүн Жөндөөлөр &gt; Атайын мүмкүнчүлүктөр бөлүмүнө өтүңүз."</string>
+    <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Атайын мүмкүнчүлүктөр функциясын иштетүү үчүн үндү катуулатуу/акырындатуу баскычтарын бир нече секунд коё бербей басып туруңуз. Ушуну менен, түзмөгүңүз бир аз башкача иштеп калышы мүмкүн.\n\nУчурдагы функциялар:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nТандалган функцияларды өзгөртүү үчүн Параметрлер &gt; Атайын мүмкүнчүлүктөр бөлүмүнө өтүңүз."</string>
     <string name="accessibility_shortcut_multiple_service_list" msgid="2128323171922023762">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
     <string name="accessibility_shortcut_single_service_warning_title" msgid="1909518473488345266">"<xliff:g id="SERVICE">%1$s</xliff:g> ыкчам баскычын иштетесизби?"</string>
-    <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"<xliff:g id="SERVICE">%1$s</xliff:g> кызматын иштетүү үчүн үндү катуулатуу/акырындатуу баскычтарын бир нече секунд коё бербей басып туруңуз. Ушуну менен, түзмөгүңүз бир аз башкача иштеп калышы мүмкүн.\n\nБаскычтардын ушул айкалышын башка функцияга дайындоо үчүн, Жөндөөлөр &gt; Атайын мүмкүнчүлүктөр бөлүмүнө өтүңүз."</string>
+    <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"<xliff:g id="SERVICE">%1$s</xliff:g> кызматын иштетүү үчүн үндү катуулатуу/акырындатуу баскычтарын бир нече секунд коё бербей басып туруңуз. Ушуну менен, түзмөгүңүз бир аз башкача иштеп калышы мүмкүн.\n\nБаскычтардын ушул айкалышын башка функцияга дайындоо үчүн, Параметрлер &gt; Атайын мүмкүнчүлүктөр бөлүмүнө өтүңүз."</string>
     <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Ооба"</string>
     <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Жок"</string>
     <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"КҮЙҮК"</string>
@@ -2069,7 +2069,7 @@
     <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Кийинчерээк эскертүү"</string>
     <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Жабуу"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Тутум"</string>
-    <string name="notification_app_name_settings" msgid="9088548800899952531">"Жөндөөлөр"</string>
+    <string name="notification_app_name_settings" msgid="9088548800899952531">"Параметрлер"</string>
     <string name="notification_appops_camera_active" msgid="8177643089272352083">"Камера"</string>
     <string name="notification_appops_microphone_active" msgid="581333393214739332">"Микрофон"</string>
     <string name="notification_appops_overlay_active" msgid="5571732753262836481">"экрандагы башка терезелердин үстүнөн көрсөтүлүүдө"</string>
diff --git a/core/res/res/values-mcc001-mnc01-b+sr+Latn/strings.xml b/core/res/res/values-mcc001-mnc01-b+sr+Latn/strings.xml
index b003fe0..7c0fc70 100644
--- a/core/res/res/values-mcc001-mnc01-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-b+sr+Latn/strings.xml
@@ -20,5 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_illegal_me" msgid="6819499009131365312">"Телефон није дозвољен MM#6"</string>
+    <string name="mmcc_illegal_me" msgid="6819499009131365312">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc030-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc030-b+sr+Latn/strings.xml
index b0a8ae5..81b9be8 100644
--- a/core/res/res/values-mcc310-mnc030-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-b+sr+Latn/strings.xml
@@ -20,7 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="656054059094417927">"SIM картица није подешена MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1782569305985001089">"SIM картица није дозвољена MM#3"</string>
-    <string name="mmcc_illegal_me" msgid="8246632898824321280">"Телефон није дозвољен MM#6"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="656054059094417927">"SIM kartica nije podešena MM#2"</string>
+    <string name="mmcc_illegal_ms" msgid="1782569305985001089">"SIM kartica nije dozvoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8246632898824321280">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc150-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc150-b+sr+Latn/strings.xml
index c70f4b7..d066eb62 100644
--- a/core/res/res/values-mcc310-mnc150-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-b+sr+Latn/strings.xml
@@ -20,5 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_illegal_me" msgid="8004509200390992737">"Телефон није дозвољен MM#6"</string>
+    <string name="mmcc_illegal_me" msgid="8004509200390992737">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc170-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc170-b+sr+Latn/strings.xml
index 011a40d..ff89bab 100644
--- a/core/res/res/values-mcc310-mnc170-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-b+sr+Latn/strings.xml
@@ -20,7 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="5424518490295341205">"SIM картица није подешена MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="3527626511418944853">"SIM картица није дозвољена MM#3"</string>
-    <string name="mmcc_illegal_me" msgid="3948912590657398489">"Телефон није дозвољен MM#6"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="5424518490295341205">"SIM kartica nije podešena MM#2"</string>
+    <string name="mmcc_illegal_ms" msgid="3527626511418944853">"SIM kartica nije dozvoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3948912590657398489">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc280-b+sr+Latn/strings.xml
index 9b0dcf1..faf51d3 100644
--- a/core/res/res/values-mcc310-mnc280-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-b+sr+Latn/strings.xml
@@ -20,7 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="1070849538022865416">"SIM картица није подешена MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="499832197298480670">"SIM картица није дозвољена MM#3"</string>
-    <string name="mmcc_illegal_me" msgid="2346111479504469688">"Телефон није дозвољен MM#6"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="1070849538022865416">"SIM kartica nije podešena MM#2"</string>
+    <string name="mmcc_illegal_ms" msgid="499832197298480670">"SIM kartica nije dozvoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="2346111479504469688">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc380-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc380-b+sr+Latn/strings.xml
index 256ad83b..e348095 100644
--- a/core/res/res/values-mcc310-mnc380-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc310-mnc380-b+sr+Latn/strings.xml
@@ -20,6 +20,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6178029798083341927">"SIM картица није подешена MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6084322234976891423">"SIM картица није дозвољена MM#3"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="6178029798083341927">"SIM kartica nije podešena MM#2"</string>
+    <string name="mmcc_illegal_ms" msgid="6084322234976891423">"SIM kartica nije dozvoljena MM#3"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc410-b+sr+Latn/strings.xml
index e8835d2..940507b 100644
--- a/core/res/res/values-mcc310-mnc410-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-b+sr+Latn/strings.xml
@@ -20,7 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="8861901652350883183">"SIM картица није подешена MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2604694337529846283">"SIM картица није дозвољена MM#3"</string>
-    <string name="mmcc_illegal_me" msgid="3099618295079374317">"Телефон није дозвољен MM#6"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="8861901652350883183">"SIM kartica nije podešena MM#2"</string>
+    <string name="mmcc_illegal_ms" msgid="2604694337529846283">"SIM kartica nije dozvoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="3099618295079374317">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc560-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc560-b+sr+Latn/strings.xml
index bacde69..2a0e83c 100644
--- a/core/res/res/values-mcc310-mnc560-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-b+sr+Latn/strings.xml
@@ -20,7 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="3526528316378889524">"SIM картица није подешена MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="4618730283812066268">"SIM картица није дозвољена MM#3"</string>
-    <string name="mmcc_illegal_me" msgid="8522039751358990401">"Телефон није дозвољен MM#6"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="3526528316378889524">"SIM kartica nije podešena MM#2"</string>
+    <string name="mmcc_illegal_ms" msgid="4618730283812066268">"SIM kartica nije dozvoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="8522039751358990401">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc950-b+sr+Latn/strings.xml
index 9005aaf..cdf92ca 100644
--- a/core/res/res/values-mcc310-mnc950-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-b+sr+Latn/strings.xml
@@ -20,7 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="615419724607901560">"SIM картица није подешена MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="7801541624846497489">"SIM картица није дозвољена MM#3"</string>
-    <string name="mmcc_illegal_me" msgid="7066936962628406316">"Телефон није дозвољен MM#6"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="615419724607901560">"SIM kartica nije podešena MM#2"</string>
+    <string name="mmcc_illegal_ms" msgid="7801541624846497489">"SIM kartica nije dozvoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="7066936962628406316">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-b+sr+Latn/strings.xml b/core/res/res/values-mcc311-mnc180-b+sr+Latn/strings.xml
index baec8cd..6cbc6ee 100644
--- a/core/res/res/values-mcc311-mnc180-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-b+sr+Latn/strings.xml
@@ -20,7 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="604133804161351810">"SIM картица није подешена MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="4073997279280371621">"SIM картица није дозвољена MM#3"</string>
-    <string name="mmcc_illegal_me" msgid="4936539345546223576">"Телефон није дозвољен MM#6"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="604133804161351810">"SIM kartica nije podešena MM#2"</string>
+    <string name="mmcc_illegal_ms" msgid="4073997279280371621">"SIM kartica nije dozvoljena MM#3"</string>
+    <string name="mmcc_illegal_me" msgid="4936539345546223576">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc312-mnc670-b+sr+Latn/strings.xml b/core/res/res/values-mcc312-mnc670-b+sr+Latn/strings.xml
index 6c738a2..d9b6793 100644
--- a/core/res/res/values-mcc312-mnc670-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-b+sr+Latn/strings.xml
@@ -20,5 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_illegal_me" msgid="8271599016773350087">"Телефон није дозвољен MM#6"</string>
+    <string name="mmcc_illegal_me" msgid="8271599016773350087">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc313-mnc100-b+sr+Latn/strings.xml b/core/res/res/values-mcc313-mnc100-b+sr+Latn/strings.xml
index 1ff6057..4740afd 100644
--- a/core/res/res/values-mcc313-mnc100-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-b+sr+Latn/strings.xml
@@ -20,5 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_illegal_me" msgid="8297733805803070310">"Телефон није дозвољен MM#6"</string>
+    <string name="mmcc_illegal_me" msgid="8297733805803070310">"Telefon nije dozvoljen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc334-mnc020-b+sr+Latn/strings.xml b/core/res/res/values-mcc334-mnc020-b+sr+Latn/strings.xml
index ddf0ce1..b27e485 100644
--- a/core/res/res/values-mcc334-mnc020-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc334-mnc020-b+sr+Latn/strings.xml
@@ -20,7 +20,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="config_pdp_reject_dialog_title" msgid="41208110171880430"></string>
-    <string name="config_pdp_reject_user_authentication_failed" msgid="4683454131283459978">"ПОТВРДА ИДЕНТИТЕТА НИЈЕ УСПЕЛА -29-"</string>
-    <string name="config_pdp_reject_service_not_subscribed" msgid="9021140729932308119">"НИСТЕ ПРЕТПЛАЋЕНИ НА УСЛУГУ -33-"</string>
-    <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="3838388706348367865">"Није дозвољено више PDN веза за одређени APN -55-"</string>
+    <string name="config_pdp_reject_user_authentication_failed" msgid="4683454131283459978">"POTVRDA IDENTITETA NIJE USPELA -29-"</string>
+    <string name="config_pdp_reject_service_not_subscribed" msgid="9021140729932308119">"NISTE PRETPLAĆENI NA USLUGU -33-"</string>
+    <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="3838388706348367865">"Nije dozvoljeno više PDN veza za određeni APN -55-"</string>
 </resources>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 32abaab..6be015a 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -368,7 +368,7 @@
     <string name="permdesc_manageOngoingCalls" msgid="7003138133829915265">"ॲपला तुमच्या डिव्हाइसवर सुरू असलेल्या कॉलचे तपशील पाहण्याची आणि या कॉलना नियंत्रित करण्याची अनुमती द्या."</string>
     <string name="permlab_readCellBroadcasts" msgid="5869884450872137693">"सेल प्रसारण मेसेज वाचा"</string>
     <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"आपल्या डिव्हाइसद्वारे प्राप्त केलेले सेल प्रसारण मेसेज वाचण्यासाठी अ‍ॅप ला अनुमती देते. काही स्थानांमध्ये तुम्हाला आणीबाणीच्या परिस्थितीची चेतावणी देण्यासाठी सेल प्रसारण सूचना वितरीत केल्या जातात. आणीबाणी सेल प्रसारण प्राप्त होते तेव्हा आपल्या डिव्हाइसच्या कार्यप्रदर्शनात किंवा कार्यात दुर्भावनापूर्ण अ‍ॅप्स व्यत्यय आणू शकतात."</string>
-    <string name="permlab_subscribedFeedsRead" msgid="217624769238425461">"सदस्यता घेतलेली फीड वाचा"</string>
+    <string name="permlab_subscribedFeedsRead" msgid="217624769238425461">"सदस्यत्व घेतलेली फीड वाचा"</string>
     <string name="permdesc_subscribedFeedsRead" msgid="6911349196661811865">"सध्या संकालित केलेल्या फीडविषयी तपशील मिळविण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_sendSms" msgid="7757368721742014252">"SMS मेसेज पाठवणे आणि पाहणे"</string>
     <string name="permdesc_sendSms" msgid="6757089798435130769">"SMS मेसेज पाठविण्यासाठी अ‍ॅप ला अनुमती देते. हे अनपेक्षित शुल्कामुळे होऊ शकते. दुर्भावनापूर्ण अ‍ॅप्स नी आपल्या पुष्टिकरणाशिवाय मेसेज पाठवल्यामुळे तुमचे पैसे खर्च होऊ शकतात."</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 42a477b..9768208 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1534,7 +1534,7 @@
     <string name="add_account_button_label" msgid="322390749416414097">"Adicionar conta"</string>
     <string name="number_picker_increment_button" msgid="7621013714795186298">"Aumentar"</string>
     <string name="number_picker_decrement_button" msgid="5116948444762708204">"Diminuir"</string>
-    <string name="number_picker_increment_scroll_mode" msgid="8403893549806805985">"<xliff:g id="VALUE">%s</xliff:g> toque e mantenha pressionado."</string>
+    <string name="number_picker_increment_scroll_mode" msgid="8403893549806805985">"<xliff:g id="VALUE">%s</xliff:g> toque e pressione."</string>
     <string name="number_picker_increment_scroll_action" msgid="8310191318914268271">"Deslize para cima para aumentar e para baixo para diminuir."</string>
     <string name="time_picker_increment_minute_button" msgid="7195870222945784300">"Aumentar minuto"</string>
     <string name="time_picker_decrement_minute_button" msgid="230925389943411490">"Diminuir minuto"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 42a477b..9768208 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1534,7 +1534,7 @@
     <string name="add_account_button_label" msgid="322390749416414097">"Adicionar conta"</string>
     <string name="number_picker_increment_button" msgid="7621013714795186298">"Aumentar"</string>
     <string name="number_picker_decrement_button" msgid="5116948444762708204">"Diminuir"</string>
-    <string name="number_picker_increment_scroll_mode" msgid="8403893549806805985">"<xliff:g id="VALUE">%s</xliff:g> toque e mantenha pressionado."</string>
+    <string name="number_picker_increment_scroll_mode" msgid="8403893549806805985">"<xliff:g id="VALUE">%s</xliff:g> toque e pressione."</string>
     <string name="number_picker_increment_scroll_action" msgid="8310191318914268271">"Deslize para cima para aumentar e para baixo para diminuir."</string>
     <string name="time_picker_increment_minute_button" msgid="7195870222945784300">"Aumentar minuto"</string>
     <string name="time_picker_decrement_minute_button" msgid="230925389943411490">"Diminuir minuto"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 83e8ced2..83fba3f 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -318,7 +318,7 @@
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Activitate fizică"</string>
     <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"să acceseze activitatea fizică"</string>
     <string name="permgrouplab_camera" msgid="9090413408963547706">"Camera foto"</string>
-    <string name="permgroupdesc_camera" msgid="7585150538459320326">"fotografieze și să înregistreze videoclipuri"</string>
+    <string name="permgroupdesc_camera" msgid="7585150538459320326">"să fotografieze și să înregistreze videoclipuri"</string>
     <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Dispozitive din apropiere"</string>
     <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"descoperă dispozitive din apropiere și conectează-te la acestea"</string>
     <string name="permgrouplab_calllog" msgid="7926834372073550288">"Jurnale de apeluri"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 12015ec..fb9a313 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1173,7 +1173,7 @@
     <string name="selected" msgid="6614607926197755875">"valt"</string>
     <string name="not_selected" msgid="410652016565864475">"inte valt"</string>
     <string name="in_progress" msgid="2149208189184319441">"pågår"</string>
-    <string name="whichApplication" msgid="5432266899591255759">"Slutför åtgärd genom att använda"</string>
+    <string name="whichApplication" msgid="5432266899591255759">"Slutför åtgärd med"</string>
     <string name="whichApplicationNamed" msgid="6969946041713975681">"Slutför åtgärden med %1$s"</string>
     <string name="whichApplicationLabel" msgid="7852182961472531728">"Slutför åtgärd"</string>
     <string name="whichViewApplication" msgid="5733194231473132945">"Öppna med"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 1a5e13b..7cebe27 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -315,7 +315,7 @@
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"మైక్రోఫోన్"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ఆడియోను రికార్డ్ చేయడానికి"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"ఫిజికల్ యాక్టివిటీ"</string>
-    <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"భౌతిక యాక్టివిటీని యాక్సెస్ చేయండి"</string>
+    <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"ఫిజికల్ యాక్టివిటీని యాక్సెస్ చేయండి"</string>
     <string name="permgrouplab_camera" msgid="9090413408963547706">"కెమెరా"</string>
     <string name="permgroupdesc_camera" msgid="7585150538459320326">"చిత్రాలను తీయడానికి మరియు వీడియోను రికార్డ్ చేయడానికి"</string>
     <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"సమీపంలోని పరికరాలు"</string>
@@ -559,7 +559,7 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"ఇది మీ స్క్రీన్ లాక్ పాస్‌వర్డ్‌ సంక్లిష్టత స్థాయి (తీవ్రంగా ఉండాలా, ఓ మోస్తరుగా ఉండాలా, తక్కువ తీవ్రంగా ఉండాలా లేదా అస్సలు తీవ్రత ఉండకూడదా) తెలుసుకోవడానికి యాప్‌ను అనుమతిస్తుంది, అంటే పొడుగు ఎంత ఉండాలి, ఏ రకమైన స్క్రీన్ లాక్ పధ్ధతి అనుసరించాలో సూచిస్తుంది. అలాగే, స్క్రీన్ లాక్‌ పాస్‌వర్డ్‌ సంక్లిష్టతను ఏ స్థాయికి సెట్ చేసుకుంటే బాగుంటుందో కూడా వినియోగదారులకు యాప్ సూచించగలదు, కానీ వినియోగదారులు నిరభ్యంతరంగా ఆ సూచనలను పట్టించుకోకుండా వారి ఇష్టం మేరకు చక్కగా సెట్ చేసుకోవచ్చు. ఇంకో ముఖ్య విషయం, స్క్రీన్ లాక్‌ అన్నది సాదా వచన రూపంలో నిల్వ చేయబడదు, కనుక ఖచ్చితమైన పాస్‌వర్డ్‌ ఏమిటనేది యాప్‌కు తెలియదు."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"నోటిఫికేషన్‌లను చూపండి"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"నోటిఫికేషన్‌లను చూపించడానికి యాప్‌ను అనుమతించండి"</string>
-    <string name="permlab_useBiometric" msgid="6314741124749633786">"బయోమెట్రిక్ హార్డ్‌వేర్‌ని ఉపయోగించు"</string>
+    <string name="permlab_useBiometric" msgid="6314741124749633786">"బయోమెట్రిక్ హార్డ్‌వేర్‌ని ఉపయోగించండి"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"ప్రమాణీకరణ కోసం బయోమెట్రిక్ హార్డ్‌వేర్‌ను ఉపయోగించడానికి యాప్‌ని అనుమతిస్తుంది"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"వేలిముద్ర హార్డ్‌వేర్‌ని మేనేజ్ చేయడానికి అనుమతి"</string>
     <string name="permdesc_manageFingerprint" msgid="2025616816437339865">"వినియోగం కోసం వేలిముద్ర టెంప్లేట్‌లను జోడించే, తొలగించే పద్ధతులను అమలు చేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
@@ -1516,8 +1516,8 @@
     <string name="share" msgid="4157615043345227321">"షేర్"</string>
     <string name="find" msgid="5015737188624767706">"కనుగొనండి"</string>
     <string name="websearch" msgid="5624340204512793290">"వెబ్ సెర్చ్"</string>
-    <string name="find_next" msgid="5341217051549648153">"తదుపరిదాన్ని కనుగొను"</string>
-    <string name="find_previous" msgid="4405898398141275532">"మునుపటిదాన్ని కనుగొను"</string>
+    <string name="find_next" msgid="5341217051549648153">"తదుపరిదాన్ని కనుగొనండి"</string>
+    <string name="find_previous" msgid="4405898398141275532">"మునుపటిదాన్ని కనుగొనండి"</string>
     <string name="gpsNotifTicker" msgid="3207361857637620780">"<xliff:g id="NAME">%s</xliff:g> నుండి లొకేషన్ రిక్వెస్ట్‌"</string>
     <string name="gpsNotifTitle" msgid="1590033371665669570">"లొకేషన్ రిక్వెస్ట్‌"</string>
     <string name="gpsNotifMessage" msgid="7346649122793758032">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) ద్వారా రిక్వెస్ట్ చేయబడింది"</string>
@@ -1702,7 +1702,7 @@
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"షార్ట్‌కట్‌లను ఎడిట్ చేయండి"</string>
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"పూర్తయింది"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"షార్ట్‌కట్‌ను ఆఫ్ చేయి"</string>
-    <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"షార్ట్‌కట్‌ను ఉపయోగించు"</string>
+    <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"షార్ట్‌కట్‌ను ఉపయోగించండి"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"కలర్ మార్పిడి"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"కలర్ కరెక్షన్"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"వన్-హ్యాండెడ్ మోడ్"</string>
@@ -2010,7 +2010,7 @@
     <string name="autofill_update_title_with_type" msgid="5264152633488495704">"<xliff:g id="TYPE">%1$s</xliff:g>ని "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"లో అప్‌డేట్ చేయాలా?"</string>
     <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"<xliff:g id="TYPE_0">%1$s</xliff:g> మరియు <xliff:g id="TYPE_1">%2$s</xliff:g>ని "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"లో అప్‌డేట్ చేయాలా?"</string>
     <string name="autofill_update_title_with_3types" msgid="1312232153076212291">"ఈ అంశాలను "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"లో అప్‌డేట్ చేయాలా: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> మరియు <xliff:g id="TYPE_2">%3$s</xliff:g> ?"</string>
-    <string name="autofill_save_yes" msgid="8035743017382012850">"సేవ్ చేయి"</string>
+    <string name="autofill_save_yes" msgid="8035743017382012850">"సేవ్ చేయండి"</string>
     <string name="autofill_save_no" msgid="9212826374207023544">"వద్దు, ధన్యవాదాలు"</string>
     <string name="autofill_save_notnow" msgid="2853932672029024195">"ఇప్పుడు కాదు"</string>
     <string name="autofill_save_never" msgid="6821841919831402526">"ఎప్పుడూ వద్దు"</string>
@@ -2156,8 +2156,8 @@
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"వ్యక్తిగత యాప్‌లు లేవు"</string>
     <string name="miniresolver_open_in_personal" msgid="3874522693661065566">"<xliff:g id="APP">%s</xliff:g>ను మీ వ్యక్తిగత ప్రొఫైల్‌లో తెరవాలా?"</string>
     <string name="miniresolver_open_in_work" msgid="4415223793669536559">"<xliff:g id="APP">%s</xliff:g>ను మీ వర్క్ ప్రొఫైల్‌లో తెరవాలా?"</string>
-    <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"వ్యక్తిగత బ్రౌజర్‌ను ఉపయోగించు"</string>
-    <string name="miniresolver_use_work_browser" msgid="543575306251952994">"వర్క్ బ్రౌజర్‌ను ఉపయోగించు"</string>
+    <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"వ్యక్తిగత బ్రౌజర్‌ను ఉపయోగించండి"</string>
+    <string name="miniresolver_use_work_browser" msgid="543575306251952994">"వర్క్ బ్రౌజర్‌ను ఉపయోగించండి"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM నెట్‌వర్క్ అన్‌లాక్ పిన్‌"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM నెట్‌వర్క్ సబ్‌సెట్ అన్‌లాక్ పిన్"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM కార్పొరేట్ అన్‌లాక్ పిన్"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 93d907e..3b3fa06 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -796,7 +796,7 @@
   <string-array name="phoneTypes">
     <item msgid="8996339953292723951">"Nhà riêng"</item>
     <item msgid="7740243458912727194">"Di động"</item>
-    <item msgid="8526146065496663766">"Cơ quan"</item>
+    <item msgid="8526146065496663766">"Nơi làm việc"</item>
     <item msgid="8150904584178569699">"Số fax cơ quan"</item>
     <item msgid="4537253139152229577">"Số fax nhà riêng"</item>
     <item msgid="6751245029698664340">"Số máy nhắn tin"</item>
@@ -805,24 +805,24 @@
   </string-array>
   <string-array name="emailAddressTypes">
     <item msgid="7786349763648997741">"Nhà riêng"</item>
-    <item msgid="435564470865989199">"Cơ quan"</item>
+    <item msgid="435564470865989199">"Nơi làm việc"</item>
     <item msgid="4199433197875490373">"Khác"</item>
     <item msgid="3233938986670468328">"Tùy chỉnh"</item>
   </string-array>
   <string-array name="postalAddressTypes">
     <item msgid="3861463339764243038">"Nhà riêng"</item>
-    <item msgid="5472578890164979109">"Cơ quan"</item>
+    <item msgid="5472578890164979109">"Nơi làm việc"</item>
     <item msgid="5718921296646594739">"Khác"</item>
     <item msgid="5523122236731783179">"Tùy chỉnh"</item>
   </string-array>
   <string-array name="imAddressTypes">
     <item msgid="588088543406993772">"Nhà riêng"</item>
-    <item msgid="5503060422020476757">"Cơ quan"</item>
+    <item msgid="5503060422020476757">"Nơi làm việc"</item>
     <item msgid="2530391194653760297">"Khác"</item>
     <item msgid="7640927178025203330">"Tùy chỉnh"</item>
   </string-array>
   <string-array name="organizationTypes">
-    <item msgid="6144047813304847762">"Cơ quan"</item>
+    <item msgid="6144047813304847762">"Nơi làm việc"</item>
     <item msgid="7402720230065674193">"Khác"</item>
     <item msgid="808230403067569648">"Tùy chỉnh"</item>
   </string-array>
@@ -839,7 +839,7 @@
     <string name="phoneTypeCustom" msgid="5120365721260686814">"Tùy chỉnh"</string>
     <string name="phoneTypeHome" msgid="3880132427643623588">"Nhà riêng"</string>
     <string name="phoneTypeMobile" msgid="1178852541462086735">"Di động"</string>
-    <string name="phoneTypeWork" msgid="6604967163358864607">"Cơ quan"</string>
+    <string name="phoneTypeWork" msgid="6604967163358864607">"Nơi làm việc"</string>
     <string name="phoneTypeFaxWork" msgid="6757519896109439123">"Số fax cơ quan"</string>
     <string name="phoneTypeFaxHome" msgid="6678559953115904345">"Số fax nhà riêng"</string>
     <string name="phoneTypePager" msgid="576402072263522767">"Số máy nhắn tin"</string>
@@ -863,16 +863,16 @@
     <string name="eventTypeOther" msgid="530671238533887997">"Khác"</string>
     <string name="emailTypeCustom" msgid="1809435350482181786">"Tùy chỉnh"</string>
     <string name="emailTypeHome" msgid="1597116303154775999">"Nhà riêng"</string>
-    <string name="emailTypeWork" msgid="2020095414401882111">"Cơ quan"</string>
+    <string name="emailTypeWork" msgid="2020095414401882111">"Nơi làm việc"</string>
     <string name="emailTypeOther" msgid="5131130857030897465">"Khác"</string>
     <string name="emailTypeMobile" msgid="787155077375364230">"Di Động"</string>
     <string name="postalTypeCustom" msgid="5645590470242939129">"Tùy chỉnh"</string>
     <string name="postalTypeHome" msgid="7562272480949727912">"Nhà riêng"</string>
-    <string name="postalTypeWork" msgid="8553425424652012826">"Cơ quan"</string>
+    <string name="postalTypeWork" msgid="8553425424652012826">"Nơi làm việc"</string>
     <string name="postalTypeOther" msgid="7094245413678857420">"Khác"</string>
     <string name="imTypeCustom" msgid="5653384545085765570">"Tùy chỉnh"</string>
     <string name="imTypeHome" msgid="6996507981044278216">"Nhà riêng"</string>
-    <string name="imTypeWork" msgid="2099668940169903123">"Cơ quan"</string>
+    <string name="imTypeWork" msgid="2099668940169903123">"Nơi làm việc"</string>
     <string name="imTypeOther" msgid="8068447383276219810">"Khác"</string>
     <string name="imProtocolCustom" msgid="4437878287653764692">"Tùy chỉnh"</string>
     <string name="imProtocolAim" msgid="4050198236506604378">"AIM"</string>
@@ -884,7 +884,7 @@
     <string name="imProtocolIcq" msgid="2410325380427389521">"ICQ"</string>
     <string name="imProtocolJabber" msgid="7919269388889582015">"Jabber"</string>
     <string name="imProtocolNetMeeting" msgid="4985002408136148256">"NetMeeting"</string>
-    <string name="orgTypeWork" msgid="8684458700669564172">"Cơ quan"</string>
+    <string name="orgTypeWork" msgid="8684458700669564172">"Nơi làm việc"</string>
     <string name="orgTypeOther" msgid="5450675258408005553">"Khác"</string>
     <string name="orgTypeCustom" msgid="1126322047677329218">"Tùy chỉnh"</string>
     <string name="relationTypeCustom" msgid="282938315217441351">"Tùy chỉnh"</string>
@@ -904,7 +904,7 @@
     <string name="relationTypeSpouse" msgid="6916682664436031703">"Vợ/chồng"</string>
     <string name="sipAddressTypeCustom" msgid="6283889809842649336">"Tùy chỉnh"</string>
     <string name="sipAddressTypeHome" msgid="5918441930656878367">"Nhà riêng"</string>
-    <string name="sipAddressTypeWork" msgid="7873967986701216770">"Cơ quan"</string>
+    <string name="sipAddressTypeWork" msgid="7873967986701216770">"Nơi làm việc"</string>
     <string name="sipAddressTypeOther" msgid="6317012577345187275">"Khác"</string>
     <string name="quick_contacts_not_available" msgid="1262709196045052223">"Không tìm thấy ứng dụng nào để xem liên hệ này."</string>
     <string name="keyguard_password_enter_pin_code" msgid="6401406801060956153">"Nhập mã PIN"</string>
diff --git a/core/res/res/values/colors_material.xml b/core/res/res/values/colors_material.xml
index ea6e1f1..a99ba15 100644
--- a/core/res/res/values/colors_material.xml
+++ b/core/res/res/values/colors_material.xml
@@ -72,8 +72,8 @@
     <item name="secondary_content_alpha_material_dark" format="float" type="dimen">.7</item>
     <item name="secondary_content_alpha_material_light" format="float" type="dimen">0.60</item>
 
-    <item name="highlight_alpha_material_light" format="float" type="dimen">0.10</item>
-    <item name="highlight_alpha_material_dark" format="float" type="dimen">0.10</item>
+    <item name="highlight_alpha_material_light" format="float" type="dimen">0.5</item>
+    <item name="highlight_alpha_material_dark" format="float" type="dimen">0.5</item>
     <item name="highlight_alpha_material_colored" format="float" type="dimen">0.10</item>
 
     <!-- Primary & accent colors -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index a8c2246..a6be07d 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -576,6 +576,10 @@
          rotations as the default behavior. -->
     <bool name="config_allowAllRotations">false</bool>
 
+    <!-- If false and config_allowAllRotations is false, the screen will rotate to the natural
+         orientation of the device when the auto-rotate policy is toggled. -->
+    <bool name="config_useCurrentRotationOnRotationLockChange">false</bool>
+
     <!-- If true, the direction rotation is applied to get to an application's requested
          orientation is reversed.  Normally, the model is that landscape is
          clockwise from portrait; thus on a portrait device an app requesting
@@ -2074,6 +2078,9 @@
          STREAM_MUSIC as if it's on TV platform. -->
     <bool name="config_single_volume">false</bool>
 
+    <!-- Volume policy -->
+    <bool name="config_volume_down_to_enter_silent">false</bool>
+
     <!-- The number of volume steps for the notification stream -->
     <integer name="config_audio_notif_vol_steps">7</integer>
 
@@ -4972,9 +4979,8 @@
     <!-- If face auth sends the user directly to home/last open app, or stays on keyguard -->
     <bool name="config_faceAuthDismissesKeyguard">true</bool>
 
-    <!-- Default value for whether a SFPS device is required to be interactive for fingerprint auth
-    to unlock the device.  -->
-    <bool name="config_requireScreenOnToAuthEnabled">false</bool>
+    <!-- Default value for performant auth feature. -->
+    <bool name="config_performantAuthDefault">false</bool>
 
     <!-- The component name for the default profile supervisor, which can be set as a profile owner
     even after user setup is complete. The defined component should be used for supervision purposes
@@ -5213,6 +5219,14 @@
          having a separating hinge. -->
     <bool name="config_isDisplayHingeAlwaysSeparating">false</bool>
 
+    <!-- Whether enabling rotation compat policy for immersive apps that prevents auto rotation
+         into non-optimal screen orientation while in fullscreen. This is needed because immersive
+         apps, such as games, are often not optimized for all orientations and can have a poor UX
+         when rotated. Additionally, some games rely on sensors for the gameplay so users can
+         trigger such rotations accidentally when auto rotation is on.
+         Applicable only if ignoreOrientationRequest is enabled. -->
+    <bool name="config_letterboxIsDisplayRotationImmersiveAppCompatPolicyEnabled">false</bool>
+
     <!-- Aspect ratio of letterboxing for fixed orientation. Values <= 1.0 will be ignored.
          Note: Activity min/max aspect ratio restrictions will still be respected.
          Therefore this override can control the maximum screen area that can be occupied by
@@ -5328,6 +5342,11 @@
         If given value is outside of this range, the option 0 (top) is assummed. -->
     <integer name="config_letterboxDefaultPositionForTabletopModeReachability">0</integer>
 
+    <!-- Whether should ignore app requested orientation in response to an app
+         calling Activity#setRequestedOrientation. See
+         LetterboxUiController#shouldIgnoreRequestedOrientation for details. -->
+    <bool name="config_letterboxIsPolicyForIgnoringRequestedOrientationEnabled">false</bool>
+
     <!-- Whether displaying letterbox education is enabled for letterboxed fullscreen apps. -->
     <bool name="config_letterboxIsEducationEnabled">false</bool>
 
@@ -5340,6 +5359,9 @@
     <!-- Whether using split screen aspect ratio as a default aspect ratio for unresizable apps. -->
     <bool name="config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled">false</bool>
 
+    <!-- Whether using display aspect ratio as a default aspect ratio for all letterboxed apps. -->
+    <bool name="config_letterboxIsDisplayAspectRatioForFixedOrientationLetterboxEnabled">false</bool>
+
     <!-- Whether the specific behaviour for translucent activities letterboxing is enabled.
          TODO(b/255532890) Enable when ignoreOrientationRequest is set -->
     <bool name="config_letterboxIsEnabledForTranslucentActivities">false</bool>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 5c3e1d6..be9f6d2 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -321,6 +321,7 @@
   <java-symbol type="bool" name="config_use_strict_phone_number_comparation_for_kazakhstan" />
   <java-symbol type="integer" name="config_phonenumber_compare_min_match" />
   <java-symbol type="bool" name="config_single_volume" />
+  <java-symbol type="bool" name="config_volume_down_to_enter_silent" />
   <java-symbol type="bool" name="config_voice_capable" />
   <java-symbol type="bool" name="config_requireCallCapableAccountForHandle" />
   <java-symbol type="bool" name="config_user_notification_of_restrictied_mobile_access" />
@@ -1732,6 +1733,7 @@
   <java-symbol type="attr" name="dialogTitleDecorLayout" />
   <java-symbol type="attr" name="dialogTitleIconsDecorLayout" />
   <java-symbol type="bool" name="config_allowAllRotations" />
+  <java-symbol type="bool" name="config_useCurrentRotationOnRotationLockChange"/>
   <java-symbol type="bool" name="config_annoy_dianne" />
   <java-symbol type="bool" name="config_startDreamImmediatelyOnDock" />
   <java-symbol type="bool" name="config_carDockEnablesAccelerometer" />
@@ -2724,7 +2726,7 @@
   <java-symbol type="array" name="config_face_acquire_vendor_biometricprompt_ignorelist" />
   <java-symbol type="bool" name="config_faceAuthSupportsSelfIllumination" />
   <java-symbol type="bool" name="config_faceAuthDismissesKeyguard" />
-  <java-symbol type="bool" name="config_requireScreenOnToAuthEnabled" />
+  <java-symbol type="bool" name="config_performantAuthDefault" />
 
   <!-- Face config -->
   <java-symbol type="integer" name="config_faceMaxTemplatesPerUser" />
@@ -4441,6 +4443,7 @@
   <java-symbol type="dimen" name="controls_thumbnail_image_max_height" />
   <java-symbol type="dimen" name="controls_thumbnail_image_max_width" />
 
+  <java-symbol type="bool" name="config_letterboxIsDisplayRotationImmersiveAppCompatPolicyEnabled" />
   <java-symbol type="dimen" name="config_fixedOrientationLetterboxAspectRatio" />
   <java-symbol type="dimen" name="config_letterboxBackgroundWallpaperBlurRadius" />
   <java-symbol type="integer" name="config_letterboxActivityCornersRadius" />
@@ -4457,9 +4460,11 @@
   <java-symbol type="integer" name="config_letterboxDefaultPositionForVerticalReachability" />
   <java-symbol type="integer" name="config_letterboxDefaultPositionForBookModeReachability" />
   <java-symbol type="integer" name="config_letterboxDefaultPositionForTabletopModeReachability" />
+  <java-symbol type="bool" name="config_letterboxIsPolicyForIgnoringRequestedOrientationEnabled" />
   <java-symbol type="bool" name="config_letterboxIsEducationEnabled" />
   <java-symbol type="dimen" name="config_letterboxDefaultMinAspectRatioForUnresizableApps" />
   <java-symbol type="bool" name="config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled" />
+  <java-symbol type="bool" name="config_letterboxIsDisplayAspectRatioForFixedOrientationLetterboxEnabled" />
   <java-symbol type="bool" name="config_isCompatFakeFocusEnabled" />
   <java-symbol type="bool" name="config_isWindowManagerCameraCompatTreatmentEnabled" />
   <java-symbol type="bool" name="config_isCameraCompatControlForStretchedIssuesEnabled" />
diff --git a/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java b/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java
index ed2b101..3768063 100644
--- a/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java
+++ b/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java
@@ -368,4 +368,20 @@
             PropertyInvalidatedCache.MODULE_BLUETOOTH, "getState");
         assertEquals(n1, "cache_key.bluetooth.get_state");
     }
+
+    @Test
+    public void testOnTrimMemory() {
+        TestCache cache = new TestCache(MODULE, "trimMemoryTest");
+        // The cache is not active until it has been invalidated once.
+        cache.invalidateCache();
+        // Populate the cache with six entries.
+        for (int i = 0; i < 6; i++) {
+            cache.query(i);
+        }
+        // The maximum number of entries in TestCache is 4, so even though six entries were
+        // created, only four are retained.
+        assertEquals(4, cache.size());
+        PropertyInvalidatedCache.onTrimMemory();
+        assertEquals(0, cache.size());
+    }
 }
diff --git a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
index f370ebd..9d6b29e 100644
--- a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
+++ b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
@@ -17,6 +17,7 @@
 package android.window;
 
 import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
@@ -60,8 +61,8 @@
     private OnBackAnimationCallback mCallback1;
     @Mock
     private OnBackAnimationCallback mCallback2;
-    @Mock
-    private BackEvent mBackEvent;
+    private final BackMotionEvent mBackEvent = new BackMotionEvent(
+            0, 0, 0, BackEvent.EDGE_LEFT, null);
 
     @Before
     public void setUp() throws Exception {
@@ -89,12 +90,12 @@
                 captor.capture());
         captor.getAllValues().get(0).getCallback().onBackStarted(mBackEvent);
         waitForIdle();
-        verify(mCallback1).onBackStarted(mBackEvent);
+        verify(mCallback1).onBackStarted(any(BackEvent.class));
         verifyZeroInteractions(mCallback2);
 
         captor.getAllValues().get(1).getCallback().onBackStarted(mBackEvent);
         waitForIdle();
-        verify(mCallback2).onBackStarted(mBackEvent);
+        verify(mCallback2).onBackStarted(any(BackEvent.class));
         verifyNoMoreInteractions(mCallback1);
     }
 
@@ -114,7 +115,7 @@
         assertEquals(captor.getValue().getPriority(), OnBackInvokedDispatcher.PRIORITY_OVERLAY);
         captor.getValue().getCallback().onBackStarted(mBackEvent);
         waitForIdle();
-        verify(mCallback1).onBackStarted(mBackEvent);
+        verify(mCallback1).onBackStarted(any(BackEvent.class));
     }
 
     @Test
@@ -152,6 +153,6 @@
         verify(mWindowSession).setOnBackInvokedCallbackInfo(Mockito.eq(mWindow), captor.capture());
         captor.getValue().getCallback().onBackStarted(mBackEvent);
         waitForIdle();
-        verify(mCallback2).onBackStarted(mBackEvent);
+        verify(mCallback2).onBackStarted(any(BackEvent.class));
     }
 }
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityWorkProfileTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityWorkProfileTest.java
index c6537c0..b6ea9dd 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityWorkProfileTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityWorkProfileTest.java
@@ -16,11 +16,14 @@
 
 package com.android.internal.app;
 
+import static android.util.PollingCheck.waitFor;
+
 import static androidx.test.espresso.Espresso.onView;
 import static androidx.test.espresso.action.ViewActions.click;
 import static androidx.test.espresso.action.ViewActions.swipeUp;
 import static androidx.test.espresso.assertion.ViewAssertions.matches;
 import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.isSelected;
 import static androidx.test.espresso.matcher.ViewMatchers.withId;
 import static androidx.test.espresso.matcher.ViewMatchers.withText;
 
@@ -49,6 +52,8 @@
 import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
 import com.android.internal.app.ChooserActivityWorkProfileTest.TestCase.Tab;
 
+import junit.framework.AssertionFailedError;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -331,8 +336,17 @@
         final int stringId = tab == Tab.WORK ? R.string.resolver_work_tab
                 : R.string.resolver_personal_tab;
 
-        onView(withText(stringId)).perform(click());
-        waitForIdle();
+        waitFor(() -> {
+            onView(withText(stringId)).perform(click());
+            waitForIdle();
+
+            try {
+                onView(withText(stringId)).check(matches(isSelected()));
+                return true;
+            } catch (AssertionFailedError e) {
+                return false;
+            }
+        });
 
         onView(withId(R.id.contentPanel))
                 .perform(swipeUp());
diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverActivityWorkProfileTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverActivityWorkProfileTest.java
index ce68906..4a79f5e 100644
--- a/core/tests/coretests/src/com/android/internal/app/ResolverActivityWorkProfileTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverActivityWorkProfileTest.java
@@ -16,11 +16,14 @@
 
 package com.android.internal.app;
 
+import static android.util.PollingCheck.waitFor;
+
 import static androidx.test.espresso.Espresso.onView;
 import static androidx.test.espresso.action.ViewActions.click;
 import static androidx.test.espresso.action.ViewActions.swipeUp;
 import static androidx.test.espresso.assertion.ViewAssertions.matches;
 import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.isSelected;
 import static androidx.test.espresso.matcher.ViewMatchers.withId;
 import static androidx.test.espresso.matcher.ViewMatchers.withText;
 
@@ -48,6 +51,8 @@
 import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
 import com.android.internal.app.ResolverActivityWorkProfileTest.TestCase.Tab;
 
+import junit.framework.AssertionFailedError;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -309,8 +314,17 @@
         final int stringId = tab == Tab.WORK ? R.string.resolver_work_tab
                 : R.string.resolver_personal_tab;
 
-        onView(withText(stringId)).perform(click());
-        waitForIdle();
+        waitFor(() -> {
+            onView(withText(stringId)).perform(click());
+            waitForIdle();
+
+            try {
+                onView(withText(stringId)).check(matches(isSelected()));
+                return true;
+            } catch (AssertionFailedError e) {
+                return false;
+            }
+        });
 
         onView(withId(R.id.contentPanel))
                 .perform(swipeUp());
diff --git a/core/tests/screenshothelpertests/Android.bp b/core/tests/screenshothelpertests/Android.bp
index 37af99c..3c71e6e 100644
--- a/core/tests/screenshothelpertests/Android.bp
+++ b/core/tests/screenshothelpertests/Android.bp
@@ -13,7 +13,7 @@
     srcs: [
         "src/**/*.java",
     ],
-    
+
     static_libs: [
         "frameworks-base-testutils",
         "androidx.test.runner",
@@ -21,6 +21,7 @@
         "androidx.test.ext.junit",
         "mockito-target-minus-junit4",
         "platform-test-annotations",
+        "testng",
     ],
 
     libs: [
diff --git a/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotHelperTest.java b/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotHelperTest.java
index 2719431..5c9894e 100644
--- a/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotHelperTest.java
+++ b/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotHelperTest.java
@@ -17,6 +17,7 @@
 package com.android.internal.util;
 
 import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;
+import static android.view.WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE;
 
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.fail;
@@ -31,9 +32,11 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.ColorSpace;
 import android.graphics.Insets;
 import android.graphics.Rect;
-import android.os.Bundle;
+import android.hardware.HardwareBuffer;
 import android.os.Handler;
 import android.os.Looper;
 import android.view.WindowManager;
@@ -79,30 +82,48 @@
 
     @Test
     public void testFullscreenScreenshot() {
-        mScreenshotHelper.takeScreenshot(TAKE_SCREENSHOT_FULLSCREEN,
+        mScreenshotHelper.takeScreenshot(
                 WindowManager.ScreenshotSource.SCREENSHOT_OTHER, mHandler, null);
     }
 
     @Test
+    public void testFullscreenScreenshotRequest() {
+        ScreenshotRequest request = new ScreenshotRequest.Builder(
+                TAKE_SCREENSHOT_FULLSCREEN, WindowManager.ScreenshotSource.SCREENSHOT_OTHER)
+                .build();
+        mScreenshotHelper.takeScreenshot(request, mHandler, null);
+    }
+
+    @Test
     public void testProvidedImageScreenshot() {
-        mScreenshotHelper.provideScreenshot(
-                new Bundle(), new Rect(), Insets.of(0, 0, 0, 0), 1, 1, new ComponentName("", ""),
-                WindowManager.ScreenshotSource.SCREENSHOT_OTHER, mHandler, null);
+        HardwareBuffer buffer = HardwareBuffer.create(
+                10, 10, HardwareBuffer.RGBA_8888, 1, HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE);
+        Bitmap bitmap = Bitmap.wrapHardwareBuffer(buffer, ColorSpace.get(ColorSpace.Named.SRGB));
+        ScreenshotRequest request = new ScreenshotRequest.Builder(
+                TAKE_SCREENSHOT_PROVIDED_IMAGE, WindowManager.ScreenshotSource.SCREENSHOT_OTHER)
+                .setTopComponent(new ComponentName("", ""))
+                .setTaskId(1)
+                .setUserId(1)
+                .setBitmap(bitmap)
+                .setBoundsOnScreen(new Rect())
+                .setInsets(Insets.NONE)
+                .build();
+        mScreenshotHelper.takeScreenshot(request, mHandler, null);
     }
 
     @Test
     public void testScreenshotTimesOut() {
         long timeoutMs = 10;
+        ScreenshotRequest request = new ScreenshotRequest.Builder(
+                TAKE_SCREENSHOT_FULLSCREEN, WindowManager.ScreenshotSource.SCREENSHOT_OTHER)
+                .build();
 
         CountDownLatch lock = new CountDownLatch(1);
-        mScreenshotHelper.takeScreenshot(TAKE_SCREENSHOT_FULLSCREEN,
-                WindowManager.ScreenshotSource.SCREENSHOT_OTHER,
-                mHandler,
-                timeoutMs,
+        mScreenshotHelper.takeScreenshotInternal(request, mHandler,
                 uri -> {
                     assertNull(uri);
                     lock.countDown();
-                });
+                }, timeoutMs);
 
         try {
             // Add tolerance for delay to prevent flakes.
diff --git a/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotRequestTest.java b/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotRequestTest.java
new file mode 100644
index 0000000..30540a5
--- /dev/null
+++ b/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotRequestTest.java
@@ -0,0 +1,139 @@
+/*
+ * 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.util;
+
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+import static android.os.UserHandle.USER_NULL;
+import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_OTHER;
+import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;
+import static android.view.WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+
+import static org.testng.Assert.assertThrows;
+
+import android.content.ComponentName;
+import android.graphics.Bitmap;
+import android.graphics.ColorSpace;
+import android.graphics.Insets;
+import android.graphics.Rect;
+import android.hardware.HardwareBuffer;
+import android.os.Parcel;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public final class ScreenshotRequestTest {
+    private final ComponentName mComponentName =
+            new ComponentName("android.test", "android.test.Component");
+
+    @Test
+    public void testSimpleScreenshot() {
+        ScreenshotRequest in =
+                new ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_OTHER).build();
+
+        Parcel parcel = Parcel.obtain();
+        in.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        ScreenshotRequest out = ScreenshotRequest.CREATOR.createFromParcel(parcel);
+
+        assertEquals(TAKE_SCREENSHOT_FULLSCREEN, out.getType());
+        assertEquals(SCREENSHOT_OTHER, out.getSource());
+        assertNull("Top component was expected to be null", out.getTopComponent());
+        assertEquals(INVALID_TASK_ID, out.getTaskId());
+        assertEquals(USER_NULL, out.getUserId());
+        assertNull("Bitmap was expected to be null", out.getBitmap());
+        assertNull("Bounds were expected to be null", out.getBoundsInScreen());
+        assertEquals(Insets.NONE, out.getInsets());
+    }
+
+    @Test
+    public void testProvidedScreenshot() {
+        Bitmap bitmap = makeHardwareBitmap(50, 50);
+        ScreenshotRequest in =
+                new ScreenshotRequest.Builder(TAKE_SCREENSHOT_PROVIDED_IMAGE, SCREENSHOT_OTHER)
+                        .setTopComponent(mComponentName)
+                        .setTaskId(2)
+                        .setUserId(3)
+                        .setBitmap(bitmap)
+                        .setBoundsOnScreen(new Rect(10, 10, 60, 60))
+                        .setInsets(Insets.of(2, 3, 4, 5))
+                        .build();
+
+        Parcel parcel = Parcel.obtain();
+        in.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        ScreenshotRequest out = ScreenshotRequest.CREATOR.createFromParcel(parcel);
+
+        assertEquals(TAKE_SCREENSHOT_PROVIDED_IMAGE, out.getType());
+        assertEquals(SCREENSHOT_OTHER, out.getSource());
+        assertEquals(mComponentName, out.getTopComponent());
+        assertEquals(2, out.getTaskId());
+        assertEquals(3, out.getUserId());
+        assertTrue("Bitmaps should be equal", out.getBitmap().sameAs(bitmap));
+        assertEquals(new Rect(10, 10, 60, 60), out.getBoundsInScreen());
+        assertEquals(Insets.of(2, 3, 4, 5), out.getInsets());
+    }
+
+    @Test
+    public void testProvidedScreenshot_nullBitmap() {
+        ScreenshotRequest.Builder inBuilder =
+                new ScreenshotRequest.Builder(TAKE_SCREENSHOT_PROVIDED_IMAGE, SCREENSHOT_OTHER)
+                        .setTopComponent(mComponentName)
+                        .setTaskId(2)
+                        .setUserId(3)
+                        .setBoundsOnScreen(new Rect(10, 10, 60, 60))
+                        .setInsets(Insets.of(2, 3, 4, 5));
+
+        assertThrows(IllegalStateException.class, inBuilder::build);
+    }
+
+    @Test
+    public void testFullScreenshot_withBitmap() {
+        // A bitmap added to a FULLSCREEN request will be ignored, but it's technically valid
+        Bitmap bitmap = makeHardwareBitmap(50, 50);
+        ScreenshotRequest in =
+                new ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_OTHER)
+                        .setBitmap(bitmap)
+                        .build();
+
+        Parcel parcel = Parcel.obtain();
+        in.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        ScreenshotRequest out = ScreenshotRequest.CREATOR.createFromParcel(parcel);
+
+        assertEquals(TAKE_SCREENSHOT_FULLSCREEN, out.getType());
+        assertEquals(SCREENSHOT_OTHER, out.getSource());
+        assertNull(out.getTopComponent());
+        assertEquals(INVALID_TASK_ID, out.getTaskId());
+        assertEquals(USER_NULL, out.getUserId());
+        assertTrue("Bitmaps should be equal", out.getBitmap().sameAs(bitmap));
+        assertNull("Bounds expected to be null", out.getBoundsInScreen());
+        assertEquals(Insets.NONE, out.getInsets());
+    }
+
+    private Bitmap makeHardwareBitmap(int width, int height) {
+        HardwareBuffer buffer = HardwareBuffer.create(
+                width, height, HardwareBuffer.RGBA_8888, 1, HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE);
+        return Bitmap.wrapHardwareBuffer(buffer, ColorSpace.get(ColorSpace.Named.SRGB));
+    }
+}
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index 417a27d..7e2cac1 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -23,7 +23,6 @@
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
 import android.animation.ValueAnimator;
-import android.annotation.ColorInt;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -983,9 +982,9 @@
         RippleShader shader = new RippleShader();
         // Grab the color for the current state and cut the alpha channel in
         // half so that the ripple and background together yield full alpha.
-        final int color = clampAlpha(mMaskColorFilter == null
+        final int color = mMaskColorFilter == null
                 ? mState.mColor.getColorForState(getState(), Color.BLACK)
-                : mMaskColorFilter.getColor());
+                : mMaskColorFilter.getColor();
         final int effectColor = mState.mEffectColor.getColorForState(getState(), Color.MAGENTA);
         final float noisePhase = AnimationUtils.currentAnimationTimeMillis();
         shader.setColor(color, effectColor);
@@ -1008,13 +1007,6 @@
         return properties;
     }
 
-    private int clampAlpha(@ColorInt int color) {
-        if (Color.alpha(color) < 128) {
-            return  (color & 0x00FFFFFF) | 0x80000000;
-        }
-        return color;
-    }
-
     @Override
     public void invalidateSelf() {
         invalidateSelf(true);
@@ -1229,7 +1221,7 @@
 
         // Grab the color for the current state and cut the alpha channel in
         // half so that the ripple and background together yield full alpha.
-        final int color = clampAlpha(mState.mColor.getColorForState(getState(), Color.BLACK));
+        final int color = mState.mColor.getColorForState(getState(), Color.BLACK);
         final Paint p = mRipplePaint;
 
         if (mMaskColorFilter != null) {
diff --git a/libs/WindowManager/Jetpack/Android.bp b/libs/WindowManager/Jetpack/Android.bp
index dc4b563..a5b192c 100644
--- a/libs/WindowManager/Jetpack/Android.bp
+++ b/libs/WindowManager/Jetpack/Android.bp
@@ -63,6 +63,12 @@
     sdk_version: "current",
 }
 
+android_library_import {
+    name: "window-extensions-core",
+    aars: ["window-extensions-core-release.aar"],
+    sdk_version: "current",
+}
+
 java_library {
     name: "androidx.window.extensions",
     srcs: [
@@ -70,7 +76,10 @@
         "src/androidx/window/util/**/*.java",
         "src/androidx/window/common/**/*.java",
     ],
-    static_libs: ["window-extensions"],
+    static_libs: [
+        "window-extensions",
+        "window-extensions-core",
+    ],
     installable: true,
     sdk_version: "core_platform",
     system_ext_specific: true,
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java
index fb0a9db..666b472 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java
@@ -17,9 +17,13 @@
 package androidx.window.extensions;
 
 import android.app.ActivityThread;
+import android.app.Application;
 import android.content.Context;
+import android.window.TaskFragmentOrganizer;
 
 import androidx.annotation.NonNull;
+import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
+import androidx.window.common.RawFoldingFeatureProducer;
 import androidx.window.extensions.area.WindowAreaComponent;
 import androidx.window.extensions.area.WindowAreaComponentImpl;
 import androidx.window.extensions.embedding.ActivityEmbeddingComponent;
@@ -27,6 +31,8 @@
 import androidx.window.extensions.layout.WindowLayoutComponent;
 import androidx.window.extensions.layout.WindowLayoutComponentImpl;
 
+import java.util.Objects;
+
 
 /**
  * The reference implementation of {@link WindowExtensions} that implements the initial API version.
@@ -34,14 +40,58 @@
 public class WindowExtensionsImpl implements WindowExtensions {
 
     private final Object mLock = new Object();
-    private volatile WindowLayoutComponent mWindowLayoutComponent;
+    private volatile DeviceStateManagerFoldingFeatureProducer mFoldingFeatureProducer;
+    private volatile WindowLayoutComponentImpl mWindowLayoutComponent;
     private volatile SplitController mSplitController;
     private volatile WindowAreaComponent mWindowAreaComponent;
 
     // TODO(b/241126279) Introduce constants to better version functionality
     @Override
     public int getVendorApiLevel() {
-        return 1;
+        return 2;
+    }
+
+    @NonNull
+    private Application getApplication() {
+        return Objects.requireNonNull(ActivityThread.currentApplication());
+    }
+
+    @NonNull
+    private DeviceStateManagerFoldingFeatureProducer getFoldingFeatureProducer() {
+        if (mFoldingFeatureProducer == null) {
+            synchronized (mLock) {
+                if (mFoldingFeatureProducer == null) {
+                    Context context = getApplication();
+                    RawFoldingFeatureProducer foldingFeatureProducer =
+                            new RawFoldingFeatureProducer(context);
+                    mFoldingFeatureProducer =
+                            new DeviceStateManagerFoldingFeatureProducer(context,
+                                    foldingFeatureProducer);
+                }
+            }
+        }
+        return mFoldingFeatureProducer;
+    }
+
+    @NonNull
+    private WindowLayoutComponentImpl getWindowLayoutComponentImpl() {
+        if (mWindowLayoutComponent == null) {
+            synchronized (mLock) {
+                if (mWindowLayoutComponent == null) {
+                    Context context = getApplication();
+                    DeviceStateManagerFoldingFeatureProducer producer =
+                            getFoldingFeatureProducer();
+                    // TODO(b/263263909) Use the organizer to tell if an Activity is embededed.
+                    // Need to improve our Dependency Injection and centralize the logic.
+                    TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(command -> {
+                        throw new RuntimeException("Not allowed!");
+                    });
+                    mWindowLayoutComponent = new WindowLayoutComponentImpl(context, organizer,
+                            producer);
+                }
+            }
+        }
+        return mWindowLayoutComponent;
     }
 
     /**
@@ -52,15 +102,7 @@
      */
     @Override
     public WindowLayoutComponent getWindowLayoutComponent() {
-        if (mWindowLayoutComponent == null) {
-            synchronized (mLock) {
-                if (mWindowLayoutComponent == null) {
-                    Context context = ActivityThread.currentApplication();
-                    mWindowLayoutComponent = new WindowLayoutComponentImpl(context);
-                }
-            }
-        }
-        return mWindowLayoutComponent;
+        return getWindowLayoutComponentImpl();
     }
 
     /**
@@ -74,7 +116,10 @@
         if (mSplitController == null) {
             synchronized (mLock) {
                 if (mSplitController == null) {
-                    mSplitController = new SplitController();
+                    mSplitController = new SplitController(
+                            getWindowLayoutComponentImpl(),
+                            getFoldingFeatureProducer()
+                    );
                 }
             }
         }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
index b910287..00e13c9 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
@@ -17,6 +17,7 @@
 package androidx.window.extensions.embedding;
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.window.TaskFragmentOperation.OP_TYPE_SET_ANIMATION_PARAMS;
 
 import static androidx.window.extensions.embedding.SplitContainer.getFinishPrimaryWithSecondaryBehavior;
 import static androidx.window.extensions.embedding.SplitContainer.getFinishSecondaryWithPrimaryBehavior;
@@ -31,8 +32,10 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.util.ArrayMap;
+import android.window.TaskFragmentAnimationParams;
 import android.window.TaskFragmentCreationParams;
 import android.window.TaskFragmentInfo;
+import android.window.TaskFragmentOperation;
 import android.window.TaskFragmentOrganizer;
 import android.window.TaskFragmentTransaction;
 import android.window.WindowContainerTransaction;
@@ -114,13 +117,14 @@
      * @param activityIntent    Intent to start the secondary Activity with.
      * @param activityOptions   ActivityOptions to start the secondary Activity with.
      * @param windowingMode     the windowing mode to set for the TaskFragments.
+     * @param splitAttributes   the {@link SplitAttributes} to represent the split.
      */
     void startActivityToSide(@NonNull WindowContainerTransaction wct,
             @NonNull IBinder launchingFragmentToken, @NonNull Rect launchingFragmentBounds,
             @NonNull Activity launchingActivity, @NonNull IBinder secondaryFragmentToken,
             @NonNull Rect secondaryFragmentBounds, @NonNull Intent activityIntent,
             @Nullable Bundle activityOptions, @NonNull SplitRule rule,
-            @WindowingMode int windowingMode) {
+            @WindowingMode int windowingMode, @NonNull SplitAttributes splitAttributes) {
         final IBinder ownerToken = launchingActivity.getActivityToken();
 
         // Create or resize the launching TaskFragment.
@@ -131,6 +135,7 @@
             createTaskFragmentAndReparentActivity(wct, launchingFragmentToken, ownerToken,
                     launchingFragmentBounds, windowingMode, launchingActivity);
         }
+        updateAnimationParams(wct, launchingFragmentToken, splitAttributes);
 
         // Create a TaskFragment for the secondary activity.
         final TaskFragmentCreationParams fragmentOptions = new TaskFragmentCreationParams.Builder(
@@ -144,6 +149,7 @@
                 .setPairedPrimaryFragmentToken(launchingFragmentToken)
                 .build();
         createTaskFragment(wct, fragmentOptions);
+        updateAnimationParams(wct, secondaryFragmentToken, splitAttributes);
         wct.startActivityInTaskFragment(secondaryFragmentToken, ownerToken, activityIntent,
                 activityOptions);
 
@@ -163,6 +169,7 @@
         resizeTaskFragment(wct, fragmentToken, new Rect());
         setAdjacentTaskFragments(wct, fragmentToken, null /* secondary */, null /* splitRule */);
         updateWindowingMode(wct, fragmentToken, WINDOWING_MODE_UNDEFINED);
+        updateAnimationParams(wct, fragmentToken, TaskFragmentAnimationParams.DEFAULT);
     }
 
     /**
@@ -175,6 +182,7 @@
         createTaskFragmentAndReparentActivity(
                 wct, fragmentToken, activity.getActivityToken(), new Rect(),
                 WINDOWING_MODE_UNDEFINED, activity);
+        updateAnimationParams(wct, fragmentToken, TaskFragmentAnimationParams.DEFAULT);
     }
 
     /**
@@ -183,10 +191,25 @@
      */
     void createTaskFragment(@NonNull WindowContainerTransaction wct, @NonNull IBinder fragmentToken,
             @NonNull IBinder ownerToken, @NonNull Rect bounds, @WindowingMode int windowingMode) {
+        createTaskFragment(wct, fragmentToken, ownerToken, bounds, windowingMode,
+                null /* pairedActivityToken */);
+    }
+
+    /**
+     * @param ownerToken The token of the activity that creates this task fragment. It does not
+     *                   have to be a child of this task fragment, but must belong to the same task.
+     * @param pairedActivityToken The token of the activity that will be reparented to this task
+     *                            fragment. When it is not {@code null}, the task fragment will be
+     *                            positioned right above it.
+     */
+    void createTaskFragment(@NonNull WindowContainerTransaction wct, @NonNull IBinder fragmentToken,
+            @NonNull IBinder ownerToken, @NonNull Rect bounds, @WindowingMode int windowingMode,
+            @Nullable IBinder pairedActivityToken) {
         final TaskFragmentCreationParams fragmentOptions = new TaskFragmentCreationParams.Builder(
                 getOrganizerToken(), fragmentToken, ownerToken)
                 .setInitialBounds(bounds)
                 .setWindowingMode(windowingMode)
+                .setPairedActivityToken(pairedActivityToken)
                 .build();
         createTaskFragment(wct, fragmentOptions);
     }
@@ -208,8 +231,10 @@
     private void createTaskFragmentAndReparentActivity(@NonNull WindowContainerTransaction wct,
             @NonNull IBinder fragmentToken, @NonNull IBinder ownerToken, @NonNull Rect bounds,
             @WindowingMode int windowingMode, @NonNull Activity activity) {
-        createTaskFragment(wct, fragmentToken, ownerToken, bounds, windowingMode);
-        wct.reparentActivityToTaskFragment(fragmentToken, activity.getActivityToken());
+        final IBinder reparentActivityToken = activity.getActivityToken();
+        createTaskFragment(wct, fragmentToken, ownerToken, bounds, windowingMode,
+                reparentActivityToken);
+        wct.reparentActivityToTaskFragment(fragmentToken, reparentActivityToken);
     }
 
     void setAdjacentTaskFragments(@NonNull WindowContainerTransaction wct,
@@ -270,6 +295,24 @@
         wct.setWindowingMode(mFragmentInfos.get(fragmentToken).getToken(), windowingMode);
     }
 
+    /**
+     * Updates the {@link TaskFragmentAnimationParams} for the given TaskFragment based on
+     * {@link SplitAttributes}.
+     */
+    void updateAnimationParams(@NonNull WindowContainerTransaction wct,
+            @NonNull IBinder fragmentToken, @NonNull SplitAttributes splitAttributes) {
+        updateAnimationParams(wct, fragmentToken, createAnimationParamsOrDefault(splitAttributes));
+    }
+
+    void updateAnimationParams(@NonNull WindowContainerTransaction wct,
+            @NonNull IBinder fragmentToken, @NonNull TaskFragmentAnimationParams animationParams) {
+        final TaskFragmentOperation operation = new TaskFragmentOperation.Builder(
+                OP_TYPE_SET_ANIMATION_PARAMS)
+                .setAnimationParams(animationParams)
+                .build();
+        wct.setTaskFragmentOperation(fragmentToken, operation);
+    }
+
     void deleteTaskFragment(@NonNull WindowContainerTransaction wct,
             @NonNull IBinder fragmentToken) {
         if (!mFragmentInfos.containsKey(fragmentToken)) {
@@ -291,4 +334,14 @@
     public void onTransactionReady(@NonNull TaskFragmentTransaction transaction) {
         mCallback.onTransactionReady(transaction);
     }
+
+    private static TaskFragmentAnimationParams createAnimationParamsOrDefault(
+            @Nullable SplitAttributes splitAttributes) {
+        if (splitAttributes == null) {
+            return TaskFragmentAnimationParams.DEFAULT;
+        }
+        return new TaskFragmentAnimationParams.Builder()
+                .setAnimationBackgroundColor(splitAttributes.getAnimationBackgroundColor())
+                .build();
+    }
 }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index 1af1313..8b3a471 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -65,6 +65,7 @@
 import android.util.Size;
 import android.util.SparseArray;
 import android.view.WindowMetrics;
+import android.window.TaskFragmentAnimationParams;
 import android.window.TaskFragmentInfo;
 import android.window.TaskFragmentParentInfo;
 import android.window.TaskFragmentTransaction;
@@ -74,8 +75,11 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.window.common.CommonFoldingFeature;
+import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
 import androidx.window.common.EmptyLifecycleCallbacksAdapter;
-import androidx.window.extensions.WindowExtensionsProvider;
+import androidx.window.extensions.WindowExtensionsImpl;
+import androidx.window.extensions.core.util.function.Consumer;
+import androidx.window.extensions.core.util.function.Function;
 import androidx.window.extensions.embedding.TransactionManager.TransactionRecord;
 import androidx.window.extensions.layout.WindowLayoutComponentImpl;
 
@@ -86,7 +90,6 @@
 import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.Executor;
-import java.util.function.Consumer;
 
 /**
  * Main controller class that manages split states and presentation.
@@ -112,7 +115,7 @@
     /**
      * A developer-defined {@link SplitAttributes} calculator to compute the current
      * {@link SplitAttributes} with the current device and window states.
-     * It is registered via {@link #setSplitAttributesCalculator(SplitAttributesCalculator)}
+     * It is registered via {@link #setSplitAttributesCalculator(Function)}
      * and unregistered via {@link #clearSplitAttributesCalculator()}.
      * This is called when:
      * <ul>
@@ -125,7 +128,7 @@
      */
     @GuardedBy("mLock")
     @Nullable
-    private SplitAttributesCalculator mSplitAttributesCalculator;
+    private Function<SplitAttributesCalculatorParams, SplitAttributes> mSplitAttributesCalculator;
 
     /**
      * Map from Task id to {@link TaskContainer} which contains all TaskFragment and split pair info
@@ -138,25 +141,19 @@
     final SparseArray<TaskContainer> mTaskContainers = new SparseArray<>();
 
     /** Callback to Jetpack to notify about changes to split states. */
+    @GuardedBy("mLock")
     @Nullable
     private Consumer<List<SplitInfo>> mEmbeddingCallback;
     private final List<SplitInfo> mLastReportedSplitStates = new ArrayList<>();
     private final Handler mHandler;
     final Object mLock = new Object();
     private final ActivityStartMonitor mActivityStartMonitor;
-    @NonNull
-    final WindowLayoutComponentImpl mWindowLayoutComponent;
 
-    public SplitController() {
-        this((WindowLayoutComponentImpl) Objects.requireNonNull(WindowExtensionsProvider
-                .getWindowExtensions().getWindowLayoutComponent()));
-    }
-
-    @VisibleForTesting
-    SplitController(@NonNull WindowLayoutComponentImpl windowLayoutComponent) {
+    public SplitController(@NonNull WindowLayoutComponentImpl windowLayoutComponent,
+            @NonNull DeviceStateManagerFoldingFeatureProducer foldingFeatureProducer) {
         final MainThreadExecutor executor = new MainThreadExecutor();
         mHandler = executor.mHandler;
-        mPresenter = new SplitPresenter(executor, this);
+        mPresenter = new SplitPresenter(executor, windowLayoutComponent, this);
         mTransactionManager = new TransactionManager(mPresenter);
         final ActivityThread activityThread = ActivityThread.currentActivityThread();
         final Application application = activityThread.getApplication();
@@ -167,11 +164,11 @@
 
         mActivityStartMonitor = new ActivityStartMonitor();
         instrumentation.addMonitor(mActivityStartMonitor);
-        mWindowLayoutComponent = windowLayoutComponent;
-        mWindowLayoutComponent.addFoldingStateChangedCallback(new FoldingFeatureListener());
+        foldingFeatureProducer.addDataChangedCallback(new FoldingFeatureListener());
     }
 
-    private class FoldingFeatureListener implements Consumer<List<CommonFoldingFeature>> {
+    private class FoldingFeatureListener
+            implements java.util.function.Consumer<List<CommonFoldingFeature>> {
         @Override
         public void accept(List<CommonFoldingFeature> foldingFeatures) {
             synchronized (mLock) {
@@ -212,7 +209,8 @@
     }
 
     @Override
-    public void setSplitAttributesCalculator(@NonNull SplitAttributesCalculator calculator) {
+    public void setSplitAttributesCalculator(
+            @NonNull Function<SplitAttributesCalculatorParams, SplitAttributes> calculator) {
         synchronized (mLock) {
             mSplitAttributesCalculator = calculator;
         }
@@ -227,7 +225,7 @@
 
     @GuardedBy("mLock")
     @Nullable
-    SplitAttributesCalculator getSplitAttributesCalculator() {
+    Function<SplitAttributesCalculatorParams, SplitAttributes> getSplitAttributesCalculator() {
         return mSplitAttributesCalculator;
     }
 
@@ -240,9 +238,22 @@
 
     /**
      * Registers the split organizer callback to notify about changes to active splits.
+     * @deprecated Use {@link #setSplitInfoCallback(Consumer)} starting with
+     * {@link WindowExtensionsImpl#getVendorApiLevel()} 2.
      */
+    @Deprecated
     @Override
-    public void setSplitInfoCallback(@NonNull Consumer<List<SplitInfo>> callback) {
+    public void setSplitInfoCallback(
+            @NonNull java.util.function.Consumer<List<SplitInfo>> callback) {
+        Consumer<List<SplitInfo>> oemConsumer = callback::accept;
+        setSplitInfoCallback(oemConsumer);
+    }
+
+    /**
+     * Registers the split organizer callback to notify about changes to active splits.
+     * @since {@link WindowExtensionsImpl#getVendorApiLevel()} 2
+     */
+    public void setSplitInfoCallback(Consumer<List<SplitInfo>> callback) {
         synchronized (mLock) {
             mEmbeddingCallback = callback;
             updateCallbackIfNecessary();
@@ -1149,6 +1160,8 @@
                 taskId);
         mPresenter.createTaskFragment(wct, expandedContainer.getTaskFragmentToken(),
                 activityInTask.getActivityToken(), new Rect(), WINDOWING_MODE_UNDEFINED);
+        mPresenter.updateAnimationParams(wct, expandedContainer.getTaskFragmentToken(),
+                TaskFragmentAnimationParams.DEFAULT);
         return expandedContainer;
     }
 
@@ -1486,7 +1499,7 @@
      * Returns the active split that has the provided containers as primary and secondary or as
      * secondary and primary, if available.
      */
-    @VisibleForTesting
+    @GuardedBy("mLock")
     @Nullable
     SplitContainer getActiveSplitForContainers(
             @NonNull TaskFragmentContainer firstContainer,
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
index 9db9f87..668a7d5 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
@@ -36,20 +36,22 @@
 import android.view.View;
 import android.view.WindowInsets;
 import android.view.WindowMetrics;
+import android.window.TaskFragmentAnimationParams;
 import android.window.TaskFragmentCreationParams;
 import android.window.WindowContainerTransaction;
 
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.window.extensions.core.util.function.Function;
 import androidx.window.extensions.embedding.SplitAttributes.SplitType;
 import androidx.window.extensions.embedding.SplitAttributes.SplitType.ExpandContainersSplitType;
 import androidx.window.extensions.embedding.SplitAttributes.SplitType.HingeSplitType;
 import androidx.window.extensions.embedding.SplitAttributes.SplitType.RatioSplitType;
-import androidx.window.extensions.embedding.SplitAttributesCalculator.SplitAttributesCalculatorParams;
 import androidx.window.extensions.embedding.TaskContainer.TaskProperties;
 import androidx.window.extensions.layout.DisplayFeature;
 import androidx.window.extensions.layout.FoldingFeature;
+import androidx.window.extensions.layout.WindowLayoutComponentImpl;
 import androidx.window.extensions.layout.WindowLayoutInfo;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -136,10 +138,14 @@
             .setSplitType(new ExpandContainersSplitType())
             .build();
 
+    private final WindowLayoutComponentImpl mWindowLayoutComponent;
     private final SplitController mController;
 
-    SplitPresenter(@NonNull Executor executor, @NonNull SplitController controller) {
+    SplitPresenter(@NonNull Executor executor,
+            @NonNull WindowLayoutComponentImpl windowLayoutComponent,
+            @NonNull SplitController controller) {
         super(executor, controller);
+        mWindowLayoutComponent = windowLayoutComponent;
         mController = controller;
         registerOrganizer();
         if (!SplitController.ENABLE_SHELL_TRANSITIONS) {
@@ -176,7 +182,7 @@
         final Rect primaryRectBounds = getBoundsForPosition(POSITION_START, taskProperties,
                 splitAttributes);
         final TaskFragmentContainer primaryContainer = prepareContainerForActivity(wct,
-                primaryActivity, primaryRectBounds, null);
+                primaryActivity, primaryRectBounds, splitAttributes, null /* containerToAvoid */);
 
         // Create new empty task fragment
         final int taskId = primaryContainer.getTaskId();
@@ -189,6 +195,7 @@
         createTaskFragment(wct, secondaryContainer.getTaskFragmentToken(),
                 primaryActivity.getActivityToken(), secondaryRectBounds,
                 windowingMode);
+        updateAnimationParams(wct, secondaryContainer.getTaskFragmentToken(), splitAttributes);
 
         // Set adjacent to each other so that the containers below will be invisible.
         setAdjacentTaskFragments(wct, primaryContainer, secondaryContainer, rule,
@@ -222,7 +229,7 @@
         final Rect primaryRectBounds = getBoundsForPosition(POSITION_START, taskProperties,
                 splitAttributes);
         final TaskFragmentContainer primaryContainer = prepareContainerForActivity(wct,
-                primaryActivity, primaryRectBounds, null);
+                primaryActivity, primaryRectBounds, splitAttributes, null /* containerToAvoid */);
 
         final Rect secondaryRectBounds = getBoundsForPosition(POSITION_END, taskProperties,
                 splitAttributes);
@@ -236,7 +243,7 @@
             containerToAvoid = curSecondaryContainer;
         }
         final TaskFragmentContainer secondaryContainer = prepareContainerForActivity(wct,
-                secondaryActivity, secondaryRectBounds, containerToAvoid);
+                secondaryActivity, secondaryRectBounds, splitAttributes, containerToAvoid);
 
         // Set adjacent to each other so that the containers below will be invisible.
         setAdjacentTaskFragments(wct, primaryContainer, secondaryContainer, rule,
@@ -253,23 +260,26 @@
      */
     private TaskFragmentContainer prepareContainerForActivity(
             @NonNull WindowContainerTransaction wct, @NonNull Activity activity,
-            @NonNull Rect bounds, @Nullable TaskFragmentContainer containerToAvoid) {
+            @NonNull Rect bounds, @NonNull SplitAttributes splitAttributes,
+            @Nullable TaskFragmentContainer containerToAvoid) {
         TaskFragmentContainer container = mController.getContainerWithActivity(activity);
         final int taskId = container != null ? container.getTaskId() : activity.getTaskId();
         if (container == null || container == containerToAvoid) {
             container = mController.newContainer(activity, taskId);
             final int windowingMode = mController.getTaskContainer(taskId)
                     .getWindowingModeForSplitTaskFragment(bounds);
-            createTaskFragment(wct, container.getTaskFragmentToken(), activity.getActivityToken(),
-                    bounds, windowingMode);
+            final IBinder reparentActivityToken = activity.getActivityToken();
+            createTaskFragment(wct, container.getTaskFragmentToken(), reparentActivityToken,
+                    bounds, windowingMode, reparentActivityToken);
             wct.reparentActivityToTaskFragment(container.getTaskFragmentToken(),
-                    activity.getActivityToken());
+                    reparentActivityToken);
         } else {
             resizeTaskFragmentIfRegistered(wct, container, bounds);
             final int windowingMode = mController.getTaskContainer(taskId)
                     .getWindowingModeForSplitTaskFragment(bounds);
             updateTaskFragmentWindowingModeIfRegistered(wct, container, windowingMode);
         }
+        updateAnimationParams(wct, container.getTaskFragmentToken(), splitAttributes);
 
         return container;
     }
@@ -314,7 +324,7 @@
                 rule, splitAttributes);
         startActivityToSide(wct, primaryContainer.getTaskFragmentToken(), primaryRectBounds,
                 launchingActivity, secondaryContainer.getTaskFragmentToken(), secondaryRectBounds,
-                activityIntent, activityOptions, rule, windowingMode);
+                activityIntent, activityOptions, rule, windowingMode, splitAttributes);
         if (isPlaceholder) {
             // When placeholder is launched in split, we should keep the focus on the primary.
             wct.requestFocusOnTaskFragment(primaryContainer.getTaskFragmentToken());
@@ -365,6 +375,8 @@
                 primaryRectBounds);
         updateTaskFragmentWindowingModeIfRegistered(wct, primaryContainer, windowingMode);
         updateTaskFragmentWindowingModeIfRegistered(wct, secondaryContainer, windowingMode);
+        updateAnimationParams(wct, primaryContainer.getTaskFragmentToken(), splitAttributes);
+        updateAnimationParams(wct, secondaryContainer.getTaskFragmentToken(), splitAttributes);
     }
 
     private void setAdjacentTaskFragments(@NonNull WindowContainerTransaction wct,
@@ -459,6 +471,24 @@
         super.updateWindowingMode(wct, fragmentToken, windowingMode);
     }
 
+    @Override
+    void updateAnimationParams(@NonNull WindowContainerTransaction wct,
+            @NonNull IBinder fragmentToken, @NonNull TaskFragmentAnimationParams animationParams) {
+        final TaskFragmentContainer container = mController.getContainer(fragmentToken);
+        if (container == null) {
+            throw new IllegalStateException("Setting animation params for a task fragment that is"
+                    + " not registered with controller.");
+        }
+
+        if (container.areLastRequestedAnimationParamsEqual(animationParams)) {
+            // Return early if the animation params were already requested
+            return;
+        }
+
+        container.setLastRequestAnimationParams(animationParams);
+        super.updateAnimationParams(wct, fragmentToken, animationParams);
+    }
+
     /**
      * Expands the split container if the current split bounds are smaller than the Activity or
      * Intent that is added to the container.
@@ -522,23 +552,24 @@
             @NonNull SplitRule rule, @Nullable Pair<Size, Size> minDimensionsPair) {
         final Configuration taskConfiguration = taskProperties.getConfiguration();
         final WindowMetrics taskWindowMetrics = getTaskWindowMetrics(taskConfiguration);
-        final SplitAttributesCalculator calculator = mController.getSplitAttributesCalculator();
+        final Function<SplitAttributesCalculatorParams, SplitAttributes> calculator =
+                mController.getSplitAttributesCalculator();
         final SplitAttributes defaultSplitAttributes = rule.getDefaultSplitAttributes();
-        final boolean isDefaultMinSizeSatisfied = rule.checkParentMetrics(taskWindowMetrics);
+        final boolean areDefaultConstraintsSatisfied = rule.checkParentMetrics(taskWindowMetrics);
         if (calculator == null) {
-            if (!isDefaultMinSizeSatisfied) {
+            if (!areDefaultConstraintsSatisfied) {
                 return EXPAND_CONTAINERS_ATTRIBUTES;
             }
             return sanitizeSplitAttributes(taskProperties, defaultSplitAttributes,
                     minDimensionsPair);
         }
-        final WindowLayoutInfo windowLayoutInfo = mController.mWindowLayoutComponent
+        final WindowLayoutInfo windowLayoutInfo = mWindowLayoutComponent
                 .getCurrentWindowLayoutInfo(taskProperties.getDisplayId(),
                         taskConfiguration.windowConfiguration);
         final SplitAttributesCalculatorParams params = new SplitAttributesCalculatorParams(
-                taskWindowMetrics, taskConfiguration, defaultSplitAttributes,
-                isDefaultMinSizeSatisfied, windowLayoutInfo, rule.getTag());
-        final SplitAttributes splitAttributes = calculator.computeSplitAttributesForParams(params);
+                taskWindowMetrics, taskConfiguration, windowLayoutInfo, defaultSplitAttributes,
+                areDefaultConstraintsSatisfied, rule.getTag());
+        final SplitAttributes splitAttributes = calculator.apply(params);
         return sanitizeSplitAttributes(taskProperties, splitAttributes, minDimensionsPair);
     }
 
@@ -814,7 +845,7 @@
         final int displayId = taskProperties.getDisplayId();
         final WindowConfiguration windowConfiguration = taskProperties.getConfiguration()
                 .windowConfiguration;
-        final WindowLayoutInfo info = mController.mWindowLayoutComponent
+        final WindowLayoutInfo info = mWindowLayoutComponent
                 .getCurrentWindowLayoutInfo(displayId, windowConfiguration);
         final List<DisplayFeature> displayFeatures = info.getDisplayFeatures();
         if (displayFeatures.isEmpty()) {
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
index 6bfdfe7..17814c6 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
@@ -26,6 +26,7 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.util.Size;
+import android.window.TaskFragmentAnimationParams;
 import android.window.TaskFragmentInfo;
 import android.window.WindowContainerTransaction;
 
@@ -108,6 +109,13 @@
     private int mLastRequestedWindowingMode = WINDOWING_MODE_UNDEFINED;
 
     /**
+     * TaskFragmentAnimationParams that was requested last via
+     * {@link android.window.WindowContainerTransaction}.
+     */
+    @NonNull
+    private TaskFragmentAnimationParams mLastAnimationParams = TaskFragmentAnimationParams.DEFAULT;
+
+    /**
      * When the TaskFragment has appeared in server, but is empty, we should remove the TaskFragment
      * if it is still empty after the timeout.
      */
@@ -133,12 +141,26 @@
         mToken = new Binder("TaskFragmentContainer");
         mTaskContainer = taskContainer;
         if (pairedPrimaryContainer != null) {
+            // The TaskFragment will be positioned right above the paired container.
             if (pairedPrimaryContainer.getTaskContainer() != taskContainer) {
                 throw new IllegalArgumentException(
                         "pairedPrimaryContainer must be in the same Task");
             }
             final int primaryIndex = taskContainer.mContainers.indexOf(pairedPrimaryContainer);
             taskContainer.mContainers.add(primaryIndex + 1, this);
+        } else if (pendingAppearedActivity != null) {
+            // The TaskFragment will be positioned right above the pending appeared Activity. If any
+            // existing TaskFragment is empty with pending Intent, it is likely that the Activity of
+            // the pending Intent hasn't been created yet, so the new Activity should be below the
+            // empty TaskFragment.
+            int i = taskContainer.mContainers.size() - 1;
+            for (; i >= 0; i--) {
+                final TaskFragmentContainer container = taskContainer.mContainers.get(i);
+                if (!container.isEmpty() || container.getPendingAppearedIntent() == null) {
+                    break;
+                }
+            }
+            taskContainer.mContainers.add(i + 1, this);
         } else {
             taskContainer.mContainers.add(this);
         }
@@ -492,6 +514,8 @@
         }
 
         if (!shouldFinishDependent) {
+            // Always finish the placeholder when the primary is finished.
+            finishPlaceholderIfAny(wct, presenter);
             return;
         }
 
@@ -518,6 +542,28 @@
         mActivitiesToFinishOnExit.clear();
     }
 
+    @GuardedBy("mController.mLock")
+    private void finishPlaceholderIfAny(@NonNull WindowContainerTransaction wct,
+            @NonNull SplitPresenter presenter) {
+        final List<TaskFragmentContainer> containersToRemove = new ArrayList<>();
+        for (TaskFragmentContainer container : mContainersToFinishOnExit) {
+            if (container.mIsFinished) {
+                continue;
+            }
+            final SplitContainer splitContainer = mController.getActiveSplitForContainers(
+                    this, container);
+            if (splitContainer != null && splitContainer.isPlaceholderContainer()
+                    && splitContainer.getSecondaryContainer() == container) {
+                // Remove the placeholder secondary TaskFragment.
+                containersToRemove.add(container);
+            }
+        }
+        mContainersToFinishOnExit.removeAll(containersToRemove);
+        for (TaskFragmentContainer container : containersToRemove) {
+            container.finish(false /* shouldFinishDependent */, presenter, wct, mController);
+        }
+    }
+
     boolean isFinished() {
         return mIsFinished;
     }
@@ -560,6 +606,21 @@
         mLastRequestedWindowingMode = windowingModes;
     }
 
+    /**
+     * Checks if last requested {@link TaskFragmentAnimationParams} are equal to the provided value.
+     */
+    boolean areLastRequestedAnimationParamsEqual(
+            @NonNull TaskFragmentAnimationParams animationParams) {
+        return mLastAnimationParams.equals(animationParams);
+    }
+
+    /**
+     * Updates the last requested {@link TaskFragmentAnimationParams}.
+     */
+    void setLastRequestAnimationParams(@NonNull TaskFragmentAnimationParams animationParams) {
+        mLastAnimationParams = animationParams;
+    }
+
     /** Gets the parent leaf Task id. */
     int getTaskId() {
         return mTaskContainer.getTaskId();
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
index 84b2bfc..8386131 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
@@ -35,6 +35,8 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.util.ArrayMap;
+import android.view.WindowManager;
+import android.window.TaskFragmentOrganizer;
 
 import androidx.annotation.GuardedBy;
 import androidx.annotation.NonNull;
@@ -43,15 +45,15 @@
 import androidx.window.common.CommonFoldingFeature;
 import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
 import androidx.window.common.EmptyLifecycleCallbacksAdapter;
-import androidx.window.common.RawFoldingFeatureProducer;
+import androidx.window.extensions.core.util.function.Consumer;
 import androidx.window.util.DataProducer;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
-import java.util.function.Consumer;
 
 /**
  * Reference implementation of androidx.window.extensions.layout OEM interface for use with
@@ -80,17 +82,25 @@
     private final Map<IBinder, ConfigurationChangeListener> mConfigurationChangeListeners =
             new ArrayMap<>();
 
-    public WindowLayoutComponentImpl(@NonNull Context context) {
+    @GuardedBy("mLock")
+    private final Map<java.util.function.Consumer<WindowLayoutInfo>, Consumer<WindowLayoutInfo>>
+            mJavaToExtConsumers = new ArrayMap<>();
+
+    private final TaskFragmentOrganizer mTaskFragmentOrganizer;
+
+    public WindowLayoutComponentImpl(@NonNull Context context,
+            @NonNull TaskFragmentOrganizer taskFragmentOrganizer,
+            @NonNull DeviceStateManagerFoldingFeatureProducer foldingFeatureProducer) {
         ((Application) context.getApplicationContext())
                 .registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
-        RawFoldingFeatureProducer foldingFeatureProducer = new RawFoldingFeatureProducer(context);
-        mFoldingFeatureProducer = new DeviceStateManagerFoldingFeatureProducer(context,
-                foldingFeatureProducer);
+        mFoldingFeatureProducer = foldingFeatureProducer;
         mFoldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
+        mTaskFragmentOrganizer = taskFragmentOrganizer;
     }
 
     /** Registers to listen to {@link CommonFoldingFeature} changes */
-    public void addFoldingStateChangedCallback(Consumer<List<CommonFoldingFeature>> consumer) {
+    public void addFoldingStateChangedCallback(
+            java.util.function.Consumer<List<CommonFoldingFeature>> consumer) {
         synchronized (mLock) {
             mFoldingFeatureProducer.addDataChangedCallback(consumer);
         }
@@ -104,13 +114,27 @@
      */
     @Override
     public void addWindowLayoutInfoListener(@NonNull Activity activity,
-            @NonNull Consumer<WindowLayoutInfo> consumer) {
-        addWindowLayoutInfoListener((Context) activity, consumer);
+            @NonNull java.util.function.Consumer<WindowLayoutInfo> consumer) {
+        final Consumer<WindowLayoutInfo> extConsumer = consumer::accept;
+        synchronized (mLock) {
+            mJavaToExtConsumers.put(consumer, extConsumer);
+        }
+        addWindowLayoutInfoListener(activity, extConsumer);
+    }
+
+    @Override
+    public void addWindowLayoutInfoListener(@NonNull @UiContext Context context,
+            @NonNull java.util.function.Consumer<WindowLayoutInfo> consumer) {
+        final Consumer<WindowLayoutInfo> extConsumer = consumer::accept;
+        synchronized (mLock) {
+            mJavaToExtConsumers.put(consumer, extConsumer);
+        }
+        addWindowLayoutInfoListener(context, extConsumer);
     }
 
     /**
-     * Similar to {@link #addWindowLayoutInfoListener(Activity, Consumer)}, but takes a UI Context
-     * as a parameter.
+     * Similar to {@link #addWindowLayoutInfoListener(Activity, java.util.function.Consumer)}, but
+     * takes a UI Context as a parameter.
      *
      * Jetpack {@link androidx.window.layout.ExtensionWindowLayoutInfoBackend} makes sure all
      * consumers related to the same {@link Context} gets updated {@link WindowLayoutInfo}
@@ -151,6 +175,18 @@
         }
     }
 
+    @Override
+    public void removeWindowLayoutInfoListener(
+            @NonNull java.util.function.Consumer<WindowLayoutInfo> consumer) {
+        final Consumer<WindowLayoutInfo> extConsumer;
+        synchronized (mLock) {
+            extConsumer = mJavaToExtConsumers.remove(consumer);
+        }
+        if (extConsumer != null) {
+            removeWindowLayoutInfoListener(extConsumer);
+        }
+    }
+
     /**
      * Removes a listener no longer interested in receiving updates.
      *
@@ -182,7 +218,7 @@
 
     @GuardedBy("mLock")
     private boolean isListeningForLayoutChanges(IBinder token) {
-        for (Context context: getContextsListeningForLayoutChanges()) {
+        for (Context context : getContextsListeningForLayoutChanges()) {
             if (token.equals(Context.getToken(context))) {
                 return true;
             }
@@ -230,8 +266,9 @@
     /**
      * Translates the {@link DisplayFeature} into a {@link WindowLayoutInfo} when a
      * valid state is found.
+     *
      * @param context a proxy for the {@link android.view.Window} that contains the
-     * {@link DisplayFeature}.
+     *                {@link DisplayFeature}.
      */
     private WindowLayoutInfo getWindowLayoutInfo(@NonNull @UiContext Context context,
             List<CommonFoldingFeature> storedFeatures) {
@@ -243,7 +280,7 @@
      * Gets the current {@link WindowLayoutInfo} computed with passed {@link WindowConfiguration}.
      *
      * @return current {@link WindowLayoutInfo} on the default display. Returns
-     *   empty {@link WindowLayoutInfo} on secondary displays.
+     * empty {@link WindowLayoutInfo} on secondary displays.
      */
     @NonNull
     public WindowLayoutInfo getCurrentWindowLayoutInfo(int displayId,
@@ -254,7 +291,7 @@
         }
     }
 
-    /** @see #getWindowLayoutInfo(Context, List)  */
+    /** @see #getWindowLayoutInfo(Context, List) */
     private WindowLayoutInfo getWindowLayoutInfo(int displayId,
             @NonNull WindowConfiguration windowConfiguration,
             List<CommonFoldingFeature> storedFeatures) {
@@ -278,7 +315,8 @@
      *
      * @param context a proxy for the {@link android.view.Window} that contains the
      * {@link DisplayFeature}.
-     * are within the {@link android.view.Window} of the {@link Activity}
+     * @return a {@link List}  of {@link DisplayFeature}s that are within the
+     * {@link android.view.Window} of the {@link Activity}
      */
     private List<DisplayFeature> getDisplayFeatures(
             @NonNull @UiContext Context context, List<CommonFoldingFeature> storedFeatures) {
@@ -317,8 +355,11 @@
     }
 
     /**
-     * Checks whether display features should be reported for the activity.
+     * Calculates if the display features should be reported for the UI Context. The calculation
+     * uses the task information because that is accurate for Activities in ActivityEmbedding mode.
      * TODO(b/238948678): Support reporting display features in all windowing modes.
+     *
+     * @return true if the display features should be reported for the UI Context, false otherwise.
      */
     private boolean shouldReportDisplayFeatures(@NonNull @UiContext Context context) {
         int displayId = context.getDisplay().getDisplayId();
@@ -337,7 +378,27 @@
                 // bounds in this case can't be computed correctly, so we should skip.
                 return false;
             }
-            windowingMode = taskConfig.windowConfiguration.getWindowingMode();
+            final Rect taskBounds = taskConfig.windowConfiguration.getBounds();
+            final WindowManager windowManager = Objects.requireNonNull(
+                    context.getSystemService(WindowManager.class));
+            final Rect currentBounds = windowManager.getCurrentWindowMetrics().getBounds();
+            final Rect maxBounds = windowManager.getMaximumWindowMetrics().getBounds();
+            boolean isTaskExpanded = maxBounds.equals(taskBounds);
+            boolean isActivityExpanded = maxBounds.equals(currentBounds);
+            /*
+             * We need to proxy being in full screen because when a user enters PiP and exits PiP
+             * the task windowingMode will report multi-window/pinned until the transition is
+             * finished in WM Shell.
+             * maxBounds == taskWindowBounds is a proxy check to verify the window is full screen
+             * For tasks that are letterboxed, we use currentBounds == maxBounds to filter these
+             * out.
+             */
+            // TODO(b/262900133) remove currentBounds check when letterboxed apps report bounds.
+            // currently we don't want to report to letterboxed apps since they do not update the
+            // window bounds when the Activity is moved.  An inaccurate fold will be reported so
+            // we skip.
+            return isTaskExpanded && (isActivityExpanded
+                    || mTaskFragmentOrganizer.isActivityEmbedded(activityToken));
         } else {
             // TODO(b/242674941): use task windowing mode for window context that associates with
             //  activity.
@@ -390,6 +451,7 @@
         }
 
         @Override
-        public void onLowMemory() {}
+        public void onLowMemory() {
+        }
     }
 }
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java
index 13a2c78..d189ae2 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java
@@ -22,6 +22,7 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
+import androidx.window.extensions.embedding.SplitAttributes;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -53,4 +54,15 @@
     public void testGetActivityEmbeddingComponent() {
         assertThat(mExtensions.getActivityEmbeddingComponent()).isNotNull();
     }
+
+    @Test
+    public void testSplitAttributes_default() {
+        // Make sure the default value in the extensions aar.
+        final SplitAttributes splitAttributes = new SplitAttributes.Builder().build();
+        assertThat(splitAttributes.getLayoutDirection())
+                .isEqualTo(SplitAttributes.LayoutDirection.LOCALE);
+        assertThat(splitAttributes.getSplitType())
+                .isEqualTo(new SplitAttributes.SplitType.RatioSplitType(0.5f));
+        assertThat(splitAttributes.getAnimationBackgroundColor()).isEqualTo(0);
+    }
 }
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java
index 2f92a57..459ec9f 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java
@@ -34,9 +34,11 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.util.Pair;
+import android.view.WindowMetrics;
 import android.window.TaskFragmentInfo;
 import android.window.WindowContainerToken;
 
+import androidx.window.extensions.core.util.function.Predicate;
 import androidx.window.extensions.embedding.SplitAttributes.SplitType;
 import androidx.window.extensions.layout.DisplayFeature;
 import androidx.window.extensions.layout.FoldingFeature;
@@ -107,7 +109,7 @@
     static SplitRule createSplitRule(@NonNull Activity primaryActivity,
             @NonNull Intent secondaryIntent, boolean clearTop) {
         final Pair<Activity, Intent> targetPair = new Pair<>(primaryActivity, secondaryIntent);
-        return new SplitPairRule.Builder(
+        return createSplitPairRuleBuilder(
                 activityPair -> false,
                 targetPair::equals,
                 w -> true)
@@ -144,7 +146,7 @@
             @NonNull Activity secondaryActivity, int finishPrimaryWithSecondary,
             int finishSecondaryWithPrimary, boolean clearTop) {
         final Pair<Activity, Activity> targetPair = new Pair<>(primaryActivity, secondaryActivity);
-        return new SplitPairRule.Builder(
+        return createSplitPairRuleBuilder(
                 targetPair::equals,
                 activityIntentPair -> false,
                 w -> true)
@@ -223,4 +225,26 @@
         displayFeatures.add(foldingFeature);
         return new WindowLayoutInfo(displayFeatures);
     }
+
+    static ActivityRule.Builder createActivityBuilder(
+            @NonNull Predicate<Activity> activityPredicate,
+            @NonNull Predicate<Intent> intentPredicate) {
+        return new ActivityRule.Builder(activityPredicate, intentPredicate);
+    }
+
+    static SplitPairRule.Builder createSplitPairRuleBuilder(
+            @NonNull Predicate<Pair<Activity, Activity>> activitiesPairPredicate,
+            @NonNull Predicate<Pair<Activity, Intent>> activityIntentPairPredicate,
+            @NonNull Predicate<WindowMetrics> windowMetricsPredicate) {
+        return new SplitPairRule.Builder(activitiesPairPredicate, activityIntentPairPredicate,
+                windowMetricsPredicate);
+    }
+
+    static SplitPlaceholderRule.Builder createSplitPlaceholderRuleBuilder(
+            @NonNull Intent placeholderIntent, @NonNull Predicate<Activity> activityPredicate,
+            @NonNull Predicate<Intent> intentPredicate,
+            @NonNull Predicate<WindowMetrics> windowMetricsPredicate) {
+        return new SplitPlaceholderRule.Builder(placeholderIntent, activityPredicate,
+                intentPredicate, windowMetricsPredicate);
+    }
 }
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
index 3cc31f9..0bf0bc8 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
@@ -34,8 +34,11 @@
 import static androidx.window.extensions.embedding.EmbeddingTestUtils.TASK_BOUNDS;
 import static androidx.window.extensions.embedding.EmbeddingTestUtils.TASK_ID;
 import static androidx.window.extensions.embedding.EmbeddingTestUtils.TEST_TAG;
+import static androidx.window.extensions.embedding.EmbeddingTestUtils.createActivityBuilder;
 import static androidx.window.extensions.embedding.EmbeddingTestUtils.createActivityInfoWithMinDimensions;
 import static androidx.window.extensions.embedding.EmbeddingTestUtils.createMockTaskFragmentInfo;
+import static androidx.window.extensions.embedding.EmbeddingTestUtils.createSplitPairRuleBuilder;
+import static androidx.window.extensions.embedding.EmbeddingTestUtils.createSplitPlaceholderRuleBuilder;
 import static androidx.window.extensions.embedding.EmbeddingTestUtils.createSplitRule;
 import static androidx.window.extensions.embedding.EmbeddingTestUtils.createTestTaskContainer;
 import static androidx.window.extensions.embedding.EmbeddingTestUtils.getSplitBounds;
@@ -90,6 +93,7 @@
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
+import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
 import androidx.window.extensions.layout.WindowLayoutComponentImpl;
 import androidx.window.extensions.layout.WindowLayoutInfo;
 
@@ -142,7 +146,9 @@
         MockitoAnnotations.initMocks(this);
         doReturn(new WindowLayoutInfo(new ArrayList<>())).when(mWindowLayoutComponent)
                 .getCurrentWindowLayoutInfo(anyInt(), any());
-        mSplitController = new SplitController(mWindowLayoutComponent);
+        DeviceStateManagerFoldingFeatureProducer producer =
+                mock(DeviceStateManagerFoldingFeatureProducer.class);
+        mSplitController = new SplitController(mWindowLayoutComponent, producer);
         mSplitPresenter = mSplitController.mPresenter;
         mSplitInfos = new ArrayList<>();
         mEmbeddingCallback = splitInfos -> {
@@ -429,7 +435,7 @@
     @Test
     public void testResolveStartActivityIntent_withoutLaunchingActivity() {
         final Intent intent = new Intent();
-        final ActivityRule expandRule = new ActivityRule.Builder(r -> false, i -> i == intent)
+        final ActivityRule expandRule = createActivityBuilder(r -> false, i -> i == intent)
                 .setShouldAlwaysExpand(true)
                 .build();
         mSplitController.setEmbeddingRules(Collections.singleton(expandRule));
@@ -1167,7 +1173,7 @@
 
     @Test
     public void testHasSamePresentation() {
-        SplitPairRule splitRule1 = new SplitPairRule.Builder(
+        SplitPairRule splitRule1 = createSplitPairRuleBuilder(
                 activityPair -> true,
                 activityIntentPair -> true,
                 windowMetrics -> true)
@@ -1175,7 +1181,7 @@
                 .setFinishPrimaryWithSecondary(DEFAULT_FINISH_PRIMARY_WITH_SECONDARY)
                 .setDefaultSplitAttributes(SPLIT_ATTRIBUTES)
                 .build();
-        SplitPairRule splitRule2 = new SplitPairRule.Builder(
+        SplitPairRule splitRule2 = createSplitPairRuleBuilder(
                 activityPair -> true,
                 activityIntentPair -> true,
                 windowMetrics -> true)
@@ -1188,7 +1194,7 @@
                 SplitController.haveSamePresentation(splitRule1, splitRule2,
                         new WindowMetrics(TASK_BOUNDS, WindowInsets.CONSUMED)));
 
-        splitRule2 = new SplitPairRule.Builder(
+        splitRule2 = createSplitPairRuleBuilder(
                 activityPair -> true,
                 activityIntentPair -> true,
                 windowMetrics -> true)
@@ -1352,7 +1358,7 @@
 
     /** Setups a rule to always expand the given intent. */
     private void setupExpandRule(@NonNull Intent expandIntent) {
-        final ActivityRule expandRule = new ActivityRule.Builder(r -> false, expandIntent::equals)
+        final ActivityRule expandRule = createActivityBuilder(r -> false, expandIntent::equals)
                 .setShouldAlwaysExpand(true)
                 .build();
         mSplitController.setEmbeddingRules(Collections.singleton(expandRule));
@@ -1360,7 +1366,7 @@
 
     /** Setups a rule to always expand the given activity. */
     private void setupExpandRule(@NonNull Activity expandActivity) {
-        final ActivityRule expandRule = new ActivityRule.Builder(expandActivity::equals, i -> false)
+        final ActivityRule expandRule = createActivityBuilder(expandActivity::equals, i -> false)
                 .setShouldAlwaysExpand(true)
                 .build();
         mSplitController.setEmbeddingRules(Collections.singleton(expandRule));
@@ -1368,7 +1374,7 @@
 
     /** Setups a rule to launch placeholder for the given activity. */
     private void setupPlaceholderRule(@NonNull Activity primaryActivity) {
-        final SplitRule placeholderRule = new SplitPlaceholderRule.Builder(PLACEHOLDER_INTENT,
+        final SplitRule placeholderRule = createSplitPlaceholderRuleBuilder(PLACEHOLDER_INTENT,
                 primaryActivity::equals, i -> false, w -> true)
                 .setDefaultSplitAttributes(SPLIT_ATTRIBUTES)
                 .build();
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java
index 6dae0a1..a288fd6 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java
@@ -19,6 +19,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.view.Display.DEFAULT_DISPLAY;
+import static android.window.TaskFragmentOperation.OP_TYPE_SET_ANIMATION_PARAMS;
 
 import static androidx.window.extensions.embedding.EmbeddingTestUtils.DEFAULT_FINISH_PRIMARY_WITH_SECONDARY;
 import static androidx.window.extensions.embedding.EmbeddingTestUtils.DEFAULT_FINISH_SECONDARY_WITH_PRIMARY;
@@ -27,6 +28,7 @@
 import static androidx.window.extensions.embedding.EmbeddingTestUtils.TASK_ID;
 import static androidx.window.extensions.embedding.EmbeddingTestUtils.createActivityInfoWithMinDimensions;
 import static androidx.window.extensions.embedding.EmbeddingTestUtils.createMockTaskFragmentInfo;
+import static androidx.window.extensions.embedding.EmbeddingTestUtils.createSplitPairRuleBuilder;
 import static androidx.window.extensions.embedding.EmbeddingTestUtils.createSplitRule;
 import static androidx.window.extensions.embedding.EmbeddingTestUtils.createWindowLayoutInfo;
 import static androidx.window.extensions.embedding.EmbeddingTestUtils.getSplitBounds;
@@ -60,17 +62,22 @@
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.graphics.Color;
 import android.graphics.Rect;
 import android.os.IBinder;
 import android.platform.test.annotations.Presubmit;
 import android.util.Pair;
 import android.util.Size;
+import android.window.TaskFragmentAnimationParams;
 import android.window.TaskFragmentInfo;
+import android.window.TaskFragmentOperation;
 import android.window.WindowContainerTransaction;
 
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
+import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
+import androidx.window.extensions.core.util.function.Function;
 import androidx.window.extensions.layout.WindowLayoutComponentImpl;
 import androidx.window.extensions.layout.WindowLayoutInfo;
 
@@ -113,7 +120,9 @@
         MockitoAnnotations.initMocks(this);
         doReturn(new WindowLayoutInfo(new ArrayList<>())).when(mWindowLayoutComponent)
                 .getCurrentWindowLayoutInfo(anyInt(), any());
-        mController = new SplitController(mWindowLayoutComponent);
+        DeviceStateManagerFoldingFeatureProducer producer =
+                mock(DeviceStateManagerFoldingFeatureProducer.class);
+        mController = new SplitController(mWindowLayoutComponent, producer);
         mPresenter = mController.mPresenter;
         spyOn(mController);
         spyOn(mPresenter);
@@ -163,7 +172,38 @@
                 WINDOWING_MODE_MULTI_WINDOW);
 
         verify(mTransaction, never()).setWindowingMode(any(), anyInt());
+    }
 
+    @Test
+    public void testUpdateAnimationParams() {
+        final TaskFragmentContainer container = mController.newContainer(mActivity, TASK_ID);
+
+        // Verify the default.
+        assertTrue(container.areLastRequestedAnimationParamsEqual(
+                TaskFragmentAnimationParams.DEFAULT));
+
+        final int bgColor = Color.GREEN;
+        final TaskFragmentAnimationParams animationParams =
+                new TaskFragmentAnimationParams.Builder()
+                        .setAnimationBackgroundColor(bgColor)
+                        .build();
+        mPresenter.updateAnimationParams(mTransaction, container.getTaskFragmentToken(),
+                animationParams);
+
+        final TaskFragmentOperation expectedOperation = new TaskFragmentOperation.Builder(
+                OP_TYPE_SET_ANIMATION_PARAMS)
+                .setAnimationParams(animationParams)
+                .build();
+        verify(mTransaction).setTaskFragmentOperation(container.getTaskFragmentToken(),
+                expectedOperation);
+        assertTrue(container.areLastRequestedAnimationParamsEqual(animationParams));
+
+        // No request to set the same animation params.
+        clearInvocations(mTransaction);
+        mPresenter.updateAnimationParams(mTransaction, container.getTaskFragmentToken(),
+                animationParams);
+
+        verify(mTransaction, never()).setTaskFragmentOperation(any(), any());
     }
 
     @Test
@@ -473,7 +513,7 @@
         final Activity secondaryActivity = createMockActivity();
         final TaskFragmentContainer bottomTf = mController.newContainer(secondaryActivity, TASK_ID);
         final TaskFragmentContainer primaryTf = mController.newContainer(mActivity, TASK_ID);
-        final SplitPairRule rule = new SplitPairRule.Builder(pair ->
+        final SplitPairRule rule = createSplitPairRuleBuilder(pair ->
                 pair.first == mActivity && pair.second == secondaryActivity, pair -> false,
                 metrics -> true)
                 .setDefaultSplitAttributes(SPLIT_ATTRIBUTES)
@@ -491,7 +531,7 @@
 
     @Test
     public void testComputeSplitAttributes() {
-        final SplitPairRule splitPairRule = new SplitPairRule.Builder(
+        final SplitPairRule splitPairRule = createSplitPairRuleBuilder(
                 activityPair -> true,
                 activityIntentPair -> true,
                 windowMetrics -> windowMetrics.getBounds().equals(TASK_BOUNDS))
@@ -523,10 +563,10 @@
                                 SplitAttributes.SplitType.RatioSplitType.splitEqually()
                         )
                 ).build();
+        final Function<SplitAttributesCalculatorParams, SplitAttributes> calculator =
+                params -> splitAttributes;
 
-        mController.setSplitAttributesCalculator(params -> {
-            return splitAttributes;
-        });
+        mController.setSplitAttributesCalculator(calculator);
 
         assertEquals(splitAttributes, mPresenter.computeSplitAttributes(taskProperties,
                 splitPairRule, null /* minDimensionsPair */));
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java
index 9877236..78b85e6 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java
@@ -45,6 +45,8 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
+import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
+import androidx.window.extensions.layout.WindowLayoutComponentImpl;
 
 import com.google.android.collect.Lists;
 
@@ -82,7 +84,10 @@
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
-        mController = new SplitController();
+        DeviceStateManagerFoldingFeatureProducer producer =
+                mock(DeviceStateManagerFoldingFeatureProducer.class);
+        WindowLayoutComponentImpl component = mock(WindowLayoutComponentImpl.class);
+        mController = new SplitController(component, producer);
         spyOn(mController);
         mActivity = createMockActivity();
         mIntent = new Intent();
@@ -149,17 +154,52 @@
                 null /* pendingAppearedIntent */, taskContainer, mController,
                 null /* pairedPrimaryContainer */);
         doReturn(container1).when(mController).getContainerWithActivity(mActivity);
-        final WindowContainerTransaction wct = new WindowContainerTransaction();
 
         // The activity is requested to be reparented, so don't finish it.
-        container0.finish(true /* shouldFinishDependent */, mPresenter, wct, mController);
+        container0.finish(true /* shouldFinishDependent */, mPresenter, mTransaction, mController);
 
         verify(mTransaction, never()).finishActivity(any());
-        verify(mPresenter).deleteTaskFragment(wct, container0.getTaskFragmentToken());
+        verify(mPresenter).deleteTaskFragment(mTransaction, container0.getTaskFragmentToken());
         verify(mController).removeContainer(container0);
     }
 
     @Test
+    public void testFinish_alwaysFinishPlaceholder() {
+        // Register container1 as a placeholder
+        final TaskContainer taskContainer = createTestTaskContainer();
+        final TaskFragmentContainer container0 = new TaskFragmentContainer(mActivity,
+                null /* pendingAppearedIntent */, taskContainer, mController,
+                null /* pairedPrimaryContainer */);
+        final TaskFragmentInfo info0 = createMockTaskFragmentInfo(container0, mActivity);
+        container0.setInfo(mTransaction, info0);
+        final Activity placeholderActivity = createMockActivity();
+        final TaskFragmentContainer container1 = new TaskFragmentContainer(placeholderActivity,
+                null /* pendingAppearedIntent */, taskContainer, mController,
+                null /* pairedPrimaryContainer */);
+        final TaskFragmentInfo info1 = createMockTaskFragmentInfo(container1, placeholderActivity);
+        container1.setInfo(mTransaction, info1);
+        final SplitAttributes splitAttributes = new SplitAttributes.Builder().build();
+        final SplitPlaceholderRule rule = new SplitPlaceholderRule.Builder(new Intent(),
+                mActivity::equals, (java.util.function.Predicate) i -> false,
+                (java.util.function.Predicate) w -> true)
+                .setDefaultSplitAttributes(splitAttributes)
+                .build();
+        mController.registerSplit(mTransaction, container0, mActivity, container1, rule,
+                splitAttributes);
+
+        // The placeholder TaskFragment should be finished even if the primary is finished with
+        // shouldFinishDependent = false.
+        container0.finish(false /* shouldFinishDependent */, mPresenter, mTransaction, mController);
+
+        assertTrue(container0.isFinished());
+        assertTrue(container1.isFinished());
+        verify(mPresenter).deleteTaskFragment(mTransaction, container0.getTaskFragmentToken());
+        verify(mPresenter).deleteTaskFragment(mTransaction, container1.getTaskFragmentToken());
+        verify(mController).removeContainer(container0);
+        verify(mController).removeContainer(container1);
+    }
+
+    @Test
     public void testSetInfo() {
         final TaskContainer taskContainer = createTestTaskContainer();
         // Pending activity should be cleared when it has appeared on server side.
@@ -488,8 +528,6 @@
         final TaskFragmentContainer tf1 = new TaskFragmentContainer(
                 null /* pendingAppearedActivity */, new Intent(), taskContainer, mController,
                 null /* pairedPrimaryTaskFragment */);
-        taskContainer.mContainers.add(tf0);
-        taskContainer.mContainers.add(tf1);
 
         // When tf2 is created with using tf0 as pairedPrimaryContainer, tf2 should be inserted
         // right above tf0.
@@ -501,6 +539,26 @@
     }
 
     @Test
+    public void testNewContainerWithPairedPendingAppearedActivity() {
+        final TaskContainer taskContainer = createTestTaskContainer();
+        final TaskFragmentContainer tf0 = new TaskFragmentContainer(
+                createMockActivity(), null /* pendingAppearedIntent */, taskContainer, mController,
+                null /* pairedPrimaryTaskFragment */);
+        final TaskFragmentContainer tf1 = new TaskFragmentContainer(
+                null /* pendingAppearedActivity */, new Intent(), taskContainer, mController,
+                null /* pairedPrimaryTaskFragment */);
+
+        // When tf2 is created with pendingAppearedActivity, tf2 should be inserted below any
+        // TaskFragment without any Activity.
+        final TaskFragmentContainer tf2 = new TaskFragmentContainer(
+                createMockActivity(), null /* pendingAppearedIntent */, taskContainer, mController,
+                null /* pairedPrimaryTaskFragment */);
+        assertEquals(0, taskContainer.indexOf(tf0));
+        assertEquals(1, taskContainer.indexOf(tf2));
+        assertEquals(2, taskContainer.indexOf(tf1));
+    }
+
+    @Test
     public void testIsVisible() {
         final TaskContainer taskContainer = createTestTaskContainer();
         final TaskFragmentContainer container = new TaskFragmentContainer(
diff --git a/libs/WindowManager/Jetpack/window-extensions-core-release.aar b/libs/WindowManager/Jetpack/window-extensions-core-release.aar
new file mode 100644
index 0000000..96ff840
--- /dev/null
+++ b/libs/WindowManager/Jetpack/window-extensions-core-release.aar
Binary files differ
diff --git a/libs/WindowManager/Jetpack/window-extensions-release.aar b/libs/WindowManager/Jetpack/window-extensions-release.aar
index 4978e04..cddbf469 100644
--- a/libs/WindowManager/Jetpack/window-extensions-release.aar
+++ b/libs/WindowManager/Jetpack/window-extensions-release.aar
Binary files differ
diff --git a/libs/WindowManager/Shell/res/color/decor_caption_title_color.xml b/libs/WindowManager/Shell/res/color/decor_title_color.xml
similarity index 100%
rename from libs/WindowManager/Shell/res/color/decor_caption_title_color.xml
rename to libs/WindowManager/Shell/res/color/decor_title_color.xml
diff --git a/libs/WindowManager/Shell/res/drawable/caption_decor_title.xml b/libs/WindowManager/Shell/res/drawable/caption_decor_title.xml
new file mode 100644
index 0000000..6114ad6
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/caption_decor_title.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<shape android:shape="rectangle"
+       android:tintMode="multiply"
+       android:tint="@color/decor_title_color"
+       xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@android:color/white" />
+</shape>
diff --git a/libs/WindowManager/Shell/res/drawable/decor_minimize_button_dark.xml b/libs/WindowManager/Shell/res/drawable/decor_minimize_button_dark.xml
index 0bcaa53..91edbf1 100644
--- a/libs/WindowManager/Shell/res/drawable/decor_minimize_button_dark.xml
+++ b/libs/WindowManager/Shell/res/drawable/decor_minimize_button_dark.xml
@@ -14,11 +14,11 @@
   ~ 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"
-        android:tint="?attr/colorControlNormal">
+        android:width="32.0dp"
+        android:height="32.0dp"
+        android:viewportWidth="32.0"
+        android:viewportHeight="32.0"
+        android:tint="@color/decor_button_dark_color">
     <path
         android:fillColor="@android:color/white" android:pathData="M6,21V19H18V21Z"/>
 </vector>
diff --git a/libs/WindowManager/Shell/res/drawable/decor_caption_menu_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_menu_background.xml
similarity index 100%
rename from libs/WindowManager/Shell/res/drawable/decor_caption_menu_background.xml
rename to libs/WindowManager/Shell/res/drawable/desktop_mode_decor_menu_background.xml
diff --git a/libs/WindowManager/Shell/res/drawable/decor_caption_title.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_title.xml
similarity index 100%
rename from libs/WindowManager/Shell/res/drawable/decor_caption_title.xml
rename to libs/WindowManager/Shell/res/drawable/desktop_mode_decor_title.xml
diff --git a/libs/WindowManager/Shell/res/layout/caption_window_decor.xml b/libs/WindowManager/Shell/res/layout/caption_window_decor.xml
new file mode 100644
index 0000000..f3d2198
--- /dev/null
+++ b/libs/WindowManager/Shell/res/layout/caption_window_decor.xml
@@ -0,0 +1,56 @@
+<?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.
+  -->
+<com.android.wm.shell.windowdecor.WindowDecorLinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/caption"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:gravity="end"
+    android:background="@drawable/caption_decor_title">
+    <Button
+        style="@style/CaptionButtonStyle"
+        android:id="@+id/back_button"
+        android:layout_gravity="center_vertical|end"
+        android:contentDescription="@string/back_button_text"
+        android:background="@drawable/decor_back_button_dark"
+        android:duplicateParentState="true"/>
+    <Space
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:elevation="2dp"/>
+    <Button
+        style="@style/CaptionButtonStyle"
+        android:id="@+id/minimize_window"
+        android:layout_gravity="center_vertical|end"
+        android:contentDescription="@string/minimize_button_text"
+        android:background="@drawable/decor_minimize_button_dark"
+        android:duplicateParentState="true"/>
+    <Button
+        style="@style/CaptionButtonStyle"
+        android:id="@+id/maximize_window"
+        android:layout_gravity="center_vertical|end"
+        android:contentDescription="@string/maximize_button_text"
+        android:background="@drawable/decor_maximize_button_dark"
+        android:duplicateParentState="true"/>
+    <Button
+        style="@style/CaptionButtonStyle"
+        android:id="@+id/close_window"
+        android:contentDescription="@string/close_button_text"
+        android:background="@drawable/decor_close_button_dark"
+        android:duplicateParentState="true"/>
+</com.android.wm.shell.windowdecor.WindowDecorLinearLayout>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/caption_handle_menu.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_decor_handle_menu.xml
similarity index 96%
rename from libs/WindowManager/Shell/res/layout/caption_handle_menu.xml
rename to libs/WindowManager/Shell/res/layout/desktop_mode_decor_handle_menu.xml
index 582a11c..8b4792a 100644
--- a/libs/WindowManager/Shell/res/layout/caption_handle_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_decor_handle_menu.xml
@@ -20,7 +20,7 @@
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:gravity="center_horizontal"
-android:background="@drawable/decor_caption_menu_background">
+android:background="@drawable/desktop_mode_decor_menu_background">
     <Button
         style="@style/CaptionButtonStyle"
         android:id="@+id/fullscreen_button"
diff --git a/libs/WindowManager/Shell/res/layout/caption_window_decoration.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor.xml
similarity index 93%
rename from libs/WindowManager/Shell/res/layout/caption_window_decoration.xml
rename to libs/WindowManager/Shell/res/layout/desktop_mode_window_decor.xml
index 51e634c..2a4cc02 100644
--- a/libs/WindowManager/Shell/res/layout/caption_window_decoration.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor.xml
@@ -16,10 +16,10 @@
   -->
 <com.android.wm.shell.windowdecor.WindowDecorLinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/caption"
+    android:id="@+id/desktop_mode_caption"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:background="@drawable/decor_caption_title">
+    android:background="@drawable/desktop_mode_decor_title">
     <Button
         style="@style/CaptionButtonStyle"
         android:id="@+id/back_button"
diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
index 78d74d74..540ae7c 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -17,79 +17,79 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="pip_phone_close" msgid="5783752637260411309">"Затвори"</string>
-    <string name="pip_phone_expand" msgid="2579292903468287504">"Прошири"</string>
-    <string name="pip_phone_settings" msgid="5468987116750491918">"Подешавања"</string>
-    <string name="pip_phone_enter_split" msgid="7042877263880641911">"Уђи на подељени екран"</string>
-    <string name="pip_menu_title" msgid="5393619322111827096">"Мени"</string>
-    <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> је слика у слици"</string>
-    <string name="pip_notification_message" msgid="8854051911700302620">"Ако не желите да <xliff:g id="NAME">%s</xliff:g> користи ову функцију, додирните да бисте отворили подешавања и искључили је."</string>
-    <string name="pip_play" msgid="3496151081459417097">"Пусти"</string>
-    <string name="pip_pause" msgid="690688849510295232">"Паузирај"</string>
-    <string name="pip_skip_to_next" msgid="8403429188794867653">"Пређи на следеће"</string>
-    <string name="pip_skip_to_prev" msgid="7172158111196394092">"Пређи на претходно"</string>
-    <string name="accessibility_action_pip_resize" msgid="4623966104749543182">"Промените величину"</string>
-    <string name="accessibility_action_pip_stash" msgid="4060775037619702641">"Ставите у тајну меморију"</string>
-    <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Уклоните из тајне меморије"</string>
-    <string name="dock_forced_resizable" msgid="1749750436092293116">"Апликација можда неће радити са подељеним екраном."</string>
-    <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Апликација не подржава подељени екран."</string>
-    <string name="dock_multi_instances_not_supported_text" msgid="5242868470666346929">"Ова апликација може да се отвори само у једном прозору."</string>
-    <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Апликација можда неће функционисати на секундарном екрану."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Апликација не подржава покретање на секундарним екранима."</string>
-    <string name="accessibility_divider" msgid="703810061635792791">"Разделник подељеног екрана"</string>
-    <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Режим целог екрана за леви екран"</string>
-    <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Леви екран 70%"</string>
-    <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Леви екран 50%"</string>
-    <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Леви екран 30%"</string>
-    <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Режим целог екрана за доњи екран"</string>
-    <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Режим целог екрана за горњи екран"</string>
-    <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Горњи екран 70%"</string>
-    <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Горњи екран 50%"</string>
-    <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Горњи екран 30%"</string>
-    <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Режим целог екрана за доњи екран"</string>
-    <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Коришћење режима једном руком"</string>
-    <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Да бисте изашли, превуците нагоре од дна екрана или додирните било где изнад апликације"</string>
-    <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Покрените режим једном руком"</string>
-    <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"Изађите из режима једном руком"</string>
-    <string name="bubbles_settings_button_description" msgid="1301286017420516912">"Подешавања за <xliff:g id="APP_NAME">%1$s</xliff:g> облачиће"</string>
-    <string name="bubble_overflow_button_content_description" msgid="8160974472718594382">"Преклапање"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="1830101076853540953">"Додај поново у групу"</string>
-    <string name="bubble_content_description_single" msgid="8495748092720065813">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> из апликације <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="8071515017164630429">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> из апликације <xliff:g id="APP_NAME">%2$s</xliff:g> и још <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="2644118920500782758">"Премести горе лево"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="5864594920870245525">"Премести горе десно"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="850271002773745634">"Премести доле лево"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Премести доле десно"</string>
-    <string name="bubbles_app_settings" msgid="3617224938701566416">"Подешавања за <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_dismiss_text" msgid="8816558050659478158">"Одбаци облачић"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Не користи облачиће за конверзацију"</string>
-    <string name="bubbles_user_education_title" msgid="2112319053732691899">"Ћаскајте у облачићима"</string>
-    <string name="bubbles_user_education_description" msgid="4215862563054175407">"Нове конверзације се приказују као плутајуће иконе или облачићи. Додирните да бисте отворили облачић. Превуците да бисте га преместили."</string>
-    <string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"Контролишите облачиће у било ком тренутку"</string>
-    <string name="bubbles_user_education_manage" msgid="3460756219946517198">"Додирните Управљајте да бисте искључили облачиће из ове апликације"</string>
-    <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Важи"</string>
-    <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Нема недавних облачића"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Овде се приказују недавни и одбачени облачићи"</string>
-    <string name="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="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Имате проблема са камером?\nДодирните да бисте поново уклопили"</string>
-    <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Проблем није решен?\nДодирните да бисте вратили"</string>
-    <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Немате проблема са камером? Додирните да бисте одбацили."</string>
-    <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Видите и урадите више"</string>
-    <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Превуците другу апликацију да бисте користили подељени екран"</string>
-    <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Двапут додирните изван апликације да бисте променили њену позицију"</string>
-    <string name="letterbox_education_got_it" msgid="4057634570866051177">"Важи"</string>
-    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Проширите за још информација."</string>
-    <string name="maximize_button_text" msgid="1650859196290301963">"Увећајте"</string>
-    <string name="minimize_button_text" msgid="271592547935841753">"Умањите"</string>
-    <string name="close_button_text" msgid="2913281996024033299">"Затворите"</string>
-    <string name="back_button_text" msgid="1469718707134137085">"Назад"</string>
-    <string name="handle_text" msgid="1766582106752184456">"Идентификатор"</string>
-    <string name="fullscreen_text" msgid="1162316685217676079">"Преко целог екрана"</string>
-    <string name="desktop_text" msgid="1077633567027630454">"Режим за рачунаре"</string>
-    <string name="split_screen_text" msgid="1396336058129570886">"Подељени екран"</string>
-    <string name="more_button_text" msgid="3655388105592893530">"Још"</string>
-    <string name="float_button_text" msgid="9221657008391364581">"Плутајуће"</string>
+    <string name="pip_phone_close" msgid="5783752637260411309">"Zatvori"</string>
+    <string name="pip_phone_expand" msgid="2579292903468287504">"Proširi"</string>
+    <string name="pip_phone_settings" msgid="5468987116750491918">"Podešavanja"</string>
+    <string name="pip_phone_enter_split" msgid="7042877263880641911">"Uđi na podeljeni ekran"</string>
+    <string name="pip_menu_title" msgid="5393619322111827096">"Meni"</string>
+    <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> je slika u slici"</string>
+    <string name="pip_notification_message" msgid="8854051911700302620">"Ako ne želite da <xliff:g id="NAME">%s</xliff:g> koristi ovu funkciju, dodirnite da biste otvorili podešavanja i isključili je."</string>
+    <string name="pip_play" msgid="3496151081459417097">"Pusti"</string>
+    <string name="pip_pause" msgid="690688849510295232">"Pauziraj"</string>
+    <string name="pip_skip_to_next" msgid="8403429188794867653">"Pređi na sledeće"</string>
+    <string name="pip_skip_to_prev" msgid="7172158111196394092">"Pređi na prethodno"</string>
+    <string name="accessibility_action_pip_resize" msgid="4623966104749543182">"Promenite veličinu"</string>
+    <string name="accessibility_action_pip_stash" msgid="4060775037619702641">"Stavite u tajnu memoriju"</string>
+    <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Uklonite iz tajne memorije"</string>
+    <string name="dock_forced_resizable" msgid="1749750436092293116">"Aplikacija možda neće raditi sa podeljenim ekranom."</string>
+    <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplikacija ne podržava podeljeni ekran."</string>
+    <string name="dock_multi_instances_not_supported_text" msgid="5242868470666346929">"Ova aplikacija može da se otvori samo u jednom prozoru."</string>
+    <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija možda neće funkcionisati na sekundarnom ekranu."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podržava pokretanje na sekundarnim ekranima."</string>
+    <string name="accessibility_divider" msgid="703810061635792791">"Razdelnik podeljenog ekrana"</string>
+    <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Režim celog ekrana za levi ekran"</string>
+    <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Levi ekran 70%"</string>
+    <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Levi ekran 50%"</string>
+    <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Levi ekran 30%"</string>
+    <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Režim celog ekrana za donji ekran"</string>
+    <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Režim celog ekrana za gornji ekran"</string>
+    <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Gornji ekran 70%"</string>
+    <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Gornji ekran 50%"</string>
+    <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Gornji ekran 30%"</string>
+    <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Režim celog ekrana za donji ekran"</string>
+    <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Korišćenje režima jednom rukom"</string>
+    <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Da biste izašli, prevucite nagore od dna ekrana ili dodirnite bilo gde iznad aplikacije"</string>
+    <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Pokrenite režim jednom rukom"</string>
+    <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"Izađite iz režima jednom rukom"</string>
+    <string name="bubbles_settings_button_description" msgid="1301286017420516912">"Podešavanja za <xliff:g id="APP_NAME">%1$s</xliff:g> oblačiće"</string>
+    <string name="bubble_overflow_button_content_description" msgid="8160974472718594382">"Preklapanje"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="1830101076853540953">"Dodaj ponovo u grupu"</string>
+    <string name="bubble_content_description_single" msgid="8495748092720065813">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> iz aplikacije <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
+    <string name="bubble_content_description_stack" msgid="8071515017164630429">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> iz aplikacije <xliff:g id="APP_NAME">%2$s</xliff:g> i još <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
+    <string name="bubble_accessibility_action_move_top_left" msgid="2644118920500782758">"Premesti gore levo"</string>
+    <string name="bubble_accessibility_action_move_top_right" msgid="5864594920870245525">"Premesti gore desno"</string>
+    <string name="bubble_accessibility_action_move_bottom_left" msgid="850271002773745634">"Premesti dole levo"</string>
+    <string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Premesti dole desno"</string>
+    <string name="bubbles_app_settings" msgid="3617224938701566416">"Podešavanja za <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
+    <string name="bubble_dismiss_text" msgid="8816558050659478158">"Odbaci oblačić"</string>
+    <string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Ne koristi oblačiće za konverzaciju"</string>
+    <string name="bubbles_user_education_title" msgid="2112319053732691899">"Ćaskajte u oblačićima"</string>
+    <string name="bubbles_user_education_description" msgid="4215862563054175407">"Nove konverzacije se prikazuju kao plutajuće ikone ili oblačići. Dodirnite da biste otvorili oblačić. Prevucite da biste ga premestili."</string>
+    <string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"Kontrolišite oblačiće u bilo kom trenutku"</string>
+    <string name="bubbles_user_education_manage" msgid="3460756219946517198">"Dodirnite Upravljajte da biste isključili oblačiće iz ove aplikacije"</string>
+    <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Važi"</string>
+    <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nema nedavnih oblačića"</string>
+    <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Ovde se prikazuju nedavni i odbačeni oblačići"</string>
+    <string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string>
+    <string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljajte"</string>
+    <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblačić je odbačen."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Dodirnite da biste restartovali ovu aplikaciju radi boljeg prikaza."</string>
+    <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Imate problema sa kamerom?\nDodirnite da biste ponovo uklopili"</string>
+    <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problem nije rešen?\nDodirnite da biste vratili"</string>
+    <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nemate problema sa kamerom? Dodirnite da biste odbacili."</string>
+    <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Vidite i uradite više"</string>
+    <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Prevucite drugu aplikaciju da biste koristili podeljeni ekran"</string>
+    <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dvaput dodirnite izvan aplikacije da biste promenili njenu poziciju"</string>
+    <string name="letterbox_education_got_it" msgid="4057634570866051177">"Važi"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Proširite za još informacija."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Uvećajte"</string>
+    <string name="minimize_button_text" msgid="271592547935841753">"Umanjite"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Zatvorite"</string>
+    <string name="back_button_text" msgid="1469718707134137085">"Nazad"</string>
+    <string name="handle_text" msgid="1766582106752184456">"Identifikator"</string>
+    <string name="fullscreen_text" msgid="1162316685217676079">"Preko celog ekrana"</string>
+    <string name="desktop_text" msgid="1077633567027630454">"Režim za računare"</string>
+    <string name="split_screen_text" msgid="1396336058129570886">"Podeljeni ekran"</string>
+    <string name="more_button_text" msgid="3655388105592893530">"Još"</string>
+    <string name="float_button_text" msgid="9221657008391364581">"Plutajuće"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml
index e850979..51a1262 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml
@@ -17,18 +17,18 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Слика у слици"</string>
-    <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Програм без наслова)"</string>
-    <string name="pip_close" msgid="2955969519031223530">"Затвори"</string>
-    <string name="pip_fullscreen" msgid="7278047353591302554">"Цео екран"</string>
-    <string name="pip_move" msgid="158770205886688553">"Премести"</string>
-    <string name="pip_expand" msgid="1051966011679297308">"Прошири"</string>
-    <string name="pip_collapse" msgid="3903295106641385962">"Скупи"</string>
-    <string name="pip_edu_text" msgid="3672999496647508701">" Двапут притисните "<annotation icon="home_icon">" HOME "</annotation>" за контроле"</string>
-    <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Мени Слика у слици."</string>
-    <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Померите налево"</string>
-    <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Померите надесно"</string>
-    <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Померите нагоре"</string>
-    <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Померите надоле"</string>
-    <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Готово"</string>
+    <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Slika u slici"</string>
+    <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Program bez naslova)"</string>
+    <string name="pip_close" msgid="2955969519031223530">"Zatvori"</string>
+    <string name="pip_fullscreen" msgid="7278047353591302554">"Ceo ekran"</string>
+    <string name="pip_move" msgid="158770205886688553">"Premesti"</string>
+    <string name="pip_expand" msgid="1051966011679297308">"Proširi"</string>
+    <string name="pip_collapse" msgid="3903295106641385962">"Skupi"</string>
+    <string name="pip_edu_text" msgid="3672999496647508701">" Dvaput pritisnite "<annotation icon="home_icon">" HOME "</annotation>" za kontrole"</string>
+    <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Meni Slika u slici."</string>
+    <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Pomerite nalevo"</string>
+    <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Pomerite nadesno"</string>
+    <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Pomerite nagore"</string>
+    <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Pomerite nadole"</string>
+    <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Gotovo"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index a57f9ae..800728b 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -19,7 +19,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="pip_phone_close" msgid="5783752637260411309">"Жабуу"</string>
     <string name="pip_phone_expand" msgid="2579292903468287504">"Жайып көрсөтүү"</string>
-    <string name="pip_phone_settings" msgid="5468987116750491918">"Жөндөөлөр"</string>
+    <string name="pip_phone_settings" msgid="5468987116750491918">"Параметрлер"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Экранды бөлүү режимине өтүү"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Меню"</string>
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> – сүрөт ичиндеги сүрөт"</string>
@@ -57,9 +57,9 @@
     <string name="bubble_content_description_single" msgid="8495748092720065813">"<xliff:g id="APP_NAME">%2$s</xliff:g> колдонмосунан <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="8071515017164630429">"<xliff:g id="APP_NAME">%2$s</xliff:g> жана дагы <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> колдонмодон <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_accessibility_action_move_top_left" msgid="2644118920500782758">"Жогорку сол жакка жылдыруу"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="5864594920870245525">"Жогорку оң жакка жылдырыңыз"</string>
+    <string name="bubble_accessibility_action_move_top_right" msgid="5864594920870245525">"Жогорку оң жакка жылдыруу"</string>
     <string name="bubble_accessibility_action_move_bottom_left" msgid="850271002773745634">"Төмөнкү сол жакка жылдыруу"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Төмөнкү оң жакка жылдырыңыз"</string>
+    <string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Төмөнкү оң жакка жылдыруу"</string>
     <string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> жөндөөлөрү"</string>
     <string name="bubble_dismiss_text" msgid="8816558050659478158">"Калкып чыкма билдирмени жабуу"</string>
     <string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Жазышууда калкып чыкма билдирмелер көрүнбөсүн"</string>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index e58e785..97a9fed 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -256,12 +256,30 @@
         }
     }
 
+    /**
+     * Creates a persistent root task in WM for a particular windowing-mode.
+     * @param displayId The display to create the root task on.
+     * @param windowingMode Windowing mode to put the root task in.
+     * @param listener The listener to get the created task callback.
+     */
     public void createRootTask(int displayId, int windowingMode, TaskListener listener) {
-        ProtoLog.v(WM_SHELL_TASK_ORG, "createRootTask() displayId=%d winMode=%d listener=%s",
+        createRootTask(displayId, windowingMode, listener, false /* removeWithTaskOrganizer */);
+    }
+
+    /**
+     * Creates a persistent root task in WM for a particular windowing-mode.
+     * @param displayId The display to create the root task on.
+     * @param windowingMode Windowing mode to put the root task in.
+     * @param listener The listener to get the created task callback.
+     * @param removeWithTaskOrganizer True if this task should be removed when organizer destroyed.
+     */
+    public void createRootTask(int displayId, int windowingMode, TaskListener listener,
+            boolean removeWithTaskOrganizer) {
+        ProtoLog.v(WM_SHELL_TASK_ORG, "createRootTask() displayId=%d winMode=%d listener=%s" ,
                 displayId, windowingMode, listener.toString());
         final IBinder cookie = new Binder();
         setPendingLaunchCookieListener(cookie, listener);
-        super.createRootTask(displayId, windowingMode, cookie);
+        super.createRootTask(displayId, windowingMode, cookie, removeWithTaskOrganizer);
     }
 
     /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java
index 477bc95..95a89b1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java
@@ -224,16 +224,6 @@
         mObscuredTouchRegion = obscuredRegion;
     }
 
-    private void onLocationChanged(WindowContainerTransaction wct) {
-        // Update based on the screen bounds
-        getBoundsOnScreen(mTmpRect);
-        getRootView().getBoundsOnScreen(mTmpRootRect);
-        if (!mTmpRootRect.contains(mTmpRect)) {
-            mTmpRect.offsetTo(0, 0);
-        }
-        wct.setBounds(mTaskToken, mTmpRect);
-    }
-
     /**
      * Call when view position or size has changed. Do not call when animating.
      */
@@ -246,10 +236,15 @@
         if (isUsingShellTransitions() && mTaskViewTransitions.hasPending()) return;
 
         WindowContainerTransaction wct = new WindowContainerTransaction();
-        onLocationChanged(wct);
+        updateWindowBounds(wct);
         mSyncQueue.queue(wct);
     }
 
+    private void updateWindowBounds(WindowContainerTransaction wct) {
+        getBoundsOnScreen(mTmpRect);
+        wct.setBounds(mTaskToken, mTmpRect);
+    }
+
     /**
      * Release this container if it is initialized.
      */
@@ -573,7 +568,7 @@
                     .apply();
 
             // TODO: determine if this is really necessary or not
-            onLocationChanged(wct);
+            updateWindowBounds(wct);
         } else {
             // The surface has already been destroyed before the task has appeared,
             // so go ahead and hide the task entirely
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index cbcd949..2363092 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -51,6 +51,7 @@
 import android.view.SurfaceControl;
 import android.window.BackAnimationAdaptor;
 import android.window.BackEvent;
+import android.window.BackMotionEvent;
 import android.window.BackNavigationInfo;
 import android.window.IBackAnimationRunner;
 import android.window.IBackNaviAnimationController;
@@ -173,11 +174,11 @@
             boolean consumed = false;
             if (mWaitingAnimation && mOnBackCallback != null) {
                 if (mTriggerBack) {
-                    final BackEvent backFinish = mTouchTracker.createProgressEvent(1);
+                    final BackMotionEvent backFinish = mTouchTracker.createProgressEvent(1);
                     dispatchOnBackProgressed(mBackToLauncherCallback, backFinish);
                     dispatchOnBackInvoked(mOnBackCallback);
                 } else {
-                    final BackEvent backFinish = mTouchTracker.createProgressEvent(0);
+                    final BackMotionEvent backFinish = mTouchTracker.createProgressEvent(0);
                     dispatchOnBackProgressed(mBackToLauncherCallback, backFinish);
                     dispatchOnBackCancelled(mOnBackCallback);
                 }
@@ -480,7 +481,7 @@
         if (!mBackGestureStarted || mBackNavigationInfo == null) {
             return;
         }
-        final BackEvent backEvent = mTouchTracker.createProgressEvent();
+        final BackMotionEvent backEvent = mTouchTracker.createProgressEvent();
         if (USE_TRANSITION && mBackAnimationController != null && mAnimationTarget != null) {
                 dispatchOnBackProgressed(mBackToLauncherCallback, backEvent);
         } else if (mEnableAnimations.get()) {
@@ -573,7 +574,7 @@
     }
 
     private void dispatchOnBackStarted(IOnBackInvokedCallback callback,
-            BackEvent backEvent) {
+            BackMotionEvent backEvent) {
         if (callback == null) {
             return;
         }
@@ -611,7 +612,7 @@
     }
 
     private void dispatchOnBackProgressed(IOnBackInvokedCallback callback,
-            BackEvent backEvent) {
+            BackMotionEvent backEvent) {
         if (callback == null) {
             return;
         }
@@ -730,7 +731,7 @@
                     }
                     dispatchOnBackStarted(mBackToLauncherCallback,
                             mTouchTracker.createStartEvent(mAnimationTarget));
-                    final BackEvent backInit = mTouchTracker.createProgressEvent();
+                    final BackMotionEvent backInit = mTouchTracker.createProgressEvent();
                     if (!mCachingBackDispatcher.consume()) {
                         dispatchOnBackProgressed(mBackToLauncherCallback, backInit);
                     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/TouchTracker.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/TouchTracker.java
index ccfac65..695ef4e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/TouchTracker.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/TouchTracker.java
@@ -19,6 +19,7 @@
 import android.os.SystemProperties;
 import android.view.RemoteAnimationTarget;
 import android.window.BackEvent;
+import android.window.BackMotionEvent;
 
 /**
  * Helper class to record the touch location for gesture and generate back events.
@@ -82,11 +83,11 @@
         mSwipeEdge = BackEvent.EDGE_LEFT;
     }
 
-    BackEvent createStartEvent(RemoteAnimationTarget target) {
-        return new BackEvent(mInitTouchX, mInitTouchY, 0, mSwipeEdge, target);
+    BackMotionEvent createStartEvent(RemoteAnimationTarget target) {
+        return new BackMotionEvent(mInitTouchX, mInitTouchY, 0, mSwipeEdge, target);
     }
 
-    BackEvent createProgressEvent() {
+    BackMotionEvent createProgressEvent() {
         float progressThreshold = PROGRESS_THRESHOLD >= 0
                 ? PROGRESS_THRESHOLD : mProgressThreshold;
         progressThreshold = progressThreshold == 0 ? 1 : progressThreshold;
@@ -109,8 +110,8 @@
         return createProgressEvent(progress);
     }
 
-    BackEvent createProgressEvent(float progress) {
-        return new BackEvent(mLatestTouchX, mLatestTouchY, progress, mSwipeEdge, null);
+    BackMotionEvent createProgressEvent(float progress) {
+        return new BackMotionEvent(mLatestTouchX, mLatestTouchY, progress, mSwipeEdge, null);
     }
 
     public void setProgressThreshold(float progressThreshold) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
index 922472a..09dc68a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
@@ -870,7 +870,8 @@
         pw.print("  desiredHeight: "); pw.println(getDesiredHeightString());
         pw.print("  suppressNotif: "); pw.println(shouldSuppressNotification());
         pw.print("  autoExpand:    "); pw.println(shouldAutoExpand());
-        pw.print("  bubbleMetadataFlagListener null: " + (mBubbleMetadataFlagListener == null));
+        pw.print("  isClearable:   "); pw.println(mIsClearable);
+        pw.println("  bubbleMetadataFlagListener null: " + (mBubbleMetadataFlagListener == null));
         if (mExpandedView != null) {
             mExpandedView.dump(pw);
         }
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 dd8afff..71e15c1 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
@@ -973,21 +973,59 @@
     }
 
     /**
-     * Adds and expands bubble for a specific intent. These bubbles are <b>not</b> backed by a n
-     * otification and remain until the user dismisses the bubble or bubble stack. Only one intent
-     * bubble is supported at a time.
+     * This method has different behavior depending on:
+     *    - if an app bubble exists
+     *    - if an app bubble is expanded
+     *
+     * If no app bubble exists, this will add and expand a bubble with the provided intent. The
+     * intent must be explicit (i.e. include a package name or fully qualified component class name)
+     * and the activity for it should be resizable.
+     *
+     * If an app bubble exists, this will toggle the visibility of it, i.e. if the app bubble is
+     * expanded, calling this method will collapse it. If the app bubble is not expanded, calling
+     * this method will expand it.
+     *
+     * These bubbles are <b>not</b> backed by a notification and remain until the user dismisses
+     * the bubble or bubble stack.
+     *
+     * Some notes:
+     *    - Only one app bubble is supported at a time
+     *    - Calling this method with a different intent than the existing app bubble will do nothing
      *
      * @param intent the intent to display in the bubble expanded view.
      */
-    public void showAppBubble(Intent intent) {
-        if (intent == null || intent.getPackage() == null) return;
+    public void showOrHideAppBubble(Intent intent) {
+        if (intent == null || intent.getPackage() == null) {
+            Log.w(TAG, "App bubble failed to show, invalid intent: " + intent
+                    + ((intent != null) ? " with package: " + intent.getPackage() : " "));
+            return;
+        }
 
         PackageManager packageManager = getPackageManagerForUser(mContext, mCurrentUserId);
         if (!isResizableActivity(intent, packageManager, KEY_APP_BUBBLE)) return;
 
-        Bubble b = new Bubble(intent, UserHandle.of(mCurrentUserId), mMainExecutor);
-        b.setShouldAutoExpand(true);
-        inflateAndAdd(b, /* suppressFlyout= */ true, /* showInShade= */ false);
+        Bubble existingAppBubble = mBubbleData.getBubbleInStackWithKey(KEY_APP_BUBBLE);
+        if (existingAppBubble != null) {
+            BubbleViewProvider selectedBubble = mBubbleData.getSelectedBubble();
+            if (isStackExpanded()) {
+                if (selectedBubble != null && KEY_APP_BUBBLE.equals(selectedBubble.getKey())) {
+                    // App bubble is expanded, lets collapse
+                    collapseStack();
+                } else {
+                    // App bubble is not selected, select it
+                    mBubbleData.setSelectedBubble(existingAppBubble);
+                }
+            } else {
+                // App bubble is not selected, select it & expand
+                mBubbleData.setSelectedBubble(existingAppBubble);
+                mBubbleData.setExpanded(true);
+            }
+        } else {
+            // App bubble does not exist, lets add and expand it
+            Bubble b = new Bubble(intent, UserHandle.of(mCurrentUserId), mMainExecutor);
+            b.setShouldAutoExpand(true);
+            inflateAndAdd(b, /* suppressFlyout= */ true, /* showInShade= */ false);
+        }
     }
 
     /**
@@ -1697,9 +1735,9 @@
         }
 
         @Override
-        public void showAppBubble(Intent intent) {
+        public void showOrHideAppBubble(Intent intent) {
             mMainExecutor.execute(() -> {
-                BubbleController.this.showAppBubble(intent);
+                BubbleController.this.showOrHideAppBubble(intent);
             });
         }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
index af31391..6230d22 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
@@ -17,6 +17,7 @@
 
 import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
 import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
+import static com.android.wm.shell.bubbles.Bubble.KEY_APP_BUBBLE;
 import static com.android.wm.shell.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_DATA;
 import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES;
 import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
@@ -684,7 +685,8 @@
         if (bubble.getPendingIntentCanceled()
                 || !(reason == Bubbles.DISMISS_AGED
                 || reason == Bubbles.DISMISS_USER_GESTURE
-                || reason == Bubbles.DISMISS_RELOAD_FROM_DISK)) {
+                || reason == Bubbles.DISMISS_RELOAD_FROM_DISK)
+                || KEY_APP_BUBBLE.equals(bubble.getKey())) {
             return;
         }
         if (DEBUG_BUBBLE_DATA) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
index 465d1ab..df43257 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
@@ -109,13 +109,28 @@
     void expandStackAndSelectBubble(Bubble bubble);
 
     /**
-     * Adds and expands bubble that is not notification based, but instead based on an intent from
-     * the app. The intent must be explicit (i.e. include a package name or fully qualified
-     * component class name) and the activity for it should be resizable.
+     * This method has different behavior depending on:
+     *    - if an app bubble exists
+     *    - if an app bubble is expanded
      *
-     * @param intent the intent to populate the bubble.
+     * If no app bubble exists, this will add and expand a bubble with the provided intent. The
+     * intent must be explicit (i.e. include a package name or fully qualified component class name)
+     * and the activity for it should be resizable.
+     *
+     * If an app bubble exists, this will toggle the visibility of it, i.e. if the app bubble is
+     * expanded, calling this method will collapse it. If the app bubble is not expanded, calling
+     * this method will expand it.
+     *
+     * These bubbles are <b>not</b> backed by a notification and remain until the user dismisses
+     * the bubble or bubble stack.
+     *
+     * Some notes:
+     *    - Only one app bubble is supported at a time
+     *    - Calling this method with a different intent than the existing app bubble will do nothing
+     *
+     * @param intent the intent to display in the bubble expanded view.
      */
-    void showAppBubble(Intent intent);
+    void showOrHideAppBubble(Intent intent);
 
     /**
      * @return a bubble that matches the provided shortcutId, if one exists.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
index 266cf29..7f7af93 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
@@ -274,29 +274,30 @@
             }
 
             if (hasImeSourceControl) {
-                final Point lastSurfacePosition = mImeSourceControl != null
-                        ? mImeSourceControl.getSurfacePosition() : null;
-                final boolean positionChanged =
-                        !imeSourceControl.getSurfacePosition().equals(lastSurfacePosition);
-                final boolean leashChanged =
-                        !haveSameLeash(mImeSourceControl, imeSourceControl);
                 if (mAnimation != null) {
+                    final Point lastSurfacePosition = hadImeSourceControl
+                            ? mImeSourceControl.getSurfacePosition() : null;
+                    final boolean positionChanged =
+                            !imeSourceControl.getSurfacePosition().equals(lastSurfacePosition);
                     if (positionChanged) {
                         startAnimation(mImeShowing, true /* forceRestart */);
                     }
                 } else {
-                    if (leashChanged) {
+                    if (!haveSameLeash(mImeSourceControl, imeSourceControl)) {
                         applyVisibilityToLeash(imeSourceControl);
                     }
                     if (!mImeShowing) {
                         removeImeSurface();
                     }
-                    if (mImeSourceControl != null) {
-                        mImeSourceControl.release(SurfaceControl::release);
-                    }
                 }
-                mImeSourceControl = imeSourceControl;
+            } else if (mAnimation != null) {
+                mAnimation.cancel();
             }
+
+            if (hadImeSourceControl && mImeSourceControl != imeSourceControl) {
+                mImeSourceControl.release(SurfaceControl::release);
+            }
+            mImeSourceControl = imeSourceControl;
         }
 
         private void applyVisibilityToLeash(InsetsSourceControl imeSourceControl) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java
index 96efeeb..8484013 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java
@@ -96,8 +96,7 @@
 
     /**
      * Different from {@link #equals(Object)}, this method compares the basic geometry properties
-     * of two {@link DisplayLayout} objects including width, height, rotation, density, cutout and
-     * insets.
+     * of two {@link DisplayLayout} objects including width, height, rotation, density, cutout.
      * @return {@code true} if the given {@link DisplayLayout} is identical geometry wise.
      */
     public boolean isSameGeometry(@NonNull DisplayLayout other) {
@@ -105,8 +104,7 @@
                 && mHeight == other.mHeight
                 && mRotation == other.mRotation
                 && mDensityDpi == other.mDensityDpi
-                && Objects.equals(mCutout, other.mCutout)
-                && Objects.equals(mStableInsets, other.mStableInsets);
+                && Objects.equals(mCutout, other.mCutout);
     }
 
     @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SingleInstanceRemoteListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SingleInstanceRemoteListener.java
index b77ac8a..e46ee28 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SingleInstanceRemoteListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SingleInstanceRemoteListener.java
@@ -29,6 +29,9 @@
  * Manages the lifecycle of a single instance of a remote listener, including the clean up if the
  * remote process dies.  All calls on this class should happen on the main shell thread.
  *
+ * Any external interface using this listener should also unregister the listener when it is
+ * invalidated, otherwise it may leak binder death recipients.
+ *
  * @param <C> The controller (must be RemoteCallable)
  * @param <L> The remote listener interface type
  */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
index a9d3c9f..abb357c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
@@ -78,6 +78,7 @@
     private final Rect mResizingBounds = new Rect();
     private final Rect mTempRect = new Rect();
     private ValueAnimator mFadeAnimator;
+    private ValueAnimator mScreenshotAnimator;
 
     private int mIconSize;
     private int mOffsetX;
@@ -135,8 +136,17 @@
 
     /** Releases the surfaces for split decor. */
     public void release(SurfaceControl.Transaction t) {
-        if (mFadeAnimator != null && mFadeAnimator.isRunning()) {
-            mFadeAnimator.cancel();
+        if (mFadeAnimator != null) {
+            if (mFadeAnimator.isRunning()) {
+                mFadeAnimator.cancel();
+            }
+            mFadeAnimator = null;
+        }
+        if (mScreenshotAnimator != null) {
+            if (mScreenshotAnimator.isRunning()) {
+                mScreenshotAnimator.cancel();
+            }
+            mScreenshotAnimator = null;
         }
         if (mViewHost != null) {
             mViewHost.release();
@@ -238,16 +248,20 @@
     /** Stops showing resizing hint. */
     public void onResized(SurfaceControl.Transaction t, Runnable animFinishedCallback) {
         if (mScreenshot != null) {
+            if (mScreenshotAnimator != null && mScreenshotAnimator.isRunning()) {
+                mScreenshotAnimator.cancel();
+            }
+
             t.setPosition(mScreenshot, mOffsetX, mOffsetY);
 
             final SurfaceControl.Transaction animT = new SurfaceControl.Transaction();
-            final ValueAnimator va = ValueAnimator.ofFloat(1, 0);
-            va.addUpdateListener(valueAnimator -> {
+            mScreenshotAnimator = ValueAnimator.ofFloat(1, 0);
+            mScreenshotAnimator.addUpdateListener(valueAnimator -> {
                 final float progress = (float) valueAnimator.getAnimatedValue();
                 animT.setAlpha(mScreenshot, progress);
                 animT.apply();
             });
-            va.addListener(new AnimatorListenerAdapter() {
+            mScreenshotAnimator.addListener(new AnimatorListenerAdapter() {
                 @Override
                 public void onAnimationStart(Animator animation) {
                     mRunningAnimationCount++;
@@ -266,7 +280,7 @@
                     }
                 }
             });
-            va.start();
+            mScreenshotAnimator.start();
         }
 
         if (mResizingIconView == null) {
@@ -292,9 +306,6 @@
                 });
                 return;
             }
-
-            // If fade-in animation is running, cancel it and re-run fade-out one.
-            mFadeAnimator.cancel();
         }
         if (mShown) {
             fadeOutDecor(animFinishedCallback);
@@ -332,6 +343,11 @@
      * directly. */
     public void fadeOutDecor(Runnable finishedCallback) {
         if (mShown) {
+            // If previous animation is running, just cancel it.
+            if (mFadeAnimator != null && mFadeAnimator.isRunning()) {
+                mFadeAnimator.cancel();
+            }
+
             startFadeAnimation(false /* show */, true, finishedCallback);
             mShown = false;
         } else {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index d3b9fa5..512a4ef 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -49,6 +49,7 @@
 import com.android.wm.shell.common.annotations.ShellBackgroundThread;
 import com.android.wm.shell.common.annotations.ShellMainThread;
 import com.android.wm.shell.desktopmode.DesktopModeController;
+import com.android.wm.shell.desktopmode.DesktopModeStatus;
 import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
 import com.android.wm.shell.desktopmode.DesktopTasksController;
 import com.android.wm.shell.draganddrop.DragAndDropController;
@@ -93,6 +94,7 @@
 import com.android.wm.shell.unfold.animation.UnfoldTaskAnimator;
 import com.android.wm.shell.unfold.qualifier.UnfoldShellTransition;
 import com.android.wm.shell.unfold.qualifier.UnfoldTransition;
+import com.android.wm.shell.windowdecor.CaptionWindowDecorViewModel;
 import com.android.wm.shell.windowdecor.DesktopModeWindowDecorViewModel;
 import com.android.wm.shell.windowdecor.WindowDecorViewModel;
 
@@ -192,7 +194,8 @@
             SyncTransactionQueue syncQueue,
             Optional<DesktopModeController> desktopModeController,
             Optional<DesktopTasksController> desktopTasksController) {
-        return new DesktopModeWindowDecorViewModel(
+        if (DesktopModeStatus.isAnyEnabled()) {
+            return new DesktopModeWindowDecorViewModel(
                     context,
                     mainHandler,
                     mainChoreographer,
@@ -201,6 +204,14 @@
                     syncQueue,
                     desktopModeController,
                     desktopTasksController);
+        }
+        return new CaptionWindowDecorViewModel(
+                    context,
+                    mainHandler,
+                    mainChoreographer,
+                    taskOrganizer,
+                    displayController,
+                    syncQueue);
     }
 
     //
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java
index f5f3573..a839a23 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java
@@ -36,6 +36,7 @@
 import android.net.Uri;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.RemoteException;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.ArraySet;
@@ -251,7 +252,8 @@
      * Show apps on desktop
      */
     void showDesktopApps() {
-        WindowContainerTransaction wct = bringDesktopAppsToFront();
+        // Bring apps to front, ignoring their visibility status to always ensure they are on top.
+        WindowContainerTransaction wct = bringDesktopAppsToFront(true /* ignoreVisibility */);
 
         if (Transitions.ENABLE_SHELL_TRANSITIONS) {
             mTransitions.startTransition(TRANSIT_TO_FRONT, wct, null /* handler */);
@@ -260,8 +262,13 @@
         }
     }
 
+    /** Get number of tasks that are marked as visible */
+    int getVisibleTaskCount() {
+        return mDesktopModeTaskRepository.getVisibleTaskCount();
+    }
+
     @NonNull
-    private WindowContainerTransaction bringDesktopAppsToFront() {
+    private WindowContainerTransaction bringDesktopAppsToFront(boolean force) {
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         final ArraySet<Integer> activeTasks = mDesktopModeTaskRepository.getActiveTasks();
         ProtoLog.d(WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront: tasks=%s", activeTasks.size());
@@ -278,12 +285,14 @@
             return wct;
         }
 
-        final boolean allActiveTasksAreVisible = taskInfos.stream()
-                .allMatch(info -> mDesktopModeTaskRepository.isVisibleTask(info.taskId));
-        if (allActiveTasksAreVisible) {
-            ProtoLog.d(WM_SHELL_DESKTOP_MODE,
-                    "bringDesktopAppsToFront: active tasks are already in front, skipping.");
-            return wct;
+        if (!force) {
+            final boolean allActiveTasksAreVisible = taskInfos.stream()
+                    .allMatch(info -> mDesktopModeTaskRepository.isVisibleTask(info.taskId));
+            if (allActiveTasksAreVisible) {
+                ProtoLog.d(WM_SHELL_DESKTOP_MODE,
+                        "bringDesktopAppsToFront: active tasks are already in front, skipping.");
+                return wct;
+            }
         }
         ProtoLog.d(WM_SHELL_DESKTOP_MODE,
                 "bringDesktopAppsToFront: reordering all active tasks to the front");
@@ -354,7 +363,7 @@
         if (wct == null) {
             wct = new WindowContainerTransaction();
         }
-        wct.merge(bringDesktopAppsToFront(), true /* transfer */);
+        wct.merge(bringDesktopAppsToFront(false /* ignoreVisibility */), true /* transfer */);
         wct.reorder(request.getTriggerTask().token, true /* onTop */);
 
         return wct;
@@ -435,5 +444,15 @@
             executeRemoteCallWithTaskPermission(mController, "showDesktopApps",
                     DesktopModeController::showDesktopApps);
         }
+
+        @Override
+        public int getVisibleTaskCount() throws RemoteException {
+            int[] result = new int[1];
+            executeRemoteCallWithTaskPermission(mController, "getVisibleTaskCount",
+                    controller -> result[0] = controller.getVisibleTaskCount(),
+                    true /* blocking */
+            );
+            return result[0];
+        }
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt
index 600ccc1..47342c9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt
@@ -143,6 +143,13 @@
     }
 
     /**
+     * Get number of tasks that are marked as visible
+     */
+    fun getVisibleTaskCount(): Int {
+        return visibleTasks.size
+    }
+
+    /**
      * Add (or move if it already exists) the task to the top of the ordered list.
      */
     fun addOrMoveFreeformTaskToTop(taskId: Int) {
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 3341470..2303325 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
@@ -84,8 +84,7 @@
     fun showDesktopApps() {
         ProtoLog.v(WM_SHELL_DESKTOP_MODE, "showDesktopApps")
         val wct = WindowContainerTransaction()
-
-        bringDesktopAppsToFront(wct)
+        bringDesktopAppsToFront(wct, force = true)
 
         // Execute transaction if there are pending operations
         if (!wct.isEmpty) {
@@ -97,6 +96,11 @@
         }
     }
 
+    /** Get number of tasks that are marked as visible */
+    fun getVisibleTaskCount(): Int {
+        return desktopModeTaskRepository.getVisibleTaskCount()
+    }
+
     /** Move a task with given `taskId` to desktop */
     fun moveToDesktop(taskId: Int) {
         shellTaskOrganizer.getRunningTaskInfo(taskId)?.let { task -> moveToDesktop(task) }
@@ -150,11 +154,11 @@
             ?: WINDOWING_MODE_UNDEFINED
     }
 
-    private fun bringDesktopAppsToFront(wct: WindowContainerTransaction) {
+    private fun bringDesktopAppsToFront(wct: WindowContainerTransaction, force: Boolean = false) {
         val activeTasks = desktopModeTaskRepository.getActiveTasks()
 
         // Skip if all tasks are already visible
-        if (activeTasks.isNotEmpty() && activeTasks.all(desktopModeTaskRepository::isVisibleTask)) {
+        if (!force && activeTasks.all(desktopModeTaskRepository::isVisibleTask)) {
             ProtoLog.d(
                 WM_SHELL_DESKTOP_MODE,
                 "bringDesktopAppsToFront: active tasks are already in front, skipping."
@@ -310,5 +314,16 @@
                 Consumer(DesktopTasksController::showDesktopApps)
             )
         }
+
+        override fun getVisibleTaskCount(): Int {
+            val result = IntArray(1)
+            ExecutorUtils.executeRemoteCallWithTaskPermission(
+                controller,
+                "getVisibleTaskCount",
+                { controller -> result[0] = controller.getVisibleTaskCount() },
+                true /* blocking */
+            )
+            return result[0]
+        }
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl
index 5042bd6..d0739e1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl
@@ -23,4 +23,7 @@
 
     /** Show apps on the desktop */
     void showDesktopApps();
+
+    /** Get count of visible desktop tasks */
+    int getVisibleTaskCount();
 }
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
index 793bad8..48487bc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
@@ -129,11 +129,11 @@
     @Override
     public void onTaskInfoChanged(RunningTaskInfo taskInfo) {
         final State state = mTasks.get(taskInfo.taskId);
-        state.mTaskInfo = taskInfo;
+
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Freeform Task Info Changed: #%d",
                 taskInfo.taskId);
-        mWindowDecorationViewModel.onTaskInfoChanged(state.mTaskInfo);
-
+        mWindowDecorationViewModel.onTaskInfoChanged(taskInfo);
+        state.mTaskInfo = taskInfo;
         if (DesktopModeStatus.isAnyEnabled()) {
             mDesktopModeTaskRepository.ifPresent(repository -> {
                 if (taskInfo.isVisible) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
index 6623f5c..26f47fc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
@@ -114,7 +114,9 @@
                 t.setPosition(leash, positionInParent.x, positionInParent.y);
                 t.setAlpha(leash, 1f);
                 t.setMatrix(leash, 1, 0, 0, 1);
-                t.show(leash);
+                if (taskInfo.isVisible) {
+                    t.show(leash);
+                }
             });
         }
     }
@@ -123,10 +125,11 @@
     public void onTaskInfoChanged(RunningTaskInfo taskInfo) {
         final State state = mTasks.get(taskInfo.taskId);
         final Point oldPositionInParent = state.mTaskInfo.positionInParent;
-        state.mTaskInfo = taskInfo;
+
         if (mWindowDecorViewModelOptional.isPresent()) {
-            mWindowDecorViewModelOptional.get().onTaskInfoChanged(state.mTaskInfo);
+            mWindowDecorViewModelOptional.get().onTaskInfoChanged(taskInfo);
         }
+        state.mTaskInfo = taskInfo;
         if (Transitions.ENABLE_SHELL_TRANSITIONS) return;
         updateRecentsForVisibleFullscreenTask(taskInfo);
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java
index cd61dbb..f6d67d8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java
@@ -47,7 +47,7 @@
 
     private final @NonNull PipBoundsState mPipBoundsState;
     private final PipSnapAlgorithm mSnapAlgorithm;
-    private final PipKeepClearAlgorithm mPipKeepClearAlgorithm;
+    private final PipKeepClearAlgorithmInterface mPipKeepClearAlgorithm;
 
     private float mDefaultSizePercent;
     private float mMinAspectRatioForMinSize;
@@ -62,7 +62,7 @@
 
     public PipBoundsAlgorithm(Context context, @NonNull PipBoundsState pipBoundsState,
             @NonNull PipSnapAlgorithm pipSnapAlgorithm,
-            @NonNull PipKeepClearAlgorithm pipKeepClearAlgorithm) {
+            @NonNull PipKeepClearAlgorithmInterface pipKeepClearAlgorithm) {
         mPipBoundsState = pipBoundsState;
         mSnapAlgorithm = pipSnapAlgorithm;
         mPipKeepClearAlgorithm = pipKeepClearAlgorithm;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipKeepClearAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipKeepClearAlgorithmInterface.java
similarity index 97%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipKeepClearAlgorithm.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipKeepClearAlgorithmInterface.java
index e3495e1..5045cf9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipKeepClearAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipKeepClearAlgorithmInterface.java
@@ -24,7 +24,7 @@
  * Interface for interacting with keep clear algorithm used to move PiP window out of the way of
  * keep clear areas.
  */
-public interface PipKeepClearAlgorithm {
+public interface PipKeepClearAlgorithmInterface {
 
     /**
      * Adjust the position of picture in picture window based on the registered keep clear areas.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index e6c7e10..83158ff 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -662,8 +662,8 @@
             }
 
             // Please file a bug to handle the unexpected transition type.
-            throw new IllegalStateException("Entering PIP with unexpected transition type="
-                    + transitTypeToString(transitType));
+            android.util.Slog.e(TAG, "Found new PIP in transition with mis-matched type="
+                    + transitTypeToString(transitType), new Throwable());
         }
         return false;
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithm.java
index 690505e..ed8dc7de 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithm.java
@@ -26,14 +26,14 @@
 import com.android.wm.shell.R;
 import com.android.wm.shell.pip.PipBoundsAlgorithm;
 import com.android.wm.shell.pip.PipBoundsState;
-import com.android.wm.shell.pip.PipKeepClearAlgorithm;
+import com.android.wm.shell.pip.PipKeepClearAlgorithmInterface;
 
 import java.util.Set;
 
 /**
  * Calculates the adjusted position that does not occlude keep clear areas.
  */
-public class PhonePipKeepClearAlgorithm implements PipKeepClearAlgorithm {
+public class PhonePipKeepClearAlgorithm implements PipKeepClearAlgorithmInterface {
 
     private boolean mKeepClearAreaGravityEnabled =
             SystemProperties.getBoolean(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
index 281ea53..431bd7b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
@@ -333,6 +333,9 @@
         mTmpDestinationRectF.set(destinationBounds);
         mMoveTransform.setRectToRect(mTmpSourceRectF, mTmpDestinationRectF, Matrix.ScaleToFit.FILL);
         final SurfaceControl surfaceControl = getSurfaceControl();
+        if (surfaceControl == null) {
+            return;
+        }
         final SurfaceControl.Transaction menuTx =
                 mSurfaceControlTransactionFactory.getTransaction();
         menuTx.setMatrix(surfaceControl, mMoveTransform, mTmpTransform);
@@ -359,6 +362,9 @@
         }
 
         final SurfaceControl surfaceControl = getSurfaceControl();
+        if (surfaceControl == null) {
+            return;
+        }
         final SurfaceControl.Transaction menuTx =
                 mSurfaceControlTransactionFactory.getTransaction();
         menuTx.setCrop(surfaceControl, destinationBounds);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index efe938f..525beb1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -46,8 +46,6 @@
 import android.graphics.Rect;
 import android.os.RemoteException;
 import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.os.UserManager;
 import android.util.Pair;
 import android.util.Size;
 import android.view.DisplayInfo;
@@ -85,7 +83,7 @@
 import com.android.wm.shell.pip.PipAppOpsListener;
 import com.android.wm.shell.pip.PipBoundsAlgorithm;
 import com.android.wm.shell.pip.PipBoundsState;
-import com.android.wm.shell.pip.PipKeepClearAlgorithm;
+import com.android.wm.shell.pip.PipKeepClearAlgorithmInterface;
 import com.android.wm.shell.pip.PipMediaController;
 import com.android.wm.shell.pip.PipParamsChangedForwarder;
 import com.android.wm.shell.pip.PipSnapAlgorithm;
@@ -137,7 +135,7 @@
     private PipAppOpsListener mAppOpsListener;
     private PipMediaController mMediaController;
     private PipBoundsAlgorithm mPipBoundsAlgorithm;
-    private PipKeepClearAlgorithm mPipKeepClearAlgorithm;
+    private PipKeepClearAlgorithmInterface mPipKeepClearAlgorithm;
     private PipBoundsState mPipBoundsState;
     private PipMotionHelper mPipMotionHelper;
     private PipTouchHandler mTouchHandler;
@@ -207,7 +205,8 @@
 
     private Consumer<Boolean> mOnIsInPipStateChangedListener;
 
-    private interface PipAnimationListener {
+    @VisibleForTesting
+    interface PipAnimationListener {
         /**
          * Notifies the listener that the Pip animation is started.
          */
@@ -379,7 +378,7 @@
             PipAnimationController pipAnimationController,
             PipAppOpsListener pipAppOpsListener,
             PipBoundsAlgorithm pipBoundsAlgorithm,
-            PipKeepClearAlgorithm pipKeepClearAlgorithm,
+            PipKeepClearAlgorithmInterface pipKeepClearAlgorithm,
             PipBoundsState pipBoundsState,
             PipMotionHelper pipMotionHelper,
             PipMediaController pipMediaController,
@@ -418,7 +417,7 @@
             PipAnimationController pipAnimationController,
             PipAppOpsListener pipAppOpsListener,
             PipBoundsAlgorithm pipBoundsAlgorithm,
-            PipKeepClearAlgorithm pipKeepClearAlgorithm,
+            PipKeepClearAlgorithmInterface pipKeepClearAlgorithm,
             @NonNull PipBoundsState pipBoundsState,
             PipMotionHelper pipMotionHelper,
             PipMediaController pipMediaController,
@@ -434,11 +433,7 @@
             Optional<OneHandedController> oneHandedController,
             ShellExecutor mainExecutor
     ) {
-        // Ensure that we are the primary user's SystemUI.
-        final int processUser = UserManager.get(context).getProcessUserId();
-        if (processUser != UserHandle.USER_SYSTEM) {
-            throw new IllegalStateException("Non-primary Pip component not currently supported.");
-        }
+
 
         mContext = context;
         mShellCommandHandler = shellCommandHandler;
@@ -621,7 +616,7 @@
                             return;
                         }
                         int oldMaxMovementBound = mPipBoundsState.getMovementBounds().bottom;
-                        onDisplayChanged(
+                        onDisplayChangedUncheck(
                                 mDisplayController.getDisplayLayout(mPipBoundsState.getDisplayId()),
                                 false /* saveRestoreSnapFraction */);
                         int newMaxMovementBound = mPipBoundsState.getMovementBounds().bottom;
@@ -707,9 +702,12 @@
     }
 
     private void onDisplayChanged(DisplayLayout layout, boolean saveRestoreSnapFraction) {
-        if (mPipBoundsState.getDisplayLayout().isSameGeometry(layout)) {
-            return;
+        if (!mPipBoundsState.getDisplayLayout().isSameGeometry(layout)) {
+            onDisplayChangedUncheck(layout, saveRestoreSnapFraction);
         }
+    }
+
+    private void onDisplayChangedUncheck(DisplayLayout layout, boolean saveRestoreSnapFraction) {
         Runnable updateDisplayLayout = () -> {
             final boolean fromRotation = Transitions.ENABLE_SHELL_TRANSITIONS
                     && mPipBoundsState.getDisplayLayout().rotation() != layout.rotation();
@@ -817,7 +815,7 @@
     @Override
     public void onKeyguardVisibilityChanged(boolean visible, boolean occluded,
             boolean animatingDismiss) {
-        if (!mPipTaskOrganizer.isInPip()) {
+        if (!mPipTransitionState.hasEnteredPip()) {
             return;
         }
         if (visible) {
@@ -872,11 +870,17 @@
                 animationType == PipAnimationController.ANIM_TYPE_BOUNDS);
     }
 
-    private void setPinnedStackAnimationListener(PipAnimationListener callback) {
+    @VisibleForTesting
+    void setPinnedStackAnimationListener(PipAnimationListener callback) {
         mPinnedStackAnimationRecentsCallback = callback;
         onPipResourceDimensionsChanged();
     }
 
+    @VisibleForTesting
+    boolean hasPinnedStackAnimationListener() {
+        return mPinnedStackAnimationRecentsCallback != null;
+    }
+
     private void onPipResourceDimensionsChanged() {
         if (mPinnedStackAnimationRecentsCallback != null) {
             mPinnedStackAnimationRecentsCallback.onPipResourceDimensionsChanged(
@@ -1166,6 +1170,8 @@
         @Override
         public void invalidate() {
             mController = null;
+            // Unregister the listener to ensure any registered binder death recipients are unlinked
+            mListener.unregister();
         }
 
         @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
index 83bc7c0..850c561 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
@@ -337,8 +337,10 @@
         mMotionHelper.synchronizePinnedStackBounds();
         reloadResources();
 
-        // Recreate the dismiss target for the new orientation.
-        mPipDismissTargetHandler.createOrUpdateDismissTarget();
+        if (mPipTaskOrganizer.isInPip()) {
+            // Recreate the dismiss target for the new orientation.
+            mPipDismissTargetHandler.createOrUpdateDismissTarget();
+        }
     }
 
     public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java
index ce34d2f..1ff77f7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java
@@ -39,7 +39,7 @@
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.pip.PipBoundsAlgorithm;
-import com.android.wm.shell.pip.PipKeepClearAlgorithm;
+import com.android.wm.shell.pip.PipKeepClearAlgorithmInterface;
 import com.android.wm.shell.pip.PipSnapAlgorithm;
 import com.android.wm.shell.pip.tv.TvPipKeepClearAlgorithm.Placement;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
@@ -65,7 +65,7 @@
             @NonNull TvPipBoundsState tvPipBoundsState,
             @NonNull PipSnapAlgorithm pipSnapAlgorithm) {
         super(context, tvPipBoundsState, pipSnapAlgorithm,
-                new PipKeepClearAlgorithm() {});
+                new PipKeepClearAlgorithmInterface() {});
         this.mTvPipBoundsState = tvPipBoundsState;
         this.mKeepClearAlgorithm = new TvPipKeepClearAlgorithm();
         reloadResources(context);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
index db0f0bf..8490f9f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
@@ -280,15 +280,22 @@
         }
     }
 
-    private void registerRecentTasksListener(IRecentTasksListener listener) {
+    @VisibleForTesting
+    void registerRecentTasksListener(IRecentTasksListener listener) {
         mListener = listener;
     }
 
-    private void unregisterRecentTasksListener() {
+    @VisibleForTesting
+    void unregisterRecentTasksListener() {
         mListener = null;
     }
 
     @VisibleForTesting
+    boolean hasRecentTasksListener() {
+        return mListener != null;
+    }
+
+    @VisibleForTesting
     ArrayList<GroupedRecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
         // Note: the returned task list is from the most-recent to least-recent order
         final List<ActivityManager.RecentTaskInfo> rawList = mActivityTaskManager.getRecentTasks(
@@ -442,6 +449,8 @@
         @Override
         public void invalidate() {
             mController = null;
+            // Unregister the listener to ensure any registered binder death recipients are unlinked
+            mListener.unregister();
         }
 
         @Override
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 ef70d9b..21eeaa2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -18,6 +18,7 @@
 
 import static android.app.ActivityManager.START_SUCCESS;
 import static android.app.ActivityManager.START_TASK_TO_FRONT;
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
 import static android.view.Display.DEFAULT_DISPLAY;
@@ -535,17 +536,11 @@
                 fillInIntent.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
                 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK");
             } else {
-                try {
-                    adapter.getRunner().onAnimationCancelled(false /* isKeyguardOccluded */);
-                    ActivityTaskManager.getService().startActivityFromRecents(taskId, options2);
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Error starting remote animation", e);
-                }
+                taskId = INVALID_TASK_ID;
                 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
                         "Cancel entering split as not supporting multi-instances");
                 Toast.makeText(mContext, R.string.dock_multi_instances_not_supported_text,
                         Toast.LENGTH_SHORT).show();
-                return;
             }
         }
         mStageCoordinator.startIntentAndTaskWithLegacyTransition(pendingIntent, fillInIntent,
@@ -586,17 +581,11 @@
                 fillInIntent2.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
                 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK");
             } else {
-                try {
-                    adapter.getRunner().onAnimationCancelled(false /* isKeyguardOccluded */);
-                    pendingIntent1.send();
-                } catch (RemoteException | PendingIntent.CanceledException e) {
-                    Slog.e(TAG, "Error starting remote animation", e);
-                }
+                pendingIntent2 = null;
                 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
                         "Cancel entering split as not supporting multi-instances");
                 Toast.makeText(mContext, R.string.dock_multi_instances_not_supported_text,
                         Toast.LENGTH_SHORT).show();
-                return;
             }
         }
         mStageCoordinator.startIntentsWithLegacyTransition(pendingIntent1, fillInIntent1, options1,
@@ -954,6 +943,8 @@
         @Override
         public void invalidate() {
             mController = null;
+            // Unregister the listener to ensure any registered binder death recipients are unlinked
+            mListener.unregister();
         }
 
         @Override
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 8ddc3c04..39cf5f1 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
@@ -605,9 +605,19 @@
             float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) {
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         if (options1 == null) options1 = new Bundle();
+        if (taskId2 == INVALID_TASK_ID) {
+            // Launching a solo task.
+            ActivityOptions activityOptions = ActivityOptions.fromBundle(options1);
+            activityOptions.update(ActivityOptions.makeRemoteAnimation(adapter));
+            options1 = activityOptions.toBundle();
+            addActivityOptions(options1, null /* launchTarget */);
+            wct.startTask(taskId1, options1);
+            mSyncQueue.queue(wct);
+            return;
+        }
+
         addActivityOptions(options1, mSideStage);
         wct.startTask(taskId1, options1);
-
         startWithLegacyTransition(wct, taskId2, options2, splitPosition, splitRatio, adapter,
                 instanceId);
     }
@@ -619,9 +629,19 @@
             RemoteAnimationAdapter adapter, InstanceId instanceId) {
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         if (options1 == null) options1 = new Bundle();
+        if (pendingIntent2 == null) {
+            // Launching a solo task.
+            ActivityOptions activityOptions = ActivityOptions.fromBundle(options1);
+            activityOptions.update(ActivityOptions.makeRemoteAnimation(adapter));
+            options1 = activityOptions.toBundle();
+            addActivityOptions(options1, null /* launchTarget */);
+            wct.sendPendingIntent(pendingIntent1, fillInIntent1, options1);
+            mSyncQueue.queue(wct);
+            return;
+        }
+
         addActivityOptions(options1, mSideStage);
         wct.sendPendingIntent(pendingIntent1, fillInIntent1, options1);
-
         startWithLegacyTransition(wct, pendingIntent2, fillInIntent2, options2, splitPosition,
                 splitRatio, adapter, instanceId);
     }
@@ -632,9 +652,19 @@
             InstanceId instanceId) {
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         if (options1 == null) options1 = new Bundle();
+        if (taskId == INVALID_TASK_ID) {
+            // Launching a solo task.
+            ActivityOptions activityOptions = ActivityOptions.fromBundle(options1);
+            activityOptions.update(ActivityOptions.makeRemoteAnimation(adapter));
+            options1 = activityOptions.toBundle();
+            addActivityOptions(options1, null /* launchTarget */);
+            wct.sendPendingIntent(pendingIntent, fillInIntent, options1);
+            mSyncQueue.queue(wct);
+            return;
+        }
+
         addActivityOptions(options1, mSideStage);
         wct.sendPendingIntent(pendingIntent, fillInIntent, options1);
-
         startWithLegacyTransition(wct, taskId, options2, splitPosition, splitRatio, adapter,
                 instanceId);
     }
@@ -646,9 +676,19 @@
             InstanceId instanceId) {
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         if (options1 == null) options1 = new Bundle();
+        if (taskId == INVALID_TASK_ID) {
+            // Launching a solo task.
+            ActivityOptions activityOptions = ActivityOptions.fromBundle(options1);
+            activityOptions.update(ActivityOptions.makeRemoteAnimation(adapter));
+            options1 = activityOptions.toBundle();
+            addActivityOptions(options1, null /* launchTarget */);
+            wct.startShortcut(mContext.getPackageName(), shortcutInfo, options1);
+            mSyncQueue.queue(wct);
+            return;
+        }
+
         addActivityOptions(options1, mSideStage);
         wct.startShortcut(mContext.getPackageName(), shortcutInfo, options1);
-
         startWithLegacyTransition(wct, taskId, options2, splitPosition, splitRatio, adapter,
                 instanceId);
     }
@@ -696,6 +736,34 @@
         mShouldUpdateRecents = false;
         mIsSplitEntering = true;
 
+        setSideStagePosition(sidePosition, wct);
+        if (!mMainStage.isActive()) {
+            mMainStage.activate(wct, false /* reparent */);
+        }
+
+        if (mainOptions == null) mainOptions = new Bundle();
+        addActivityOptions(mainOptions, mMainStage);
+        mainOptions = wrapAsSplitRemoteAnimation(adapter, mainOptions);
+
+        updateWindowBounds(mSplitLayout, wct);
+        if (mainTaskId == INVALID_TASK_ID) {
+            wct.sendPendingIntent(mainPendingIntent, mainFillInIntent, mainOptions);
+        } else {
+            wct.startTask(mainTaskId, mainOptions);
+        }
+
+        wct.reorder(mRootTaskInfo.token, true);
+        wct.setForceTranslucent(mRootTaskInfo.token, false);
+
+        mSyncQueue.queue(wct);
+        mSyncQueue.runInSync(t -> {
+            setDividerVisibility(true, t);
+        });
+
+        setEnterInstanceId(instanceId);
+    }
+
+    private Bundle wrapAsSplitRemoteAnimation(RemoteAnimationAdapter adapter, Bundle options) {
         final WindowContainerTransaction evictWct = new WindowContainerTransaction();
         if (isSplitScreenVisible()) {
             mMainStage.evictAllChildren(evictWct);
@@ -739,37 +807,9 @@
         };
         RemoteAnimationAdapter wrappedAdapter = new RemoteAnimationAdapter(
                 wrapper, adapter.getDuration(), adapter.getStatusBarTransitionDelay());
-
-        if (mainOptions == null) {
-            mainOptions = ActivityOptions.makeRemoteAnimation(wrappedAdapter).toBundle();
-        } else {
-            ActivityOptions mainActivityOptions = ActivityOptions.fromBundle(mainOptions);
-            mainActivityOptions.update(ActivityOptions.makeRemoteAnimation(wrappedAdapter));
-            mainOptions = mainActivityOptions.toBundle();
-        }
-
-        setSideStagePosition(sidePosition, wct);
-        if (!mMainStage.isActive()) {
-            mMainStage.activate(wct, false /* reparent */);
-        }
-
-        if (mainOptions == null) mainOptions = new Bundle();
-        addActivityOptions(mainOptions, mMainStage);
-        updateWindowBounds(mSplitLayout, wct);
-        if (mainTaskId == INVALID_TASK_ID) {
-            wct.sendPendingIntent(mainPendingIntent, mainFillInIntent, mainOptions);
-        } else {
-            wct.startTask(mainTaskId, mainOptions);
-        }
-        wct.reorder(mRootTaskInfo.token, true);
-        wct.setForceTranslucent(mRootTaskInfo.token, false);
-
-        mSyncQueue.queue(wct);
-        mSyncQueue.runInSync(t -> {
-            setDividerVisibility(true, t);
-        });
-
-        setEnterInstanceId(instanceId);
+        ActivityOptions activityOptions = ActivityOptions.fromBundle(options);
+        activityOptions.update(ActivityOptions.makeRemoteAnimation(wrappedAdapter));
+        return activityOptions.toBundle();
     }
 
     private void setEnterInstanceId(InstanceId instanceId) {
@@ -1052,6 +1092,7 @@
             mSideStage.removeAllTasks(wct, false /* toTop */);
             mMainStage.deactivate(wct, false /* toTop */);
             wct.reorder(mRootTaskInfo.token, false /* onTop */);
+            wct.setForceTranslucent(mRootTaskInfo.token, true);
             wct.setBounds(mSideStage.mRootTaskInfo.token, mTempRect1);
             onTransitionAnimationComplete();
         } else {
@@ -1083,6 +1124,7 @@
                     mMainStage.deactivate(finishedWCT, childrenToTop == mMainStage /* toTop */);
                     mSideStage.removeAllTasks(finishedWCT, childrenToTop == mSideStage /* toTop */);
                     finishedWCT.reorder(mRootTaskInfo.token, false /* toTop */);
+                    finishedWCT.setForceTranslucent(mRootTaskInfo.token, true);
                     finishedWCT.setBounds(mSideStage.mRootTaskInfo.token, mTempRect1);
                     mSyncQueue.queue(finishedWCT);
                     mSyncQueue.runInSync(at -> {
@@ -1228,8 +1270,10 @@
         return SPLIT_POSITION_UNDEFINED;
     }
 
-    private void addActivityOptions(Bundle opts, StageTaskListener stage) {
-        opts.putParcelable(KEY_LAUNCH_ROOT_TASK_TOKEN, stage.mRootTaskInfo.token);
+    private void addActivityOptions(Bundle opts, @Nullable StageTaskListener launchTarget) {
+        if (launchTarget != null) {
+            opts.putParcelable(KEY_LAUNCH_ROOT_TASK_TOKEN, launchTarget.mRootTaskInfo.token);
+        }
         // Put BAL flags to avoid activity start aborted. Otherwise, flows like shortcut to split
         // will be canceled.
         opts.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED, true);
@@ -1463,6 +1507,12 @@
     }
 
     private void onStageVisibilityChanged(StageListenerImpl stageListener) {
+        // If split didn't active, just ignore this callback because we should already did these
+        // on #applyExitSplitScreen.
+        if (!isSplitActive()) {
+            return;
+        }
+
         final boolean sideStageVisible = mSideStageListener.mVisible;
         final boolean mainStageVisible = mMainStageListener.mVisible;
 
@@ -1471,20 +1521,23 @@
             return;
         }
 
+        // Check if it needs to dismiss split screen when both stage invisible.
+        if (!mainStageVisible && mExitSplitScreenOnHide) {
+            exitSplitScreen(null /* childrenToTop */, EXIT_REASON_RETURN_HOME);
+            return;
+        }
+
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         if (!mainStageVisible) {
+            // Split entering background.
             wct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token,
                     true /* setReparentLeafTaskIfRelaunch */);
             wct.setForceTranslucent(mRootTaskInfo.token, true);
-            // Both stages are not visible, check if it needs to dismiss split screen.
-            if (mExitSplitScreenOnHide) {
-                exitSplitScreen(null /* childrenToTop */, EXIT_REASON_RETURN_HOME);
-            }
         } else {
             wct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token,
                     false /* setReparentLeafTaskIfRelaunch */);
-            wct.setForceTranslucent(mRootTaskInfo.token, false);
         }
+
         mSyncQueue.queue(wct);
         mSyncQueue.runInSync(t -> {
             setDividerVisibility(mainStageVisible, t);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java
index 0c23f10..be2e793 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java
@@ -39,6 +39,7 @@
 import android.window.TaskSnapshot;
 
 import androidx.annotation.BinderThread;
+import androidx.annotation.VisibleForTesting;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.function.TriConsumer;
@@ -138,10 +139,16 @@
      *
      * @param listener The callback when need a starting window.
      */
+    @VisibleForTesting
     void setStartingWindowListener(TriConsumer<Integer, Integer, Integer> listener) {
         mTaskLaunchingCallback = listener;
     }
 
+    @VisibleForTesting
+    boolean hasStartingWindowListener() {
+        return mTaskLaunchingCallback != null;
+    }
+
     /**
      * Called when a task need a starting window.
      */
@@ -281,6 +288,8 @@
         @Override
         public void invalidate() {
             mController = null;
+            // Unregister the listener to ensure any registered binder death recipients are unlinked
+            mListener.unregister();
         }
 
         @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java
index fdf073f..3f944cb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java
@@ -164,7 +164,8 @@
      * Updates the given bundle with the set of external interfaces, invalidating the old set of
      * binders.
      */
-    private void createExternalInterfaces(Bundle output) {
+    @VisibleForTesting
+    public void createExternalInterfaces(Bundle output) {
         // Invalidate the old binders
         for (int i = 0; i < mExternalInterfaces.size(); i++) {
             mExternalInterfaces.valueAt(i).invalidate();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
index b714d2e..39fe455 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
@@ -370,8 +370,6 @@
                         // If this is a transferred starting window, we want it immediately visible.
                         && (change.getFlags() & FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT) == 0) {
                     t.setAlpha(leash, 0.f);
-                    // fix alpha in finish transaction in case the animator itself no-ops.
-                    finishT.setAlpha(leash, 1.f);
                 }
             } else if (mode == TRANSIT_CLOSE || mode == TRANSIT_TO_BACK) {
                 finishT.hide(leash);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
new file mode 100644
index 0000000..129924a
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
@@ -0,0 +1,266 @@
+/*
+ * 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.windowdecor;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+
+import android.app.ActivityManager.RunningTaskInfo;
+import android.content.Context;
+import android.os.Handler;
+import android.util.SparseArray;
+import android.view.Choreographer;
+import android.view.MotionEvent;
+import android.view.SurfaceControl;
+import android.view.View;
+import android.window.WindowContainerToken;
+import android.window.WindowContainerTransaction;
+
+import com.android.wm.shell.R;
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.SyncTransactionQueue;
+import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
+
+/**
+ * View model for the window decoration with a caption and shadows. Works with
+ * {@link CaptionWindowDecoration}.
+ */
+public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
+    private final ShellTaskOrganizer mTaskOrganizer;
+    private final Context mContext;
+    private final Handler mMainHandler;
+    private final Choreographer mMainChoreographer;
+    private final DisplayController mDisplayController;
+    private final SyncTransactionQueue mSyncQueue;
+    private TaskOperations mTaskOperations;
+
+    private final SparseArray<CaptionWindowDecoration> mWindowDecorByTaskId = new SparseArray<>();
+
+    public CaptionWindowDecorViewModel(
+            Context context,
+            Handler mainHandler,
+            Choreographer mainChoreographer,
+            ShellTaskOrganizer taskOrganizer,
+            DisplayController displayController,
+            SyncTransactionQueue syncQueue) {
+        mContext = context;
+        mMainHandler = mainHandler;
+        mMainChoreographer = mainChoreographer;
+        mTaskOrganizer = taskOrganizer;
+        mDisplayController = displayController;
+        mSyncQueue = syncQueue;
+    }
+
+    @Override
+    public void setFreeformTaskTransitionStarter(FreeformTaskTransitionStarter transitionStarter) {
+        mTaskOperations = new TaskOperations(transitionStarter, mContext, mSyncQueue);
+    }
+
+    @Override
+    public boolean onTaskOpening(
+            RunningTaskInfo taskInfo,
+            SurfaceControl taskSurface,
+            SurfaceControl.Transaction startT,
+            SurfaceControl.Transaction finishT) {
+        if (!shouldShowWindowDecor(taskInfo)) return false;
+        createWindowDecoration(taskInfo, taskSurface, startT, finishT);
+        return true;
+    }
+
+    @Override
+    public void onTaskInfoChanged(RunningTaskInfo taskInfo) {
+        final CaptionWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId);
+
+        if (decoration == null) return;
+
+        decoration.relayout(taskInfo);
+        setupCaptionColor(taskInfo, decoration);
+    }
+
+    @Override
+    public void onTaskChanging(
+            RunningTaskInfo taskInfo,
+            SurfaceControl taskSurface,
+            SurfaceControl.Transaction startT,
+            SurfaceControl.Transaction finishT) {
+        final CaptionWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId);
+
+        if (!shouldShowWindowDecor(taskInfo)) {
+            if (decoration != null) {
+                destroyWindowDecoration(taskInfo);
+            }
+            return;
+        }
+
+        if (decoration == null) {
+            createWindowDecoration(taskInfo, taskSurface, startT, finishT);
+        } else {
+            decoration.relayout(taskInfo, startT, finishT);
+        }
+    }
+
+    @Override
+    public void onTaskClosing(
+            RunningTaskInfo taskInfo,
+            SurfaceControl.Transaction startT,
+            SurfaceControl.Transaction finishT) {
+        final CaptionWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId);
+        if (decoration == null) return;
+
+        decoration.relayout(taskInfo, startT, finishT);
+    }
+
+    @Override
+    public void destroyWindowDecoration(RunningTaskInfo taskInfo) {
+        final CaptionWindowDecoration decoration =
+                mWindowDecorByTaskId.removeReturnOld(taskInfo.taskId);
+        if (decoration == null) return;
+
+        decoration.close();
+    }
+
+    private void setupCaptionColor(RunningTaskInfo taskInfo, CaptionWindowDecoration decoration) {
+        final int statusBarColor = taskInfo.taskDescription.getStatusBarColor();
+        decoration.setCaptionColor(statusBarColor);
+    }
+
+    private boolean shouldShowWindowDecor(RunningTaskInfo taskInfo) {
+        return taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM
+                || (taskInfo.getActivityType() == ACTIVITY_TYPE_STANDARD
+                    && taskInfo.configuration.windowConfiguration.getDisplayWindowingMode()
+                        == WINDOWING_MODE_FREEFORM);
+    }
+
+    private void createWindowDecoration(
+            RunningTaskInfo taskInfo,
+            SurfaceControl taskSurface,
+            SurfaceControl.Transaction startT,
+            SurfaceControl.Transaction finishT) {
+        final CaptionWindowDecoration oldDecoration = mWindowDecorByTaskId.get(taskInfo.taskId);
+        if (oldDecoration != null) {
+            // close the old decoration if it exists to avoid two window decorations being added
+            oldDecoration.close();
+        }
+        final CaptionWindowDecoration windowDecoration =
+                new CaptionWindowDecoration(
+                        mContext,
+                        mDisplayController,
+                        mTaskOrganizer,
+                        taskInfo,
+                        taskSurface,
+                        mMainHandler,
+                        mMainChoreographer,
+                        mSyncQueue);
+        mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration);
+
+        final TaskPositioner taskPositioner =
+                new TaskPositioner(mTaskOrganizer, windowDecoration);
+        final CaptionTouchEventListener touchEventListener =
+                new CaptionTouchEventListener(taskInfo, taskPositioner);
+        windowDecoration.setCaptionListeners(touchEventListener, touchEventListener);
+        windowDecoration.setDragResizeCallback(taskPositioner);
+        windowDecoration.relayout(taskInfo, startT, finishT);
+        setupCaptionColor(taskInfo, windowDecoration);
+    }
+
+    private class CaptionTouchEventListener implements
+            View.OnClickListener, View.OnTouchListener {
+
+        private final int mTaskId;
+        private final WindowContainerToken mTaskToken;
+        private final DragResizeCallback mDragResizeCallback;
+
+        private int mDragPointerId = -1;
+
+        private CaptionTouchEventListener(
+                RunningTaskInfo taskInfo,
+                DragResizeCallback dragResizeCallback) {
+            mTaskId = taskInfo.taskId;
+            mTaskToken = taskInfo.token;
+            mDragResizeCallback = dragResizeCallback;
+        }
+
+        @Override
+        public void onClick(View v) {
+            final int id = v.getId();
+            if (id == R.id.close_window) {
+                mTaskOperations.closeTask(mTaskToken);
+            } else if (id == R.id.back_button) {
+                mTaskOperations.injectBackKey();
+            } else if (id == R.id.minimize_window) {
+                mTaskOperations.minimizeTask(mTaskToken);
+            } else if (id == R.id.maximize_window) {
+                RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId);
+                mTaskOperations.maximizeTask(taskInfo);
+            }
+        }
+
+        @Override
+        public boolean onTouch(View v, MotionEvent e) {
+            if (v.getId() != R.id.caption) {
+                return false;
+            }
+            handleEventForMove(e);
+
+            if (e.getAction() != MotionEvent.ACTION_DOWN) {
+                return false;
+            }
+            final RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId);
+            if (taskInfo.isFocused) {
+                return false;
+            }
+            final WindowContainerTransaction wct = new WindowContainerTransaction();
+            wct.reorder(mTaskToken, true /* onTop */);
+            mSyncQueue.queue(wct);
+            return true;
+        }
+
+        /**
+         * @param e {@link MotionEvent} to process
+         * @return {@code true} if a drag is happening; or {@code false} if it is not
+         */
+        private void handleEventForMove(MotionEvent e) {
+            final RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId);
+            if (taskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
+                return;
+            }
+            switch (e.getActionMasked()) {
+                case MotionEvent.ACTION_DOWN: {
+                    mDragPointerId = e.getPointerId(0);
+                    mDragResizeCallback.onDragResizeStart(
+                            0 /* ctrlType */, e.getRawX(0), e.getRawY(0));
+                    break;
+                }
+                case MotionEvent.ACTION_MOVE: {
+                    int dragPointerIdx = e.findPointerIndex(mDragPointerId);
+                    mDragResizeCallback.onDragResizeMove(
+                            e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx));
+                    break;
+                }
+                case MotionEvent.ACTION_UP:
+                case MotionEvent.ACTION_CANCEL: {
+                    int dragPointerIdx = e.findPointerIndex(mDragPointerId);
+                    mDragResizeCallback.onDragResizeEnd(
+                            e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx));
+                    break;
+                }
+            }
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
new file mode 100644
index 0000000..d26f1fc
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
@@ -0,0 +1,227 @@
+/*
+ * 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.windowdecor;
+
+import android.app.ActivityManager.RunningTaskInfo;
+import android.app.WindowConfiguration;
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.graphics.Color;
+import android.graphics.drawable.GradientDrawable;
+import android.graphics.drawable.VectorDrawable;
+import android.os.Handler;
+import android.view.Choreographer;
+import android.view.SurfaceControl;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.window.WindowContainerTransaction;
+
+import com.android.wm.shell.R;
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.SyncTransactionQueue;
+
+/**
+ * Defines visuals and behaviors of a window decoration of a caption bar and shadows. It works with
+ * {@link CaptionWindowDecorViewModel}. The caption bar contains a back button, minimize button,
+ * maximize button and close button.
+ */
+public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearLayout> {
+    private final Handler mHandler;
+    private final Choreographer mChoreographer;
+    private final SyncTransactionQueue mSyncQueue;
+
+    private View.OnClickListener mOnCaptionButtonClickListener;
+    private View.OnTouchListener mOnCaptionTouchListener;
+    private DragResizeCallback mDragResizeCallback;
+    private DragResizeInputListener mDragResizeListener;
+    private final DragDetector mDragDetector;
+
+    private RelayoutParams mRelayoutParams = new RelayoutParams();
+    private final RelayoutResult<WindowDecorLinearLayout> mResult =
+            new RelayoutResult<>();
+
+    CaptionWindowDecoration(
+            Context context,
+            DisplayController displayController,
+            ShellTaskOrganizer taskOrganizer,
+            RunningTaskInfo taskInfo,
+            SurfaceControl taskSurface,
+            Handler handler,
+            Choreographer choreographer,
+            SyncTransactionQueue syncQueue) {
+        super(context, displayController, taskOrganizer, taskInfo, taskSurface);
+
+        mHandler = handler;
+        mChoreographer = choreographer;
+        mSyncQueue = syncQueue;
+        mDragDetector = new DragDetector(ViewConfiguration.get(context).getScaledTouchSlop());
+    }
+
+    void setCaptionListeners(
+            View.OnClickListener onCaptionButtonClickListener,
+            View.OnTouchListener onCaptionTouchListener) {
+        mOnCaptionButtonClickListener = onCaptionButtonClickListener;
+        mOnCaptionTouchListener = onCaptionTouchListener;
+    }
+
+    void setDragResizeCallback(DragResizeCallback dragResizeCallback) {
+        mDragResizeCallback = dragResizeCallback;
+    }
+
+    @Override
+    void relayout(RunningTaskInfo taskInfo) {
+        final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+        relayout(taskInfo, t, t);
+        mSyncQueue.runInSync(transaction -> {
+            transaction.merge(t);
+            t.close();
+        });
+    }
+
+    void relayout(RunningTaskInfo taskInfo,
+            SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT) {
+        final int shadowRadiusID = taskInfo.isFocused
+                ? R.dimen.freeform_decor_shadow_focused_thickness
+                : R.dimen.freeform_decor_shadow_unfocused_thickness;
+        final boolean isFreeform =
+                taskInfo.getWindowingMode() == WindowConfiguration.WINDOWING_MODE_FREEFORM;
+        final boolean isDragResizeable = isFreeform && taskInfo.isResizeable;
+
+        final WindowDecorLinearLayout oldRootView = mResult.mRootView;
+        final SurfaceControl oldDecorationSurface = mDecorationContainerSurface;
+        final WindowContainerTransaction wct = new WindowContainerTransaction();
+
+        final int outsetLeftId = R.dimen.freeform_resize_handle;
+        final int outsetTopId = R.dimen.freeform_resize_handle;
+        final int outsetRightId = R.dimen.freeform_resize_handle;
+        final int outsetBottomId = R.dimen.freeform_resize_handle;
+
+        mRelayoutParams.reset();
+        mRelayoutParams.mRunningTaskInfo = taskInfo;
+        mRelayoutParams.mLayoutResId = R.layout.caption_window_decor;
+        mRelayoutParams.mCaptionHeightId = R.dimen.freeform_decor_caption_height;
+        mRelayoutParams.mShadowRadiusId = shadowRadiusID;
+        if (isDragResizeable) {
+            mRelayoutParams.setOutsets(outsetLeftId, outsetTopId, outsetRightId, outsetBottomId);
+        }
+
+        relayout(mRelayoutParams, startT, finishT, wct, oldRootView, mResult);
+        // After this line, mTaskInfo is up-to-date and should be used instead of taskInfo
+
+        mTaskOrganizer.applyTransaction(wct);
+
+        if (mResult.mRootView == null) {
+            // This means something blocks the window decor from showing, e.g. the task is hidden.
+            // Nothing is set up in this case including the decoration surface.
+            return;
+        }
+        if (oldRootView != mResult.mRootView) {
+            setupRootView();
+        }
+
+        if (!isDragResizeable) {
+            closeDragResizeListener();
+            return;
+        }
+
+        if (oldDecorationSurface != mDecorationContainerSurface || mDragResizeListener == null) {
+            closeDragResizeListener();
+            mDragResizeListener = new DragResizeInputListener(
+                    mContext,
+                    mHandler,
+                    mChoreographer,
+                    mDisplay.getDisplayId(),
+                    mDecorationContainerSurface,
+                    mDragResizeCallback);
+        }
+
+        final int touchSlop = ViewConfiguration.get(mResult.mRootView.getContext())
+                .getScaledTouchSlop();
+        mDragDetector.setTouchSlop(touchSlop);
+
+        final int resize_handle = mResult.mRootView.getResources()
+                .getDimensionPixelSize(R.dimen.freeform_resize_handle);
+        final int resize_corner = mResult.mRootView.getResources()
+                .getDimensionPixelSize(R.dimen.freeform_resize_corner);
+        mDragResizeListener.setGeometry(
+                mResult.mWidth, mResult.mHeight, resize_handle, resize_corner, touchSlop);
+    }
+
+    /**
+     * Sets up listeners when a new root view is created.
+     */
+    private void setupRootView() {
+        final View caption = mResult.mRootView.findViewById(R.id.caption);
+        caption.setOnTouchListener(mOnCaptionTouchListener);
+        final View close = caption.findViewById(R.id.close_window);
+        close.setOnClickListener(mOnCaptionButtonClickListener);
+        final View back = caption.findViewById(R.id.back_button);
+        back.setOnClickListener(mOnCaptionButtonClickListener);
+        final View minimize = caption.findViewById(R.id.minimize_window);
+        minimize.setOnClickListener(mOnCaptionButtonClickListener);
+        final View maximize = caption.findViewById(R.id.maximize_window);
+        maximize.setOnClickListener(mOnCaptionButtonClickListener);
+    }
+
+    void setCaptionColor(int captionColor) {
+        if (mResult.mRootView == null) {
+            return;
+        }
+
+        final View caption = mResult.mRootView.findViewById(R.id.caption);
+        final GradientDrawable captionDrawable = (GradientDrawable) caption.getBackground();
+        captionDrawable.setColor(captionColor);
+
+        final int buttonTintColorRes =
+                Color.valueOf(captionColor).luminance() < 0.5
+                        ? R.color.decor_button_light_color
+                        : R.color.decor_button_dark_color;
+        final ColorStateList buttonTintColor =
+                caption.getResources().getColorStateList(buttonTintColorRes, null /* theme */);
+
+        final View back = caption.findViewById(R.id.back_button);
+        final VectorDrawable backBackground = (VectorDrawable) back.getBackground();
+        backBackground.setTintList(buttonTintColor);
+
+        final View minimize = caption.findViewById(R.id.minimize_window);
+        final VectorDrawable minimizeBackground = (VectorDrawable) minimize.getBackground();
+        minimizeBackground.setTintList(buttonTintColor);
+
+        final View maximize = caption.findViewById(R.id.maximize_window);
+        final VectorDrawable maximizeBackground = (VectorDrawable) maximize.getBackground();
+        maximizeBackground.setTintList(buttonTintColor);
+
+        final View close = caption.findViewById(R.id.close_window);
+        final VectorDrawable closeBackground = (VectorDrawable) close.getBackground();
+        closeBackground.setTintList(buttonTintColor);
+    }
+
+    private void closeDragResizeListener() {
+        if (mDragResizeListener == null) {
+            return;
+        }
+        mDragResizeListener.close();
+        mDragResizeListener = null;
+    }
+
+    @Override
+    public void close() {
+        closeDragResizeListener();
+        super.close();
+    }
+}
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 b500f5f..2863adc 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
@@ -27,17 +27,12 @@
 import android.hardware.input.InputManager;
 import android.os.Handler;
 import android.os.Looper;
-import android.os.SystemClock;
-import android.util.Log;
 import android.util.SparseArray;
 import android.view.Choreographer;
 import android.view.InputChannel;
-import android.view.InputDevice;
 import android.view.InputEvent;
 import android.view.InputEventReceiver;
 import android.view.InputMonitor;
-import android.view.KeyCharacterMap;
-import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.SurfaceControl;
 import android.view.View;
@@ -55,7 +50,6 @@
 import com.android.wm.shell.desktopmode.DesktopModeStatus;
 import com.android.wm.shell.desktopmode.DesktopTasksController;
 import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
-import com.android.wm.shell.transition.Transitions;
 
 import java.util.Optional;
 
@@ -74,9 +68,8 @@
     private final Choreographer mMainChoreographer;
     private final DisplayController mDisplayController;
     private final SyncTransactionQueue mSyncQueue;
-    private FreeformTaskTransitionStarter mTransitionStarter;
-    private Optional<DesktopModeController> mDesktopModeController;
-    private Optional<DesktopTasksController> mDesktopTasksController;
+    private final Optional<DesktopModeController> mDesktopModeController;
+    private final Optional<DesktopTasksController> mDesktopTasksController;
     private boolean mTransitionDragActive;
 
     private SparseArray<EventReceiver> mEventReceiversByDisplay = new SparseArray<>();
@@ -84,7 +77,8 @@
     private final SparseArray<DesktopModeWindowDecoration> mWindowDecorByTaskId =
             new SparseArray<>();
     private final DragStartListenerImpl mDragStartListener = new DragStartListenerImpl();
-    private InputMonitorFactory mInputMonitorFactory;
+    private final InputMonitorFactory mInputMonitorFactory;
+    private TaskOperations mTaskOperations;
 
     public DesktopModeWindowDecorViewModel(
             Context context,
@@ -136,7 +130,7 @@
 
     @Override
     public void setFreeformTaskTransitionStarter(FreeformTaskTransitionStarter transitionStarter) {
-        mTransitionStarter = transitionStarter;
+        mTaskOperations = new TaskOperations(transitionStarter, mContext, mSyncQueue);
     }
 
     @Override
@@ -153,12 +147,11 @@
     @Override
     public void onTaskInfoChanged(RunningTaskInfo taskInfo) {
         final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId);
-
         if (decoration == null) return;
+        final RunningTaskInfo oldTaskInfo = decoration.mTaskInfo;
 
-        int oldDisplayId = decoration.mDisplay.getDisplayId();
-        if (taskInfo.displayId != oldDisplayId) {
-            removeTaskFromEventReceiver(oldDisplayId);
+        if (taskInfo.displayId != oldTaskInfo.displayId) {
+            removeTaskFromEventReceiver(oldTaskInfo.displayId);
             incrementEventReceiverTasks(taskInfo.displayId);
         }
 
@@ -205,13 +198,13 @@
         if (decoration == null) return;
 
         decoration.close();
-        int displayId = taskInfo.displayId;
+        final int displayId = taskInfo.displayId;
         if (mEventReceiversByDisplay.contains(displayId)) {
             removeTaskFromEventReceiver(displayId);
         }
     }
 
-    private class CaptionTouchEventListener implements
+    private class DesktopModeTouchEventListener implements
             View.OnClickListener, View.OnTouchListener {
 
         private final int mTaskId;
@@ -221,7 +214,7 @@
 
         private int mDragPointerId = -1;
 
-        private CaptionTouchEventListener(
+        private DesktopModeTouchEventListener(
                 RunningTaskInfo taskInfo,
                 DragResizeCallback dragResizeCallback,
                 DragDetector dragDetector) {
@@ -233,18 +226,12 @@
 
         @Override
         public void onClick(View v) {
-            DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
+            final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
             final int id = v.getId();
             if (id == R.id.close_window) {
-                WindowContainerTransaction wct = new WindowContainerTransaction();
-                wct.removeTask(mTaskToken);
-                if (Transitions.ENABLE_SHELL_TRANSITIONS) {
-                    mTransitionStarter.startRemoveTransition(wct);
-                } else {
-                    mSyncQueue.queue(wct);
-                }
+                mTaskOperations.closeTask(mTaskToken);
             } else if (id == R.id.back_button) {
-                injectBackKey();
+                mTaskOperations.injectBackKey();
             } else if (id == R.id.caption_handle) {
                 decoration.createHandleMenu();
             } else if (id == R.id.desktop_button) {
@@ -259,30 +246,11 @@
             }
         }
 
-        private void injectBackKey() {
-            sendBackEvent(KeyEvent.ACTION_DOWN);
-            sendBackEvent(KeyEvent.ACTION_UP);
-        }
-
-        private void sendBackEvent(int action) {
-            final long when = SystemClock.uptimeMillis();
-            final KeyEvent ev = new KeyEvent(when, when, action, KeyEvent.KEYCODE_BACK,
-                    0 /* repeat */, 0 /* metaState */, KeyCharacterMap.VIRTUAL_KEYBOARD,
-                    0 /* scancode */, KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
-                    InputDevice.SOURCE_KEYBOARD);
-
-            ev.setDisplayId(mContext.getDisplay().getDisplayId());
-            if (!InputManager.getInstance()
-                    .injectInputEvent(ev, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC)) {
-                Log.e(TAG, "Inject input event fail");
-            }
-        }
-
         @Override
         public boolean onTouch(View v, MotionEvent e) {
             boolean isDrag = false;
-            int id = v.getId();
-            if (id != R.id.caption_handle && id != R.id.caption) {
+            final int id = v.getId();
+            if (id != R.id.caption_handle && id != R.id.desktop_mode_caption) {
                 return false;
             }
             if (id == R.id.caption_handle) {
@@ -292,11 +260,11 @@
             if (e.getAction() != MotionEvent.ACTION_DOWN) {
                 return isDrag;
             }
-            RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId);
+            final RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId);
             if (taskInfo.isFocused) {
                 return isDrag;
             }
-            WindowContainerTransaction wct = new WindowContainerTransaction();
+            final WindowContainerTransaction wct = new WindowContainerTransaction();
             wct.reorder(mTaskToken, true /* onTop */);
             mSyncQueue.queue(wct);
             return true;
@@ -307,7 +275,7 @@
          * @return {@code true} if a drag is happening; or {@code false} if it is not
          */
         private void handleEventForMove(MotionEvent e) {
-            RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId);
+            final RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId);
             if (DesktopModeStatus.isProto2Enabled()
                     && taskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
                 return;
@@ -326,16 +294,16 @@
                     break;
                 }
                 case MotionEvent.ACTION_MOVE: {
-                    int dragPointerIdx = e.findPointerIndex(mDragPointerId);
+                    final int dragPointerIdx = e.findPointerIndex(mDragPointerId);
                     mDragResizeCallback.onDragResizeMove(
                             e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx));
                     break;
                 }
                 case MotionEvent.ACTION_UP:
                 case MotionEvent.ACTION_CANCEL: {
-                    int dragPointerIdx = e.findPointerIndex(mDragPointerId);
-                    int statusBarHeight = mDisplayController.getDisplayLayout(taskInfo.displayId)
-                            .stableInsets().top;
+                    final int dragPointerIdx = e.findPointerIndex(mDragPointerId);
+                    final int statusBarHeight = mDisplayController
+                            .getDisplayLayout(taskInfo.displayId).stableInsets().top;
                     mDragResizeCallback.onDragResizeEnd(
                             e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx));
                     if (e.getRawY(dragPointerIdx) <= statusBarHeight) {
@@ -409,7 +377,7 @@
      */
     private void incrementEventReceiverTasks(int displayId) {
         if (mEventReceiversByDisplay.contains(displayId)) {
-            EventReceiver eventReceiver = mEventReceiversByDisplay.get(displayId);
+            final EventReceiver eventReceiver = mEventReceiversByDisplay.get(displayId);
             eventReceiver.incrementTaskNumber();
         } else {
             createInputChannel(displayId);
@@ -419,7 +387,7 @@
     // If all tasks on this display are gone, we don't need to monitor its input.
     private void removeTaskFromEventReceiver(int displayId) {
         if (!mEventReceiversByDisplay.contains(displayId)) return;
-        EventReceiver eventReceiver = mEventReceiversByDisplay.get(displayId);
+        final EventReceiver eventReceiver = mEventReceiversByDisplay.get(displayId);
         if (eventReceiver == null) return;
         eventReceiver.decrementTaskNumber();
         if (eventReceiver.getTasksOnDisplay() == 0) {
@@ -434,7 +402,7 @@
      */
     private void handleReceivedMotionEvent(MotionEvent ev, InputMonitor inputMonitor) {
         if (DesktopModeStatus.isProto2Enabled()) {
-            DesktopModeWindowDecoration focusedDecor = getFocusedDecor();
+            final DesktopModeWindowDecoration focusedDecor = getFocusedDecor();
             if (focusedDecor == null
                     || focusedDecor.mTaskInfo.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
                 handleCaptionThroughStatusBar(ev);
@@ -459,9 +427,9 @@
 
     // If an UP/CANCEL action is received outside of caption bounds, turn off handle menu
     private void handleEventOutsideFocusedCaption(MotionEvent ev) {
-        int action = ev.getActionMasked();
+        final int action = ev.getActionMasked();
         if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
-            DesktopModeWindowDecoration focusedDecor = getFocusedDecor();
+            final DesktopModeWindowDecoration focusedDecor = getFocusedDecor();
             if (focusedDecor == null) {
                 return;
             }
@@ -481,7 +449,7 @@
         switch (ev.getActionMasked()) {
             case MotionEvent.ACTION_DOWN: {
                 // Begin drag through status bar if applicable.
-                DesktopModeWindowDecoration focusedDecor = getFocusedDecor();
+                final DesktopModeWindowDecoration focusedDecor = getFocusedDecor();
                 if (focusedDecor != null) {
                     boolean dragFromStatusBarAllowed = false;
                     if (DesktopModeStatus.isProto2Enabled()) {
@@ -500,14 +468,14 @@
                 break;
             }
             case MotionEvent.ACTION_UP: {
-                DesktopModeWindowDecoration focusedDecor = getFocusedDecor();
+                final DesktopModeWindowDecoration focusedDecor = getFocusedDecor();
                 if (focusedDecor == null) {
                     mTransitionDragActive = false;
                     return;
                 }
                 if (mTransitionDragActive) {
                     mTransitionDragActive = false;
-                    int statusBarHeight = mDisplayController
+                    final int statusBarHeight = mDisplayController
                             .getDisplayLayout(focusedDecor.mTaskInfo.displayId).stableInsets().top;
                     if (ev.getY() > statusBarHeight) {
                         if (DesktopModeStatus.isProto2Enabled()) {
@@ -531,10 +499,10 @@
 
     @Nullable
     private DesktopModeWindowDecoration getFocusedDecor() {
-        int size = mWindowDecorByTaskId.size();
+        final int size = mWindowDecorByTaskId.size();
         DesktopModeWindowDecoration focusedDecor = null;
         for (int i = 0; i < size; i++) {
-            DesktopModeWindowDecoration decor = mWindowDecorByTaskId.valueAt(i);
+            final DesktopModeWindowDecoration decor = mWindowDecorByTaskId.valueAt(i);
             if (decor != null && decor.isFocused()) {
                 focusedDecor = decor;
                 break;
@@ -544,16 +512,16 @@
     }
 
     private void createInputChannel(int displayId) {
-        InputManager inputManager = InputManager.getInstance();
-        InputMonitor inputMonitor =
+        final InputManager inputManager = InputManager.getInstance();
+        final InputMonitor inputMonitor =
                 mInputMonitorFactory.create(inputManager, mContext);
-        EventReceiver eventReceiver = new EventReceiver(inputMonitor,
+        final EventReceiver eventReceiver = new EventReceiver(inputMonitor,
                 inputMonitor.getInputChannel(), Looper.myLooper());
         mEventReceiversByDisplay.put(displayId, eventReceiver);
     }
 
     private void disposeInputChannel(int displayId) {
-        EventReceiver eventReceiver = mEventReceiversByDisplay.removeReturnOld(displayId);
+        final EventReceiver eventReceiver = mEventReceiversByDisplay.removeReturnOld(displayId);
         if (eventReceiver != null) {
             eventReceiver.dispose();
         }
@@ -572,7 +540,7 @@
             SurfaceControl taskSurface,
             SurfaceControl.Transaction startT,
             SurfaceControl.Transaction finishT) {
-        DesktopModeWindowDecoration oldDecoration = mWindowDecorByTaskId.get(taskInfo.taskId);
+        final DesktopModeWindowDecoration oldDecoration = mWindowDecorByTaskId.get(taskInfo.taskId);
         if (oldDecoration != null) {
             // close the old decoration if it exists to avoid two window decorations being added
             oldDecoration.close();
@@ -589,10 +557,10 @@
                         mSyncQueue);
         mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration);
 
-        TaskPositioner taskPositioner =
+        final TaskPositioner taskPositioner =
                 new TaskPositioner(mTaskOrganizer, windowDecoration, mDragStartListener);
-        CaptionTouchEventListener touchEventListener =
-                new CaptionTouchEventListener(
+        final DesktopModeTouchEventListener touchEventListener =
+                new DesktopModeTouchEventListener(
                         taskInfo, taskPositioner, windowDecoration.getDragDetector());
         windowDecoration.setCaptionListeners(touchEventListener, touchEventListener);
         windowDecoration.setDragResizeCallback(taskPositioner);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index 467f374..1a38d24 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -56,17 +56,14 @@
     private View.OnClickListener mOnCaptionButtonClickListener;
     private View.OnTouchListener mOnCaptionTouchListener;
     private DragResizeCallback mDragResizeCallback;
-
     private DragResizeInputListener mDragResizeListener;
+    private final DragDetector mDragDetector;
 
     private RelayoutParams mRelayoutParams = new RelayoutParams();
     private final WindowDecoration.RelayoutResult<WindowDecorLinearLayout> mResult =
             new WindowDecoration.RelayoutResult<>();
 
     private boolean mDesktopActive;
-
-    private DragDetector mDragDetector;
-
     private AdditionalWindow mHandleMenu;
 
     DesktopModeWindowDecoration(
@@ -121,18 +118,18 @@
                 taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM;
         final boolean isDragResizeable = isFreeform && taskInfo.isResizeable;
 
-        WindowDecorLinearLayout oldRootView = mResult.mRootView;
+        final WindowDecorLinearLayout oldRootView = mResult.mRootView;
         final SurfaceControl oldDecorationSurface = mDecorationContainerSurface;
         final WindowContainerTransaction wct = new WindowContainerTransaction();
 
-        int outsetLeftId = R.dimen.freeform_resize_handle;
-        int outsetTopId = R.dimen.freeform_resize_handle;
-        int outsetRightId = R.dimen.freeform_resize_handle;
-        int outsetBottomId = R.dimen.freeform_resize_handle;
+        final int outsetLeftId = R.dimen.freeform_resize_handle;
+        final int outsetTopId = R.dimen.freeform_resize_handle;
+        final int outsetRightId = R.dimen.freeform_resize_handle;
+        final int outsetBottomId = R.dimen.freeform_resize_handle;
 
         mRelayoutParams.reset();
         mRelayoutParams.mRunningTaskInfo = taskInfo;
-        mRelayoutParams.mLayoutResId = R.layout.caption_window_decoration;
+        mRelayoutParams.mLayoutResId = R.layout.desktop_mode_window_decor;
         mRelayoutParams.mCaptionHeightId = R.dimen.freeform_decor_caption_height;
         mRelayoutParams.mCaptionWidthId = R.dimen.freeform_decor_caption_width;
         mRelayoutParams.mShadowRadiusId = shadowRadiusID;
@@ -152,7 +149,7 @@
         mRelayoutParams.setCaptionPosition(captionLeft, captionTop);
 
         relayout(mRelayoutParams, startT, finishT, wct, oldRootView, mResult);
-        taskInfo = null; // Clear it just in case we use it accidentally
+        // After this line, mTaskInfo is up-to-date and should be used instead of taskInfo
 
         mTaskOrganizer.applyTransaction(wct);
 
@@ -197,12 +194,13 @@
                     mDragResizeCallback);
         }
 
-        int touchSlop = ViewConfiguration.get(mResult.mRootView.getContext()).getScaledTouchSlop();
+        final int touchSlop = ViewConfiguration.get(mResult.mRootView.getContext())
+                .getScaledTouchSlop();
         mDragDetector.setTouchSlop(touchSlop);
 
-        int resize_handle = mResult.mRootView.getResources()
+        final int resize_handle = mResult.mRootView.getResources()
                 .getDimensionPixelSize(R.dimen.freeform_resize_handle);
-        int resize_corner = mResult.mRootView.getResources()
+        final int resize_corner = mResult.mRootView.getResources()
                 .getDimensionPixelSize(R.dimen.freeform_resize_corner);
         mDragResizeListener.setGeometry(
                 mResult.mWidth, mResult.mHeight, resize_handle, resize_corner, touchSlop);
@@ -212,27 +210,27 @@
      * Sets up listeners when a new root view is created.
      */
     private void setupRootView() {
-        View caption = mResult.mRootView.findViewById(R.id.caption);
+        final View caption = mResult.mRootView.findViewById(R.id.desktop_mode_caption);
         caption.setOnTouchListener(mOnCaptionTouchListener);
-        View close = caption.findViewById(R.id.close_window);
+        final View close = caption.findViewById(R.id.close_window);
         close.setOnClickListener(mOnCaptionButtonClickListener);
-        View back = caption.findViewById(R.id.back_button);
+        final View back = caption.findViewById(R.id.back_button);
         back.setOnClickListener(mOnCaptionButtonClickListener);
-        View handle = caption.findViewById(R.id.caption_handle);
+        final View handle = caption.findViewById(R.id.caption_handle);
         handle.setOnTouchListener(mOnCaptionTouchListener);
         handle.setOnClickListener(mOnCaptionButtonClickListener);
         updateButtonVisibility();
     }
 
     private void setupHandleMenu() {
-        View menu = mHandleMenu.mWindowViewHost.getView();
-        View fullscreen = menu.findViewById(R.id.fullscreen_button);
+        final View menu = mHandleMenu.mWindowViewHost.getView();
+        final View fullscreen = menu.findViewById(R.id.fullscreen_button);
         fullscreen.setOnClickListener(mOnCaptionButtonClickListener);
-        View desktop = menu.findViewById(R.id.desktop_button);
+        final View desktop = menu.findViewById(R.id.desktop_button);
         desktop.setOnClickListener(mOnCaptionButtonClickListener);
-        View split = menu.findViewById(R.id.split_screen_button);
+        final View split = menu.findViewById(R.id.split_screen_button);
         split.setOnClickListener(mOnCaptionButtonClickListener);
-        View more = menu.findViewById(R.id.more_button);
+        final View more = menu.findViewById(R.id.more_button);
         more.setOnClickListener(mOnCaptionButtonClickListener);
     }
 
@@ -242,8 +240,8 @@
      * @param visible whether or not the caption should be visible
      */
     private void setCaptionVisibility(boolean visible) {
-        int v = visible ? View.VISIBLE : View.GONE;
-        View captionView = mResult.mRootView.findViewById(R.id.caption);
+        final int v = visible ? View.VISIBLE : View.GONE;
+        final View captionView = mResult.mRootView.findViewById(R.id.desktop_mode_caption);
         captionView.setVisibility(v);
         if (!visible) closeHandleMenu();
     }
@@ -264,19 +262,19 @@
      * Show or hide buttons
      */
     void setButtonVisibility(boolean visible) {
-        int visibility = visible ? View.VISIBLE : View.GONE;
-        View caption = mResult.mRootView.findViewById(R.id.caption);
-        View back = caption.findViewById(R.id.back_button);
-        View close = caption.findViewById(R.id.close_window);
+        final int visibility = visible ? View.VISIBLE : View.GONE;
+        final View caption = mResult.mRootView.findViewById(R.id.desktop_mode_caption);
+        final View back = caption.findViewById(R.id.back_button);
+        final View close = caption.findViewById(R.id.close_window);
         back.setVisibility(visibility);
         close.setVisibility(visibility);
-        int buttonTintColorRes =
+        final int buttonTintColorRes =
                 mDesktopActive ? R.color.decor_button_dark_color
                         : R.color.decor_button_light_color;
-        ColorStateList buttonTintColor =
+        final ColorStateList buttonTintColor =
                 caption.getResources().getColorStateList(buttonTintColorRes, null /* theme */);
-        View handle = caption.findViewById(R.id.caption_handle);
-        VectorDrawable handleBackground = (VectorDrawable) handle.getBackground();
+        final View handle = caption.findViewById(R.id.caption_handle);
+        final VectorDrawable handleBackground = (VectorDrawable) handle.getBackground();
         handleBackground.setTintList(buttonTintColor);
         caption.getBackground().setTint(visible ? Color.WHITE : Color.TRANSPARENT);
     }
@@ -297,14 +295,14 @@
      * Create and display handle menu window
      */
     void createHandleMenu() {
-        SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+        final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
         final Resources resources = mDecorWindowContext.getResources();
-        int x = mRelayoutParams.mCaptionX;
-        int y = mRelayoutParams.mCaptionY;
-        int width = loadDimensionPixelSize(resources, mRelayoutParams.mCaptionWidthId);
-        int height = loadDimensionPixelSize(resources, mRelayoutParams.mCaptionHeightId);
+        final int x = mRelayoutParams.mCaptionX;
+        final int y = mRelayoutParams.mCaptionY;
+        final int width = loadDimensionPixelSize(resources, mRelayoutParams.mCaptionWidthId);
+        final int height = loadDimensionPixelSize(resources, mRelayoutParams.mCaptionHeightId);
         String namePrefix = "Caption Menu";
-        mHandleMenu = addWindow(R.layout.caption_handle_menu, namePrefix, t,
+        mHandleMenu = addWindow(R.layout.desktop_mode_decor_handle_menu, namePrefix, t,
                 x - mResult.mDecorContainerOffsetX, y - mResult.mDecorContainerOffsetY,
                 width, height);
         mSyncQueue.runInSync(transaction -> {
@@ -336,7 +334,7 @@
      */
     void closeHandleMenuIfNeeded(MotionEvent ev) {
         if (isHandleMenuActive()) {
-            if (!checkEventInCaptionView(ev, R.id.caption)) {
+            if (!checkEventInCaptionView(ev, R.id.desktop_mode_caption)) {
                 closeHandleMenu();
             }
         }
@@ -353,8 +351,8 @@
      * @return the point of the input in local space
      */
     private PointF offsetCaptionLocation(MotionEvent ev) {
-        PointF result = new PointF(ev.getX(), ev.getY());
-        Point positionInParent = mTaskOrganizer.getRunningTaskInfo(mTaskInfo.taskId)
+        final PointF result = new PointF(ev.getX(), ev.getY());
+        final Point positionInParent = mTaskOrganizer.getRunningTaskInfo(mTaskInfo.taskId)
                 .positionInParent;
         result.offset(-mRelayoutParams.mCaptionX, -mRelayoutParams.mCaptionY);
         result.offset(-positionInParent.x, -positionInParent.y);
@@ -370,8 +368,8 @@
      */
     private boolean checkEventInCaptionView(MotionEvent ev, int layoutId) {
         if (mResult.mRootView == null) return false;
-        PointF inputPoint = offsetCaptionLocation(ev);
-        View view = mResult.mRootView.findViewById(layoutId);
+        final PointF inputPoint = offsetCaptionLocation(ev);
+        final View view = mResult.mRootView.findViewById(layoutId);
         return view != null && view.pointInView(inputPoint.x, inputPoint.y, 0);
     }
 
@@ -389,20 +387,20 @@
      */
     void checkClickEvent(MotionEvent ev) {
         if (mResult.mRootView == null) return;
-        View caption = mResult.mRootView.findViewById(R.id.caption);
-        PointF inputPoint = offsetCaptionLocation(ev);
+        final View caption = mResult.mRootView.findViewById(R.id.desktop_mode_caption);
+        final PointF inputPoint = offsetCaptionLocation(ev);
         if (!isHandleMenuActive()) {
-            View handle = caption.findViewById(R.id.caption_handle);
+            final View handle = caption.findViewById(R.id.caption_handle);
             clickIfPointInView(inputPoint, handle);
         } else {
-            View menu = mHandleMenu.mWindowViewHost.getView();
-            View fullscreen = menu.findViewById(R.id.fullscreen_button);
+            final View menu = mHandleMenu.mWindowViewHost.getView();
+            final View fullscreen = menu.findViewById(R.id.fullscreen_button);
             if (clickIfPointInView(inputPoint, fullscreen)) return;
-            View desktop = menu.findViewById(R.id.desktop_button);
+            final View desktop = menu.findViewById(R.id.desktop_button);
             if (clickIfPointInView(inputPoint, desktop)) return;
-            View split = menu.findViewById(R.id.split_screen_button);
+            final View split = menu.findViewById(R.id.split_screen_button);
             if (clickIfPointInView(inputPoint, split)) return;
-            View more = menu.findViewById(R.id.more_button);
+            final View more = menu.findViewById(R.id.more_button);
             clickIfPointInView(inputPoint, more);
         }
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskOperations.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskOperations.java
new file mode 100644
index 0000000..aea3404
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskOperations.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 com.android.wm.shell.windowdecor;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+
+import android.app.ActivityManager.RunningTaskInfo;
+import android.content.Context;
+import android.hardware.input.InputManager;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.InputDevice;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.window.WindowContainerToken;
+import android.window.WindowContainerTransaction;
+
+import com.android.wm.shell.common.SyncTransactionQueue;
+import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
+import com.android.wm.shell.transition.Transitions;
+
+/**
+ * Utility class to handle task operations performed on a window decoration.
+ */
+class TaskOperations {
+    private static final String TAG = "TaskOperations";
+
+    private final FreeformTaskTransitionStarter mTransitionStarter;
+    private final Context mContext;
+    private final SyncTransactionQueue mSyncQueue;
+
+    TaskOperations(FreeformTaskTransitionStarter transitionStarter, Context context,
+            SyncTransactionQueue syncQueue) {
+        mTransitionStarter = transitionStarter;
+        mContext = context;
+        mSyncQueue = syncQueue;
+    }
+
+    void injectBackKey() {
+        sendBackEvent(KeyEvent.ACTION_DOWN);
+        sendBackEvent(KeyEvent.ACTION_UP);
+    }
+
+    private void sendBackEvent(int action) {
+        final long when = SystemClock.uptimeMillis();
+        final KeyEvent ev = new KeyEvent(when, when, action, KeyEvent.KEYCODE_BACK,
+                0 /* repeat */, 0 /* metaState */, KeyCharacterMap.VIRTUAL_KEYBOARD,
+                0 /* scancode */, KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
+                InputDevice.SOURCE_KEYBOARD);
+
+        ev.setDisplayId(mContext.getDisplay().getDisplayId());
+        if (!InputManager.getInstance()
+                .injectInputEvent(ev, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC)) {
+            Log.e(TAG, "Inject input event fail");
+        }
+    }
+
+    void closeTask(WindowContainerToken taskToken) {
+        WindowContainerTransaction wct = new WindowContainerTransaction();
+        wct.removeTask(taskToken);
+        if (Transitions.ENABLE_SHELL_TRANSITIONS) {
+            mTransitionStarter.startRemoveTransition(wct);
+        } else {
+            mSyncQueue.queue(wct);
+        }
+    }
+
+    void minimizeTask(WindowContainerToken taskToken) {
+        WindowContainerTransaction wct = new WindowContainerTransaction();
+        wct.reorder(taskToken, false);
+        if (Transitions.ENABLE_SHELL_TRANSITIONS) {
+            mTransitionStarter.startMinimizedModeTransition(wct);
+        } else {
+            mSyncQueue.queue(wct);
+        }
+    }
+
+    void maximizeTask(RunningTaskInfo taskInfo) {
+        WindowContainerTransaction wct = new WindowContainerTransaction();
+        int targetWindowingMode = taskInfo.getWindowingMode() != WINDOWING_MODE_FULLSCREEN
+                ? WINDOWING_MODE_FULLSCREEN : WINDOWING_MODE_FREEFORM;
+        int displayWindowingMode =
+                taskInfo.configuration.windowConfiguration.getDisplayWindowingMode();
+        wct.setWindowingMode(taskInfo.token,
+                targetWindowingMode == displayWindowingMode
+                        ? WINDOWING_MODE_UNDEFINED : targetWindowingMode);
+        if (targetWindowingMode == WINDOWING_MODE_FULLSCREEN) {
+            wct.setBounds(taskInfo.token, null);
+        }
+        if (Transitions.ENABLE_SHELL_TRANSITIONS) {
+            mTransitionStarter.startWindowingModeTransition(targetWindowingMode, wct);
+        } else {
+            mSyncQueue.queue(wct);
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskPositioner.java
index a49a300..20631f8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskPositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskPositioner.java
@@ -47,6 +47,10 @@
     private int mCtrlType;
     private DragStartListener mDragStartListener;
 
+    TaskPositioner(ShellTaskOrganizer taskOrganizer, WindowDecoration windowDecoration) {
+        this(taskOrganizer, windowDecoration, dragStartListener -> {});
+    }
+
     TaskPositioner(ShellTaskOrganizer taskOrganizer, WindowDecoration windowDecoration,
             DragStartListener dragStartListener) {
         mTaskOrganizer = taskOrganizer;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TaskViewTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TaskViewTest.java
index ff1d2990..d5bb901 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TaskViewTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TaskViewTest.java
@@ -28,9 +28,11 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -82,13 +84,14 @@
     @Mock
     SyncTransactionQueue mSyncQueue;
     @Mock
-    TaskViewTransitions mTaskViewTransitions;
+    Transitions mTransitions;
 
     SurfaceSession mSession;
     SurfaceControl mLeash;
 
     Context mContext;
     TaskView mTaskView;
+    TaskViewTransitions mTaskViewTransitions;
 
     @Before
     public void setUp() {
@@ -118,6 +121,10 @@
             return null;
         }).when(mSyncQueue).runInSync(any());
 
+        if (Transitions.ENABLE_SHELL_TRANSITIONS) {
+            doReturn(true).when(mTransitions).isRegistered();
+        }
+        mTaskViewTransitions = spy(new TaskViewTransitions(mTransitions));
         mTaskView = new TaskView(mContext, mOrganizer, mTaskViewTransitions, mSyncQueue);
         mTaskView.setListener(mExecutor, mViewListener);
     }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
index 2e328b0..2754496 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
@@ -53,6 +53,7 @@
 import android.view.RemoteAnimationTarget;
 import android.view.SurfaceControl;
 import android.window.BackEvent;
+import android.window.BackMotionEvent;
 import android.window.BackNavigationInfo;
 import android.window.IBackNaviAnimationController;
 import android.window.IOnBackInvokedCallback;
@@ -246,10 +247,11 @@
         // Check that back start and progress is dispatched when first move.
         doMotionEvent(MotionEvent.ACTION_MOVE, 100);
         simulateRemoteAnimationStart(BackNavigationInfo.TYPE_RETURN_TO_HOME, animationTarget);
-        ArgumentCaptor<BackEvent> backEventCaptor = ArgumentCaptor.forClass(BackEvent.class);
+        ArgumentCaptor<BackMotionEvent> backEventCaptor =
+                ArgumentCaptor.forClass(BackMotionEvent.class);
         verify(mIOnBackInvokedCallback).onBackStarted(backEventCaptor.capture());
         assertEquals(animationTarget, backEventCaptor.getValue().getDepartingAnimationTarget());
-        verify(mIOnBackInvokedCallback, atLeastOnce()).onBackProgressed(any(BackEvent.class));
+        verify(mIOnBackInvokedCallback, atLeastOnce()).onBackProgressed(any(BackMotionEvent.class));
 
         // Check that back invocation is dispatched.
         mController.setTriggerBack(true);   // Fake trigger back
@@ -271,17 +273,18 @@
 
         RemoteAnimationTarget animationTarget = createAnimationTarget();
         IOnBackInvokedCallback appCallback = mock(IOnBackInvokedCallback.class);
-        ArgumentCaptor<BackEvent> backEventCaptor = ArgumentCaptor.forClass(BackEvent.class);
+        ArgumentCaptor<BackMotionEvent> backEventCaptor =
+                ArgumentCaptor.forClass(BackMotionEvent.class);
         createNavigationInfo(animationTarget, null, null,
                 BackNavigationInfo.TYPE_RETURN_TO_HOME, appCallback, false);
 
         triggerBackGesture();
 
-        verify(appCallback, never()).onBackStarted(any(BackEvent.class));
+        verify(appCallback, never()).onBackStarted(any(BackMotionEvent.class));
         verify(appCallback, never()).onBackProgressed(backEventCaptor.capture());
         verify(appCallback, times(1)).onBackInvoked();
 
-        verify(mIOnBackInvokedCallback, never()).onBackStarted(any(BackEvent.class));
+        verify(mIOnBackInvokedCallback, never()).onBackStarted(any(BackMotionEvent.class));
         verify(mIOnBackInvokedCallback, never()).onBackProgressed(backEventCaptor.capture());
         verify(mIOnBackInvokedCallback, never()).onBackInvoked();
     }
@@ -314,7 +317,7 @@
         doMotionEvent(MotionEvent.ACTION_DOWN, 0);
         doMotionEvent(MotionEvent.ACTION_MOVE, 100);
         simulateRemoteAnimationStart(BackNavigationInfo.TYPE_RETURN_TO_HOME, animationTarget);
-        verify(mIOnBackInvokedCallback).onBackStarted(any(BackEvent.class));
+        verify(mIOnBackInvokedCallback).onBackStarted(any(BackMotionEvent.class));
     }
 
     @Test
@@ -333,7 +336,7 @@
         doMotionEvent(MotionEvent.ACTION_DOWN, 0);
         doMotionEvent(MotionEvent.ACTION_MOVE, 100);
         simulateRemoteAnimationStart(BackNavigationInfo.TYPE_RETURN_TO_HOME, animationTarget);
-        verify(mIOnBackInvokedCallback).onBackStarted(any(BackEvent.class));
+        verify(mIOnBackInvokedCallback).onBackStarted(any(BackMotionEvent.class));
     }
 
 
@@ -349,7 +352,7 @@
         // Check that back start and progress is dispatched when first move.
         doMotionEvent(MotionEvent.ACTION_MOVE, 100);
         simulateRemoteAnimationStart(BackNavigationInfo.TYPE_RETURN_TO_HOME, animationTarget);
-        verify(mIOnBackInvokedCallback).onBackStarted(any(BackEvent.class));
+        verify(mIOnBackInvokedCallback).onBackStarted(any(BackMotionEvent.class));
 
         // Check that back invocation is dispatched.
         mController.setTriggerBack(true);   // Fake trigger back
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/TouchTrackerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/TouchTrackerTest.java
index 3aefc3f..ba9c159 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/TouchTrackerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/TouchTrackerTest.java
@@ -19,6 +19,7 @@
 import static org.junit.Assert.assertEquals;
 
 import android.window.BackEvent;
+import android.window.BackMotionEvent;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -38,7 +39,7 @@
     @Test
     public void generatesProgress_onStart() {
         mTouchTracker.setGestureStartLocation(INITIAL_X_LEFT_EDGE, 0, BackEvent.EDGE_LEFT);
-        BackEvent event = mTouchTracker.createStartEvent(null);
+        BackMotionEvent event = mTouchTracker.createStartEvent(null);
         assertEquals(event.getProgress(), 0f, 0f);
     }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
index e6711ac..8b025cd 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
@@ -16,6 +16,8 @@
 
 package com.android.wm.shell.bubbles;
 
+import static com.android.wm.shell.bubbles.Bubble.KEY_APP_BUBBLE;
+
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
@@ -32,6 +34,7 @@
 
 import android.app.Notification;
 import android.app.PendingIntent;
+import android.content.Intent;
 import android.content.LocusId;
 import android.graphics.drawable.Icon;
 import android.os.Bundle;
@@ -94,6 +97,7 @@
     private Bubble mBubbleInterruptive;
     private Bubble mBubbleDismissed;
     private Bubble mBubbleLocusId;
+    private Bubble mAppBubble;
 
     private BubbleData mBubbleData;
     private TestableBubblePositioner mPositioner;
@@ -178,6 +182,11 @@
                 mBubbleMetadataFlagListener,
                 mPendingIntentCanceledListener,
                 mMainExecutor);
+
+        Intent appBubbleIntent = new Intent(mContext, BubblesTestActivity.class);
+        appBubbleIntent.setPackage(mContext.getPackageName());
+        mAppBubble = new Bubble(appBubbleIntent, new UserHandle(1), mMainExecutor);
+
         mPositioner = new TestableBubblePositioner(mContext,
                 mock(WindowManager.class));
         mBubbleData = new BubbleData(getContext(), mBubbleLogger, mPositioner,
@@ -1089,6 +1098,18 @@
         assertOverflowChangedTo(ImmutableList.of());
     }
 
+    @Test
+    public void test_removeAppBubble_skipsOverflow() {
+        mBubbleData.notificationEntryUpdated(mAppBubble, true /* suppressFlyout*/,
+                false /* showInShade */);
+        assertThat(mBubbleData.getBubbleInStackWithKey(KEY_APP_BUBBLE)).isEqualTo(mAppBubble);
+
+        mBubbleData.dismissBubbleWithKey(KEY_APP_BUBBLE, Bubbles.DISMISS_USER_GESTURE);
+
+        assertThat(mBubbleData.getOverflowBubbleWithKey(KEY_APP_BUBBLE)).isNull();
+        assertThat(mBubbleData.getBubbleInStackWithKey(KEY_APP_BUBBLE)).isNull();
+    }
+
     private void verifyUpdateReceived() {
         verify(mListener).applyUpdate(mUpdateCaptor.capture());
         reset(mListener);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java
index 9967e5f..262ee72 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java
@@ -22,6 +22,8 @@
 import static android.view.WindowInsets.Type.ime;
 
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
@@ -131,6 +133,15 @@
         verify(mT).show(any());
     }
 
+    @Test
+    public void insetsControlChanged_updateImeSourceControl() {
+        mPerDisplay.insetsControlChanged(insetsStateWithIme(false), insetsSourceControl());
+        assertNotNull(mPerDisplay.mImeSourceControl);
+
+        mPerDisplay.insetsControlChanged(new InsetsState(), new InsetsSourceControl[]{});
+        assertNull(mPerDisplay.mImeSourceControl);
+    }
+
     private InsetsSourceControl[] insetsSourceControl() {
         return new InsetsSourceControl[]{
                 new InsetsSourceControl(
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
index 08af3d3..7997a7e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
@@ -279,7 +279,7 @@
     }
 
     @Test
-    public void testShowDesktopApps_appsAlreadyVisible_doesNothing() {
+    public void testShowDesktopApps_appsAlreadyVisible_bringsToFront() {
         final RunningTaskInfo task1 = createFreeformTask();
         mDesktopModeTaskRepository.addActiveTask(task1.taskId);
         mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task1.taskId);
@@ -294,8 +294,17 @@
         mController.showDesktopApps();
 
         final WindowContainerTransaction wct = getBringAppsToFrontTransaction();
-        // No reordering needed.
-        assertThat(wct.getHierarchyOps()).isEmpty();
+        // Check wct has reorder calls
+        assertThat(wct.getHierarchyOps()).hasSize(2);
+        // Task 1 appeared first, must be first reorder to top.
+        HierarchyOp op1 = wct.getHierarchyOps().get(0);
+        assertThat(op1.getType()).isEqualTo(HIERARCHY_OP_TYPE_REORDER);
+        assertThat(op1.getContainer()).isEqualTo(task1.token.asBinder());
+
+        // Task 2 appeared last, must be last reorder to top.
+        HierarchyOp op2 = wct.getHierarchyOps().get(1);
+        assertThat(op2.getType()).isEqualTo(HIERARCHY_OP_TYPE_REORDER);
+        assertThat(op2.getContainer()).isEqualTo(task2.token.asBinder());
     }
 
     @Test
@@ -325,6 +334,41 @@
     }
 
     @Test
+    public void testGetVisibleTaskCount_noTasks_returnsZero() {
+        assertThat(mController.getVisibleTaskCount()).isEqualTo(0);
+    }
+
+    @Test
+    public void testGetVisibleTaskCount_twoTasks_bothVisible_returnsTwo() {
+        RunningTaskInfo task1 = createFreeformTask();
+        mDesktopModeTaskRepository.addActiveTask(task1.taskId);
+        mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task1.taskId);
+        mDesktopModeTaskRepository.updateVisibleFreeformTasks(task1.taskId, true /* visible */);
+
+        RunningTaskInfo task2 = createFreeformTask();
+        mDesktopModeTaskRepository.addActiveTask(task2.taskId);
+        mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task2.taskId);
+        mDesktopModeTaskRepository.updateVisibleFreeformTasks(task2.taskId, true /* visible */);
+
+        assertThat(mController.getVisibleTaskCount()).isEqualTo(2);
+    }
+
+    @Test
+    public void testGetVisibleTaskCount_twoTasks_oneVisible_returnsOne() {
+        RunningTaskInfo task1 = createFreeformTask();
+        mDesktopModeTaskRepository.addActiveTask(task1.taskId);
+        mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task1.taskId);
+        mDesktopModeTaskRepository.updateVisibleFreeformTasks(task1.taskId, true /* visible */);
+
+        RunningTaskInfo task2 = createFreeformTask();
+        mDesktopModeTaskRepository.addActiveTask(task2.taskId);
+        mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task2.taskId);
+        mDesktopModeTaskRepository.updateVisibleFreeformTasks(task2.taskId, false /* visible */);
+
+        assertThat(mController.getVisibleTaskCount()).isEqualTo(1);
+    }
+
+    @Test
     public void testHandleTransitionRequest_desktopModeNotActive_returnsNull() {
         when(DesktopModeStatus.isActive(any())).thenReturn(false);
         WindowContainerTransaction wct = mController.handleRequest(
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt
index 1e43a59..45cb3a0 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt
@@ -141,6 +141,36 @@
     }
 
     @Test
+    fun getVisibleTaskCount() {
+        // No tasks, count is 0
+        assertThat(repo.getVisibleTaskCount()).isEqualTo(0)
+
+        // New task increments count to 1
+        repo.updateVisibleFreeformTasks(taskId = 1, visible = true)
+        assertThat(repo.getVisibleTaskCount()).isEqualTo(1)
+
+        // Visibility update to same task does not increase count
+        repo.updateVisibleFreeformTasks(taskId = 1, visible = true)
+        assertThat(repo.getVisibleTaskCount()).isEqualTo(1)
+
+        // Second task visible increments count
+        repo.updateVisibleFreeformTasks(taskId = 2, visible = true)
+        assertThat(repo.getVisibleTaskCount()).isEqualTo(2)
+
+        // Hiding a task decrements count
+        repo.updateVisibleFreeformTasks(taskId = 1, visible = false)
+        assertThat(repo.getVisibleTaskCount()).isEqualTo(1)
+
+        // Hiding all tasks leaves count at 0
+        repo.updateVisibleFreeformTasks(taskId = 2, visible = false)
+        assertThat(repo.getVisibleTaskCount()).isEqualTo(0)
+
+        // Hiding a not existing task, count remains at 0
+        repo.updateVisibleFreeformTasks(taskId = 999, visible = false)
+        assertThat(repo.getVisibleTaskCount()).isEqualTo(0)
+    }
+
+    @Test
     fun addOrMoveFreeformTaskToTop_didNotExist_addsToTop() {
         repo.addOrMoveFreeformTaskToTop(5)
         repo.addOrMoveFreeformTaskToTop(6)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index 9a92879..f16beee 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -150,8 +150,8 @@
     }
 
     @Test
-    fun showDesktopApps_appsAlreadyVisible_doesNothing() {
-        setUpHomeTask()
+    fun showDesktopApps_appsAlreadyVisible_bringsToFront() {
+        val homeTask = setUpHomeTask()
         val task1 = setUpFreeformTask()
         val task2 = setUpFreeformTask()
         markTaskVisible(task1)
@@ -159,7 +159,12 @@
 
         controller.showDesktopApps()
 
-        verifyWCTNotExecuted()
+        val wct = getLatestWct()
+        assertThat(wct.hierarchyOps).hasSize(3)
+        // Expect order to be from bottom: home, task1, task2
+        wct.assertReorderAt(index = 0, homeTask)
+        wct.assertReorderAt(index = 1, task1)
+        wct.assertReorderAt(index = 2, task2)
     }
 
     @Test
@@ -192,6 +197,27 @@
     }
 
     @Test
+    fun getVisibleTaskCount_noTasks_returnsZero() {
+        assertThat(controller.getVisibleTaskCount()).isEqualTo(0)
+    }
+
+    @Test
+    fun getVisibleTaskCount_twoTasks_bothVisible_returnsTwo() {
+        setUpHomeTask()
+        setUpFreeformTask().also(::markTaskVisible)
+        setUpFreeformTask().also(::markTaskVisible)
+        assertThat(controller.getVisibleTaskCount()).isEqualTo(2)
+    }
+
+    @Test
+    fun getVisibleTaskCount_twoTasks_oneVisible_returnsOne() {
+        setUpHomeTask()
+        setUpFreeformTask().also(::markTaskVisible)
+        setUpFreeformTask().also(::markTaskHidden)
+        assertThat(controller.getVisibleTaskCount()).isEqualTo(1)
+    }
+
+    @Test
     fun moveToDesktop() {
         val task = setUpFullscreenTask()
         controller.moveToDesktop(task)
@@ -207,6 +233,23 @@
     }
 
     @Test
+    fun moveToDesktop_otherFreeformTasksBroughtToFront() {
+        val homeTask = setUpHomeTask()
+        val freeformTask = setUpFreeformTask()
+        val fullscreenTask = setUpFullscreenTask()
+        markTaskHidden(freeformTask)
+
+        controller.moveToDesktop(fullscreenTask)
+
+        with(getLatestWct()) {
+            assertThat(hierarchyOps).hasSize(3)
+            assertReorderSequence(homeTask, freeformTask, fullscreenTask)
+            assertThat(changes[fullscreenTask.token.asBinder()]?.windowingMode)
+                .isEqualTo(WINDOWING_MODE_FREEFORM)
+        }
+    }
+
+    @Test
     fun moveToFullscreen() {
         val task = setUpFreeformTask()
         controller.moveToFullscreen(task)
@@ -406,3 +449,9 @@
     assertThat(op.type).isEqualTo(HIERARCHY_OP_TYPE_REORDER)
     assertThat(op.container).isEqualTo(task.token.asBinder())
 }
+
+private fun WindowContainerTransaction.assertReorderSequence(vararg tasks: RunningTaskInfo) {
+    for (i in tasks.indices) {
+        assertReorderAt(i, tasks[i])
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java
index 262e429..298d0a6 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java
@@ -64,7 +64,7 @@
         initializeMockResources();
         mPipBoundsState = new PipBoundsState(mContext);
         mPipBoundsAlgorithm = new PipBoundsAlgorithm(mContext, mPipBoundsState,
-                new PipSnapAlgorithm(), new PipKeepClearAlgorithm() {});
+                new PipSnapAlgorithm(), new PipKeepClearAlgorithmInterface() {});
 
         mPipBoundsState.setDisplayLayout(
                 new DisplayLayout(mDefaultDisplayInfo, mContext.getResources(), true, true));
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
index 9088077..17e7d74 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
@@ -98,7 +98,7 @@
         mPipBoundsState = new PipBoundsState(mContext);
         mPipTransitionState = new PipTransitionState();
         mPipBoundsAlgorithm = new PipBoundsAlgorithm(mContext, mPipBoundsState,
-                new PipSnapAlgorithm(), new PipKeepClearAlgorithm() {});
+                new PipSnapAlgorithm(), new PipKeepClearAlgorithmInterface() {});
         mMainExecutor = new TestShellExecutor();
         mPipTaskOrganizer = new PipTaskOrganizer(mContext,
                 mMockSyncTransactionQueue, mPipTransitionState, mPipBoundsState,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
index d06fb55..35c09a1 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
@@ -18,7 +18,9 @@
 
 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
 
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
@@ -30,11 +32,15 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import static java.lang.Integer.MAX_VALUE;
+
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
+import android.graphics.Point;
 import android.graphics.Rect;
+import android.os.Bundle;
 import android.os.RemoteException;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
@@ -59,6 +65,7 @@
 import com.android.wm.shell.pip.PipTaskOrganizer;
 import com.android.wm.shell.pip.PipTransitionController;
 import com.android.wm.shell.pip.PipTransitionState;
+import com.android.wm.shell.recents.IRecentTasksListener;
 import com.android.wm.shell.sysui.ShellCommandHandler;
 import com.android.wm.shell.sysui.ShellController;
 import com.android.wm.shell.sysui.ShellInit;
@@ -135,12 +142,12 @@
 
     @Test
     public void instantiatePipController_addInitCallback() {
-        verify(mShellInit, times(1)).addInitCallback(any(), any());
+        verify(mShellInit, times(1)).addInitCallback(any(), eq(mPipController));
     }
 
     @Test
     public void instantiateController_registerDumpCallback() {
-        verify(mMockShellCommandHandler, times(1)).addDumpCallback(any(), any());
+        verify(mMockShellCommandHandler, times(1)).addDumpCallback(any(), eq(mPipController));
     }
 
     @Test
@@ -156,7 +163,7 @@
     @Test
     public void instantiatePipController_registerExternalInterface() {
         verify(mShellController, times(1)).addExternalInterface(
-                eq(ShellSharedConstants.KEY_EXTRA_SHELL_PIP), any(), any());
+                eq(ShellSharedConstants.KEY_EXTRA_SHELL_PIP), any(), eq(mPipController));
     }
 
     @Test
@@ -185,6 +192,24 @@
     }
 
     @Test
+    public void testInvalidateExternalInterface_unregistersListener() {
+        mPipController.setPinnedStackAnimationListener(new PipController.PipAnimationListener() {
+            @Override
+            public void onPipAnimationStarted() {}
+            @Override
+            public void onPipResourceDimensionsChanged(int cornerRadius, int shadowRadius) {}
+            @Override
+            public void onExpandPip() {}
+        });
+        assertTrue(mPipController.hasPinnedStackAnimationListener());
+        // Create initial interface
+        mShellController.createExternalInterfaces(new Bundle());
+        // Recreate the interface to trigger invalidation of the previous instance
+        mShellController.createExternalInterfaces(new Bundle());
+        assertFalse(mPipController.hasPinnedStackAnimationListener());
+    }
+
+    @Test
     public void createPip_notSupported_returnsNull() {
         Context spyContext = spy(mContext);
         PackageManager mockPackageManager = mock(PackageManager.class);
@@ -252,6 +277,10 @@
         final int displayId = 1;
         final Rect bounds = new Rect(0, 0, 10, 10);
         when(mMockPipBoundsAlgorithm.getDefaultBounds()).thenReturn(bounds);
+        when(mMockPipBoundsState.getBounds()).thenReturn(bounds);
+        when(mMockPipBoundsState.getMinSize()).thenReturn(new Point(1, 1));
+        when(mMockPipBoundsState.getMaxSize()).thenReturn(new Point(MAX_VALUE, MAX_VALUE));
+        when(mMockPipBoundsState.getBounds()).thenReturn(bounds);
         when(mMockPipBoundsState.getDisplayId()).thenReturn(displayId);
         when(mMockPipBoundsState.getDisplayLayout()).thenReturn(mMockDisplayLayout1);
         when(mMockDisplayController.getDisplayLayout(displayId)).thenReturn(mMockDisplayLayout2);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java
index 3bd2ae7..c1993b2 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java
@@ -37,7 +37,7 @@
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.pip.PipBoundsAlgorithm;
 import com.android.wm.shell.pip.PipBoundsState;
-import com.android.wm.shell.pip.PipKeepClearAlgorithm;
+import com.android.wm.shell.pip.PipKeepClearAlgorithmInterface;
 import com.android.wm.shell.pip.PipSnapAlgorithm;
 import com.android.wm.shell.pip.PipTaskOrganizer;
 import com.android.wm.shell.pip.PipTransitionController;
@@ -90,8 +90,8 @@
         MockitoAnnotations.initMocks(this);
         mPipBoundsState = new PipBoundsState(mContext);
         final PipSnapAlgorithm pipSnapAlgorithm = new PipSnapAlgorithm();
-        final PipKeepClearAlgorithm pipKeepClearAlgorithm =
-                new PipKeepClearAlgorithm() {};
+        final PipKeepClearAlgorithmInterface pipKeepClearAlgorithm =
+                new PipKeepClearAlgorithmInterface() {};
         final PipBoundsAlgorithm pipBoundsAlgorithm = new PipBoundsAlgorithm(mContext,
                 mPipBoundsState, pipSnapAlgorithm, pipKeepClearAlgorithm);
         final PipMotionHelper motionHelper = new PipMotionHelper(mContext, mPipBoundsState,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
index 474d6aa..8ad2932 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
@@ -34,7 +34,7 @@
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.pip.PipBoundsAlgorithm;
 import com.android.wm.shell.pip.PipBoundsState;
-import com.android.wm.shell.pip.PipKeepClearAlgorithm;
+import com.android.wm.shell.pip.PipKeepClearAlgorithmInterface;
 import com.android.wm.shell.pip.PipSnapAlgorithm;
 import com.android.wm.shell.pip.PipTaskOrganizer;
 import com.android.wm.shell.pip.PipTransitionController;
@@ -106,7 +106,7 @@
         mPipBoundsState = new PipBoundsState(mContext);
         mPipSnapAlgorithm = new PipSnapAlgorithm();
         mPipBoundsAlgorithm = new PipBoundsAlgorithm(mContext, mPipBoundsState, mPipSnapAlgorithm,
-                new PipKeepClearAlgorithm() {});
+                new PipKeepClearAlgorithmInterface() {});
         PipMotionHelper pipMotionHelper = new PipMotionHelper(mContext, mPipBoundsState,
                 mPipTaskOrganizer, mPhonePipMenuController, mPipSnapAlgorithm,
                 mMockPipTransitionController, mFloatingContentCoordinator);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
index f6ac3ee..82392ad9 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
@@ -23,6 +23,7 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
@@ -45,6 +46,7 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.graphics.Rect;
+import android.os.Bundle;
 import android.view.SurfaceControl;
 
 import androidx.test.filters.SmallTest;
@@ -87,8 +89,6 @@
     @Mock
     private TaskStackListenerImpl mTaskStackListener;
     @Mock
-    private ShellController mShellController;
-    @Mock
     private ShellCommandHandler mShellCommandHandler;
     @Mock
     private DesktopModeTaskRepository mDesktopModeTaskRepository;
@@ -97,7 +97,9 @@
 
     private ShellTaskOrganizer mShellTaskOrganizer;
     private RecentTasksController mRecentTasksController;
+    private RecentTasksController mRecentTasksControllerReal;
     private ShellInit mShellInit;
+    private ShellController mShellController;
     private TestShellExecutor mMainExecutor;
 
     @Before
@@ -105,9 +107,12 @@
         mMainExecutor = new TestShellExecutor();
         when(mContext.getPackageManager()).thenReturn(mock(PackageManager.class));
         mShellInit = spy(new ShellInit(mMainExecutor));
-        mRecentTasksController = spy(new RecentTasksController(mContext, mShellInit,
+        mShellController = spy(new ShellController(mShellInit, mShellCommandHandler,
+                mMainExecutor));
+        mRecentTasksControllerReal = new RecentTasksController(mContext, mShellInit,
                 mShellController, mShellCommandHandler, mTaskStackListener, mActivityTaskManager,
-                Optional.of(mDesktopModeTaskRepository), mMainExecutor));
+                Optional.of(mDesktopModeTaskRepository), mMainExecutor);
+        mRecentTasksController = spy(mRecentTasksControllerReal);
         mShellTaskOrganizer = new ShellTaskOrganizer(mShellInit, mShellCommandHandler,
                 null /* sizeCompatUI */, Optional.empty(), Optional.of(mRecentTasksController),
                 mMainExecutor);
@@ -132,6 +137,20 @@
     }
 
     @Test
+    public void testInvalidateExternalInterface_unregistersListener() {
+        // Note: We have to use the real instance of the controller here since that is the instance
+        // that is passed to ShellController internally, and the instance that the listener will be
+        // unregistered from
+        mRecentTasksControllerReal.registerRecentTasksListener(new IRecentTasksListener.Default());
+        assertTrue(mRecentTasksControllerReal.hasRecentTasksListener());
+        // Create initial interface
+        mShellController.createExternalInterfaces(new Bundle());
+        // Recreate the interface to trigger invalidation of the previous instance
+        mShellController.createExternalInterfaces(new Bundle());
+        assertFalse(mRecentTasksControllerReal.hasRecentTasksListener());
+    }
+
+    @Test
     public void testAddRemoveSplitNotifyChange() {
         ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1);
         ActivityManager.RecentTaskInfo t2 = makeTaskInfo(2);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
index f8ded77..ea3af9d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
@@ -27,11 +27,14 @@
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assume.assumeTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isA;
 import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
@@ -46,6 +49,7 @@
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
+import android.os.Bundle;
 
 import androidx.test.annotation.UiThreadTest;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -86,7 +90,6 @@
 public class SplitScreenControllerTests extends ShellTestCase {
 
     @Mock ShellInit mShellInit;
-    @Mock ShellController mShellController;
     @Mock ShellCommandHandler mShellCommandHandler;
     @Mock ShellTaskOrganizer mTaskOrganizer;
     @Mock SyncTransactionQueue mSyncQueue;
@@ -103,12 +106,15 @@
     @Mock RecentTasksController mRecentTasks;
     @Captor ArgumentCaptor<Intent> mIntentCaptor;
 
+    private ShellController mShellController;
     private SplitScreenController mSplitScreenController;
 
     @Before
     public void setup() {
         assumeTrue(ActivityTaskManager.supportsSplitScreenMultiWindow(mContext));
         MockitoAnnotations.initMocks(this);
+        mShellController = spy(new ShellController(mShellInit, mShellCommandHandler,
+                mMainExecutor));
         mSplitScreenController = spy(new SplitScreenController(mContext, mShellInit,
                 mShellCommandHandler, mShellController, mTaskOrganizer, mSyncQueue,
                 mRootTDAOrganizer, mDisplayController, mDisplayImeController,
@@ -118,7 +124,7 @@
 
     @Test
     public void instantiateController_addInitCallback() {
-        verify(mShellInit, times(1)).addInitCallback(any(), any());
+        verify(mShellInit, times(1)).addInitCallback(any(), isA(SplitScreenController.class));
     }
 
     @Test
@@ -159,6 +165,19 @@
     }
 
     @Test
+    public void testInvalidateExternalInterface_unregistersListener() {
+        mSplitScreenController.onInit();
+        mSplitScreenController.registerSplitScreenListener(
+                new SplitScreen.SplitScreenListener() {});
+        verify(mStageCoordinator).registerSplitScreenListener(any());
+        // Create initial interface
+        mShellController.createExternalInterfaces(new Bundle());
+        // Recreate the interface to trigger invalidation of the previous instance
+        mShellController.createExternalInterfaces(new Bundle());
+        verify(mStageCoordinator).unregisterSplitScreenListener(any());
+    }
+
+    @Test
     public void testStartIntent_appendsNoUserActionFlag() {
         Intent startIntent = createStartIntent("startActivity");
         PendingIntent pendingIntent =
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 65e1ea8..0bb809d 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
@@ -29,11 +29,13 @@
 import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE;
 import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
 import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_RETURN_HOME;
+import static com.android.wm.shell.transition.Transitions.TRANSIT_SPLIT_DISMISS;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.notNull;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
@@ -45,6 +47,8 @@
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
 import android.window.WindowContainerToken;
@@ -57,6 +61,7 @@
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.TestRunningTaskInfoBuilder;
+import com.android.wm.shell.TestShellExecutor;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayImeController;
 import com.android.wm.shell.common.DisplayInsetsController;
@@ -65,6 +70,8 @@
 import com.android.wm.shell.common.TransactionPool;
 import com.android.wm.shell.common.split.SplitLayout;
 import com.android.wm.shell.splitscreen.SplitScreen.SplitScreenListener;
+import com.android.wm.shell.sysui.ShellController;
+import com.android.wm.shell.sysui.ShellInit;
 import com.android.wm.shell.transition.Transitions;
 
 import org.junit.Before;
@@ -98,11 +105,7 @@
     @Mock
     private DisplayInsetsController mDisplayInsetsController;
     @Mock
-    private Transitions mTransitions;
-    @Mock
     private TransactionPool mTransactionPool;
-    @Mock
-    private ShellExecutor mMainExecutor;
 
     private final Rect mBounds1 = new Rect(10, 20, 30, 40);
     private final Rect mBounds2 = new Rect(5, 10, 15, 20);
@@ -112,11 +115,16 @@
     private SurfaceControl mRootLeash;
     private ActivityManager.RunningTaskInfo mRootTask;
     private StageCoordinator mStageCoordinator;
+    private Transitions mTransitions;
+    private final TestShellExecutor mMainExecutor = new TestShellExecutor();
+    private final ShellExecutor mAnimExecutor = new TestShellExecutor();
+    private final Handler mMainHandler = new Handler(Looper.getMainLooper());
 
     @Before
     @UiThreadTest
     public void setup() {
         MockitoAnnotations.initMocks(this);
+        mTransitions = createTestTransitions();
         mStageCoordinator = spy(new StageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue,
                 mTaskOrganizer, mMainStage, mSideStage, mDisplayController, mDisplayImeController,
                 mDisplayInsetsController, mSplitLayout, mTransitions, mTransactionPool,
@@ -329,7 +337,20 @@
 
         mStageCoordinator.onFoldedStateChanged(true);
 
-        verify(mStageCoordinator).onSplitScreenExit();
-        verify(mMainStage).deactivate(any(WindowContainerTransaction.class), eq(false));
+        if (Transitions.ENABLE_SHELL_TRANSITIONS) {
+            verify(mTaskOrganizer).startNewTransition(eq(TRANSIT_SPLIT_DISMISS), notNull());
+        } else {
+            verify(mStageCoordinator).onSplitScreenExit();
+            verify(mMainStage).deactivate(any(WindowContainerTransaction.class), eq(false));
+        }
+    }
+
+    private Transitions createTestTransitions() {
+        ShellInit shellInit = new ShellInit(mMainExecutor);
+        final Transitions t = new Transitions(mContext, shellInit, mock(ShellController.class),
+                mTaskOrganizer, mTransactionPool, mock(DisplayController.class), mMainExecutor,
+                mMainHandler, mAnimExecutor);
+        shellInit.init();
+        return t;
     }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingWindowControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingWindowControllerTests.java
index 90165d1..10dec9e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingWindowControllerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingWindowControllerTests.java
@@ -16,9 +16,12 @@
 
 package com.android.wm.shell.startingsurface;
 
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isA;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
@@ -27,16 +30,19 @@
 
 import android.content.Context;
 import android.hardware.display.DisplayManager;
+import android.os.Bundle;
 import android.view.Display;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.android.internal.util.function.TriConsumer;
 import com.android.launcher3.icons.IconProvider;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.sysui.ShellCommandHandler;
 import com.android.wm.shell.sysui.ShellController;
 import com.android.wm.shell.sysui.ShellInit;
 import com.android.wm.shell.sysui.ShellSharedConstants;
@@ -59,7 +65,7 @@
 
     private @Mock Context mContext;
     private @Mock DisplayManager mDisplayManager;
-    private @Mock ShellController mShellController;
+    private @Mock ShellCommandHandler mShellCommandHandler;
     private @Mock ShellTaskOrganizer mTaskOrganizer;
     private @Mock ShellExecutor mMainExecutor;
     private @Mock StartingWindowTypeAlgorithm mTypeAlgorithm;
@@ -67,6 +73,7 @@
     private @Mock TransactionPool mTransactionPool;
     private StartingWindowController mController;
     private ShellInit mShellInit;
+    private ShellController mShellController;
 
     @Before
     public void setUp() {
@@ -74,6 +81,8 @@
         doReturn(mock(Display.class)).when(mDisplayManager).getDisplay(anyInt());
         doReturn(mDisplayManager).when(mContext).getSystemService(eq(DisplayManager.class));
         mShellInit = spy(new ShellInit(mMainExecutor));
+        mShellController = spy(new ShellController(mShellInit, mShellCommandHandler,
+                mMainExecutor));
         mController = new StartingWindowController(mContext, mShellInit, mShellController,
                 mTaskOrganizer, mMainExecutor, mTypeAlgorithm, mIconProvider, mTransactionPool);
         mShellInit.init();
@@ -81,7 +90,7 @@
 
     @Test
     public void instantiateController_addInitCallback() {
-        verify(mShellInit, times(1)).addInitCallback(any(), any());
+        verify(mShellInit, times(1)).addInitCallback(any(), isA(StartingWindowController.class));
     }
 
     @Test
@@ -89,4 +98,18 @@
         verify(mShellController, times(1)).addExternalInterface(
                 eq(ShellSharedConstants.KEY_EXTRA_SHELL_STARTING_WINDOW), any(), any());
     }
+
+    @Test
+    public void testInvalidateExternalInterface_unregistersListener() {
+        mController.setStartingWindowListener(new TriConsumer<Integer, Integer, Integer>() {
+            @Override
+            public void accept(Integer integer, Integer integer2, Integer integer3) {}
+        });
+        assertTrue(mController.hasStartingWindowListener());
+        // Create initial interface
+        mShellController.createExternalInterfaces(new Bundle());
+        // Recreate the interface to trigger invalidation of the previous instance
+        mShellController.createExternalInterfaces(new Bundle());
+        assertFalse(mController.hasStartingWindowListener());
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/sysui/ShellControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/sysui/ShellControllerTest.java
index fbc50c6..8d92d08 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/sysui/ShellControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/sysui/ShellControllerTest.java
@@ -34,6 +34,7 @@
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.TestShellExecutor;
 import com.android.wm.shell.common.ExternalInterfaceBinder;
 import com.android.wm.shell.common.ShellExecutor;
 
@@ -61,10 +62,9 @@
     @Mock
     private ShellCommandHandler mShellCommandHandler;
     @Mock
-    private ShellExecutor mExecutor;
-    @Mock
     private Context mTestUserContext;
 
+    private TestShellExecutor mExecutor;
     private ShellController mController;
     private TestConfigurationChangeListener mConfigChangeListener;
     private TestKeyguardChangeListener mKeyguardChangeListener;
@@ -77,6 +77,7 @@
         mKeyguardChangeListener = new TestKeyguardChangeListener();
         mConfigChangeListener = new TestConfigurationChangeListener();
         mUserChangeListener = new TestUserChangeListener();
+        mExecutor = new TestShellExecutor();
         mController = new ShellController(mShellInit, mShellCommandHandler, mExecutor);
         mController.onConfigurationChanged(getConfigurationCopy());
     }
@@ -104,6 +105,7 @@
 
         Bundle b = new Bundle();
         mController.asShell().createExternalInterfaces(b);
+        mExecutor.flushAll();
         assertTrue(b.getIBinder(EXTRA_TEST_BINDER) == callback);
     }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
index c764741..595c3b4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
@@ -936,7 +936,7 @@
         TransitionInfoBuilder addChange(@WindowManager.TransitionType int mode,
                 RunningTaskInfo taskInfo) {
             final TransitionInfo.Change change =
-                    new TransitionInfo.Change(null /* token */, null /* leash */);
+                    new TransitionInfo.Change(null /* token */, createMockSurface(true));
             change.setMode(mode);
             change.setTaskInfo(taskInfo);
             mInfo.addChange(change);
@@ -961,7 +961,7 @@
         final TransitionInfo.Change mChange;
 
         ChangeBuilder(@WindowManager.TransitionType int mode) {
-            mChange = new TransitionInfo.Change(null /* token */, null /* leash */);
+            mChange = new TransitionInfo.Change(null /* token */, createMockSurface(true));
             mChange.setMode(mode);
         }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldAnimationControllerTest.java
index 81eefe2..8196c5a 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldAnimationControllerTest.java
@@ -224,16 +224,18 @@
         mUnfoldAnimationController.onTaskAppeared(taskInfo, mLeash);
         assertThat(mTaskAnimator1.mResetTasks).doesNotContain(taskInfo.taskId);
 
+        mUnfoldAnimationController.onStateChangeStarted();
         mUnfoldAnimationController.onTaskVanished(taskInfo);
+        mUnfoldAnimationController.onStateChangeFinished();
 
         assertThat(mTaskAnimator1.mResetTasks).contains(taskInfo.taskId);
     }
 
     @Test
-    public void testApplicablePinnedTaskDisappeared_doesNotResetSurface() {
-        mTaskAnimator1.setTaskMatcher((info) -> info.getWindowingMode() == 2);
+    public void testApplicableTaskDisappeared_noStateChange_doesNotResetSurface() {
+        mTaskAnimator1.setTaskMatcher((info) -> info.getWindowingMode() == 0);
         RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
-                .setWindowingMode(2).build();
+                .setWindowingMode(0).build();
         mUnfoldAnimationController.onTaskAppeared(taskInfo, mLeash);
         assertThat(mTaskAnimator1.mResetTasks).doesNotContain(taskInfo.taskId);
 
@@ -249,7 +251,9 @@
                 .setWindowingMode(0).build();
 
         mUnfoldAnimationController.onTaskAppeared(taskInfo, mLeash);
+        mUnfoldAnimationController.onStateChangeStarted();
         mUnfoldAnimationController.onTaskVanished(taskInfo);
+        mUnfoldAnimationController.onStateChangeFinished();
 
         assertThat(mTaskAnimator1.mResetTasks).doesNotContain(taskInfo.taskId);
     }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.java
index a5e3a2e..3550721 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.java
@@ -205,28 +205,32 @@
                     "testEventReceiversOnMultipleDisplays", /*width=*/ 400, /*height=*/ 400,
                     /*densityDpi=*/ 320, surfaceView.getHolder().getSurface(),
                     DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
-            int secondaryDisplayId = secondaryDisplay.getDisplay().getDisplayId();
+            try {
+                int secondaryDisplayId = secondaryDisplay.getDisplay().getDisplayId();
 
-            final int taskId = 1;
-            final ActivityManager.RunningTaskInfo taskInfo =
-                    createTaskInfo(taskId, Display.DEFAULT_DISPLAY, WINDOWING_MODE_FREEFORM);
-            final ActivityManager.RunningTaskInfo secondTaskInfo =
-                    createTaskInfo(taskId + 1, secondaryDisplayId, WINDOWING_MODE_FREEFORM);
-            final ActivityManager.RunningTaskInfo thirdTaskInfo =
-                    createTaskInfo(taskId + 2, secondaryDisplayId, WINDOWING_MODE_FREEFORM);
+                final int taskId = 1;
+                final ActivityManager.RunningTaskInfo taskInfo =
+                        createTaskInfo(taskId, Display.DEFAULT_DISPLAY, WINDOWING_MODE_FREEFORM);
+                final ActivityManager.RunningTaskInfo secondTaskInfo =
+                        createTaskInfo(taskId + 1, secondaryDisplayId, WINDOWING_MODE_FREEFORM);
+                final ActivityManager.RunningTaskInfo thirdTaskInfo =
+                        createTaskInfo(taskId + 2, secondaryDisplayId, WINDOWING_MODE_FREEFORM);
 
-            SurfaceControl surfaceControl = mock(SurfaceControl.class);
-            final SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class);
-            final SurfaceControl.Transaction finishT = mock(SurfaceControl.Transaction.class);
+                SurfaceControl surfaceControl = mock(SurfaceControl.class);
+                final SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class);
+                final SurfaceControl.Transaction finishT = mock(SurfaceControl.Transaction.class);
 
-            mDesktopModeWindowDecorViewModel.onTaskOpening(taskInfo, surfaceControl, startT,
-                    finishT);
-            mDesktopModeWindowDecorViewModel.onTaskOpening(secondTaskInfo, surfaceControl,
-                    startT, finishT);
-            mDesktopModeWindowDecorViewModel.onTaskOpening(thirdTaskInfo, surfaceControl,
-                    startT, finishT);
-            mDesktopModeWindowDecorViewModel.destroyWindowDecoration(thirdTaskInfo);
-            mDesktopModeWindowDecorViewModel.destroyWindowDecoration(taskInfo);
+                mDesktopModeWindowDecorViewModel.onTaskOpening(taskInfo, surfaceControl, startT,
+                        finishT);
+                mDesktopModeWindowDecorViewModel.onTaskOpening(secondTaskInfo, surfaceControl,
+                        startT, finishT);
+                mDesktopModeWindowDecorViewModel.onTaskOpening(thirdTaskInfo, surfaceControl,
+                        startT, finishT);
+                mDesktopModeWindowDecorViewModel.destroyWindowDecoration(thirdTaskInfo);
+                mDesktopModeWindowDecorViewModel.destroyWindowDecoration(taskInfo);
+            } finally {
+                secondaryDisplay.release();
+            }
         });
         verify(mMockInputMonitorFactory, times(2)).create(any(), any());
         verify(mInputMonitor, times(1)).dispose();
@@ -239,7 +243,7 @@
             r.run();
             latch.countDown();
         });
-        latch.await(20, TimeUnit.MILLISECONDS);
+        latch.await(1, TimeUnit.SECONDS);
     }
 
     private static ActivityManager.RunningTaskInfo createTaskInfo(int taskId,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
index dd9ab98..ec4f17f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
@@ -48,6 +48,7 @@
 import android.view.View;
 import android.view.ViewRootImpl;
 import android.view.WindowManager.LayoutParams;
+import android.window.TaskConstants;
 import android.window.WindowContainerTransaction;
 
 import androidx.test.filters.SmallTest;
@@ -232,7 +233,8 @@
         verify(mMockSurfaceControlStartT)
                 .setColor(taskBackgroundSurface, new float[] {1.f, 1.f, 0.f});
         verify(mMockSurfaceControlStartT).setShadowRadius(taskBackgroundSurface, 10);
-        verify(mMockSurfaceControlStartT).setLayer(taskBackgroundSurface, -1);
+        verify(mMockSurfaceControlStartT).setLayer(taskBackgroundSurface,
+                TaskConstants.TASK_CHILD_LAYER_TASK_BACKGROUND);
         verify(mMockSurfaceControlStartT).show(taskBackgroundSurface);
 
         verify(captionContainerSurfaceBuilder).setParent(decorContainerSurface);
@@ -560,7 +562,8 @@
             int height = loadDimensionPixelSize(resources, mRelayoutParams.mCaptionHeightId);
             String name = "Test Window";
             WindowDecoration.AdditionalWindow additionalWindow =
-                    addWindow(R.layout.caption_handle_menu, name, mMockSurfaceControlAddWindowT,
+                    addWindow(R.layout.desktop_mode_decor_handle_menu, name,
+                            mMockSurfaceControlAddWindowT,
                             x - mRelayoutResult.mDecorContainerOffsetX,
                             y - mRelayoutResult.mDecorContainerOffsetY,
                             width, height);
diff --git a/media/java/android/media/ImageWriter.java b/media/java/android/media/ImageWriter.java
index 308bb3e..766e2a9 100644
--- a/media/java/android/media/ImageWriter.java
+++ b/media/java/android/media/ImageWriter.java
@@ -452,17 +452,15 @@
      * @see Image#close
      */
     public Image dequeueInputImage() {
-        synchronized (mCloseLock) {
-            if (mDequeuedImages.size() >= mMaxImages) {
-                throw new IllegalStateException(
-                        "Already dequeued max number of Images " + mMaxImages);
-            }
-            WriterSurfaceImage newImage = new WriterSurfaceImage(this);
-            nativeDequeueInputImage(mNativeContext, newImage);
-            mDequeuedImages.add(newImage);
-            newImage.mIsImageValid = true;
-            return newImage;
+        if (mDequeuedImages.size() >= mMaxImages) {
+            throw new IllegalStateException(
+                    "Already dequeued max number of Images " + mMaxImages);
         }
+        WriterSurfaceImage newImage = new WriterSurfaceImage(this);
+        nativeDequeueInputImage(mNativeContext, newImage);
+        mDequeuedImages.add(newImage);
+        newImage.mIsImageValid = true;
+        return newImage;
     }
 
     /**
@@ -521,52 +519,50 @@
             throw new IllegalArgumentException("image shouldn't be null");
         }
 
-        synchronized (mCloseLock) {
-            boolean ownedByMe = isImageOwnedByMe(image);
-            if (ownedByMe && !(((WriterSurfaceImage) image).mIsImageValid)) {
-                throw new IllegalStateException("Image from ImageWriter is invalid");
+        boolean ownedByMe = isImageOwnedByMe(image);
+        if (ownedByMe && !(((WriterSurfaceImage) image).mIsImageValid)) {
+            throw new IllegalStateException("Image from ImageWriter is invalid");
+        }
+
+        // For images from other components that have non-null owner, need to detach first,
+        // then attach. Images without owners must already be attachable.
+        if (!ownedByMe) {
+            if ((image.getOwner() instanceof ImageReader)) {
+                ImageReader prevOwner = (ImageReader) image.getOwner();
+
+                prevOwner.detachImage(image);
+            } else if (image.getOwner() != null) {
+                throw new IllegalArgumentException(
+                        "Only images from ImageReader can be queued to"
+                                + " ImageWriter, other image source is not supported yet!");
             }
 
-            // For images from other components that have non-null owner, need to detach first,
-            // then attach. Images without owners must already be attachable.
-            if (!ownedByMe) {
-                if ((image.getOwner() instanceof ImageReader)) {
-                    ImageReader prevOwner = (ImageReader) image.getOwner();
+            attachAndQueueInputImage(image);
+            // This clears the native reference held by the original owner.
+            // When this Image is detached later by this ImageWriter, the
+            // native memory won't be leaked.
+            image.close();
+            return;
+        }
 
-                    prevOwner.detachImage(image);
-                } else if (image.getOwner() != null) {
-                    throw new IllegalArgumentException(
-                            "Only images from ImageReader can be queued to"
-                                    + " ImageWriter, other image source is not supported yet!");
-                }
+        Rect crop = image.getCropRect();
+        nativeQueueInputImage(mNativeContext, image, image.getTimestamp(), image.getDataSpace(),
+                crop.left, crop.top, crop.right, crop.bottom, image.getTransform(),
+                image.getScalingMode());
 
-                attachAndQueueInputImage(image);
-                // This clears the native reference held by the original owner.
-                // When this Image is detached later by this ImageWriter, the
-                // native memory won't be leaked.
-                image.close();
-                return;
-            }
-
-            Rect crop = image.getCropRect();
-            nativeQueueInputImage(mNativeContext, image, image.getTimestamp(), image.getDataSpace(),
-                    crop.left, crop.top, crop.right, crop.bottom, image.getTransform(),
-                    image.getScalingMode());
-
-            /**
-             * Only remove and cleanup the Images that are owned by this
-             * ImageWriter. Images detached from other owners are only temporarily
-             * owned by this ImageWriter and will be detached immediately after they
-             * are released by downstream consumers, so there is no need to keep
-             * track of them in mDequeuedImages.
-             */
-            if (ownedByMe) {
-                mDequeuedImages.remove(image);
-                // Do not call close here, as close is essentially cancel image.
-                WriterSurfaceImage wi = (WriterSurfaceImage) image;
-                wi.clearSurfacePlanes();
-                wi.mIsImageValid = false;
-            }
+        /**
+         * Only remove and cleanup the Images that are owned by this
+         * ImageWriter. Images detached from other owners are only temporarily
+         * owned by this ImageWriter and will be detached immediately after they
+         * are released by downstream consumers, so there is no need to keep
+         * track of them in mDequeuedImages.
+         */
+        if (ownedByMe) {
+            mDequeuedImages.remove(image);
+            // Do not call close here, as close is essentially cancel image.
+            WriterSurfaceImage wi = (WriterSurfaceImage) image;
+            wi.clearSurfacePlanes();
+            wi.mIsImageValid = false;
         }
     }
 
@@ -702,11 +698,11 @@
      */
     @Override
     public void close() {
+        setOnImageReleasedListener(null, null);
         synchronized (mCloseLock) {
             if (!mIsWriterValid) {
                 return;
             }
-            setOnImageReleasedListener(null, null);
             for (Image image : mDequeuedImages) {
                 image.close();
             }
@@ -836,14 +832,12 @@
         }
 
         final Handler handler;
-        final boolean isWriterValid;
         synchronized (iw.mListenerLock) {
             handler = iw.mListenerHandler;
         }
-        synchronized (iw.mCloseLock) {
-            isWriterValid = iw.mIsWriterValid;
-        }
-        if (handler != null && isWriterValid) {
+
+        if (handler != null) {
+            // The ListenerHandler will take care of ensuring that the parent ImageWriter is valid
             handler.sendEmptyMessage(0);
         }
     }
diff --git a/media/java/android/media/session/ISession.aidl b/media/java/android/media/session/ISession.aidl
index 9bf126b..31fb8d0 100644
--- a/media/java/android/media/session/ISession.aidl
+++ b/media/java/android/media/session/ISession.aidl
@@ -35,7 +35,7 @@
     ISessionController getController();
     void setFlags(int flags);
     void setActive(boolean active);
-    void setMediaButtonReceiver(in PendingIntent mbr, String sessionPackageName);
+    void setMediaButtonReceiver(in PendingIntent mbr);
     void setMediaButtonBroadcastReceiver(in ComponentName broadcastReceiver);
     void setLaunchPendingIntent(in PendingIntent pi);
     void destroySession();
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index bc00c40..84ecc06 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -286,7 +286,7 @@
     @Deprecated
     public void setMediaButtonReceiver(@Nullable PendingIntent mbr) {
         try {
-            mBinder.setMediaButtonReceiver(mbr, mContext.getPackageName());
+            mBinder.setMediaButtonReceiver(mbr);
         } catch (RemoteException e) {
             Log.wtf(TAG, "Failure in setMediaButtonReceiver.", e);
         }
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedBackupTaskTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedBackupTaskTest.java
index f6914ef..23d6e34 100644
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedBackupTaskTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedBackupTaskTest.java
@@ -22,8 +22,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupTaskTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupTaskTest.java
index 096b2da..bfc5d0d 100644
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupTaskTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupTaskTest.java
@@ -18,9 +18,9 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertThrows;
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTaskTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTaskTest.java
index fa4fef5..222b882 100644
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTaskTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTaskTest.java
@@ -19,8 +19,8 @@
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertFalse;
@@ -41,13 +41,6 @@
 import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
 import com.android.server.backup.testing.CryptoTestUtils;
 
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import javax.crypto.SecretKey;
-
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -59,6 +52,14 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.crypto.SecretKey;
+
+
 @RunWith(RobolectricTestRunner.class)
 public class EncryptedKvBackupTaskTest {
     private static final boolean INCREMENTAL = true;
diff --git a/packages/BackupRestoreConfirmation/res/values-b+sr+Latn/strings.xml b/packages/BackupRestoreConfirmation/res/values-b+sr+Latn/strings.xml
index e7bdd2f..ab55120 100644
--- a/packages/BackupRestoreConfirmation/res/values-b+sr+Latn/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-b+sr+Latn/strings.xml
@@ -16,23 +16,23 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Резервна копије свих података"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Потпуно враћање"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Захтевана је потпуна резервна копија свих података на повезани рачунар. Да ли желите да дозволите то?\n\nАко нисте лично захтевали резервну копију, не дозвољавајте наставак радње."</string>
-    <string name="allow_backup_button_label" msgid="4217228747769644068">"Направи резервну копију мојих података"</string>
-    <string name="deny_backup_button_label" msgid="6009119115581097708">"Не прави резервне копије"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Захтевано је потпуно враћање свих података са повезаног рачунара. Да ли желите да дозволите то?\n\nАко нисте лично захтевали враћање, не дозвољавајте наставак радње. Тиме ћете заменити све податке који су тренутно на уређају!"</string>
-    <string name="allow_restore_button_label" msgid="3081286752277127827">"Врати моје податке"</string>
-    <string name="deny_restore_button_label" msgid="1724367334453104378">"Не враћај"</string>
-    <string name="current_password_text" msgid="8268189555578298067">"Унесите тренутну лозинку резервне копије у наставку:"</string>
-    <string name="device_encryption_restore_text" msgid="1570864916855208992">"Унесите лозинку уређаја за шифровање у наставку."</string>
-    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Унесите лозинку уређаја за шифровање. Ово ће се користити и за шифровање резервне архиве."</string>
-    <string name="backup_enc_password_text" msgid="4981585714795233099">"Унесите лозинку коју ћете користити за шифровање података потпуне резервне копије. Ако то поље оставите празно, користиће се тренутна лозинка резервне копије:"</string>
-    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Ако желите да шифрујете податке потпуне резервне копије, унесите лозинку у наставку."</string>
-    <string name="restore_enc_password_text" msgid="6140898525580710823">"Ако су подаци за враћање шифровани, унесите лозинку у наставку:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Покретање прављења резервне копије..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Резервна копија је направљена"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Покретање враћања..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Враћање је завршено"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Време за радњу је истекло"</string>
+    <string name="backup_confirm_title" msgid="827563724209303345">"Rezervna kopije svih podataka"</string>
+    <string name="restore_confirm_title" msgid="5469365809567486602">"Potpuno vraćanje"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Zahtevana je potpuna rezervna kopija svih podataka na povezani računar. Da li želite da dozvolite to?\n\nAko niste lično zahtevali rezervnu kopiju, ne dozvoljavajte nastavak radnje."</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"Napravi rezervnu kopiju mojih podataka"</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"Ne pravi rezervne kopije"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Zahtevano je potpuno vraćanje svih podataka sa povezanog računara. Da li želite da dozvolite to?\n\nAko niste lično zahtevali vraćanje, ne dozvoljavajte nastavak radnje. Time ćete zameniti sve podatke koji su trenutno na uređaju!"</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"Vrati moje podatke"</string>
+    <string name="deny_restore_button_label" msgid="1724367334453104378">"Ne vraćaj"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"Unesite trenutnu lozinku rezervne kopije u nastavku:"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"Unesite lozinku uređaja za šifrovanje u nastavku."</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Unesite lozinku uređaja za šifrovanje. Ovo će se koristiti i za šifrovanje rezervne arhive."</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"Unesite lozinku koju ćete koristiti za šifrovanje podataka potpune rezervne kopije. Ako to polje ostavite prazno, koristiće se trenutna lozinka rezervne kopije:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Ako želite da šifrujete podatke potpune rezervne kopije, unesite lozinku u nastavku."</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"Ako su podaci za vraćanje šifrovani, unesite lozinku u nastavku:"</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"Pokretanje pravljenja rezervne kopije..."</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"Rezervna kopija je napravljena"</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"Pokretanje vraćanja..."</string>
+    <string name="toast_restore_ended" msgid="1764041639199696132">"Vraćanje je završeno"</string>
+    <string name="toast_timeout" msgid="5276598587087626877">"Vreme za radnju je isteklo"</string>
 </resources>
diff --git a/packages/CarrierDefaultApp/res/values-b+sr+Latn/strings.xml b/packages/CarrierDefaultApp/res/values-b+sr+Latn/strings.xml
index 34c3bdc..5d55790 100644
--- a/packages/CarrierDefaultApp/res/values-b+sr+Latn/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-b+sr+Latn/strings.xml
@@ -2,16 +2,16 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
-    <string name="android_system_label" msgid="2797790869522345065">"Мобилни оператер"</string>
-    <string name="portal_notification_id" msgid="5155057562457079297">"Мобилни подаци су потрошени"</string>
-    <string name="no_data_notification_id" msgid="668400731803969521">"Мобилни подаци су деактивирани"</string>
-    <string name="portal_notification_detail" msgid="2295729385924660881">"Додирните да бисте посетили веб-сајт %s"</string>
-    <string name="no_data_notification_detail" msgid="3112125343857014825">"Контактирајте добављача услуге %s"</string>
-    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Нема везе за пренос података преко мобилног оператера"</string>
-    <string name="no_mobile_data_connection" msgid="544980465184147010">"Додајте податке или пакет за роминг преко оператера %s"</string>
-    <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Статус мобилних података"</string>
-    <string name="action_bar_label" msgid="4290345990334377177">"Пријавите се на мобилну мрежу"</string>
-    <string name="ssl_error_warning" msgid="3127935140338254180">"Мрежа којој покушавате да се придружите има безбедносних проблема."</string>
-    <string name="ssl_error_example" msgid="6188711843183058764">"На пример, страница за пријављивање можда не припада приказаној организацији."</string>
-    <string name="ssl_error_continue" msgid="1138548463994095584">"Ипак настави преко прегледача"</string>
+    <string name="android_system_label" msgid="2797790869522345065">"Mobilni operater"</string>
+    <string name="portal_notification_id" msgid="5155057562457079297">"Mobilni podaci su potrošeni"</string>
+    <string name="no_data_notification_id" msgid="668400731803969521">"Mobilni podaci su deaktivirani"</string>
+    <string name="portal_notification_detail" msgid="2295729385924660881">"Dodirnite da biste posetili veb-sajt %s"</string>
+    <string name="no_data_notification_detail" msgid="3112125343857014825">"Kontaktirajte dobavljača usluge %s"</string>
+    <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Nema veze za prenos podataka preko mobilnog operatera"</string>
+    <string name="no_mobile_data_connection" msgid="544980465184147010">"Dodajte podatke ili paket za roming preko operatera %s"</string>
+    <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status mobilnih podataka"</string>
+    <string name="action_bar_label" msgid="4290345990334377177">"Prijavite se na mobilnu mrežu"</string>
+    <string name="ssl_error_warning" msgid="3127935140338254180">"Mreža kojoj pokušavate da se pridružite ima bezbednosnih problema."</string>
+    <string name="ssl_error_example" msgid="6188711843183058764">"Na primer, stranica za prijavljivanje možda ne pripada prikazanoj organizaciji."</string>
+    <string name="ssl_error_continue" msgid="1138548463994095584">"Ipak nastavi preko pregledača"</string>
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-af/strings.xml b/packages/CompanionDeviceManager/res/values-af/strings.xml
index 004b563..59f3caa 100644
--- a/packages/CompanionDeviceManager/res/values-af/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-af/strings.xml
@@ -20,7 +20,7 @@
     <string name="confirmation_title" msgid="3785000297483688997">"Gee &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang tot jou &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"horlosie"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Kies \'n <xliff:g id="PROFILE_NAME">%1$s</xliff:g> om deur &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; bestuur te word"</string>
-    <string name="summary_watch" msgid="3002344206574997652">"Hierdie program is nodig om jou <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te bestuur. <xliff:g id="APP_NAME">%2$s</xliff:g> sal toegelaat word om interaksie met jou kennisgewings te hê, en sal toegang hê tot jou Foon-, SMS-, Kontakte-, Kalender- en Toestelle in die Omtrek-toestemming."</string>
+    <string name="summary_watch" msgid="3002344206574997652">"Hierdie app is nodig om jou <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te bestuur. <xliff:g id="APP_NAME">%2$s</xliff:g> sal toegelaat word om interaksie met jou kennisgewings te hê, en sal toegang hê tot jou Foon-, SMS-, Kontakte-, Kalender- en Toestelle in die Omtrek-toestemming."</string>
     <string name="permission_apps" msgid="6142133265286656158">"Programme"</string>
     <string name="permission_apps_summary" msgid="798718816711515431">"Stroom jou foon se programme"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Gee &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang tot hierdie inligting op jou foon"</string>
diff --git a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
index 354ff2c..855c4cf 100644
--- a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
@@ -16,33 +16,33 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="4470785958457506021">"Менаџер придруженог уређаја"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Дозволите да &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; приступа уређају &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="profile_name_watch" msgid="576290739483672360">"сат"</string>
-    <string name="chooser_title" msgid="2262294130493605839">"Одаберите профил <xliff:g id="PROFILE_NAME">%1$s</xliff:g> којим ће управљати апликација &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="3002344206574997652">"Ова апликација је потребна за управљање уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> ће добити дозволу за интеракцију са обавештењима и приступ дозволама за телефон, SMS, контакте, календар, евиденције позива и уређаје у близини."</string>
-    <string name="permission_apps" msgid="6142133265286656158">"Апликације"</string>
-    <string name="permission_apps_summary" msgid="798718816711515431">"Стримујте апликације на телефону"</string>
-    <string name="title_app_streaming" msgid="2270331024626446950">"Дозволите да &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; приступа овим информацијама са телефона"</string>
-    <string name="helper_title_app_streaming" msgid="4151687003439969765">"Услуге на више уређаја"</string>
-    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за стримовање апликација између уређаја"</string>
+    <string name="app_label" msgid="4470785958457506021">"Menadžer pridruženog uređaja"</string>
+    <string name="confirmation_title" msgid="3785000297483688997">"Dozvolite da &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pristupa uređaju &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="profile_name_watch" msgid="576290739483672360">"sat"</string>
+    <string name="chooser_title" msgid="2262294130493605839">"Odaberite <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kojim će upravljati aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="summary_watch" msgid="3002344206574997652">"Ova aplikacija je potrebna za upravljanje uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> će dobiti dozvolu za interakciju sa obaveštenjima i pristup dozvolama za telefon, SMS, kontakte, kalendar, evidencije poziva i uređaje u blizini."</string>
+    <string name="permission_apps" msgid="6142133265286656158">"Aplikacije"</string>
+    <string name="permission_apps_summary" msgid="798718816711515431">"Strimujte aplikacije na telefonu"</string>
+    <string name="title_app_streaming" msgid="2270331024626446950">"Dozvolite da &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pristupa ovim informacijama sa telefona"</string>
+    <string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluge na više uređaja"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za strimovanje aplikacija između uređaja"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
-    <string name="title_computer" msgid="4693714143506569253">"Дозволите да &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; приступа овим информацијама са телефона"</string>
+    <string name="title_computer" msgid="4693714143506569253">"Dozvolite da &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pristupa ovim informacijama sa telefona"</string>
     <string name="summary_computer" msgid="3798467601598297062"></string>
-    <string name="permission_notification" msgid="693762568127741203">"Обавештења"</string>
-    <string name="permission_notification_summary" msgid="884075314530071011">"Може да чита сва обавештења, укључујући информације попут контаката, порука и слика"</string>
-    <string name="permission_storage" msgid="6831099350839392343">"Слике и медији"</string>
+    <string name="permission_notification" msgid="693762568127741203">"Obaveštenja"</string>
+    <string name="permission_notification_summary" msgid="884075314530071011">"Može da čita sva obaveštenja, uključujući informacije poput kontakata, poruka i slika"</string>
+    <string name="permission_storage" msgid="6831099350839392343">"Slike i mediji"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
-    <string name="helper_title_computer" msgid="4671071173916176037">"Google Play услуге"</string>
-    <string name="helper_summary_computer" msgid="9050724687678157852">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за приступ сликама, медијском садржају и обавештењима са телефона"</string>
-    <string name="profile_name_generic" msgid="6851028682723034988">"уређај"</string>
+    <string name="helper_title_computer" msgid="4671071173916176037">"Google Play usluge"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za pristup slikama, medijskom sadržaju i obaveštenjima sa telefona"</string>
+    <string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
-    <string name="consent_yes" msgid="8344487259618762872">"Дозволи"</string>
-    <string name="consent_no" msgid="2640796915611404382">"Не дозволи"</string>
-    <string name="consent_back" msgid="2560683030046918882">"Назад"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Пренесите дозволе за апликације на сат"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Да бисмо поједноставили подешавање сата, апликације инсталиране на сату током подешавања ће користити исте дозволе као телефон.\n\n Те дозволе могу да обухватају приступ микрофону и локацији сата."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Икона апликације"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Дугме за више информација"</string>
+    <string name="consent_yes" msgid="8344487259618762872">"Dozvoli"</string>
+    <string name="consent_no" msgid="2640796915611404382">"Ne dozvoli"</string>
+    <string name="consent_back" msgid="2560683030046918882">"Nazad"</string>
+    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Prenesite dozvole za aplikacije na sat"</string>
+    <string name="permission_sync_summary" msgid="8873391306499120778">"Da bismo pojednostavili podešavanje sata, aplikacije instalirane na satu tokom podešavanja će koristiti iste dozvole kao telefon.\n\n Te dozvole mogu da obuhvataju pristup mikrofonu i lokaciji sata."</string>
+    <string name="vendor_icon_description" msgid="4445875290032225965">"Ikona aplikacije"</string>
+    <string name="vendor_header_button_description" msgid="6566660389500630608">"Dugme za više informacija"</string>
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-bs/strings.xml b/packages/CompanionDeviceManager/res/values-bs/strings.xml
index d7423ac..d1a1419 100644
--- a/packages/CompanionDeviceManager/res/values-bs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bs/strings.xml
@@ -19,8 +19,8 @@
     <string name="app_label" msgid="4470785958457506021">"Prateći upravitelj uređaja"</string>
     <string name="confirmation_title" msgid="3785000297483688997">"Dozvolite aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da pristupa uređaju &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"sat"</string>
-    <string name="chooser_title" msgid="2262294130493605839">"Odaberite uređaj <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kojim će upravljati aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="3002344206574997652">"Ova aplikacija je potrebna za upravljanje profilom: <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikaciji <xliff:g id="APP_NAME">%2$s</xliff:g> će se dozvoliti da ostvari interakciju s vašim obavještenjima i da pristupi odobrenjima za Telefon, SMS, Kontakte, Kalendar, Zapisnike poziva i Uređaje u blizini."</string>
+    <string name="chooser_title" msgid="2262294130493605839">"Odaberite uređaj \"<xliff:g id="PROFILE_NAME">%1$s</xliff:g>\" kojim će upravljati aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="summary_watch" msgid="3002344206574997652">"Ova aplikacija je potrebna za upravljanje uređajem \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". Aplikacija <xliff:g id="APP_NAME">%2$s</xliff:g> će moći stupati u interakciju s vašim obavještenjima i pristupati odobrenjima za Telefon, SMS, Kontakte, Kalendar, Zapisnike poziva i Uređaje u blizini."</string>
     <string name="permission_apps" msgid="6142133265286656158">"Aplikacije"</string>
     <string name="permission_apps_summary" msgid="798718816711515431">"Prenosite aplikacije s telefona"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Dozvolite da aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pristupa ovim informacijama s telefona"</string>
diff --git a/packages/CompanionDeviceManager/res/values-cs/strings.xml b/packages/CompanionDeviceManager/res/values-cs/strings.xml
index 51d4b74..a7fcd88 100644
--- a/packages/CompanionDeviceManager/res/values-cs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-cs/strings.xml
@@ -20,7 +20,7 @@
     <string name="confirmation_title" msgid="3785000297483688997">"Povolit aplikaci &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; přístup k vašemu zařízení &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"hodinky"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Vyberte zařízení <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, které chcete spravovat pomocí aplikace &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="3002344206574997652">"Tato aplikace je nutná ke správě zařízení <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikace <xliff:g id="APP_NAME">%2$s</xliff:g> bude moci interagovat s vašimi oznámeními a získá přístup k telefonu, SMS, kontaktům, kalendáři, seznamům hovorů a zařízením v okolí."</string>
+    <string name="summary_watch" msgid="3002344206574997652">"Tato aplikace je nutná ke správě zařízení „<xliff:g id="DEVICE_NAME">%1$s</xliff:g>“. Aplikace <xliff:g id="APP_NAME">%2$s</xliff:g> bude moci interagovat s vašimi oznámeními a získá přístup k telefonu, SMS, kontaktům, kalendáři, seznamům hovorů a zařízením v okolí."</string>
     <string name="permission_apps" msgid="6142133265286656158">"Aplikace"</string>
     <string name="permission_apps_summary" msgid="798718816711515431">"Streamujte aplikace v telefonu"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Povolte aplikaci &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; přístup k těmto informacím z vašeho telefonu"</string>
diff --git a/packages/CompanionDeviceManager/res/values-da/strings.xml b/packages/CompanionDeviceManager/res/values-da/strings.xml
index 5ba30ec..fb2398c 100644
--- a/packages/CompanionDeviceManager/res/values-da/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-da/strings.xml
@@ -19,7 +19,7 @@
     <string name="app_label" msgid="4470785958457506021">"Medfølgende enhedsadministrator"</string>
     <string name="confirmation_title" msgid="3785000297483688997">"Tillad, at &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; får adgang til dit &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ur"</string>
-    <string name="chooser_title" msgid="2262294130493605839">"Vælg den enhed (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>), som skal administreres af &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="chooser_title" msgid="2262294130493605839">"Vælg det <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, som skal administreres af &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="summary_watch" msgid="3002344206574997652">"Du skal bruge denne app for at administrere dit <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får tilladelse til at interagere med dine notifikationer og får adgang til dine tilladelser Opkald, Sms, Kalender, Opkaldshistorik og Enheder i nærheden."</string>
     <string name="permission_apps" msgid="6142133265286656158">"Apps"</string>
     <string name="permission_apps_summary" msgid="798718816711515431">"Stream din telefons apps"</string>
diff --git a/packages/CompanionDeviceManager/res/values-et/strings.xml b/packages/CompanionDeviceManager/res/values-et/strings.xml
index 1f5fdb8..d3cb03b 100644
--- a/packages/CompanionDeviceManager/res/values-et/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-et/strings.xml
@@ -19,7 +19,7 @@
     <string name="app_label" msgid="4470785958457506021">"Kaasseadme haldur"</string>
     <string name="confirmation_title" msgid="3785000297483688997">"Lubage rakendusel &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; teie seadmele &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; juurde pääseda"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"käekell"</string>
-    <string name="chooser_title" msgid="2262294130493605839">"Valige seade <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, mida haldab rakendus &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="chooser_title" msgid="2262294130493605839">"Valige <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, mida haldab rakendus &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="summary_watch" msgid="3002344206574997652">"Seda rakendust on vaja teie profiili <xliff:g id="DEVICE_NAME">%1$s</xliff:g> haldamiseks. Rakendusel <xliff:g id="APP_NAME">%2$s</xliff:g> lubatakse kasutada teie märguandeid ja pääseda juurde teie telefoni, SMS-ide, kontaktide, kalendri, kõnelogide ja läheduses olevate seadmete lubadele."</string>
     <string name="permission_apps" msgid="6142133265286656158">"Rakendused"</string>
     <string name="permission_apps_summary" msgid="798718816711515431">"Telefoni rakenduste voogesitamine"</string>
diff --git a/packages/CompanionDeviceManager/res/values-eu/strings.xml b/packages/CompanionDeviceManager/res/values-eu/strings.xml
index d5e9b07..03c32ba 100644
--- a/packages/CompanionDeviceManager/res/values-eu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml
@@ -20,7 +20,7 @@
     <string name="confirmation_title" msgid="3785000297483688997">"Eman &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; atzitzeko baimena &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aplikazioari"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"erlojua"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Aukeratu &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; aplikazioak kudeatu beharreko <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
-    <string name="summary_watch" msgid="3002344206574997652">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> kudeatzeko beharrezkoa da aplikazio hau. Jakinarazpenekin interakzioan aritzeko eta telefonoa, SMSak, kontaktuak, egutegia, deien erregistroa eta inguruko gailuak atzitzeko baimenak izango ditu <xliff:g id="APP_NAME">%2$s</xliff:g> aplikazioak."</string>
+    <string name="summary_watch" msgid="3002344206574997652">"Aplikazio hau <xliff:g id="DEVICE_NAME">%1$s</xliff:g> kudeatzeko beharrezkoa da. Jakinarazpenekin interakzioan aritzeko eta telefonoa, SMSak, kontaktuak, egutegia, deien erregistroa eta inguruko gailuak atzitzeko baimenak izango ditu <xliff:g id="APP_NAME">%2$s</xliff:g> aplikazioak."</string>
     <string name="permission_apps" msgid="6142133265286656158">"Aplikazioak"</string>
     <string name="permission_apps_summary" msgid="798718816711515431">"Igorri zuzenean telefonoko aplikazioak"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Eman informazioa telefonotik hartzeko baimena &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aplikazioari"</string>
diff --git a/packages/CompanionDeviceManager/res/values-gl/strings.xml b/packages/CompanionDeviceManager/res/values-gl/strings.xml
index aaaef4b..a89bd8a 100644
--- a/packages/CompanionDeviceManager/res/values-gl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gl/strings.xml
@@ -19,8 +19,8 @@
     <string name="app_label" msgid="4470785958457506021">"Xestor de dispositivos complementarios"</string>
     <string name="confirmation_title" msgid="3785000297483688997">"Permitir que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda ao teu dispositivo (&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;)"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"reloxo"</string>
-    <string name="chooser_title" msgid="2262294130493605839">"Escolle un perfil (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) para que o xestione a aplicación &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="3002344206574997652">"Esta aplicación é necesaria para xestionar o teu dispositivo (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>). <xliff:g id="APP_NAME">%2$s</xliff:g> poderá interactuar coas túas notificacións e acceder aos permisos do teu teléfono, das SMS, dos contactos, do calendario, dos rexistros de chamadas e dos dispositivos próximos."</string>
+    <string name="chooser_title" msgid="2262294130493605839">"Escolle un dispositivo (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) para que o xestione a aplicación &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="summary_watch" msgid="3002344206574997652">"Esta aplicación é necesaria para xestionar o teu dispositivo (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>). <xliff:g id="APP_NAME">%2$s</xliff:g> poderá interactuar coas túas notificacións e acceder aos permisos Teléfono, SMS, Contactos, Calendario, Rexistros de chamadas e Dispositivos próximos."</string>
     <string name="permission_apps" msgid="6142133265286656158">"Aplicacións"</string>
     <string name="permission_apps_summary" msgid="798718816711515431">"Emite as aplicacións do teu teléfono"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Permitir que a aplicación &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información desde o teu teléfono"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hr/strings.xml b/packages/CompanionDeviceManager/res/values-hr/strings.xml
index 7f8a589..a2ea9f1 100644
--- a/packages/CompanionDeviceManager/res/values-hr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hr/strings.xml
@@ -19,7 +19,7 @@
     <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
     <string name="confirmation_title" msgid="3785000297483688997">"Dopustite aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da pristupa vašem uređaju &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"satom"</string>
-    <string name="chooser_title" msgid="2262294130493605839">"Odaberite profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kojim će upravljati aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="chooser_title" msgid="2262294130493605839">"Odaberite <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kojim će upravljati aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="summary_watch" msgid="3002344206574997652">"Ta je aplikacija potrebna za upravljanje vašim uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikacija <xliff:g id="APP_NAME">%2$s</xliff:g> moći će stupati u interakciju s vašim obavijestima i pristupati dopuštenjima za telefon, SMS-ove, kontakte, kalendar, zapisnike poziva i uređaje u blizini."</string>
     <string name="permission_apps" msgid="6142133265286656158">"Aplikacije"</string>
     <string name="permission_apps_summary" msgid="798718816711515431">"Streaming aplikacija vašeg telefona"</string>
diff --git a/packages/CompanionDeviceManager/res/values-my/strings.xml b/packages/CompanionDeviceManager/res/values-my/strings.xml
index 1362ddf..9682741 100644
--- a/packages/CompanionDeviceManager/res/values-my/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-my/strings.xml
@@ -20,7 +20,7 @@
     <string name="confirmation_title" msgid="3785000297483688997">"သင်၏ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ကို သုံးရန် &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ကို ခွင့်ပြုပါ"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"နာရီ"</string>
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; က စီမံခန့်ခွဲရန် <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ကို ရွေးချယ်ပါ"</string>
-    <string name="summary_watch" msgid="3002344206574997652">"သင်၏ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ကို စီမံခန့်ခွဲရန် ဤအက်ပ်ကိုလိုအပ်သည်။ သင်၏ ‘ဖုန်း’၊ ‘SMS စာတိုစနစ်’၊ ‘အဆက်အသွယ်များ’၊ ‘ပြက္ခဒိန်’၊ ‘ခေါ်ဆိုမှတ်တမ်း’ နှင့် \'အနီးတစ်ဝိုက်ရှိ စက်များ\' ခွင့်ပြုချက်များကို သုံးရန်နှင့် အကြောင်းကြားချက်များကို ပြန်လှန်တုံ့ပြန်ရန် <xliff:g id="APP_NAME">%2$s</xliff:g> အား ခွင့်ပြုပါမည်။"</string>
+    <string name="summary_watch" msgid="3002344206574997652">"သင်၏ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ကို စီမံခန့်ခွဲရန် ဤအက်ပ်ကိုလိုအပ်သည်။ သင်၏ ‘ဖုန်း’၊ ‘SMS စာတိုစနစ်’၊ ‘အဆက်အသွယ်များ’၊ ‘ပြက္ခဒိန်’၊ ‘ခေါ်ဆိုမှတ်တမ်း’ နှင့် \'အနီးတစ်ဝိုက်ရှိ စက်များ\' အတွက် ခွင့်ပြုချက်များကို သုံးရန်နှင့် အကြောင်းကြားချက်များကို ပြန်လှန်တုံ့ပြန်ရန် <xliff:g id="APP_NAME">%2$s</xliff:g> အား ခွင့်ပြုပါမည်။"</string>
     <string name="permission_apps" msgid="6142133265286656158">"အက်ပ်များ"</string>
     <string name="permission_apps_summary" msgid="798718816711515431">"သင့်ဖုန်းရှိအက်ပ်များကို တိုက်ရိုက်လွှင့်နိုင်သည်"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ကို သင့်ဖုန်းမှ ဤအချက်အလက် သုံးခွင့်ပြုမည်"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sl/strings.xml b/packages/CompanionDeviceManager/res/values-sl/strings.xml
index 9ba67c4..67881fa 100644
--- a/packages/CompanionDeviceManager/res/values-sl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sl/strings.xml
@@ -19,7 +19,7 @@
     <string name="app_label" msgid="4470785958457506021">"Upravitelj spremljevalnih naprav"</string>
     <string name="confirmation_title" msgid="3785000297483688997">"Aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; dovolite dostop do naprave &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ura"</string>
-    <string name="chooser_title" msgid="2262294130493605839">"Izbira naprave <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, ki jo bo upravljala aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="chooser_title" msgid="2262294130493605839">"Izbira naprave »<xliff:g id="PROFILE_NAME">%1$s</xliff:g>«, ki jo bo upravljala aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="summary_watch" msgid="3002344206574997652">"Ta aplikacija je potrebna za upravljanje naprave »<xliff:g id="DEVICE_NAME">%1$s</xliff:g>«. Aplikaciji <xliff:g id="APP_NAME">%2$s</xliff:g> bosta omogočena interakcija z obvestili in uporaba dovoljenj Telefon, SMS, Stiki, Koledar, Dnevniki klicev in Naprave v bližini."</string>
     <string name="permission_apps" msgid="6142133265286656158">"Aplikacije"</string>
     <string name="permission_apps_summary" msgid="798718816711515431">"Pretočno predvajanje aplikacij telefona"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sq/strings.xml b/packages/CompanionDeviceManager/res/values-sq/strings.xml
index a3258e0..082f7b5 100644
--- a/packages/CompanionDeviceManager/res/values-sq/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sq/strings.xml
@@ -19,7 +19,7 @@
     <string name="app_label" msgid="4470785958457506021">"Menaxheri i pajisjes shoqëruese"</string>
     <string name="confirmation_title" msgid="3785000297483688997">"Lejo që &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; të ketë qasje te &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ora inteligjente"</string>
-    <string name="chooser_title" msgid="2262294130493605839">"Zgjidh një profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> që do të menaxhohet nga &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="chooser_title" msgid="2262294130493605839">"Zgjidh \"<xliff:g id="PROFILE_NAME">%1$s</xliff:g>\" që do të menaxhohet nga &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="summary_watch" msgid="3002344206574997652">"Ky aplikacion nevojitet për të menaxhuar profilin tënd të <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> do të lejohet të ndërveprojë me njoftimet e tua dhe të ketë qasje te lejet e \"Telefonit\", \"SMS-ve\", \"Kontakteve\", \"Kalendarit\", \"Evidencave të telefonatave\" dhe \"Pajisjeve në afërsi\"."</string>
     <string name="permission_apps" msgid="6142133265286656158">"Aplikacionet"</string>
     <string name="permission_apps_summary" msgid="798718816711515431">"Transmeto aplikacionet e telefonit tënd"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sr/strings.xml b/packages/CompanionDeviceManager/res/values-sr/strings.xml
index 354ff2c..160f4ee 100644
--- a/packages/CompanionDeviceManager/res/values-sr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sr/strings.xml
@@ -19,7 +19,7 @@
     <string name="app_label" msgid="4470785958457506021">"Менаџер придруженог уређаја"</string>
     <string name="confirmation_title" msgid="3785000297483688997">"Дозволите да &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; приступа уређају &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"сат"</string>
-    <string name="chooser_title" msgid="2262294130493605839">"Одаберите профил <xliff:g id="PROFILE_NAME">%1$s</xliff:g> којим ће управљати апликација &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="chooser_title" msgid="2262294130493605839">"Одаберите <xliff:g id="PROFILE_NAME">%1$s</xliff:g> којим ће управљати апликација &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="summary_watch" msgid="3002344206574997652">"Ова апликација је потребна за управљање уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> ће добити дозволу за интеракцију са обавештењима и приступ дозволама за телефон, SMS, контакте, календар, евиденције позива и уређаје у близини."</string>
     <string name="permission_apps" msgid="6142133265286656158">"Апликације"</string>
     <string name="permission_apps_summary" msgid="798718816711515431">"Стримујте апликације на телефону"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ta/strings.xml b/packages/CompanionDeviceManager/res/values-ta/strings.xml
index da2ea44..30ed5cf 100644
--- a/packages/CompanionDeviceManager/res/values-ta/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ta/strings.xml
@@ -19,7 +19,7 @@
     <string name="app_label" msgid="4470785958457506021">"கம்பேனியன் சாதன நிர்வாகி"</string>
     <string name="confirmation_title" msgid="3785000297483688997">"உங்கள் &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; சாதனத்தை அணுக &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ஆப்ஸை அனுமதியுங்கள்"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"வாட்ச்"</string>
-    <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; ஆப்ஸ் நிர்வகிக்கக்கூடிய <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ஐத் தேர்ந்தெடுங்கள்"</string>
+    <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; ஆப்ஸ் நிர்வகிக்கக்கூடிய <xliff:g id="PROFILE_NAME">%1$s</xliff:g> தேர்ந்தெடுக்கப்பட வேண்டும்"</string>
     <string name="summary_watch" msgid="3002344206574997652">"உங்கள் <xliff:g id="DEVICE_NAME">%1$s</xliff:g> சாதனத்தை நிர்வகிக்க இந்த ஆப்ஸ் தேவைப்படுகிறது. உங்கள் அறிவிப்புகளைப் பயன்படுத்துவதற்கான அனுமதியையும் மொபைல், மெசேஜ், தொடர்புகள், கேலெண்டர், அழைப்புப் பதிவுகள், அருகிலுள்ள சாதனங்கள் ஆகியவற்றின் அனுமதிகளுக்கான அணுகலையும் <xliff:g id="APP_NAME">%2$s</xliff:g> ஆப்ஸ் பெறும்."</string>
     <string name="permission_apps" msgid="6142133265286656158">"ஆப்ஸ்"</string>
     <string name="permission_apps_summary" msgid="798718816711515431">"உங்கள் மொபைலின் ஆப்ஸை ஸ்ட்ரீம் செய்யலாம்"</string>
diff --git a/packages/DynamicSystemInstallationService/res/values-b+sr+Latn/strings.xml b/packages/DynamicSystemInstallationService/res/values-b+sr+Latn/strings.xml
index e0c6b2f..0e770da 100644
--- a/packages/DynamicSystemInstallationService/res/values-b+sr+Latn/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-b+sr+Latn/strings.xml
@@ -1,17 +1,17 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="keyguard_description" msgid="8582605799129954556">"Унесите лозинку и наставите до динамичних ажурирања система"</string>
-    <string name="notification_install_completed" msgid="6252047868415172643">"Динамични систем је спреман. Да бисте почели да га користите, рестартујте уређај."</string>
-    <string name="notification_install_inprogress" msgid="7383334330065065017">"Инсталира се"</string>
-    <string name="notification_install_failed" msgid="4066039210317521404">"Инсталирање није успело"</string>
-    <string name="notification_image_validation_failed" msgid="2720357826403917016">"Валидација слике диска није успела. Откажите инсталацију."</string>
-    <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Тренутно је покренут динамични систем. Рестартујте да бисте користили оригиналну верзију Android-а."</string>
-    <string name="notification_action_cancel" msgid="5929299408545961077">"Откажи"</string>
-    <string name="notification_action_discard" msgid="1817481003134947493">"Одбаци"</string>
-    <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Рестартуј"</string>
-    <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Рестартуј"</string>
-    <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Динамични систем је одбачен"</string>
-    <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Рестартовање или учитавање динамичног система није успело"</string>
-    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Онемогућавање динамичног система није успело"</string>
+    <string name="keyguard_description" msgid="8582605799129954556">"Unesite lozinku i nastavite do dinamičnih ažuriranja sistema"</string>
+    <string name="notification_install_completed" msgid="6252047868415172643">"Dinamični sistem je spreman. Da biste počeli da ga koristite, restartujte uređaj."</string>
+    <string name="notification_install_inprogress" msgid="7383334330065065017">"Instalira se"</string>
+    <string name="notification_install_failed" msgid="4066039210317521404">"Instaliranje nije uspelo"</string>
+    <string name="notification_image_validation_failed" msgid="2720357826403917016">"Validacija slike diska nije uspela. Otkažite instalaciju."</string>
+    <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Trenutno je pokrenut dinamični sistem. Restartujte da biste koristili originalnu verziju Android-a."</string>
+    <string name="notification_action_cancel" msgid="5929299408545961077">"Otkaži"</string>
+    <string name="notification_action_discard" msgid="1817481003134947493">"Odbaci"</string>
+    <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Restartuj"</string>
+    <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Restartuj"</string>
+    <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dinamični sistem je odbačen"</string>
+    <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Restartovanje ili učitavanje dinamičnog sistema nije uspelo"</string>
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Onemogućavanje dinamičnog sistema nije uspelo"</string>
 </resources>
diff --git a/packages/InputDevices/res/values-b+sr+Latn/strings.xml b/packages/InputDevices/res/values-b+sr+Latn/strings.xml
index 973b833..1fc84f3 100644
--- a/packages/InputDevices/res/values-b+sr+Latn/strings.xml
+++ b/packages/InputDevices/res/values-b+sr+Latn/strings.xml
@@ -1,53 +1,53 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="8016145283189546017">"Улазни уређаји"</string>
-    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android тастатура"</string>
-    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"енглеска (УК)"</string>
-    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"енглеска (САД)"</string>
-    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"енглеска (САД), међународни стил"</string>
-    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"енглеска (САД), Colemak стил"</string>
-    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"енглеска (САД), Dvorak стил"</string>
-    <string name="keyboard_layout_english_us_workman_label" msgid="2944541595262173111">"енглеска (САД), Workman стил"</string>
-    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"немачка"</string>
-    <string name="keyboard_layout_french_label" msgid="813450119589383723">"француска"</string>
-    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"француска (Канада)"</string>
-    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"руска"</string>
-    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"руска, Mac стил"</string>
-    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"шпанска"</string>
-    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"швајцарско француска"</string>
-    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"швајцарско немачка"</string>
-    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"белгијска"</string>
-    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"бугарска"</string>
-    <string name="keyboard_layout_bulgarian_phonetic" msgid="7568914730360106653">"бугарска фонетска"</string>
-    <string name="keyboard_layout_italian" msgid="6497079660449781213">"италијанска"</string>
-    <string name="keyboard_layout_danish" msgid="8036432066627127851">"данска"</string>
-    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"норвешка"</string>
-    <string name="keyboard_layout_swedish" msgid="732959109088479351">"шведска"</string>
-    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"финска"</string>
-    <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_hungarian" msgid="4154963661406035109">"мађарска"</string>
-    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"исландска"</string>
-    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"бразилска"</string>
-    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"португалска"</string>
-    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"словачка"</string>
-    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"словеначка"</string>
-    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"турска"</string>
-    <string name="keyboard_layout_turkish_f" msgid="9130320856010776018">"турска F"</string>
-    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"украјинска"</string>
-    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"арапски"</string>
-    <string name="keyboard_layout_greek" msgid="7289253560162386040">"грчки"</string>
-    <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"хебрејски"</string>
-    <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"литвански"</string>
-    <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"шпански (Латинска Америка)"</string>
-    <string name="keyboard_layout_latvian" msgid="4405417142306250595">"летонски"</string>
-    <string name="keyboard_layout_persian" msgid="3920643161015888527">"персијска"</string>
-    <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"азербејџанска"</string>
-    <string name="keyboard_layout_polish" msgid="1121588624094925325">"пољски"</string>
-    <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"белоруски"</string>
-    <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"монголска"</string>
-    <string name="keyboard_layout_georgian" msgid="4596185456863747454">"грузијска"</string>
+    <string name="app_label" msgid="8016145283189546017">"Ulazni uređaji"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android tastatura"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"engleska (UK)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"engleska (SAD)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"engleska (SAD), međunarodni stil"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"engleska (SAD), Colemak stil"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"engleska (SAD), Dvorak stil"</string>
+    <string name="keyboard_layout_english_us_workman_label" msgid="2944541595262173111">"engleska (SAD), Workman stil"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"nemačka"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"francuska"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"francuska (Kanada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"ruska"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"ruska, Mac stil"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"španska"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"švajcarsko francuska"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"švajcarsko nemačka"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"belgijska"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"bugarska"</string>
+    <string name="keyboard_layout_bulgarian_phonetic" msgid="7568914730360106653">"bugarska fonetska"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"italijanska"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"danska"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"norveška"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"švedska"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"finska"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"hrvatska"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"češka"</string>
+    <string name="keyboard_layout_czech_qwerty" msgid="3331402534128515501">"Stil češke QWERTY tastature"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"estonska"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"mađarska"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"islandska"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"brazilska"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"portugalska"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"slovačka"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"slovenačka"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"turska"</string>
+    <string name="keyboard_layout_turkish_f" msgid="9130320856010776018">"turska F"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"ukrajinska"</string>
+    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"arapski"</string>
+    <string name="keyboard_layout_greek" msgid="7289253560162386040">"grčki"</string>
+    <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"hebrejski"</string>
+    <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"litvanski"</string>
+    <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"španski (Latinska Amerika)"</string>
+    <string name="keyboard_layout_latvian" msgid="4405417142306250595">"letonski"</string>
+    <string name="keyboard_layout_persian" msgid="3920643161015888527">"persijska"</string>
+    <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"azerbejdžanska"</string>
+    <string name="keyboard_layout_polish" msgid="1121588624094925325">"poljski"</string>
+    <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"beloruski"</string>
+    <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"mongolska"</string>
+    <string name="keyboard_layout_georgian" msgid="4596185456863747454">"gruzijska"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml b/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
index d964d3f..f646b20 100644
--- a/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
+++ b/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
@@ -16,81 +16,81 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="7488448184431507488">"Програм за инстал. пакета"</string>
-    <string name="install" msgid="711829760615509273">"Инсталирај"</string>
-    <string name="update" msgid="3932142540719227615">"Ажурирај"</string>
-    <string name="done" msgid="6632441120016885253">"Готово"</string>
-    <string name="cancel" msgid="1018267193425558088">"Откажи"</string>
-    <string name="installing" msgid="4921993079741206516">"Инсталира се..."</string>
-    <string name="installing_app" msgid="1165095864863849422">"Инсталира се <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="5987363587661783896">"Апликација је инсталирана."</string>
-    <string name="install_confirm_question" msgid="7663733664476363311">"Желите да инсталирате ову апликацију?"</string>
-    <string name="install_confirm_question_update" msgid="3348888852318388584">"Желите да ажурирате ову апликацију?"</string>
-    <string name="install_failed" msgid="5777824004474125469">"Апликација није инсталирана."</string>
-    <string name="install_failed_blocked" msgid="8512284352994752094">"Инсталирање пакета је блокирано."</string>
-    <string name="install_failed_conflict" msgid="3493184212162521426">"Апликација није инсталирана јер је пакет неусаглашен са постојећим пакетом."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Апликација није инсталирана јер није компатибилна са таблетом."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Ова апликација није компатибилна са ТВ-ом."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Апликација није инсталирана јер није компатибилна са телефоном."</string>
-    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Апликација није инсталирана јер је пакет неважећи."</string>
-    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Нисмо успели да инсталирамо апликацију <xliff:g id="APP_NAME">%1$s</xliff:g> на таблет."</string>
-    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Нисмо успели да инсталирамо апликацију <xliff:g id="APP_NAME">%1$s</xliff:g> на ТВ."</string>
-    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Нисмо успели да инсталирамо апликацију <xliff:g id="APP_NAME">%1$s</xliff:g> на телефон."</string>
-    <string name="launch" msgid="3952550563999890101">"Отвори"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Администратор не дозвољава инсталирање апликација добијених из непознатих извора"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Овај корисник не може да инсталира непознате апликације"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Овом кориснику није дозвољено да инсталира апликације"</string>
-    <string name="ok" msgid="7871959885003339302">"Потврди"</string>
-    <string name="manage_applications" msgid="5400164782453975580">"Управљајте апл."</string>
-    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Нема више простора"</string>
-    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Нисмо успели да инсталирамо апликацију <xliff:g id="APP_NAME">%1$s</xliff:g>. Ослободите простор и пробајте поново."</string>
-    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Апликација није пронађена"</string>
-    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Апликација није пронађена на листи инсталираних апликација."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Није дозвољено"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Актуелном кориснику није дозвољено да обави ово деинсталирање."</string>
-    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Грешка"</string>
-    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Деинсталирање апликације није успело."</string>
-    <string name="uninstall_application_title" msgid="4045420072401428123">"Деинсталирај апликацију"</string>
-    <string name="uninstall_update_title" msgid="824411791011583031">"Деинсталирај ажурирање"</string>
-    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> је део следеће апликације:"</string>
-    <string name="uninstall_application_text" msgid="3816830743706143980">"Желите да деинсталирате ову апликацију?"</string>
-    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Да ли желите да деинсталирате ову апликацију за "<b>"све"</b>" кориснике? Апликација и подаци уз ње биће уклоњени за "<b>"све"</b>" кориснике овог уређаја."</string>
-    <string name="uninstall_application_text_user" msgid="498072714173920526">"Желите ли да деинсталирате ову апликацију за корисника <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_application_text_current_user_work_profile" msgid="8788387739022366193">"Да ли желите да деинсталирате ову апликацију са пословног профила?"</string>
-    <string name="uninstall_update_text" msgid="863648314632448705">"Желите ли да замените ову апликацију фабричком верзијом? Сви подаци ће бити уклоњени."</string>
-    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Желите ли да замените ову апликацију фабричком верзијом? Сви подаци ће бити уклоњени. Ово утиче на све кориснике овог уређаја, укључујући и оне са пословним профилима."</string>
-    <string name="uninstall_keep_data" msgid="7002379587465487550">"Задржи <xliff:g id="SIZE">%1$s</xliff:g> података апликације."</string>
-    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Активна деинсталирања"</string>
-    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Неуспела деинсталирања"</string>
-    <string name="uninstalling" msgid="8709566347688966845">"Деинсталира се…"</string>
-    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> се деинсталира…"</string>
-    <string name="uninstall_done" msgid="439354138387969269">"Деинсталирање је завршено."</string>
-    <string name="uninstall_done_app" msgid="4588850984473605768">"Апликација <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> је деинсталирана"</string>
-    <string name="uninstall_failed" msgid="1847750968168364332">"Деинсталирање није успело."</string>
-    <string name="uninstall_failed_app" msgid="5506028705017601412">"Деинсталирање апликације <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> није успело."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Не можете да деинсталирате апликацију за активног администратора уређаја"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Не можете да деинсталирате апликацију за активног администратора уређаја за <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Ова апликација је обавезна за неке кориснике или профиле, а деинсталирана је за друге"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Ова апликација је обавезна за ваш профил и не може да се деинсталира."</string>
-    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Ова апликација је обавезна за администратора уређаја и не може да се деинсталира."</string>
-    <string name="manage_device_administrators" msgid="3092696419363842816">"Управљајте апликацијама администратора уређаја"</string>
-    <string name="manage_users" msgid="1243995386982560813">"Управљаjте корисницима"</string>
-    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Нисмо успели да деинсталирамо апликацију <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Дошло је до проблема при рашчлањивању пакета."</string>
+    <string name="app_name" msgid="7488448184431507488">"Program za instal. paketa"</string>
+    <string name="install" msgid="711829760615509273">"Instaliraj"</string>
+    <string name="update" msgid="3932142540719227615">"Ažuriraj"</string>
+    <string name="done" msgid="6632441120016885253">"Gotovo"</string>
+    <string name="cancel" msgid="1018267193425558088">"Otkaži"</string>
+    <string name="installing" msgid="4921993079741206516">"Instalira se..."</string>
+    <string name="installing_app" msgid="1165095864863849422">"Instalira se <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Aplikacija je instalirana."</string>
+    <string name="install_confirm_question" msgid="7663733664476363311">"Želite da instalirate ovu aplikaciju?"</string>
+    <string name="install_confirm_question_update" msgid="3348888852318388584">"Želite da ažurirate ovu aplikaciju?"</string>
+    <string name="install_failed" msgid="5777824004474125469">"Aplikacija nije instalirana."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Instaliranje paketa je blokirano."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacija nije instalirana jer je paket neusaglašen sa postojećim paketom."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Aplikacija nije instalirana jer nije kompatibilna sa tabletom."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Ova aplikacija nije kompatibilna sa TV-om."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Aplikacija nije instalirana jer nije kompatibilna sa telefonom."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Aplikacija nije instalirana jer je paket nevažeći."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Nismo uspeli da instaliramo aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> na tablet."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Nismo uspeli da instaliramo aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> na TV."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Nismo uspeli da instaliramo aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> na telefon."</string>
+    <string name="launch" msgid="3952550563999890101">"Otvori"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Administrator ne dozvoljava instaliranje aplikacija dobijenih iz nepoznatih izvora"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Ovaj korisnik ne može da instalira nepoznate aplikacije"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Ovom korisniku nije dozvoljeno da instalira aplikacije"</string>
+    <string name="ok" msgid="7871959885003339302">"Potvrdi"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Upravljajte apl."</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Nema više prostora"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Nismo uspeli da instaliramo aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>. Oslobodite prostor i probajte ponovo."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Aplikacija nije pronađena"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Aplikacija nije pronađena na listi instaliranih aplikacija."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Nije dozvoljeno"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Aktuelnom korisniku nije dozvoljeno da obavi ovo deinstaliranje."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Greška"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Deinstaliranje aplikacije nije uspelo."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Deinstaliraj aplikaciju"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Deinstaliraj ažuriranje"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> je deo sledeće aplikacije:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Želite da deinstalirate ovu aplikaciju?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Da li želite da deinstalirate ovu aplikaciju za "<b>"sve"</b>" korisnike? Aplikacija i podaci uz nje biće uklonjeni za "<b>"sve"</b>" korisnike ovog uređaja."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Želite li da deinstalirate ovu aplikaciju za korisnika <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_application_text_current_user_work_profile" msgid="8788387739022366193">"Da li želite da deinstalirate ovu aplikaciju sa poslovnog profila?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Želite li da zamenite ovu aplikaciju fabričkom verzijom? Svi podaci će biti uklonjeni."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Želite li da zamenite ovu aplikaciju fabričkom verzijom? Svi podaci će biti uklonjeni. Ovo utiče na sve korisnike ovog uređaja, uključujući i one sa poslovnim profilima."</string>
+    <string name="uninstall_keep_data" msgid="7002379587465487550">"Zadrži <xliff:g id="SIZE">%1$s</xliff:g> podataka aplikacije."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Aktivna deinstaliranja"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Neuspela deinstaliranja"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Deinstalira se…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> se deinstalira…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Deinstaliranje je završeno."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Aplikacija <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> je deinstalirana"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Deinstaliranje nije uspelo."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Deinstaliranje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nije uspelo."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Ne možete da deinstalirate aplikaciju za aktivnog administratora uređaja"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Ne možete da deinstalirate aplikaciju za aktivnog administratora uređaja za <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Ova aplikacija je obavezna za neke korisnike ili profile, a deinstalirana je za druge"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Ova aplikacija je obavezna za vaš profil i ne može da se deinstalira."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Ova aplikacija je obavezna za administratora uređaja i ne može da se deinstalira."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Upravljajte aplikacijama administratora uređaja"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Upravljajte korisnicima"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Nismo uspeli da deinstaliramo aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Došlo je do problema pri raščlanjivanju paketa."</string>
     <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Радње Инсталирај/Деинсталирај нису подржане у Wear-у."</string>
-    <string name="message_staging" msgid="8032722385658438567">"Апликација се припрема…"</string>
-    <string name="app_name_unknown" msgid="6881210203354323926">"Непознато"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"Из безбедносних разлога таблету тренутно није дозвољено да инсталира непознате апликације из овог извора. То можете да промените у подешавањима."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"Из безбедносних разлога телевизору тренутно није дозвољено да инсталира непознате апликације из овог извора. То можете да промените у подешавањима."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"Из безбедносних разлога телефону тренутно није дозвољено да инсталира непознате апликације из овог извора. То можете да промените у подешавањима."</string>
-    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Телефон и лични подаци су подложнији нападу непознатих апликација. Ако инсталирате ову апликацију, прихватате да сте одговорни за евентуална оштећења телефона или губитак података до којих може да дође због њеног коришћења."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Таблет и лични подаци су подложнији нападу непознатих апликација. Ако инсталирате ову апликацију, прихватате да сте одговорни за евентуална оштећења таблета или губитак података до којих може да дође због њеног коришћења."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"ТВ и лични подаци су подложнији нападу непознатих апликација. Ако инсталирате ову апликацију, прихватате да сте одговорни за евентуална оштећења ТВ-а или губитак података до којих може да дође због њеног коришћења."</string>
-    <string name="anonymous_source_continue" msgid="4375745439457209366">"Настави"</string>
-    <string name="external_sources_settings" msgid="4046964413071713807">"Подешавања"</string>
-    <string name="wear_app_channel" msgid="1960809674709107850">"Инсталирање/деинсталирање Wear апликац."</string>
-    <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Обавештење о инсталирању апликације"</string>
-    <string name="notification_installation_success_message" msgid="6450467996056038442">"Инсталирана је"</string>
-    <string name="notification_installation_success_status" msgid="3172502643504323321">"Апликација „<xliff:g id="APPNAME">%1$s</xliff:g>“ је инсталирана"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Radnje Instaliraj/Deinstaliraj nisu podržane u Wear-u."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Aplikacija se priprema…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Nepoznato"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"Iz bezbednosnih razloga tabletu trenutno nije dozvoljeno da instalira nepoznate aplikacije iz ovog izvora. To možete da promenite u podešavanjima."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"Iz bezbednosnih razloga televizoru trenutno nije dozvoljeno da instalira nepoznate aplikacije iz ovog izvora. To možete da promenite u podešavanjima."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"Iz bezbednosnih razloga telefonu trenutno nije dozvoljeno da instalira nepoznate aplikacije iz ovog izvora. To možete da promenite u podešavanjima."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Telefon i lični podaci su podložniji napadu nepoznatih aplikacija. Ako instalirate ovu aplikaciju, prihvatate da ste odgovorni za eventualna oštećenja telefona ili gubitak podataka do kojih može da dođe zbog njenog korišćenja."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Tablet i lični podaci su podložniji napadu nepoznatih aplikacija. Ako instalirate ovu aplikaciju, prihvatate da ste odgovorni za eventualna oštećenja tableta ili gubitak podataka do kojih može da dođe zbog njenog korišćenja."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"TV i lični podaci su podložniji napadu nepoznatih aplikacija. Ako instalirate ovu aplikaciju, prihvatate da ste odgovorni za eventualna oštećenja TV-a ili gubitak podataka do kojih može da dođe zbog njenog korišćenja."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Nastavi"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Podešavanja"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Instaliranje/deinstaliranje Wear aplikac."</string>
+    <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Obaveštenje o instaliranju aplikacije"</string>
+    <string name="notification_installation_success_message" msgid="6450467996056038442">"Instalirana je"</string>
+    <string name="notification_installation_success_status" msgid="3172502643504323321">"Aplikacija „<xliff:g id="APPNAME">%1$s</xliff:g>“ je instalirana"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ky/strings.xml b/packages/PackageInstaller/res/values-ky/strings.xml
index 2684fd9..0f19fe8 100644
--- a/packages/PackageInstaller/res/values-ky/strings.xml
+++ b/packages/PackageInstaller/res/values-ky/strings.xml
@@ -88,7 +88,7 @@
     <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Планшетиңиз жана жеке дайын-даректериңиз белгисиз колдонмолордон зыян тартып калышы мүмкүн. Бул колдонмону орнотуп, аны пайдалануудан улам планшетиңизге кандайдыр бир зыян келтирилсе же дайын-даректериңизды жоготуп алсаңыз, өзүңүз жооптуу болосуз."</string>
     <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Сыналгыңыз жана жеке дайын-даректериңиз белгисиз колдонмолордон зыян тартып калышы мүмкүн. Бул колдонмону орнотуп, аны пайдалануудан улам сыналгыңызга кандайдыр бир зыян келтирилсе же дайын-даректериңизды жоготуп алсаңыз, өзүңүз жооптуу болосуз."</string>
     <string name="anonymous_source_continue" msgid="4375745439457209366">"Улантуу"</string>
-    <string name="external_sources_settings" msgid="4046964413071713807">"Жөндөөлөр"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Параметрлер"</string>
     <string name="wear_app_channel" msgid="1960809674709107850">"Тагынма колдонмолорду орнотуу/чыгаруу"</string>
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Колдонмолорду орноткучтун билдирмелери"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Ийгиликтүү орнотулду"</string>
diff --git a/packages/PackageInstaller/res/values-tl/strings.xml b/packages/PackageInstaller/res/values-tl/strings.xml
index 5606eb5..fc50ce2 100644
--- a/packages/PackageInstaller/res/values-tl/strings.xml
+++ b/packages/PackageInstaller/res/values-tl/strings.xml
@@ -43,7 +43,7 @@
     <string name="ok" msgid="7871959885003339302">"OK"</string>
     <string name="manage_applications" msgid="5400164782453975580">"Pamahalaan ang app"</string>
     <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Wala nang espasyo"</string>
-    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Hindi ma-install ang <xliff:g id="APP_NAME">%1$s</xliff:g>. Magbakante ng ilang espasyo at subukang muli."</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Hindi ma-install ang <xliff:g id="APP_NAME">%1$s</xliff:g>. Magbakante ng ilang espasyo at subukan ulit."</string>
     <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Hindi nakita ang app"</string>
     <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Hindi nakita ang app sa listahan ng mga naka-install na app."</string>
     <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Hindi pinapayagan"</string>
diff --git a/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml b/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
index bc29999..07615ae 100644
--- a/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
+++ b/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
@@ -16,98 +16,98 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="4469836075319831821">"Штампање из меморије"</string>
-    <string name="more_options_button" msgid="2243228396432556771">"Још опција"</string>
-    <string name="label_destination" msgid="9132510997381599275">"Одредиште"</string>
-    <string name="label_copies" msgid="3634531042822968308">"Копије"</string>
-    <string name="label_copies_summary" msgid="3861966063536529540">"Копија:"</string>
-    <string name="label_paper_size" msgid="908654383827777759">"Величина папира"</string>
-    <string name="label_paper_size_summary" msgid="5668204981332138168">"Величина папира:"</string>
-    <string name="label_color" msgid="1108690305218188969">"Боја"</string>
-    <string name="label_duplex" msgid="5370037254347072243">"Двострано"</string>
-    <string name="label_orientation" msgid="2853142581990496477">"Положај"</string>
-    <string name="label_pages" msgid="7768589729282182230">"Странице"</string>
-    <string name="destination_default_text" msgid="5422708056807065710">"Изаберите штампач"</string>
-    <string name="template_all_pages" msgid="3322235982020148762">"Све странице (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
-    <string name="template_page_range" msgid="428638530038286328">"Опсег од <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
-    <string name="pages_range_example" msgid="8558694453556945172">"нпр. 1–5, 8, 11–13"</string>
-    <string name="print_preview" msgid="8010217796057763343">"Преглед пре штампања"</string>
-    <string name="install_for_print_preview" msgid="6366303997385509332">"Инсталирај PDF приказивач за преглед"</string>
-    <string name="printing_app_crashed" msgid="854477616686566398">"Апликација за штампање је отказала"</string>
-    <string name="generating_print_job" msgid="3119608742651698916">"Генерисање задатка за штампање"</string>
-    <string name="save_as_pdf" msgid="5718454119847596853">"Сачувај као PDF"</string>
-    <string name="all_printers" msgid="5018829726861876202">"Сви штампачи…"</string>
-    <string name="print_dialog" msgid="32628687461331979">"Дијалог за штампање"</string>
+    <string name="app_label" msgid="4469836075319831821">"Štampanje iz memorije"</string>
+    <string name="more_options_button" msgid="2243228396432556771">"Još opcija"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Odredište"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Kopije"</string>
+    <string name="label_copies_summary" msgid="3861966063536529540">"Kopija:"</string>
+    <string name="label_paper_size" msgid="908654383827777759">"Veličina papira"</string>
+    <string name="label_paper_size_summary" msgid="5668204981332138168">"Veličina papira:"</string>
+    <string name="label_color" msgid="1108690305218188969">"Boja"</string>
+    <string name="label_duplex" msgid="5370037254347072243">"Dvostrano"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Položaj"</string>
+    <string name="label_pages" msgid="7768589729282182230">"Stranice"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Izaberite štampač"</string>
+    <string name="template_all_pages" msgid="3322235982020148762">"Sve stranice (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="template_page_range" msgid="428638530038286328">"Opseg od <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"npr. 1–5, 8, 11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Pregled pre štampanja"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Instaliraj PDF prikazivač za pregled"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Aplikacija za štampanje je otkazala"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Generisanje zadatka za štampanje"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Sačuvaj kao PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Svi štampači…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Dijalog za štampanje"</string>
     <string name="current_page_template" msgid="5145005201131935302">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g>/<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
-    <string name="page_description_template" msgid="6831239682256197161">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g>. страница од <xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
-    <string name="summary_template" msgid="8899734908625669193">"Резиме, копије (<xliff:g id="COPIES">%1$s</xliff:g>), величина папира <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
-    <string name="expand_handle" msgid="7282974448109280522">"Регулатор за ширење"</string>
-    <string name="collapse_handle" msgid="6886637989442507451">"Регулатор за скупљање"</string>
-    <string name="print_button" msgid="645164566271246268">"Штампај"</string>
-    <string name="savetopdf_button" msgid="2976186791686924743">"Сачувај у PDF-у"</string>
-    <string name="print_options_expanded" msgid="6944679157471691859">"Опције штампања су проширене"</string>
-    <string name="print_options_collapsed" msgid="7455930445670414332">"Опције штампања су скупљене"</string>
-    <string name="search" msgid="5421724265322228497">"Претражи"</string>
-    <string name="all_printers_label" msgid="3178848870161526399">"Сви штампачи"</string>
-    <string name="add_print_service_label" msgid="5356702546188981940">"Додај услугу"</string>
-    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Оквир за претрагу је приказан"</string>
-    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Оквир за претрагу је сакривен"</string>
-    <string name="print_add_printer" msgid="1088656468360653455">"Додај штампач"</string>
-    <string name="print_select_printer" msgid="7388760939873368698">"Изабери штампач"</string>
-    <string name="print_forget_printer" msgid="5035287497291910766">"Заборави штампач"</string>
+    <string name="page_description_template" msgid="6831239682256197161">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g>. stranica od <xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+    <string name="summary_template" msgid="8899734908625669193">"Rezime, kopije (<xliff:g id="COPIES">%1$s</xliff:g>), veličina papira <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+    <string name="expand_handle" msgid="7282974448109280522">"Regulator za širenje"</string>
+    <string name="collapse_handle" msgid="6886637989442507451">"Regulator za skupljanje"</string>
+    <string name="print_button" msgid="645164566271246268">"Štampaj"</string>
+    <string name="savetopdf_button" msgid="2976186791686924743">"Sačuvaj u PDF-u"</string>
+    <string name="print_options_expanded" msgid="6944679157471691859">"Opcije štampanja su proširene"</string>
+    <string name="print_options_collapsed" msgid="7455930445670414332">"Opcije štampanja su skupljene"</string>
+    <string name="search" msgid="5421724265322228497">"Pretraži"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Svi štampači"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Dodaj uslugu"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Okvir za pretragu je prikazan"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Okvir za pretragu je sakriven"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Dodaj štampač"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Izaberi štampač"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Zaboravi štampač"</string>
     <plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
-      <item quantity="one">Пронађен је <xliff:g id="COUNT_1">%1$s</xliff:g> штампач</item>
-      <item quantity="few">Пронађена су <xliff:g id="COUNT_1">%1$s</xliff:g> штампача</item>
-      <item quantity="other">Пронађено је <xliff:g id="COUNT_1">%1$s</xliff:g> штампача</item>
+      <item quantity="one">Pronađen je <xliff:g id="COUNT_1">%1$s</xliff:g> štampač</item>
+      <item quantity="few">Pronađena su <xliff:g id="COUNT_1">%1$s</xliff:g> štampača</item>
+      <item quantity="other">Pronađeno je <xliff:g id="COUNT_1">%1$s</xliff:g> štampača</item>
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
-    <string name="printer_info_desc" msgid="7181988788991581654">"Још информација о овом штампачу"</string>
-    <string name="notification_channel_progress" msgid="872788690775721436">"Активни задаци штампања"</string>
-    <string name="notification_channel_failure" msgid="9042250774797916414">"Неуспели задаци штампања"</string>
-    <string name="could_not_create_file" msgid="3425025039427448443">"Прављење датотеке није успело"</string>
-    <string name="print_services_disabled_toast" msgid="9089060734685174685">"Неке услуге штампања су онемогућене"</string>
-    <string name="print_searching_for_printers" msgid="6550424555079932867">"Тражење штампача"</string>
-    <string name="print_no_print_services" msgid="8561247706423327966">"Ниједна услуга штампања није омогућена"</string>
-    <string name="print_no_printers" msgid="4869403323900054866">"Није пронађен ниједан штампач"</string>
-    <string name="cannot_add_printer" msgid="7840348733668023106">"Није могуће додати штампаче"</string>
-    <string name="select_to_add_printers" msgid="3800709038689830974">"Изаберите да бисте додали штампач"</string>
-    <string name="enable_print_service" msgid="3482815747043533842">"Изаберите да бисте омогућили"</string>
-    <string name="enabled_services_title" msgid="7036986099096582296">"Омогућене услуге"</string>
-    <string name="recommended_services_title" msgid="3799434882937956924">"Препоручене услуге"</string>
-    <string name="disabled_services_title" msgid="7313253167968363211">"Онемогућене услуге"</string>
-    <string name="all_services_title" msgid="5578662754874906455">"Све услуге"</string>
+    <string name="printer_info_desc" msgid="7181988788991581654">"Još informacija o ovom štampaču"</string>
+    <string name="notification_channel_progress" msgid="872788690775721436">"Aktivni zadaci štampanja"</string>
+    <string name="notification_channel_failure" msgid="9042250774797916414">"Neuspeli zadaci štampanja"</string>
+    <string name="could_not_create_file" msgid="3425025039427448443">"Pravljenje datoteke nije uspelo"</string>
+    <string name="print_services_disabled_toast" msgid="9089060734685174685">"Neke usluge štampanja su onemogućene"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Traženje štampača"</string>
+    <string name="print_no_print_services" msgid="8561247706423327966">"Nijedna usluga štampanja nije omogućena"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Nije pronađen nijedan štampač"</string>
+    <string name="cannot_add_printer" msgid="7840348733668023106">"Nije moguće dodati štampače"</string>
+    <string name="select_to_add_printers" msgid="3800709038689830974">"Izaberite da biste dodali štampač"</string>
+    <string name="enable_print_service" msgid="3482815747043533842">"Izaberite da biste omogućili"</string>
+    <string name="enabled_services_title" msgid="7036986099096582296">"Omogućene usluge"</string>
+    <string name="recommended_services_title" msgid="3799434882937956924">"Preporučene usluge"</string>
+    <string name="disabled_services_title" msgid="7313253167968363211">"Onemogućene usluge"</string>
+    <string name="all_services_title" msgid="5578662754874906455">"Sve usluge"</string>
     <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138">
-      <item quantity="one">Инсталирајте да бисте открили <xliff:g id="COUNT_1">%1$s</xliff:g> штампач</item>
-      <item quantity="few">Инсталирајте да бисте открили <xliff:g id="COUNT_1">%1$s</xliff:g> штампача</item>
-      <item quantity="other">Инсталирајте да бисте открили <xliff:g id="COUNT_1">%1$s</xliff:g> штампача</item>
+      <item quantity="one">Instalirajte da biste otkrili <xliff:g id="COUNT_1">%1$s</xliff:g> štampač</item>
+      <item quantity="few">Instalirajte da biste otkrili <xliff:g id="COUNT_1">%1$s</xliff:g> štampača</item>
+      <item quantity="other">Instalirajte da biste otkrili <xliff:g id="COUNT_1">%1$s</xliff:g> štampača</item>
     </plurals>
-    <string name="printing_notification_title_template" msgid="295903957762447362">"Штампа се <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
-    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Отказује се <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
-    <string name="failed_notification_title_template" msgid="2256217208186530973">"Грешка штампача <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
-    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Штампач је блокирао <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
-    <string name="cancel" msgid="4373674107267141885">"Откажи"</string>
-    <string name="restart" msgid="2472034227037808749">"Рестартуј"</string>
-    <string name="no_connection_to_printer" msgid="2159246915977282728">"Нема везе са штампачем"</string>
-    <string name="reason_unknown" msgid="5507940196503246139">"непознато"</string>
-    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Желите ли да користите <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
-    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Документ може да прође кроз један или више сервера на путу до штампача."</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Štampa se <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Otkazuje se <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Greška štampača <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Štampač je blokirao <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancel" msgid="4373674107267141885">"Otkaži"</string>
+    <string name="restart" msgid="2472034227037808749">"Restartuj"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Nema veze sa štampačem"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"nepoznato"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Želite li da koristite <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokument može da prođe kroz jedan ili više servera na putu do štampača."</string>
   <string-array name="color_mode_labels">
-    <item msgid="7602948745415174937">"Црно-бело"</item>
-    <item msgid="2762241247228983754">"Боја"</item>
+    <item msgid="7602948745415174937">"Crno-belo"</item>
+    <item msgid="2762241247228983754">"Boja"</item>
   </string-array>
   <string-array name="duplex_mode_labels">
-    <item msgid="3882302912790928315">"Ништа"</item>
-    <item msgid="7296563835355641719">"Дуга ивица"</item>
-    <item msgid="79513688117503758">"Кратка ивица"</item>
+    <item msgid="3882302912790928315">"Ništa"</item>
+    <item msgid="7296563835355641719">"Duga ivica"</item>
+    <item msgid="79513688117503758">"Kratka ivica"</item>
   </string-array>
   <string-array name="orientation_labels">
-    <item msgid="4061931020926489228">"Усправно"</item>
-    <item msgid="3199660090246166812">"Водоравно"</item>
+    <item msgid="4061931020926489228">"Uspravno"</item>
+    <item msgid="3199660090246166812">"Vodoravno"</item>
   </string-array>
-    <string name="print_write_error_message" msgid="5787642615179572543">"Уписивање у датотеку није могуће"</string>
-    <string name="print_error_default_message" msgid="8602678405502922346">"Жао нам је, ово није успело. Пробајте поново."</string>
-    <string name="print_error_retry" msgid="1426421728784259538">"Пробајте поново"</string>
-    <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Овај штампач тренутно није доступан."</string>
-    <string name="print_cannot_load_page" msgid="6179560924492912009">"Није успео приказ прегледа"</string>
-    <string name="print_preparing_preview" msgid="3939930735671364712">"Припрема прегледа..."</string>
+    <string name="print_write_error_message" msgid="5787642615179572543">"Upisivanje u datoteku nije moguće"</string>
+    <string name="print_error_default_message" msgid="8602678405502922346">"Žao nam je, ovo nije uspelo. Probajte ponovo."</string>
+    <string name="print_error_retry" msgid="1426421728784259538">"Probajte ponovo"</string>
+    <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Ovaj štampač trenutno nije dostupan."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Nije uspeo prikaz pregleda"</string>
+    <string name="print_preparing_preview" msgid="3939930735671364712">"Priprema pregleda..."</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-eu/strings.xml b/packages/PrintSpooler/res/values-eu/strings.xml
index 49ca881..cf4b258 100644
--- a/packages/PrintSpooler/res/values-eu/strings.xml
+++ b/packages/PrintSpooler/res/values-eu/strings.xml
@@ -32,7 +32,7 @@
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> orriko tartea"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"adib., 1-5, 8,11-13"</string>
     <string name="print_preview" msgid="8010217796057763343">"Inprimatze-aurrebista"</string>
-    <string name="install_for_print_preview" msgid="6366303997385509332">"Aurrebista ikusteko, instalatu PDF dokumentuen ikustailea"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Aurrebista ikusteko, instalatu PDFen ikustailea"</string>
     <string name="printing_app_crashed" msgid="854477616686566398">"Inprimatzeko aplikazioak matxura izan du"</string>
     <string name="generating_print_job" msgid="3119608742651698916">"Inprimatze-lana sortzen"</string>
     <string name="save_as_pdf" msgid="5718454119847596853">"Gorde PDF gisa"</string>
diff --git a/packages/PrintSpooler/res/values-te/strings.xml b/packages/PrintSpooler/res/values-te/strings.xml
index c11e2b7..36dbeba 100644
--- a/packages/PrintSpooler/res/values-te/strings.xml
+++ b/packages/PrintSpooler/res/values-te/strings.xml
@@ -35,7 +35,7 @@
     <string name="install_for_print_preview" msgid="6366303997385509332">"ప్రివ్యూ చేయడానికి PDF వ్యూయర్‌ను ఇన్‌స్టాల్ చేయండి"</string>
     <string name="printing_app_crashed" msgid="854477616686566398">"ముద్రణ యాప్ క్రాష్ అయ్యింది"</string>
     <string name="generating_print_job" msgid="3119608742651698916">"ముద్రణ జాబ్‌ను ఉత్పన్నం చేస్తోంది"</string>
-    <string name="save_as_pdf" msgid="5718454119847596853">"PDF లాగా సేవ్ చేయి"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"PDF లాగా సేవ్ చేయండి"</string>
     <string name="all_printers" msgid="5018829726861876202">"అన్ని ప్రింటర్‌లు…"</string>
     <string name="print_dialog" msgid="32628687461331979">"ముద్రణ డైలాగ్"</string>
     <string name="current_page_template" msgid="5145005201131935302">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g>/<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
@@ -44,7 +44,7 @@
     <string name="expand_handle" msgid="7282974448109280522">"విస్తరణ హ్యాండిల్"</string>
     <string name="collapse_handle" msgid="6886637989442507451">"కుదింపు హ్యాండిల్"</string>
     <string name="print_button" msgid="645164566271246268">"ప్రింట్ చేయండి"</string>
-    <string name="savetopdf_button" msgid="2976186791686924743">"PDF లాగా సేవ్ చేయి"</string>
+    <string name="savetopdf_button" msgid="2976186791686924743">"PDF లాగా సేవ్ చేయండి"</string>
     <string name="print_options_expanded" msgid="6944679157471691859">"ముద్రణ ఎంపికలు విస్తరించబడ్డాయి"</string>
     <string name="print_options_collapsed" msgid="7455930445670414332">"ముద్రణ ఎంపికలు కుదించబడ్డాయి"</string>
     <string name="search" msgid="5421724265322228497">"సెర్చ్"</string>
diff --git a/packages/SettingsLib/BannerMessagePreference/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/BannerMessagePreference/res/values-b+sr+Latn/strings.xml
index 68a2d5b..ca16c3d 100644
--- a/packages/SettingsLib/BannerMessagePreference/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/BannerMessagePreference/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="accessibility_banner_message_dismiss" msgid="5272928723898304168">"Одбаците"</string>
+    <string name="accessibility_banner_message_dismiss" msgid="5272928723898304168">"Odbacite"</string>
 </resources>
diff --git a/packages/SettingsLib/FooterPreference/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/FooterPreference/res/values-b+sr+Latn/strings.xml
index 9a73269..993ec9a 100644
--- a/packages/SettingsLib/FooterPreference/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/FooterPreference/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="settingslib_learn_more_text" msgid="7385478101223578464">"Сазнајте више"</string>
+    <string name="settingslib_learn_more_text" msgid="7385478101223578464">"Saznajte više"</string>
 </resources>
diff --git a/packages/SettingsLib/HelpUtils/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/HelpUtils/res/values-b+sr+Latn/strings.xml
index ee550bc..a917a76 100644
--- a/packages/SettingsLib/HelpUtils/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/HelpUtils/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="help_feedback_label" msgid="7106780063063027882">"Помоћ и повратне информације"</string>
+    <string name="help_feedback_label" msgid="7106780063063027882">"Pomoć i povratne informacije"</string>
 </resources>
diff --git a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java
index 468a976..1592094 100644
--- a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java
+++ b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java
@@ -59,6 +59,18 @@
     private Uri mImageUri;
     private Drawable mImageDrawable;
     private View mMiddleGroundView;
+    private OnBindListener mOnBindListener;
+
+    /**
+     * Interface to listen in on when {@link #onBindViewHolder(PreferenceViewHolder)} occurs.
+     */
+    public interface OnBindListener {
+        /**
+         * Called when when {@link #onBindViewHolder(PreferenceViewHolder)} occurs.
+         * @param animationView the animation view for this preference.
+         */
+        void onBind(LottieAnimationView animationView);
+    }
 
     private final Animatable2.AnimationCallback mAnimationCallback =
             new Animatable2.AnimationCallback() {
@@ -133,6 +145,17 @@
         if (IS_ENABLED_LOTTIE_ADAPTIVE_COLOR) {
             ColorUtils.applyDynamicColors(getContext(), illustrationView);
         }
+
+        if (mOnBindListener != null) {
+            mOnBindListener.onBind(illustrationView);
+        }
+    }
+
+    /**
+     * Sets a listener to be notified when the views are binded.
+     */
+    public void setOnBindListener(OnBindListener listener) {
+        mOnBindListener = listener;
     }
 
     /**
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-b+sr+Latn/strings.xml
index 9d006a7..e09afbf 100644
--- a/packages/SettingsLib/RestrictedLockUtils/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-b+sr+Latn/strings.xml
@@ -17,6 +17,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="enabled_by_admin" msgid="6630472777476410137">"Администратор је омогућио"</string>
-    <string name="disabled_by_admin" msgid="4023569940620832713">"Администратор је онемогућио"</string>
+    <string name="enabled_by_admin" msgid="6630472777476410137">"Administrator je omogućio"</string>
+    <string name="disabled_by_admin" msgid="4023569940620832713">"Administrator je onemogućio"</string>
 </resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/SearchWidget/res/values-b+sr+Latn/strings.xml
index 81a7baf..112b2ea 100644
--- a/packages/SettingsLib/SearchWidget/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/SearchWidget/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="search_menu" msgid="1914043873178389845">"Претражите подешавања"</string>
+    <string name="search_menu" msgid="1914043873178389845">"Pretražite podešavanja"</string>
 </resources>
diff --git a/packages/SettingsLib/SelectorWithWidgetPreference/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/SelectorWithWidgetPreference/res/values-b+sr+Latn/strings.xml
index 1478a00..d51823f 100644
--- a/packages/SettingsLib/SelectorWithWidgetPreference/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/SelectorWithWidgetPreference/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="settings_label" msgid="5948970810295631236">"Подешавања"</string>
+    <string name="settings_label" msgid="5948970810295631236">"Podešavanja"</string>
 </resources>
diff --git a/packages/SettingsLib/SelectorWithWidgetPreference/res/values-ky/strings.xml b/packages/SettingsLib/SelectorWithWidgetPreference/res/values-ky/strings.xml
index f4a893a..bcd6784b 100644
--- a/packages/SettingsLib/SelectorWithWidgetPreference/res/values-ky/strings.xml
+++ b/packages/SettingsLib/SelectorWithWidgetPreference/res/values-ky/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="settings_label" msgid="5948970810295631236">"Жөндөөлөр"</string>
+    <string name="settings_label" msgid="5948970810295631236">"Параметрлер"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index d11cd9e..6d8bf5f 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> oor tot vol"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> oor tot vol"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – Laaiproses word geoptimeer"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – Laaiproses word geoptimeer"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Onbekend"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Laai"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Laai tans vinnig"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index ec3942e..6087f6b 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"እስኪሞላ ድረስ <xliff:g id="TIME">%1$s</xliff:g> ይቀራል"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - እስኪሞላ ድረስ <xliff:g id="TIME">%2$s</xliff:g> ይቀራል"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - ኃይል መሙላት እንዲተባ ተደርጓል"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - ኃይል መሙላት እንዲተባ ተደርጓል"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"ያልታወቀ"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"ኃይል በመሙላት ላይ"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ኃይል በፍጥነት በመሙላት ላይ"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index f451091..50edd6c 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"يتبقّى <xliff:g id="TIME">%1$s</xliff:g> حتى اكتمال شحن البطارية."</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - يتبقّى <xliff:g id="TIME">%2$s</xliff:g> حتى اكتمال شحن البطارية."</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - تم تحسين الشحن"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - تم تحسين الشحن"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"غير معروف"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"جارٍ الشحن"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"جارٍ الشحن سريعًا"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 27ea8cb..7377c3e 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"সম্পূৰ্ণ হ’বলৈ <xliff:g id="TIME">%1$s</xliff:g> বাকী আছে"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"সম্পূৰ্ণ হ’বলৈ <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> বাকী আছে"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - চাৰ্জিং অপ্টিমাইজ কৰা হৈছে"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - চাৰ্জিং অপ্টিমাইজ কৰা হৈছে"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"অজ্ঞাত"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"চাৰ্জ কৰি থকা হৈছে"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"দ্ৰুততাৰে চাৰ্জ হৈছে"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index e167f6a..9ed15e0 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Tam şarj edilənədək <xliff:g id="TIME">%1$s</xliff:g> qalıb"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - tam şarj edilənədək <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Şarj optimallaşdırılıb"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Şarj optimallaşdırılıb"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Naməlum"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Enerji doldurma"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Sürətlə doldurulur"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
index a95e47b..63b08fa 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
@@ -22,49 +22,49 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
   <string-array name="wifi_status">
     <item msgid="1596683495752107015"></item>
-    <item msgid="3288373008277313483">"Скенирање..."</item>
-    <item msgid="6050951078202663628">"Повезивање…"</item>
-    <item msgid="8356618438494652335">"Потврђује се аутентичност..."</item>
-    <item msgid="2837871868181677206">"Преузимање IP адресе..."</item>
-    <item msgid="4613015005934755724">"Повезано"</item>
-    <item msgid="3763530049995655072">"Обустављено"</item>
-    <item msgid="7852381437933824454">"Прекидање везе..."</item>
-    <item msgid="5046795712175415059">"Веза је прекинута"</item>
-    <item msgid="2473654476624070462">"Неуспешно"</item>
-    <item msgid="9146847076036105115">"Блокирано"</item>
-    <item msgid="4543924085816294893">"Привремено избегавање лоше везе"</item>
+    <item msgid="3288373008277313483">"Skeniranje..."</item>
+    <item msgid="6050951078202663628">"Povezivanje…"</item>
+    <item msgid="8356618438494652335">"Potvrđuje se autentičnost..."</item>
+    <item msgid="2837871868181677206">"Preuzimanje IP adrese..."</item>
+    <item msgid="4613015005934755724">"Povezano"</item>
+    <item msgid="3763530049995655072">"Obustavljeno"</item>
+    <item msgid="7852381437933824454">"Prekidanje veze..."</item>
+    <item msgid="5046795712175415059">"Veza je prekinuta"</item>
+    <item msgid="2473654476624070462">"Neuspešno"</item>
+    <item msgid="9146847076036105115">"Blokirano"</item>
+    <item msgid="4543924085816294893">"Privremeno izbegavanje loše veze"</item>
   </string-array>
   <string-array name="wifi_status_with_ssid">
     <item msgid="5969842512724979061"></item>
-    <item msgid="1818677602615822316">"Скенирање..."</item>
-    <item msgid="8339720953594087771">"Повезивање са мрежом <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
-    <item msgid="3028983857109369308">"Проверавање идентитета мреже <xliff:g id="NETWORK_NAME">%1$s</xliff:g>..."</item>
-    <item msgid="4287401332778341890">"Добијање IP адресе од мреже <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
-    <item msgid="1043944043827424501">"Повезано са мрежом <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item>
-    <item msgid="7445993821842009653">"Обустављено"</item>
-    <item msgid="1175040558087735707">"Прекидање везе са мрежом <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
-    <item msgid="699832486578171722">"Веза је прекинута"</item>
-    <item msgid="522383512264986901">"Неуспешно"</item>
-    <item msgid="3602596701217484364">"Блокирано"</item>
-    <item msgid="1999413958589971747">"Привремено избегавање лоше везе"</item>
+    <item msgid="1818677602615822316">"Skeniranje..."</item>
+    <item msgid="8339720953594087771">"Povezivanje sa mrežom <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
+    <item msgid="3028983857109369308">"Proveravanje identiteta mreže <xliff:g id="NETWORK_NAME">%1$s</xliff:g>..."</item>
+    <item msgid="4287401332778341890">"Dobijanje IP adrese od mreže <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
+    <item msgid="1043944043827424501">"Povezano sa mrežom <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item>
+    <item msgid="7445993821842009653">"Obustavljeno"</item>
+    <item msgid="1175040558087735707">"Prekidanje veze sa mrežom <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
+    <item msgid="699832486578171722">"Veza je prekinuta"</item>
+    <item msgid="522383512264986901">"Neuspešno"</item>
+    <item msgid="3602596701217484364">"Blokirano"</item>
+    <item msgid="1999413958589971747">"Privremeno izbegavanje loše veze"</item>
   </string-array>
   <string-array name="hdcp_checking_titles">
-    <item msgid="2377230797542526134">"Никад не проверавај"</item>
-    <item msgid="3919638466823112484">"Потражи само DRM садржај"</item>
-    <item msgid="9048424957228926377">"Увек проверавај"</item>
+    <item msgid="2377230797542526134">"Nikad ne proveravaj"</item>
+    <item msgid="3919638466823112484">"Potraži samo DRM sadržaj"</item>
+    <item msgid="9048424957228926377">"Uvek proveravaj"</item>
   </string-array>
   <string-array name="hdcp_checking_summaries">
-    <item msgid="4045840870658484038">"Никада не користи HDCP проверу"</item>
-    <item msgid="8254225038262324761">"Користи HDCP проверу само за DRM садржај"</item>
-    <item msgid="6421717003037072581">"Увек користи HDCP проверу"</item>
+    <item msgid="4045840870658484038">"Nikada ne koristi HDCP proveru"</item>
+    <item msgid="8254225038262324761">"Koristi HDCP proveru samo za DRM sadržaj"</item>
+    <item msgid="6421717003037072581">"Uvek koristi HDCP proveru"</item>
   </string-array>
   <string-array name="bt_hci_snoop_log_entries">
-    <item msgid="695678520785580527">"Онемогућено"</item>
-    <item msgid="6336372935919715515">"Омогућено филтрирано"</item>
-    <item msgid="2779123106632690576">"Омогућено"</item>
+    <item msgid="695678520785580527">"Onemogućeno"</item>
+    <item msgid="6336372935919715515">"Omogućeno filtrirano"</item>
+    <item msgid="2779123106632690576">"Omogućeno"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
-    <item msgid="6603880723315236832">"AVRCP 1.5 (подразумевано)"</item>
+    <item msgid="6603880723315236832">"AVRCP 1.5 (podrazumevano)"</item>
     <item msgid="1637054408779685086">"AVRCP 1.3"</item>
     <item msgid="5896162189744596291">"AVRCP 1.4"</item>
     <item msgid="7556896992111771426">"AVRCP 1.6"</item>
@@ -76,7 +76,7 @@
     <item msgid="1963366694959681026">"avrcp16"</item>
   </string-array>
   <string-array name="bluetooth_map_versions">
-    <item msgid="8786402640610987099">"MAP 1.2 (подразумевано)"</item>
+    <item msgid="8786402640610987099">"MAP 1.2 (podrazumevano)"</item>
     <item msgid="6817922176194686449">"MAP 1.3"</item>
     <item msgid="3423518690032737851">"MAP 1.4"</item>
   </string-array>
@@ -86,81 +86,81 @@
     <item msgid="8147982633566548515">"map14"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="2494959071796102843">"Користи избор система (подразумевано)"</item>
+    <item msgid="2494959071796102843">"Koristi izbor sistema (podrazumevano)"</item>
     <item msgid="4055460186095649420">"SBC"</item>
     <item msgid="720249083677397051">"AAC"</item>
-    <item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> аудио"</item>
-    <item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> аудио"</item>
+    <item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
+    <item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
     <item msgid="3825367753087348007">"LDAC"</item>
     <item msgid="328951785723550863">"LC3"</item>
     <item msgid="506175145534048710">"Opus"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="8868109554557331312">"Користи избор система (подразумевано)"</item>
+    <item msgid="8868109554557331312">"Koristi izbor sistema (podrazumevano)"</item>
     <item msgid="9024885861221697796">"SBC"</item>
     <item msgid="4688890470703790013">"AAC"</item>
-    <item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> аудио"</item>
-    <item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> аудио"</item>
+    <item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
+    <item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
     <item msgid="2553206901068987657">"LDAC"</item>
     <item msgid="3940992993241040716">"LC3"</item>
     <item msgid="7940970833006181407">"Opus"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
-    <item msgid="926809261293414607">"Користи избор система (подразумевано)"</item>
+    <item msgid="926809261293414607">"Koristi izbor sistema (podrazumevano)"</item>
     <item msgid="8003118270854840095">"44,1 kHz"</item>
     <item msgid="3208896645474529394">"48,0 kHz"</item>
     <item msgid="8420261949134022577">"88,2 kHz"</item>
     <item msgid="8887519571067543785">"96,0 kHz"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_sample_rate_summaries">
-    <item msgid="2284090879080331090">"Користи избор система (подразумевано)"</item>
+    <item msgid="2284090879080331090">"Koristi izbor sistema (podrazumevano)"</item>
     <item msgid="1872276250541651186">"44,1 kHz"</item>
     <item msgid="8736780630001704004">"48,0 kHz"</item>
     <item msgid="7698585706868856888">"88,2 kHz"</item>
     <item msgid="8946330945963372966">"96,0 kHz"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_bits_per_sample_titles">
-    <item msgid="2574107108483219051">"Користи избор система (подразумевано)"</item>
-    <item msgid="4671992321419011165">"16 битова по узорку"</item>
-    <item msgid="1933898806184763940">"24 бита по узорку"</item>
-    <item msgid="1212577207279552119">"32 бита по узорку"</item>
+    <item msgid="2574107108483219051">"Koristi izbor sistema (podrazumevano)"</item>
+    <item msgid="4671992321419011165">"16 bitova po uzorku"</item>
+    <item msgid="1933898806184763940">"24 bita po uzorku"</item>
+    <item msgid="1212577207279552119">"32 bita po uzorku"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_bits_per_sample_summaries">
-    <item msgid="9196208128729063711">"Користи избор система (подразумевано)"</item>
-    <item msgid="1084497364516370912">"16 битова по узорку"</item>
-    <item msgid="2077889391457961734">"24 бита по узорку"</item>
-    <item msgid="3836844909491316925">"32 бита по узорку"</item>
+    <item msgid="9196208128729063711">"Koristi izbor sistema (podrazumevano)"</item>
+    <item msgid="1084497364516370912">"16 bitova po uzorku"</item>
+    <item msgid="2077889391457961734">"24 bita po uzorku"</item>
+    <item msgid="3836844909491316925">"32 bita po uzorku"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_channel_mode_titles">
-    <item msgid="3014194562841654656">"Користи избор система (подразумевано)"</item>
-    <item msgid="5982952342181788248">"Моно"</item>
-    <item msgid="927546067692441494">"Стерео"</item>
+    <item msgid="3014194562841654656">"Koristi izbor sistema (podrazumevano)"</item>
+    <item msgid="5982952342181788248">"Mono"</item>
+    <item msgid="927546067692441494">"Stereo"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_channel_mode_summaries">
-    <item msgid="1997302811102880485">"Користи избор система (подразумевано)"</item>
-    <item msgid="8005696114958453588">"Моно"</item>
-    <item msgid="1333279807604675720">"Стерео"</item>
+    <item msgid="1997302811102880485">"Koristi izbor sistema (podrazumevano)"</item>
+    <item msgid="8005696114958453588">"Mono"</item>
+    <item msgid="1333279807604675720">"Stereo"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
-    <item msgid="1241278021345116816">"Оптимизовано за квалитет звука (990 kb/s/909 kb/s)"</item>
-    <item msgid="3523665555859696539">"Уједначен квалитет звука и везе (660 kb/s/606 kb/s)"</item>
-    <item msgid="886408010459747589">"Оптимизовано за квалитет везе (330 kb/s/303 kb/s)"</item>
-    <item msgid="3808414041654351577">"Најбоље могуће (прилагодљива брзина преноса)"</item>
+    <item msgid="1241278021345116816">"Optimizovano za kvalitet zvuka (990 kb/s/909 kb/s)"</item>
+    <item msgid="3523665555859696539">"Ujednačen kvalitet zvuka i veze (660 kb/s/606 kb/s)"</item>
+    <item msgid="886408010459747589">"Optimizovano za kvalitet veze (330 kb/s/303 kb/s)"</item>
+    <item msgid="3808414041654351577">"Najbolje moguće (prilagodljiva brzina prenosa)"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
-    <item msgid="804499336721569838">"Оптимизовано за квалитет звука"</item>
-    <item msgid="7451422070435297462">"Уједначен квалитет звука и везе"</item>
-    <item msgid="6173114545795428901">"Оптимизовано за квалитет везе"</item>
-    <item msgid="4349908264188040530">"Најбоље могуће (прилагодљива брзина преноса)"</item>
+    <item msgid="804499336721569838">"Optimizovano za kvalitet zvuka"</item>
+    <item msgid="7451422070435297462">"Ujednačen kvalitet zvuka i veze"</item>
+    <item msgid="6173114545795428901">"Optimizovano za kvalitet veze"</item>
+    <item msgid="4349908264188040530">"Najbolje moguće (prilagodljiva brzina prenosa)"</item>
   </string-array>
   <string-array name="bluetooth_audio_active_device_summaries">
     <item msgid="8019740759207729126"></item>
-    <item msgid="204248102837117183">", активан"</item>
-    <item msgid="253388653486517049">", активан (медијски)"</item>
-    <item msgid="5001852592115448348">", активан (телефон)"</item>
+    <item msgid="204248102837117183">", aktivan"</item>
+    <item msgid="253388653486517049">", aktivan (medijski)"</item>
+    <item msgid="5001852592115448348">", aktivan (telefon)"</item>
   </string-array>
   <string-array name="select_logd_size_titles">
-    <item msgid="1191094707770726722">"Искључено"</item>
+    <item msgid="1191094707770726722">"Isključeno"</item>
     <item msgid="7839165897132179888">"64 kB"</item>
     <item msgid="2715700596495505626">"256 kB"</item>
     <item msgid="7099386891713159947">"1 MB"</item>
@@ -168,107 +168,107 @@
     <item msgid="6078203297886482480">"8 MB"</item>
   </string-array>
   <string-array name="select_logd_size_lowram_titles">
-    <item msgid="1145807928339101085">"Искључено"</item>
+    <item msgid="1145807928339101085">"Isključeno"</item>
     <item msgid="4064786181089783077">"64 kB"</item>
     <item msgid="3052710745383602630">"256 kB"</item>
     <item msgid="3691785423374588514">"1 MB"</item>
   </string-array>
   <string-array name="select_logd_size_summaries">
-    <item msgid="409235464399258501">"Искључено"</item>
-    <item msgid="4195153527464162486">"64 kB по међумеморији евиденције"</item>
-    <item msgid="7464037639415220106">"256 kB по међумеморији евиденције"</item>
-    <item msgid="8539423820514360724">"1 MB по међумеморији евиденције"</item>
-    <item msgid="1984761927103140651">"4 MB по међумеморији евиденције"</item>
-    <item msgid="2983219471251787208">"8 MB по међумеморији евиденције"</item>
+    <item msgid="409235464399258501">"Isključeno"</item>
+    <item msgid="4195153527464162486">"64 kB po međumemoriji evidencije"</item>
+    <item msgid="7464037639415220106">"256 kB po međumemoriji evidencije"</item>
+    <item msgid="8539423820514360724">"1 MB po međumemoriji evidencije"</item>
+    <item msgid="1984761927103140651">"4 MB po međumemoriji evidencije"</item>
+    <item msgid="2983219471251787208">"8 MB po međumemoriji evidencije"</item>
   </string-array>
   <string-array name="select_logpersist_titles">
-    <item msgid="704720725704372366">"Искључено"</item>
-    <item msgid="6014837961827347618">"Све"</item>
-    <item msgid="7387060437894578132">"Све сeм радија"</item>
-    <item msgid="7300881231043255746">"само језгро"</item>
+    <item msgid="704720725704372366">"Isključeno"</item>
+    <item msgid="6014837961827347618">"Sve"</item>
+    <item msgid="7387060437894578132">"Sve sem radija"</item>
+    <item msgid="7300881231043255746">"samo jezgro"</item>
   </string-array>
   <string-array name="select_logpersist_summaries">
-    <item msgid="97587758561106269">"Искључено"</item>
-    <item msgid="7126170197336963369">"Све међумеморије евиденција"</item>
-    <item msgid="7167543126036181392">"Све осим међумеморија евиденција за радио"</item>
-    <item msgid="5135340178556563979">"само међумеморија евиденције језгра"</item>
+    <item msgid="97587758561106269">"Isključeno"</item>
+    <item msgid="7126170197336963369">"Sve međumemorije evidencija"</item>
+    <item msgid="7167543126036181392">"Sve osim međumemorija evidencija za radio"</item>
+    <item msgid="5135340178556563979">"samo međumemorija evidencije jezgra"</item>
   </string-array>
   <string-array name="window_animation_scale_entries">
-    <item msgid="2675263395797191850">"Анимација је искључена"</item>
-    <item msgid="5790132543372767872">"Размера анимације 0,5x"</item>
-    <item msgid="2529692189302148746">"Размера анимације 1x"</item>
-    <item msgid="8072785072237082286">"Размера анимације 1,5x"</item>
-    <item msgid="3531560925718232560">"Размера анимације 2x"</item>
-    <item msgid="4542853094898215187">"Размера анимације 5x"</item>
-    <item msgid="5643881346223901195">"Размера анимације 10x"</item>
+    <item msgid="2675263395797191850">"Animacija je isključena"</item>
+    <item msgid="5790132543372767872">"Razmera animacije 0,5x"</item>
+    <item msgid="2529692189302148746">"Razmera animacije 1x"</item>
+    <item msgid="8072785072237082286">"Razmera animacije 1,5x"</item>
+    <item msgid="3531560925718232560">"Razmera animacije 2x"</item>
+    <item msgid="4542853094898215187">"Razmera animacije 5x"</item>
+    <item msgid="5643881346223901195">"Razmera animacije 10x"</item>
   </string-array>
   <string-array name="transition_animation_scale_entries">
-    <item msgid="3376676813923486384">"Анимација је искључена"</item>
-    <item msgid="753422683600269114">"Размера анимације 0,5x"</item>
-    <item msgid="3695427132155563489">"Размера анимације 1x"</item>
-    <item msgid="9032615844198098981">"Размера анимације 1,5x"</item>
-    <item msgid="8473868962499332073">"Размера анимације 2x"</item>
-    <item msgid="4403482320438668316">"Размера анимације 5x"</item>
-    <item msgid="169579387974966641">"Размера анимације 10x"</item>
+    <item msgid="3376676813923486384">"Animacija je isključena"</item>
+    <item msgid="753422683600269114">"Razmera animacije 0,5x"</item>
+    <item msgid="3695427132155563489">"Razmera animacije 1x"</item>
+    <item msgid="9032615844198098981">"Razmera animacije 1,5x"</item>
+    <item msgid="8473868962499332073">"Razmera animacije 2x"</item>
+    <item msgid="4403482320438668316">"Razmera animacije 5x"</item>
+    <item msgid="169579387974966641">"Razmera animacije 10x"</item>
   </string-array>
   <string-array name="animator_duration_scale_entries">
-    <item msgid="6416998593844817378">"Анимација је искључена"</item>
-    <item msgid="875345630014338616">"Размера анимације 0,5x"</item>
-    <item msgid="2753729231187104962">"Размера анимације 1x"</item>
-    <item msgid="1368370459723665338">"Размера анимације 1,5x"</item>
-    <item msgid="5768005350534383389">"Размера анимације 2x"</item>
-    <item msgid="3728265127284005444">"Размера анимације 5x"</item>
-    <item msgid="2464080977843960236">"Размера анимације 10x"</item>
+    <item msgid="6416998593844817378">"Animacija je isključena"</item>
+    <item msgid="875345630014338616">"Razmera animacije 0,5x"</item>
+    <item msgid="2753729231187104962">"Razmera animacije 1x"</item>
+    <item msgid="1368370459723665338">"Razmera animacije 1,5x"</item>
+    <item msgid="5768005350534383389">"Razmera animacije 2x"</item>
+    <item msgid="3728265127284005444">"Razmera animacije 5x"</item>
+    <item msgid="2464080977843960236">"Razmera animacije 10x"</item>
   </string-array>
   <string-array name="overlay_display_devices_entries">
-    <item msgid="4497393944195787240">"Ништа"</item>
-    <item msgid="8461943978957133391">"480 пиксела"</item>
-    <item msgid="6923083594932909205">"480 пиксела (безбедно)"</item>
-    <item msgid="1226941831391497335">"720 пиксела"</item>
-    <item msgid="7051983425968643928">"720 пиксела (безбедно)"</item>
-    <item msgid="7765795608738980305">"1080 пиксела"</item>
-    <item msgid="8084293856795803592">"1080 пиксела (безбедно)"</item>
+    <item msgid="4497393944195787240">"Ništa"</item>
+    <item msgid="8461943978957133391">"480 piksela"</item>
+    <item msgid="6923083594932909205">"480 piksela (bezbedno)"</item>
+    <item msgid="1226941831391497335">"720 piksela"</item>
+    <item msgid="7051983425968643928">"720 piksela (bezbedno)"</item>
+    <item msgid="7765795608738980305">"1080 piksela"</item>
+    <item msgid="8084293856795803592">"1080 piksela (bezbedno)"</item>
     <item msgid="938784192903353277">"4K"</item>
-    <item msgid="8612549335720461635">"4K (безбедно)"</item>
-    <item msgid="7322156123728520872">"4K (увећана резолуција)"</item>
-    <item msgid="7735692090314849188">"4K (увећана резолуција, безбедно)"</item>
-    <item msgid="7346816300608639624">"720 пиксела, 1080 пикс. (2 екрана)"</item>
+    <item msgid="8612549335720461635">"4K (bezbedno)"</item>
+    <item msgid="7322156123728520872">"4K (uvećana rezolucija)"</item>
+    <item msgid="7735692090314849188">"4K (uvećana rezolucija, bezbedno)"</item>
+    <item msgid="7346816300608639624">"720 piksela, 1080 piks. (2 ekrana)"</item>
   </string-array>
   <string-array name="enable_opengl_traces_entries">
-    <item msgid="4433736508877934305">"Ниједан"</item>
+    <item msgid="4433736508877934305">"Nijedan"</item>
     <item msgid="9140053004929079158">"Logcat"</item>
-    <item msgid="3866871644917859262">"Systrace (графика)"</item>
-    <item msgid="7345673972166571060">"Групно позивање функције glGetError"</item>
+    <item msgid="3866871644917859262">"Systrace (grafika)"</item>
+    <item msgid="7345673972166571060">"Grupno pozivanje funkcije glGetError"</item>
   </string-array>
   <string-array name="show_non_rect_clip_entries">
-    <item msgid="2482978351289846212">"Искључено"</item>
-    <item msgid="3405519300199774027">"Нацртај област за исецање која није правоугаоног облика плавом бојом"</item>
-    <item msgid="1212561935004167943">"Истакни зеленом тестиране команде за цртање"</item>
+    <item msgid="2482978351289846212">"Isključeno"</item>
+    <item msgid="3405519300199774027">"Nacrtaj oblast za isecanje koja nije pravougaonog oblika plavom bojom"</item>
+    <item msgid="1212561935004167943">"Istakni zelenom testirane komande za crtanje"</item>
   </string-array>
   <string-array name="track_frame_time_entries">
-    <item msgid="634406443901014984">"Искључено"</item>
-    <item msgid="1288760936356000927">"На екрану у виду трака"</item>
-    <item msgid="5023908510820531131">"У <xliff:g id="AS_TYPED_COMMAND">adb shell dumpsys gfxinfo</xliff:g>"</item>
+    <item msgid="634406443901014984">"Isključeno"</item>
+    <item msgid="1288760936356000927">"Na ekranu u vidu traka"</item>
+    <item msgid="5023908510820531131">"U <xliff:g id="AS_TYPED_COMMAND">adb shell dumpsys gfxinfo</xliff:g>"</item>
   </string-array>
   <string-array name="debug_hw_overdraw_entries">
-    <item msgid="1968128556747588800">"Искључи"</item>
-    <item msgid="3033215374382962216">"Прикажи области преклапања"</item>
-    <item msgid="3474333938380896988">"Прикажи области за деутераномалију"</item>
+    <item msgid="1968128556747588800">"Isključi"</item>
+    <item msgid="3033215374382962216">"Prikaži oblasti preklapanja"</item>
+    <item msgid="3474333938380896988">"Prikaži oblasti za deuteranomaliju"</item>
   </string-array>
   <string-array name="app_process_limit_entries">
-    <item msgid="794656271086646068">"Стандардно ограничење"</item>
-    <item msgid="8628438298170567201">"Без позадинских процеса"</item>
-    <item msgid="915752993383950932">"Највише један процес"</item>
-    <item msgid="8554877790859095133">"Највише два процеса"</item>
-    <item msgid="9060830517215174315">"Највише три процеса"</item>
-    <item msgid="6506681373060736204">"Највише четири процеса"</item>
+    <item msgid="794656271086646068">"Standardno ograničenje"</item>
+    <item msgid="8628438298170567201">"Bez pozadinskih procesa"</item>
+    <item msgid="915752993383950932">"Najviše jedan proces"</item>
+    <item msgid="8554877790859095133">"Najviše dva procesa"</item>
+    <item msgid="9060830517215174315">"Najviše tri procesa"</item>
+    <item msgid="6506681373060736204">"Najviše četiri procesa"</item>
   </string-array>
   <string-array name="usb_configuration_titles">
-    <item msgid="3358668781763928157">"Пуни се"</item>
-    <item msgid="7804797564616858506">"MTP (протокол за трансфер медија)"</item>
-    <item msgid="910925519184248772">"PTP (протокол за пренос слика)"</item>
-    <item msgid="3825132913289380004">"RNDIS (USB етернет)"</item>
-    <item msgid="8828567335701536560">"Извор звука"</item>
+    <item msgid="3358668781763928157">"Puni se"</item>
+    <item msgid="7804797564616858506">"MTP (protokol za transfer medija)"</item>
+    <item msgid="910925519184248772">"PTP (protokol za prenos slika)"</item>
+    <item msgid="3825132913289380004">"RNDIS (USB eternet)"</item>
+    <item msgid="8828567335701536560">"Izvor zvuka"</item>
     <item msgid="8688681727755534982">"MIDI"</item>
   </string-array>
   <string-array name="avatar_image_descriptions">
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 68af019..38e6812 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -20,7 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_fail_to_scan" msgid="2333336097603822490">"Није могуће скенирати мреже"</string>
+    <string name="wifi_fail_to_scan" msgid="2333336097603822490">"Nije moguće skenirati mreže"</string>
     <string name="wifi_security_short_wep" msgid="7939809393561636237">"WEP"</string>
     <string name="wifi_security_short_wpa" msgid="6998160832497442533">"WPA"</string>
     <string name="wifi_security_short_wpa2" msgid="7697856994856831026">"WPA2"</string>
@@ -30,10 +30,10 @@
     <string name="wifi_security_short_eap_wpa2_wpa3" msgid="6455656470422244501">"RSN-EAP"</string>
     <string name="wifi_security_short_sae" msgid="78353562671556266">"WPA3"</string>
     <string name="wifi_security_short_psk_sae" msgid="4965830739185952958">"WPA2/WPA3"</string>
-    <string name="wifi_security_short_none_owe" msgid="8827409046261759703">"Ништа/OWE"</string>
+    <string name="wifi_security_short_none_owe" msgid="8827409046261759703">"Ništa/OWE"</string>
     <string name="wifi_security_short_owe" msgid="5073524307942025369">"OWE"</string>
     <string name="wifi_security_short_eap_suiteb" msgid="4174071135081556115">"Suite-B-192"</string>
-    <string name="wifi_security_none" msgid="7392696451280611452">"Нема"</string>
+    <string name="wifi_security_none" msgid="7392696451280611452">"Nema"</string>
     <string name="wifi_security_wep" msgid="1413627788581122366">"WEP"</string>
     <string name="wifi_security_wpa" msgid="1072450904799930636">"WPA-Personal"</string>
     <string name="wifi_security_wpa2" msgid="4038267581230425543">"WPA2-Personal"</string>
@@ -46,593 +46,591 @@
     <string name="wifi_security_passpoint" msgid="2209078477216565387">"Passpoint"</string>
     <string name="wifi_security_sae" msgid="3644520541721422843">"WPA3-Personal"</string>
     <string name="wifi_security_psk_sae" msgid="8135104122179904684">"WPA2/WPA3-Personal"</string>
-    <string name="wifi_security_none_owe" msgid="5241745828327404101">"Ништа/Enhanced Open"</string>
+    <string name="wifi_security_none_owe" msgid="5241745828327404101">"Ništa/Enhanced Open"</string>
     <string name="wifi_security_owe" msgid="3343421403561657809">"Enhanced Open"</string>
-    <string name="wifi_security_eap_suiteb" msgid="415842785991698142">"WPA3-Enterprise, 192-битни"</string>
-    <string name="wifi_remembered" msgid="3266709779723179188">"Сачувано"</string>
-    <string name="wifi_disconnected" msgid="7054450256284661757">"Веза је прекинута"</string>
-    <string name="wifi_disabled_generic" msgid="2651916945380294607">"Онемогућено"</string>
-    <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP конфигурација је отказала"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Није повезано због лошег квалитета мреже"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi веза је отказала"</string>
-    <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Проблем са потврдом идентитета"</string>
-    <string name="wifi_cant_connect" msgid="5718417542623056783">"Повезивање није успело"</string>
-    <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Повезивање са „<xliff:g id="AP_NAME">%1$s</xliff:g>“ није успело"</string>
-    <string name="wifi_check_password_try_again" msgid="8817789642851605628">"Проверите лозинку и пробајте поново"</string>
-    <string name="wifi_not_in_range" msgid="1541760821805777772">"Није у опсегу"</string>
-    <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Аутоматско повезивање није успело"</string>
-    <string name="wifi_no_internet" msgid="1774198889176926299">"Нема приступа интернету"</string>
-    <string name="saved_network" msgid="7143698034077223645">"Сачувао/ла је <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Повезани сте на мрежу са ограничењем"</string>
-    <string name="connected_via_network_scorer" msgid="7665725527352893558">"Аутоматски повезано преко %1$s"</string>
-    <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Аутоматски повезано преко добављача оцене мреже"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Веза је успостављена преко приступне тачке %1$s"</string>
-    <string name="connected_via_app" msgid="3532267661404276584">"Повезано преко: <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Доступна је преко приступне тачке %1$s"</string>
-    <string name="tap_to_sign_up" msgid="5356397741063740395">"Додирните да бисте се регистровали"</string>
-    <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Нема интернета"</string>
-    <string name="private_dns_broken" msgid="1984159464346556931">"Приступ приватном DNS серверу није успео"</string>
-    <string name="wifi_limited_connection" msgid="1184778285475204682">"Ограничена веза"</string>
-    <string name="wifi_status_no_internet" msgid="3799933875988829048">"Нема интернета"</string>
-    <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Треба да се пријавите"</string>
-    <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Приступна тачка је привремено заузета"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Повезано преко %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Доступно преко %1$s"</string>
-    <string name="osu_opening_provider" msgid="4318105381295178285">"Отвара се <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
-    <string name="osu_connect_failed" msgid="9107873364807159193">"Повезивање није успело"</string>
-    <string name="osu_completing_sign_up" msgid="8412636665040390901">"Регистрација се довршава…"</string>
-    <string name="osu_sign_up_failed" msgid="5605453599586001793">"Довршавање регистрације није успело. Додирните да бисте пробали поново."</string>
-    <string name="osu_sign_up_complete" msgid="7640183358878916847">"Регистрација је довршена. Повезује се…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Веома спора"</string>
-    <string name="speed_label_slow" msgid="6069917670665664161">"Спора"</string>
-    <string name="speed_label_okay" msgid="1253594383880810424">"Потврди"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Средња"</string>
-    <string name="speed_label_fast" msgid="2677719134596044051">"Брза"</string>
-    <string name="speed_label_very_fast" msgid="8215718029533182439">"Веома брза"</string>
-    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Истекло"</string>
+    <string name="wifi_security_eap_suiteb" msgid="415842785991698142">"WPA3-Enterprise, 192-bitni"</string>
+    <string name="wifi_remembered" msgid="3266709779723179188">"Sačuvano"</string>
+    <string name="wifi_disconnected" msgid="7054450256284661757">"Veza je prekinuta"</string>
+    <string name="wifi_disabled_generic" msgid="2651916945380294607">"Onemogućeno"</string>
+    <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP konfiguracija je otkazala"</string>
+    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Nije povezano zbog lošeg kvaliteta mreže"</string>
+    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi veza je otkazala"</string>
+    <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Problem sa potvrdom identiteta"</string>
+    <string name="wifi_cant_connect" msgid="5718417542623056783">"Povezivanje nije uspelo"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Povezivanje sa „<xliff:g id="AP_NAME">%1$s</xliff:g>“ nije uspelo"</string>
+    <string name="wifi_check_password_try_again" msgid="8817789642851605628">"Proverite lozinku i probajte ponovo"</string>
+    <string name="wifi_not_in_range" msgid="1541760821805777772">"Nije u opsegu"</string>
+    <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Automatsko povezivanje nije uspelo"</string>
+    <string name="wifi_no_internet" msgid="1774198889176926299">"Nema pristupa internetu"</string>
+    <string name="saved_network" msgid="7143698034077223645">"Sačuvao/la je <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Povezani ste na mrežu sa ograničenjem"</string>
+    <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatski povezano preko %1$s"</string>
+    <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatski povezano preko dobavljača ocene mreže"</string>
+    <string name="connected_via_passpoint" msgid="7735442932429075684">"Veza je uspostavljena preko pristupne tačke %1$s"</string>
+    <string name="connected_via_app" msgid="3532267661404276584">"Povezano preko: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="available_via_passpoint" msgid="1716000261192603682">"Dostupna je preko pristupne tačke %1$s"</string>
+    <string name="tap_to_sign_up" msgid="5356397741063740395">"Dodirnite da biste se registrovali"</string>
+    <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Nema interneta"</string>
+    <string name="private_dns_broken" msgid="1984159464346556931">"Pristup privatnom DNS serveru nije uspeo"</string>
+    <string name="wifi_limited_connection" msgid="1184778285475204682">"Ograničena veza"</string>
+    <string name="wifi_status_no_internet" msgid="3799933875988829048">"Nema interneta"</string>
+    <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Treba da se prijavite"</string>
+    <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Pristupna tačka je privremeno zauzeta"</string>
+    <string name="connected_via_carrier" msgid="1968057009076191514">"Povezano preko %1$s"</string>
+    <string name="available_via_carrier" msgid="465598683092718294">"Dostupno preko %1$s"</string>
+    <string name="osu_opening_provider" msgid="4318105381295178285">"Otvara se <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+    <string name="osu_connect_failed" msgid="9107873364807159193">"Povezivanje nije uspelo"</string>
+    <string name="osu_completing_sign_up" msgid="8412636665040390901">"Registracija se dovršava…"</string>
+    <string name="osu_sign_up_failed" msgid="5605453599586001793">"Dovršavanje registracije nije uspelo. Dodirnite da biste probali ponovo."</string>
+    <string name="osu_sign_up_complete" msgid="7640183358878916847">"Registracija je dovršena. Povezuje se…"</string>
+    <string name="speed_label_very_slow" msgid="8526005255731597666">"Veoma spora"</string>
+    <string name="speed_label_slow" msgid="6069917670665664161">"Spora"</string>
+    <string name="speed_label_okay" msgid="1253594383880810424">"Potvrdi"</string>
+    <string name="speed_label_medium" msgid="9078405312828606976">"Srednja"</string>
+    <string name="speed_label_fast" msgid="2677719134596044051">"Brza"</string>
+    <string name="speed_label_very_fast" msgid="8215718029533182439">"Veoma brza"</string>
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Isteklo"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
-    <string name="bluetooth_disconnected" msgid="7739366554710388701">"Веза је прекинута"</string>
-    <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Прекидање везе..."</string>
-    <string name="bluetooth_connecting" msgid="5871702668260192755">"Повезивање…"</string>
-    <string name="bluetooth_connected" msgid="8065345572198502293">"Повезано: <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_pairing" msgid="4269046942588193600">"Упаривање..."</string>
-    <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Повезано (без телефона): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Повезано (без медија): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Повезано је (без приступа порукама): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Повезано (без телефона или медија): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Повезано, ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Повезано (без телефона), ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="6499078454894324287">"Повезано (без медија), ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"Повезано (без телефона или медија), ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
-    <string name="bluetooth_active_battery_level" msgid="3450745316700494425">"Активан, ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_active_battery_level_untethered" msgid="2706188607604205362">"Активно, Л: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> батерије, Д: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> батерије"</string>
-    <string name="bluetooth_battery_level" msgid="2893696778200201555">"Ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"Л: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> батерије, Д: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> батерије"</string>
-    <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Активан"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Активно, само с леве стране"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Активно, с десне стране"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Активно, с леве и десне стране"</string>
-    <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Звук медија"</string>
-    <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Телефонски позиви"</string>
-    <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Пренос датотеке"</string>
-    <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Улазни уређај"</string>
-    <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Приступ Интернету"</string>
-    <string name="bluetooth_profile_pbap" msgid="4262303387989406171">"Дељење контаката и историје позива"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="6466456791354759132">"Користите за дељење контаката и историје позива"</string>
-    <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Дељење интернет везе"</string>
-    <string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS-ови"</string>
-    <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Приступ SIM картици"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD звук: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD звук"</string>
-    <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Слушни апарати"</string>
+    <string name="bluetooth_disconnected" msgid="7739366554710388701">"Veza je prekinuta"</string>
+    <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Prekidanje veze..."</string>
+    <string name="bluetooth_connecting" msgid="5871702668260192755">"Povezivanje…"</string>
+    <string name="bluetooth_connected" msgid="8065345572198502293">"Povezano: <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_pairing" msgid="4269046942588193600">"Uparivanje..."</string>
+    <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Povezano (bez telefona): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Povezano (bez medija): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Povezano je (bez pristupa porukama): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Povezano (bez telefona ili medija): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Povezano, nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Povezano (bez telefona), nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="6499078454894324287">"Povezano (bez medija), nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"Povezano (bez telefona ili medija), nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
+    <string name="bluetooth_active_battery_level" msgid="3450745316700494425">"Aktivan, nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_active_battery_level_untethered" msgid="2706188607604205362">"Aktivno, L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> baterije, D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> baterije"</string>
+    <string name="bluetooth_battery_level" msgid="2893696778200201555">"Nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> baterije, D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> baterije"</string>
+    <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktivan"</string>
+    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktivno, samo s leve strane"</string>
+    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktivno, s desne strane"</string>
+    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktivno, s leve i desne strane"</string>
+    <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Zvuk medija"</string>
+    <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefonski pozivi"</string>
+    <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Prenos datoteke"</string>
+    <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Ulazni uređaj"</string>
+    <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Pristup Internetu"</string>
+    <string name="bluetooth_profile_pbap" msgid="4262303387989406171">"Deljenje kontakata i istorije poziva"</string>
+    <string name="bluetooth_profile_pbap_summary" msgid="6466456791354759132">"Koristite za deljenje kontakata i istorije poziva"</string>
+    <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Deljenje internet veze"</string>
+    <string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS-ovi"</string>
+    <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Pristup SIM kartici"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD zvuk: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD zvuk"</string>
+    <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Slušni aparati"</string>
     <string name="bluetooth_profile_le_audio" msgid="3237854988278539061">"LE audio"</string>
-    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Повезано са слушним апаратима"</string>
-    <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Повезано са LE audio"</string>
-    <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Повезано са звуком медија"</string>
-    <string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Повезано са звуком телефона"</string>
-    <string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Повезано са сервером за пренос датотека"</string>
-    <string name="bluetooth_map_profile_summary_connected" msgid="4141725591784669181">"Повезано је са мапом"</string>
-    <string name="bluetooth_sap_profile_summary_connected" msgid="1280297388033001037">"Веза са тачком приступа услугама је успостављена"</string>
-    <string name="bluetooth_opp_profile_summary_not_connected" msgid="3959741824627764954">"Није повезано са сервером за пренос датотека"</string>
-    <string name="bluetooth_hid_profile_summary_connected" msgid="3923653977051684833">"Повезан са улазним уређајем"</string>
-    <string name="bluetooth_pan_user_profile_summary_connected" msgid="380469653827505727">"Повезано је са уређајем ради приступа интернету"</string>
-    <string name="bluetooth_pan_nap_profile_summary_connected" msgid="3744773111299503493">"Локална интернет веза се дели са уређајем"</string>
-    <string name="bluetooth_pan_profile_summary_use_for" msgid="7422039765025340313">"Користи за приступ интернету"</string>
-    <string name="bluetooth_map_profile_summary_use_for" msgid="4453622103977592583">"Користи се за мапу"</string>
-    <string name="bluetooth_sap_profile_summary_use_for" msgid="6204902866176714046">"Користи за приступ SIM картици"</string>
-    <string name="bluetooth_a2dp_profile_summary_use_for" msgid="7324694226276491807">"Коришћење за звук медија"</string>
-    <string name="bluetooth_headset_profile_summary_use_for" msgid="808970643123744170">"Коришћење за аудио телефона"</string>
-    <string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Коришћење за пренос датотека"</string>
-    <string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Користи за улаз"</string>
-    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Користи за слушне апарате"</string>
-    <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Користите за LE_AUDIO"</string>
-    <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Упари"</string>
-    <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"УПАРИ"</string>
-    <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Откажи"</string>
-    <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Упаривање омогућава приступ контактима и историји позива након повезивања."</string>
-    <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Упаривање са уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g> није могуће."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Упаривање са уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g> није могуће због нетачног PIN-а или приступног кода."</string>
-    <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Није могуће комуницирати са уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> је одбио/ла упаривање"</string>
-    <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Рачунар"</string>
-    <string name="bluetooth_talkback_headset" msgid="3406852564400882682">"Наглавне слушалице"</string>
-    <string name="bluetooth_talkback_phone" msgid="868393783858123880">"Позови"</string>
-    <string name="bluetooth_talkback_imaging" msgid="8781682986822514331">"Обрада слика"</string>
-    <string name="bluetooth_talkback_headphone" msgid="8613073829180337091">"Слушалице"</string>
-    <string name="bluetooth_talkback_input_peripheral" msgid="5133944817800149942">"Периферни уређај за унос"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Povezano sa slušnim aparatima"</string>
+    <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Povezano sa LE audio"</string>
+    <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Povezano sa zvukom medija"</string>
+    <string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Povezano sa zvukom telefona"</string>
+    <string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Povezano sa serverom za prenos datoteka"</string>
+    <string name="bluetooth_map_profile_summary_connected" msgid="4141725591784669181">"Povezano je sa mapom"</string>
+    <string name="bluetooth_sap_profile_summary_connected" msgid="1280297388033001037">"Veza sa tačkom pristupa uslugama je uspostavljena"</string>
+    <string name="bluetooth_opp_profile_summary_not_connected" msgid="3959741824627764954">"Nije povezano sa serverom za prenos datoteka"</string>
+    <string name="bluetooth_hid_profile_summary_connected" msgid="3923653977051684833">"Povezan sa ulaznim uređajem"</string>
+    <string name="bluetooth_pan_user_profile_summary_connected" msgid="380469653827505727">"Povezano je sa uređajem radi pristupa internetu"</string>
+    <string name="bluetooth_pan_nap_profile_summary_connected" msgid="3744773111299503493">"Lokalna internet veza se deli sa uređajem"</string>
+    <string name="bluetooth_pan_profile_summary_use_for" msgid="7422039765025340313">"Koristi za pristup internetu"</string>
+    <string name="bluetooth_map_profile_summary_use_for" msgid="4453622103977592583">"Koristi se za mapu"</string>
+    <string name="bluetooth_sap_profile_summary_use_for" msgid="6204902866176714046">"Koristi za pristup SIM kartici"</string>
+    <string name="bluetooth_a2dp_profile_summary_use_for" msgid="7324694226276491807">"Korišćenje za zvuk medija"</string>
+    <string name="bluetooth_headset_profile_summary_use_for" msgid="808970643123744170">"Korišćenje za audio telefona"</string>
+    <string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Korišćenje za prenos datoteka"</string>
+    <string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Koristi za ulaz"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Koristi za slušne aparate"</string>
+    <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Koristite za LE_AUDIO"</string>
+    <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Upari"</string>
+    <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"UPARI"</string>
+    <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Otkaži"</string>
+    <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Uparivanje omogućava pristup kontaktima i istoriji poziva nakon povezivanja."</string>
+    <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Uparivanje sa uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g> nije moguće."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Uparivanje sa uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g> nije moguće zbog netačnog PIN-a ili pristupnog koda."</string>
+    <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Nije moguće komunicirati sa uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+    <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> je odbio/la uparivanje"</string>
+    <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Računar"</string>
+    <string name="bluetooth_talkback_headset" msgid="3406852564400882682">"Naglavne slušalice"</string>
+    <string name="bluetooth_talkback_phone" msgid="868393783858123880">"Pozovi"</string>
+    <string name="bluetooth_talkback_imaging" msgid="8781682986822514331">"Obrada slika"</string>
+    <string name="bluetooth_talkback_headphone" msgid="8613073829180337091">"Slušalice"</string>
+    <string name="bluetooth_talkback_input_peripheral" msgid="5133944817800149942">"Periferni uređaj za unos"</string>
     <string name="bluetooth_talkback_bluetooth" msgid="1143241359781999989">"Bluetooth"</string>
-    <string name="accessibility_wifi_off" msgid="1195445715254137155">"WiFi је искључен."</string>
-    <string name="accessibility_no_wifi" msgid="5297119459491085771">"WiFi веза је прекинута."</string>
-    <string name="accessibility_wifi_one_bar" msgid="6025652717281815212">"WiFi сигнал има једну црту."</string>
-    <string name="accessibility_wifi_two_bars" msgid="687800024970972270">"WiFi сигнал има две црте."</string>
-    <string name="accessibility_wifi_three_bars" msgid="779895671061950234">"WiFi сигнал има три црте."</string>
-    <string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"WiFi сигнал је најјачи."</string>
-    <string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Отворена мрежа"</string>
-    <string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Безбедна мрежа"</string>
-    <string name="process_kernel_label" msgid="950292573930336765">"Android ОС"</string>
-    <string name="data_usage_uninstalled_apps" msgid="1933665711856171491">"Уклоњене апликације"</string>
-    <string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"Уклоњене апликације и корисници"</string>
-    <string name="data_usage_ota" msgid="7984667793701597001">"Ажурирања система"</string>
-    <string name="tether_settings_title_usb" msgid="3728686573430917722">"USB привезивање"</string>
-    <string name="tether_settings_title_wifi" msgid="4803402057533895526">"Преносни хотспот"</string>
-    <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Bluetooth привезивање"</string>
-    <string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Привезивање"</string>
-    <string name="tether_settings_title_all" msgid="8910259483383010470">"Привезивање и преносни хотспот"</string>
-    <string name="managed_user_title" msgid="449081789742645723">"Све радне апликације"</string>
-    <string name="unknown" msgid="3544487229740637809">"Непознато"</string>
-    <string name="running_process_item_user_label" msgid="3988506293099805796">"Корисник: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
-    <string name="launch_defaults_some" msgid="3631650616557252926">"Подешене су неке подразумеване вредности"</string>
-    <string name="launch_defaults_none" msgid="8049374306261262709">"Нису подешене подразумеване вредности"</string>
-    <string name="tts_settings" msgid="8130616705989351312">"Подешавања преласка из текста у говор"</string>
-    <string name="tts_settings_title" msgid="7602210956640483039">"Претварање текста у говор"</string>
-    <string name="tts_default_rate_title" msgid="3964187817364304022">"Брзина говора"</string>
-    <string name="tts_default_rate_summary" msgid="3781937042151716987">"Брзина изговарања текста"</string>
-    <string name="tts_default_pitch_title" msgid="6988592215554485479">"Ниво"</string>
-    <string name="tts_default_pitch_summary" msgid="9132719475281551884">"Утиче на тон синтетизованог говора"</string>
-    <string name="tts_default_lang_title" msgid="4698933575028098940">"Језик"</string>
-    <string name="tts_lang_use_system" msgid="6312945299804012406">"Користи језик система"</string>
-    <string name="tts_lang_not_selected" msgid="7927823081096056147">"Језик није изабран"</string>
-    <string name="tts_default_lang_summary" msgid="9042620014800063470">"Подешава глас специфичан за језик намењен говорном тексту"</string>
-    <string name="tts_play_example_title" msgid="1599468547216481684">"Послушај пример"</string>
-    <string name="tts_play_example_summary" msgid="634044730710636383">"Пуштање кратке демонстрације синтезе говора"</string>
-    <string name="tts_install_data_title" msgid="1829942496472751703">"Инсталирај гласовне податке"</string>
-    <string name="tts_install_data_summary" msgid="3608874324992243851">"Инсталирање говорних података потребних за синтезу говора"</string>
-    <string name="tts_engine_security_warning" msgid="3372432853837988146">"Ова технологија за синтезу говора можда може да прикупља сав текст који ће бити изговорен, укључујући личне податке као што су лозинке и бројеви кредитних картица. То потиче из технологије <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>. Желите ли да омогућите коришћење ове технологије за синтезу говора?"</string>
-    <string name="tts_engine_network_required" msgid="8722087649733906851">"За овај језик је потребна исправна мрежна веза за претварање текста у говор."</string>
-    <string name="tts_default_sample_string" msgid="6388016028292967973">"Ово је пример синтезе говора"</string>
-    <string name="tts_status_title" msgid="8190784181389278640">"Статус подразумеваног језика"</string>
-    <string name="tts_status_ok" msgid="8583076006537547379">"<xliff:g id="LOCALE">%1$s</xliff:g> је подржан у потпуности"</string>
-    <string name="tts_status_requires_network" msgid="8327617638884678896">"<xliff:g id="LOCALE">%1$s</xliff:g> захтева везу са мрежом"</string>
-    <string name="tts_status_not_supported" msgid="2702997696245523743">"<xliff:g id="LOCALE">%1$s</xliff:g> није подржан"</string>
-    <string name="tts_status_checking" msgid="8026559918948285013">"Проверава се..."</string>
-    <string name="tts_engine_settings_title" msgid="7849477533103566291">"Подешавања за <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
-    <string name="tts_engine_settings_button" msgid="477155276199968948">"Покрени подешавања машине"</string>
-    <string name="tts_engine_preference_section_title" msgid="3861562305498624904">"Жељена машина"</string>
-    <string name="tts_general_section_title" msgid="8919671529502364567">"Општа"</string>
-    <string name="tts_reset_speech_pitch_title" msgid="7149398585468413246">"Ресетујте висину тона говора"</string>
-    <string name="tts_reset_speech_pitch_summary" msgid="6822904157021406449">"Ресетујте висину тона којом се текст изговара на подразумевану."</string>
+    <string name="accessibility_wifi_off" msgid="1195445715254137155">"WiFi je isključen."</string>
+    <string name="accessibility_no_wifi" msgid="5297119459491085771">"WiFi veza je prekinuta."</string>
+    <string name="accessibility_wifi_one_bar" msgid="6025652717281815212">"WiFi signal ima jednu crtu."</string>
+    <string name="accessibility_wifi_two_bars" msgid="687800024970972270">"WiFi signal ima dve crte."</string>
+    <string name="accessibility_wifi_three_bars" msgid="779895671061950234">"WiFi signal ima tri crte."</string>
+    <string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"WiFi signal je najjači."</string>
+    <string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Otvorena mreža"</string>
+    <string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Bezbedna mreža"</string>
+    <string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
+    <string name="data_usage_uninstalled_apps" msgid="1933665711856171491">"Uklonjene aplikacije"</string>
+    <string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"Uklonjene aplikacije i korisnici"</string>
+    <string name="data_usage_ota" msgid="7984667793701597001">"Ažuriranja sistema"</string>
+    <string name="tether_settings_title_usb" msgid="3728686573430917722">"USB privezivanje"</string>
+    <string name="tether_settings_title_wifi" msgid="4803402057533895526">"Prenosni hotspot"</string>
+    <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Bluetooth privezivanje"</string>
+    <string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Privezivanje"</string>
+    <string name="tether_settings_title_all" msgid="8910259483383010470">"Privezivanje i prenosni hotspot"</string>
+    <string name="managed_user_title" msgid="449081789742645723">"Sve radne aplikacije"</string>
+    <string name="unknown" msgid="3544487229740637809">"Nepoznato"</string>
+    <string name="running_process_item_user_label" msgid="3988506293099805796">"Korisnik: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="launch_defaults_some" msgid="3631650616557252926">"Podešene su neke podrazumevane vrednosti"</string>
+    <string name="launch_defaults_none" msgid="8049374306261262709">"Nisu podešene podrazumevane vrednosti"</string>
+    <string name="tts_settings" msgid="8130616705989351312">"Podešavanja prelaska iz teksta u govor"</string>
+    <string name="tts_settings_title" msgid="7602210956640483039">"Pretvaranje teksta u govor"</string>
+    <string name="tts_default_rate_title" msgid="3964187817364304022">"Brzina govora"</string>
+    <string name="tts_default_rate_summary" msgid="3781937042151716987">"Brzina izgovaranja teksta"</string>
+    <string name="tts_default_pitch_title" msgid="6988592215554485479">"Nivo"</string>
+    <string name="tts_default_pitch_summary" msgid="9132719475281551884">"Utiče na ton sintetizovanog govora"</string>
+    <string name="tts_default_lang_title" msgid="4698933575028098940">"Jezik"</string>
+    <string name="tts_lang_use_system" msgid="6312945299804012406">"Koristi jezik sistema"</string>
+    <string name="tts_lang_not_selected" msgid="7927823081096056147">"Jezik nije izabran"</string>
+    <string name="tts_default_lang_summary" msgid="9042620014800063470">"Podešava glas specifičan za jezik namenjen govornom tekstu"</string>
+    <string name="tts_play_example_title" msgid="1599468547216481684">"Poslušaj primer"</string>
+    <string name="tts_play_example_summary" msgid="634044730710636383">"Puštanje kratke demonstracije sinteze govora"</string>
+    <string name="tts_install_data_title" msgid="1829942496472751703">"Instaliraj glasovne podatke"</string>
+    <string name="tts_install_data_summary" msgid="3608874324992243851">"Instaliranje govornih podataka potrebnih za sintezu govora"</string>
+    <string name="tts_engine_security_warning" msgid="3372432853837988146">"Ova tehnologija za sintezu govora možda može da prikuplja sav tekst koji će biti izgovoren, uključujući lične podatke kao što su lozinke i brojevi kreditnih kartica. To potiče iz tehnologije <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>. Želite li da omogućite korišćenje ove tehnologije za sintezu govora?"</string>
+    <string name="tts_engine_network_required" msgid="8722087649733906851">"Za ovaj jezik je potrebna ispravna mrežna veza za pretvaranje teksta u govor."</string>
+    <string name="tts_default_sample_string" msgid="6388016028292967973">"Ovo je primer sinteze govora"</string>
+    <string name="tts_status_title" msgid="8190784181389278640">"Status podrazumevanog jezika"</string>
+    <string name="tts_status_ok" msgid="8583076006537547379">"<xliff:g id="LOCALE">%1$s</xliff:g> je podržan u potpunosti"</string>
+    <string name="tts_status_requires_network" msgid="8327617638884678896">"<xliff:g id="LOCALE">%1$s</xliff:g> zahteva vezu sa mrežom"</string>
+    <string name="tts_status_not_supported" msgid="2702997696245523743">"<xliff:g id="LOCALE">%1$s</xliff:g> nije podržan"</string>
+    <string name="tts_status_checking" msgid="8026559918948285013">"Proverava se..."</string>
+    <string name="tts_engine_settings_title" msgid="7849477533103566291">"Podešavanja za <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
+    <string name="tts_engine_settings_button" msgid="477155276199968948">"Pokreni podešavanja mašine"</string>
+    <string name="tts_engine_preference_section_title" msgid="3861562305498624904">"Željena mašina"</string>
+    <string name="tts_general_section_title" msgid="8919671529502364567">"Opšta"</string>
+    <string name="tts_reset_speech_pitch_title" msgid="7149398585468413246">"Resetujte visinu tona govora"</string>
+    <string name="tts_reset_speech_pitch_summary" msgid="6822904157021406449">"Resetujte visinu tona kojom se tekst izgovara na podrazumevanu."</string>
   <string-array name="tts_rate_entries">
-    <item msgid="9004239613505400644">"Веома споро"</item>
-    <item msgid="1815382991399815061">"Споро"</item>
-    <item msgid="3075292553049300105">"Нормално"</item>
-    <item msgid="1158955023692670059">"Брзо"</item>
-    <item msgid="5664310435707146591">"Брже"</item>
-    <item msgid="5491266922147715962">"Веома брзо"</item>
-    <item msgid="7659240015901486196">"Убрзано"</item>
-    <item msgid="7147051179282410945">"Веома убрзано"</item>
-    <item msgid="581904787661470707">"Најбрже"</item>
+    <item msgid="9004239613505400644">"Veoma sporo"</item>
+    <item msgid="1815382991399815061">"Sporo"</item>
+    <item msgid="3075292553049300105">"Normalno"</item>
+    <item msgid="1158955023692670059">"Brzo"</item>
+    <item msgid="5664310435707146591">"Brže"</item>
+    <item msgid="5491266922147715962">"Veoma brzo"</item>
+    <item msgid="7659240015901486196">"Ubrzano"</item>
+    <item msgid="7147051179282410945">"Veoma ubrzano"</item>
+    <item msgid="581904787661470707">"Najbrže"</item>
   </string-array>
-    <string name="choose_profile" msgid="343803890897657450">"Изаберите профил"</string>
-    <string name="category_personal" msgid="6236798763159385225">"Лично"</string>
-    <string name="category_work" msgid="4014193632325996115">"Посао"</string>
-    <string name="development_settings_title" msgid="140296922921597393">"Опције за програмере"</string>
-    <string name="development_settings_enable" msgid="4285094651288242183">"Омогући опције за програмере"</string>
-    <string name="development_settings_summary" msgid="8718917813868735095">"Подешавање опција за програмирање апликације"</string>
-    <string name="development_settings_not_available" msgid="355070198089140951">"Опције за програмере нису доступне за овог корисника"</string>
-    <string name="vpn_settings_not_available" msgid="2894137119965668920">"Подешавања VPN-а нису доступна за овог корисника"</string>
-    <string name="tethering_settings_not_available" msgid="266821736434699780">"Подешавања привезивања нису доступна за овог корисника"</string>
-    <string name="apn_settings_not_available" msgid="1147111671403342300">"Подешавања назива приступне тачке нису доступна за овог корисника"</string>
-    <string name="enable_adb" msgid="8072776357237289039">"Отклањање USB грешака"</string>
-    <string name="enable_adb_summary" msgid="3711526030096574316">"Режим отклањања грешака када је USB повезан"</string>
-    <string name="clear_adb_keys" msgid="3010148733140369917">"Опозивање одобрења за уклањање USB грешака"</string>
-    <string name="enable_adb_wireless" msgid="6973226350963971018">"Бежично отклањање грешака"</string>
-    <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Режим за отклањање грешака када је Wi‑Fi повезан"</string>
-    <string name="adb_wireless_error" msgid="721958772149779856">"Грешка"</string>
-    <string name="adb_wireless_settings" msgid="2295017847215680229">"Бежично отклањање грешака"</string>
-    <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Да бисте видели и користили доступне уређаје, укључите бежично отклањање грешака"</string>
-    <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Упарите уређај помоћу QR кода"</string>
-    <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Упарите нове уређаје помоћу читача QR кода"</string>
-    <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Упарите уређај помоћу кода за упаривање"</string>
-    <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Упарите нове уређаје помоћу шестоцифреног кода"</string>
-    <string name="adb_paired_devices_title" msgid="5268997341526217362">"Упарени уређаји"</string>
-    <string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"Тренутно је повезано"</string>
-    <string name="adb_wireless_device_details_title" msgid="7129369670526565786">"Детаљи о уређају"</string>
-    <string name="adb_device_forget" msgid="193072400783068417">"Заборави"</string>
-    <string name="adb_device_fingerprint_title_format" msgid="291504822917843701">"Отисак прста на уређају: <xliff:g id="FINGERPRINT_PARAM">%1$s</xliff:g>"</string>
-    <string name="adb_wireless_connection_failed_title" msgid="664211177427438438">"Повезивање није успело"</string>
-    <string name="adb_wireless_connection_failed_message" msgid="9213896700171602073">"Уверите се да је <xliff:g id="DEVICE_NAME">%1$s</xliff:g> повезан са одговарајућом мрежом"</string>
-    <string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"Упарите са уређајем"</string>
-    <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Кôд за упаривање преко Wi‑Fi-ја"</string>
-    <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Упаривање није успело"</string>
-    <string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Уверите се да је уређај повезан на исту мрежу."</string>
-    <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Упарите уређај помоћу Wi‑Fi мреже или тако што ћете скенирати QR кôд"</string>
-    <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Упарује се уређај…"</string>
-    <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Упаривање уређаја није успело. QR кôд је погрешан или уређај није повезан са истом мрежом."</string>
-    <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP адреса и порт"</string>
-    <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Скенирај QR кôд"</string>
-    <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Упарите уређај помоћу Wi‑Fi мреже тако што ћете скенирати QR кôд"</string>
-    <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Повежите се на WiFi мрежу"</string>
-    <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, отклањање грешака, програмер"</string>
-    <string name="bugreport_in_power" msgid="8664089072534638709">"Пречица за извештај о грешкама"</string>
-    <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Приказује дугме у менију дугмета за укључивање за прављење извештаја о грешкама"</string>
-    <string name="keep_screen_on" msgid="1187161672348797558">"Не закључавај"</string>
-    <string name="keep_screen_on_summary" msgid="1510731514101925829">"Екран неће бити у режиму спавања током пуњења"</string>
-    <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Омогући snoop евид. за Bluetooth HCI"</string>
-    <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"Сними Bluetooth пакете. (Укључите/искључите Bluetooth када промените ово подешавање)"</string>
-    <string name="oem_unlock_enable" msgid="5334869171871566731">"Откључавање OEM-a"</string>
-    <string name="oem_unlock_enable_summary" msgid="5857388174390953829">"Дозволи откључавање функције за покретање"</string>
-    <string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"Желите ли да дозволите откључавање произвођача оригиналне опреме (OEM)?"</string>
-    <string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"УПОЗОРЕЊЕ: Функције за заштиту уређаја неће функционисати на овом уређају док је ово подешавање укључено."</string>
-    <string name="mock_location_app" msgid="6269380172542248304">"Изаберите апликацију за лажну локацију"</string>
-    <string name="mock_location_app_not_set" msgid="6972032787262831155">"Апликација за лажну локацију није подешена"</string>
-    <string name="mock_location_app_set" msgid="4706722469342913843">"Апликација за лажну локацију: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="debug_networking_category" msgid="6829757985772659599">"Умрежавање"</string>
-    <string name="wifi_display_certification" msgid="1805579519992520381">"Сертификација бежичног екрана"</string>
-    <string name="wifi_verbose_logging" msgid="1785910450009679371">"Омогући детаљнију евиденцију за Wi‑Fi"</string>
-    <string name="wifi_scan_throttling" msgid="2985624788509913617">"Успоравање WiFi скенирања"</string>
-    <string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"Насумично разврставање MAC адреса по WiFi-ју са прекидима"</string>
-    <string name="mobile_data_always_on" msgid="8275958101875563572">"Мобилни подаци су увек активни"</string>
-    <string name="tethering_hardware_offload" msgid="4116053719006939161">"Хардверско убрзање привезивања"</string>
-    <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Прикажи Bluetooth уређаје без назива"</string>
-    <string name="bluetooth_disable_absolute_volume" msgid="1452342324349203434">"Онемогући главно подешавање јачине звука"</string>
-    <string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Омогући Gabeldorsche"</string>
-    <string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Верзија Bluetooth AVRCP-а"</string>
-    <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Изаберите верзију Bluetooth AVRCP-а"</string>
-    <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Верзија Bluetooth MAP-а"</string>
-    <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Изаберите верзију Bluetooth MAP-а"</string>
-    <string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth аудио кодек"</string>
-    <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Изаберите Bluetooth аудио кодек\n"</string>
-    <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Брзина узорковања за Bluetooth аудио"</string>
-    <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title" msgid="5876305103137067798">"Изаберите Bluetooth аудио кодек:\n брзина узорковања"</string>
-    <string name="bluetooth_select_a2dp_codec_type_help_info" msgid="8647200416514412338">"Ако је нека ставка засивљена, то значи да је телефон или слушалице не подржавају"</string>
-    <string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="6253965294594390806">"Битова по узорку за Bluetooth аудио"</string>
-    <string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="4898693684282596143">"Изаберите Bluetooth аудио кодек:\n број битова по узорку"</string>
-    <string name="bluetooth_select_a2dp_codec_channel_mode" msgid="364277285688014427">"Режим канала за Bluetooth аудио"</string>
-    <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="2076949781460359589">"Изаберите Bluetooth аудио кодек:\n режим канала"</string>
-    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3233402355917446304">"Bluetooth аудио кодек LDAC: квалитет репродукције"</string>
-    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"Изаберите Bluetooth аудио LDAC кодек:\n квалитет снимка"</string>
-    <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"Стримовање: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
-    <string name="select_private_dns_configuration_title" msgid="7887550926056143018">"Приватни DNS"</string>
-    <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"Изаберите режим приватног DNS-а"</string>
-    <string name="private_dns_mode_off" msgid="7065962499349997041">"Искључено"</string>
-    <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"Аутоматски"</string>
-    <string name="private_dns_mode_provider" msgid="3619040641762557028">"Име хоста добављача услуге приватног DNS-а"</string>
-    <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"Унесите име хоста добављача услуге DNS-а"</string>
-    <string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"Повезивање није успело"</string>
-    <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Приказује опције за сертификацију бежичног екрана"</string>
-    <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Повећава ниво евидентирања за Wi‑Fi. Приказ по SSID RSSI-у у бирачу Wi‑Fi мреже"</string>
-    <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Смањује потрошњу батерије и побољшава учинак мреже"</string>
-    <string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Када је овај режим омогућен, MAC адреса овог уређаја може да се промени сваки пут када се повеже са мрежом на којој је омогућено насумично разврставање MAC адреса."</string>
-    <string name="wifi_metered_label" msgid="8737187690304098638">"Са ограничењем"</string>
-    <string name="wifi_unmetered_label" msgid="6174142840934095093">"Без ограничења"</string>
-    <string name="select_logd_size_title" msgid="1604578195914595173">"Величине бафера података у програму за евидентирање"</string>
-    <string name="select_logd_size_dialog_title" msgid="2105401994681013578">"Изаберите величине по баферу евиденције"</string>
-    <string name="dev_logpersist_clear_warning_title" msgid="8631859265777337991">"Желите ли да обришете стални меморијски простор програма за евидентирање?"</string>
-    <string name="dev_logpersist_clear_warning_message" msgid="6447590867594287413">"Када их више не надгледамо помоћу сталног програма за евидентирање, дужни смо да обришемо податке из програма за евидентирање који су трајно смештени на уређају."</string>
-    <string name="select_logpersist_title" msgid="447071974007104196">"Чувај евидентиране податке на уређају"</string>
-    <string name="select_logpersist_dialog_title" msgid="7745193591195485594">"Изаберите међумеморије евиденције које ћете стално чувати на уређају."</string>
-    <string name="select_usb_configuration_title" msgid="6339801314922294586">"Изаберите конфигурацију USB-а"</string>
-    <string name="select_usb_configuration_dialog_title" msgid="3579567144722589237">"Изаберите конфигурацију USB-а"</string>
-    <string name="allow_mock_location" msgid="2102650981552527884">"Дозволи лажне локације"</string>
-    <string name="allow_mock_location_summary" msgid="179780881081354579">"Дозволи лажне локације"</string>
-    <string name="debug_view_attributes" msgid="3539609843984208216">"Омогући проверу атрибута за преглед"</string>
-    <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Мобилни подаци су увек активни, чак и када је Wi‑Fi активан (ради брзе промене мреже)."</string>
-    <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Користи се хардверско убрзање привезивања ако је доступно"</string>
-    <string name="adb_warning_title" msgid="7708653449506485728">"Дозволи отклањање USB грешака?"</string>
-    <string name="adb_warning_message" msgid="8145270656419669221">"Отклањање USB грешака намењено је само за сврхе програмирања. Користите га за копирање података са рачунара на уређај и обратно, инсталирање апликација на уређају без обавештења и читање података из евиденције."</string>
-    <string name="adbwifi_warning_title" msgid="727104571653031865">"Желите да дозволите бежично отклањање грешака?"</string>
-    <string name="adbwifi_warning_message" msgid="8005936574322702388">"Бежично отклањање грешака намењено је само програмирању. Користите га за копирање података са рачунара на уређај и обратно, инсталирање апликација на уређају без обавештења и читање података из евиденције."</string>
-    <string name="adb_keys_warning_message" msgid="2968555274488101220">"Желите ли да опозовете приступ отклањању USB грешака са свих рачунара које сте претходно одобрили?"</string>
-    <string name="dev_settings_warning_title" msgid="8251234890169074553">"Желите ли да омогућите програмерска подешавања?"</string>
-    <string name="dev_settings_warning_message" msgid="37741686486073668">"Ова подешавања су намењена само за програмирање. Могу да изазову престанак функционисања или неочекивано понашање уређаја и апликација на њему."</string>
-    <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Верификуј апликације преко USB-а"</string>
-    <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Проверава да ли су апликације инсталиране преко ADB-а/ADT-а штетне."</string>
-    <string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Приказује Bluetooth уређаје без назива (само MAC адресе)"</string>
-    <string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Онемогућава главно подешавање јачине звука на Bluetooth уређају у случају проблема са јачином звука на даљинским уређајима, као што су изузетно велика јачина звука или недостатак контроле."</string>
-    <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Омогућава групу Bluetooth Gabeldorsche функција."</string>
-    <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Омогућава функцију Побољшано повезивање."</string>
-    <string name="enable_terminal_title" msgid="3834790541986303654">"Локални терминал"</string>
-    <string name="enable_terminal_summary" msgid="2481074834856064500">"Омогући апл. терминала за приступ локалном командном окружењу"</string>
-    <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP провера"</string>
-    <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Подешавање понашања HDCP провере"</string>
-    <string name="debug_debugging_category" msgid="535341063709248842">"Отклањање грешака"</string>
-    <string name="debug_app" msgid="8903350241392391766">"Изаберите апликацију за отклањање грешака"</string>
-    <string name="debug_app_not_set" msgid="1934083001283807188">"Нема подешених апликација за отклањање грешака"</string>
-    <string name="debug_app_set" msgid="6599535090477753651">"Апликација за отклањање грешака: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="select_application" msgid="2543228890535466325">"Бирање апликације"</string>
-    <string name="no_application" msgid="9038334538870247690">"Ниједна"</string>
-    <string name="wait_for_debugger" msgid="7461199843335409809">"Сачекај програм за отклањање грешака"</string>
-    <string name="wait_for_debugger_summary" msgid="6846330006113363286">"Апликација чека програм за отклањање грешака да приложи пре извршавања"</string>
-    <string name="debug_input_category" msgid="7349460906970849771">"Унос"</string>
-    <string name="debug_drawing_category" msgid="5066171112313666619">"Цртање"</string>
-    <string name="debug_hw_drawing_category" msgid="5830815169336975162">"Хардверски убрзано приказивање"</string>
-    <string name="media_category" msgid="8122076702526144053">"Медији"</string>
-    <string name="debug_monitoring_category" msgid="1597387133765424994">"Надгледање"</string>
-    <string name="strict_mode" msgid="889864762140862437">"Омогућен је строги режим"</string>
-    <string name="strict_mode_summary" msgid="1838248687233554654">"Екран трепери када апликације обављају дуге операције на главној нити"</string>
-    <string name="pointer_location" msgid="7516929526199520173">"Локација показивача"</string>
-    <string name="pointer_location_summary" msgid="957120116989798464">"Преклопни елемент са тренутним подацима о додиру"</string>
-    <string name="show_touches" msgid="8437666942161289025">"Приказуј додире"</string>
-    <string name="show_touches_summary" msgid="3692861665994502193">"Приказује визуелне повратне информације за додире"</string>
-    <string name="show_screen_updates" msgid="2078782895825535494">"Прикажи ажурирања површине"</string>
-    <string name="show_screen_updates_summary" msgid="2126932969682087406">"Осветљава све површине прозора када се ажурирају"</string>
-    <string name="show_hw_screen_updates" msgid="2021286231267747506">"Прикажи ажурирања приказа"</string>
-    <string name="show_hw_screen_updates_summary" msgid="3539770072741435691">"Осветљава приказе у прозорима када се црта"</string>
-    <string name="show_hw_layers_updates" msgid="5268370750002509767">"Прикажи ажурирања хардверских слојева"</string>
-    <string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"Хардверски слојеви трепере зелено када се ажурирају"</string>
-    <string name="debug_hw_overdraw" msgid="8944851091008756796">"Отклони грешке GPU преклапања"</string>
-    <string name="disable_overlays" msgid="4206590799671557143">"Онемогући HW постављене елементе"</string>
-    <string name="disable_overlays_summary" msgid="1954852414363338166">"Увек се користи GPU за компоновање екрана"</string>
-    <string name="simulate_color_space" msgid="1206503300335835151">"Симулирај простор боје"</string>
-    <string name="enable_opengl_traces_title" msgid="4638773318659125196">"Омогући OpenGL трагове"</string>
-    <string name="usb_audio_disable_routing" msgid="3367656923544254975">"Онемогући USB преусм. звука"</string>
-    <string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"Онемогућава аутоматско преусмеравање на USB аудио периферне уређаје"</string>
-    <string name="debug_layout" msgid="1659216803043339741">"Прикажи границе распореда"</string>
-    <string name="debug_layout_summary" msgid="8825829038287321978">"Приказује границе клипа, маргине итд."</string>
-    <string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Наметни смер распореда здесна налево"</string>
-    <string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Намеће смер распореда екрана здесна налево за све локалитете"</string>
-    <string name="window_blurs" msgid="6831008984828425106">"Дозволи замагљења прозора"</string>
-    <string name="force_msaa" msgid="4081288296137775550">"Наметни 4x MSAA"</string>
-    <string name="force_msaa_summary" msgid="9070437493586769500">"Омогућава 4x MSAA у OpenGL ES 2.0 апликацијама"</string>
-    <string name="show_non_rect_clip" msgid="7499758654867881817">"Отклони грешке исецања области неправоугаоног облика"</string>
-    <string name="track_frame_time" msgid="522674651937771106">"Рендеруј помоћу HWUI-а"</string>
-    <string name="enable_gpu_debug_layers" msgid="4986675516188740397">"Омогући слојеве за отклањање грешака GPU-a"</string>
-    <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Учитава отклањање грешака GPU-a у апл. за отклањање грешака"</string>
-    <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Опширне евиденције продавца"</string>
-    <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Уврштава у извештаје о грешкама додатне посебне евиденције продавца за уређаје, које могу да садрже приватне податке, да троше више батерије и/или да користе више меморије."</string>
-    <string name="window_animation_scale_title" msgid="5236381298376812508">"Размера анимације прозора"</string>
-    <string name="transition_animation_scale_title" msgid="1278477690695439337">"Размера анимације прелаза"</string>
-    <string name="animator_duration_scale_title" msgid="7082913931326085176">"Аниматорова размера трајања"</string>
-    <string name="overlay_display_devices_title" msgid="5411894622334469607">"Симулирај секундарне екране"</string>
-    <string name="debug_applications_category" msgid="5394089406638954196">"Апликације"</string>
-    <string name="immediately_destroy_activities" msgid="1826287490705167403">"Не чувај активности"</string>
-    <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Уништава сваку активност чим је корисник напусти"</string>
-    <string name="app_process_limit_title" msgid="8361367869453043007">"Ограничење позадинских процеса"</string>
-    <string name="show_all_anrs" msgid="9160563836616468726">"Прикажи ANR-ове у позадини"</string>
-    <string name="show_all_anrs_summary" msgid="8562788834431971392">"Приказује дијалог Апликација не реагује за апликације у позадини"</string>
-    <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Приказуј упозорења због канала за обавештења"</string>
-    <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Приказује упозорење на екрану када апликација постави обавештење без важећег канала"</string>
-    <string name="force_allow_on_external" msgid="9187902444231637880">"Принудно дозволи апликације у спољној"</string>
-    <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Омогућава уписивање свих апликација у спољну меморију, без обзира на вредности манифеста"</string>
-    <string name="force_resizable_activities" msgid="7143612144399959606">"Принудно омогући промену величине активности"</string>
-    <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Омогућава промену величине свих активности за режим са више прозора, без обзира на вредности манифеста."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Омогући прозоре произвољног формата"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Омогућава подршку за експерименталне прозоре произвољног формата."</string>
-    <string name="desktop_mode" msgid="2389067840550544462">"Режим за рачунаре"</string>
-    <string name="local_backup_password_title" msgid="4631017948933578709">"Лозинка резервне копије за рачунар"</string>
-    <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Резервне копије читавог система тренутно нису заштићене"</string>
-    <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Додирните да бисте променили или уклонили лозинку за прављење резервних копија читавог система на рачунару"</string>
-    <string name="local_backup_password_toast_success" msgid="4891666204428091604">"Постављена је нова лозинка резервне копије"</string>
-    <string name="local_backup_password_toast_confirmation_mismatch" msgid="2994718182129097733">"Нова лозинка и њена потврда се не подударају"</string>
-    <string name="local_backup_password_toast_validation_failure" msgid="714669442363647122">"Постављање лозинке резервне копије није успело"</string>
-    <string name="loading_injected_setting_summary" msgid="8394446285689070348">"Учитава се…"</string>
+    <string name="choose_profile" msgid="343803890897657450">"Izaberite profil"</string>
+    <string name="category_personal" msgid="6236798763159385225">"Lično"</string>
+    <string name="category_work" msgid="4014193632325996115">"Posao"</string>
+    <string name="development_settings_title" msgid="140296922921597393">"Opcije za programere"</string>
+    <string name="development_settings_enable" msgid="4285094651288242183">"Omogući opcije za programere"</string>
+    <string name="development_settings_summary" msgid="8718917813868735095">"Podešavanje opcija za programiranje aplikacije"</string>
+    <string name="development_settings_not_available" msgid="355070198089140951">"Opcije za programere nisu dostupne za ovog korisnika"</string>
+    <string name="vpn_settings_not_available" msgid="2894137119965668920">"Podešavanja VPN-a nisu dostupna za ovog korisnika"</string>
+    <string name="tethering_settings_not_available" msgid="266821736434699780">"Podešavanja privezivanja nisu dostupna za ovog korisnika"</string>
+    <string name="apn_settings_not_available" msgid="1147111671403342300">"Podešavanja naziva pristupne tačke nisu dostupna za ovog korisnika"</string>
+    <string name="enable_adb" msgid="8072776357237289039">"Otklanjanje USB grešaka"</string>
+    <string name="enable_adb_summary" msgid="3711526030096574316">"Režim otklanjanja grešaka kada je USB povezan"</string>
+    <string name="clear_adb_keys" msgid="3010148733140369917">"Opozivanje odobrenja za uklanjanje USB grešaka"</string>
+    <string name="enable_adb_wireless" msgid="6973226350963971018">"Bežično otklanjanje grešaka"</string>
+    <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Režim za otklanjanje grešaka kada je Wi‑Fi povezan"</string>
+    <string name="adb_wireless_error" msgid="721958772149779856">"Greška"</string>
+    <string name="adb_wireless_settings" msgid="2295017847215680229">"Bežično otklanjanje grešaka"</string>
+    <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Da biste videli i koristili dostupne uređaje, uključite bežično otklanjanje grešaka"</string>
+    <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Uparite uređaj pomoću QR koda"</string>
+    <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Uparite nove uređaje pomoću čitača QR koda"</string>
+    <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Uparite uređaj pomoću koda za uparivanje"</string>
+    <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Uparite nove uređaje pomoću šestocifrenog koda"</string>
+    <string name="adb_paired_devices_title" msgid="5268997341526217362">"Upareni uređaji"</string>
+    <string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"Trenutno je povezano"</string>
+    <string name="adb_wireless_device_details_title" msgid="7129369670526565786">"Detalji o uređaju"</string>
+    <string name="adb_device_forget" msgid="193072400783068417">"Zaboravi"</string>
+    <string name="adb_device_fingerprint_title_format" msgid="291504822917843701">"Otisak prsta na uređaju: <xliff:g id="FINGERPRINT_PARAM">%1$s</xliff:g>"</string>
+    <string name="adb_wireless_connection_failed_title" msgid="664211177427438438">"Povezivanje nije uspelo"</string>
+    <string name="adb_wireless_connection_failed_message" msgid="9213896700171602073">"Uverite se da je <xliff:g id="DEVICE_NAME">%1$s</xliff:g> povezan sa odgovarajućom mrežom"</string>
+    <string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"Uparite sa uređajem"</string>
+    <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Kôd za uparivanje preko Wi‑Fi-ja"</string>
+    <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Uparivanje nije uspelo"</string>
+    <string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Uverite se da je uređaj povezan na istu mrežu."</string>
+    <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Uparite uređaj pomoću Wi‑Fi mreže ili tako što ćete skenirati QR kôd"</string>
+    <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Uparuje se uređaj…"</string>
+    <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Uparivanje uređaja nije uspelo. QR kôd je pogrešan ili uređaj nije povezan sa istom mrežom."</string>
+    <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP adresa i port"</string>
+    <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Skeniraj QR kôd"</string>
+    <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Uparite uređaj pomoću Wi‑Fi mreže tako što ćete skenirati QR kôd"</string>
+    <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Povežite se na WiFi mrežu"</string>
+    <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, otklanjanje grešaka, programer"</string>
+    <string name="bugreport_in_power" msgid="8664089072534638709">"Prečica za izveštaj o greškama"</string>
+    <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Prikazuje dugme u meniju dugmeta za uključivanje za pravljenje izveštaja o greškama"</string>
+    <string name="keep_screen_on" msgid="1187161672348797558">"Ne zaključavaj"</string>
+    <string name="keep_screen_on_summary" msgid="1510731514101925829">"Ekran neće biti u režimu spavanja tokom punjenja"</string>
+    <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Omogući snoop evid. za Bluetooth HCI"</string>
+    <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"Snimi Bluetooth pakete. (Uključite/isključite Bluetooth kada promenite ovo podešavanje)"</string>
+    <string name="oem_unlock_enable" msgid="5334869171871566731">"Otključavanje OEM-a"</string>
+    <string name="oem_unlock_enable_summary" msgid="5857388174390953829">"Dozvoli otključavanje funkcije za pokretanje"</string>
+    <string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"Želite li da dozvolite otključavanje proizvođača originalne opreme (OEM)?"</string>
+    <string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"UPOZORENJE: Funkcije za zaštitu uređaja neće funkcionisati na ovom uređaju dok je ovo podešavanje uključeno."</string>
+    <string name="mock_location_app" msgid="6269380172542248304">"Izaberite aplikaciju za lažnu lokaciju"</string>
+    <string name="mock_location_app_not_set" msgid="6972032787262831155">"Aplikacija za lažnu lokaciju nije podešena"</string>
+    <string name="mock_location_app_set" msgid="4706722469342913843">"Aplikacija za lažnu lokaciju: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="debug_networking_category" msgid="6829757985772659599">"Umrežavanje"</string>
+    <string name="wifi_display_certification" msgid="1805579519992520381">"Sertifikacija bežičnog ekrana"</string>
+    <string name="wifi_verbose_logging" msgid="1785910450009679371">"Omogući detaljniju evidenciju za Wi‑Fi"</string>
+    <string name="wifi_scan_throttling" msgid="2985624788509913617">"Usporavanje WiFi skeniranja"</string>
+    <string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"Nasumično razvrstavanje MAC adresa po WiFi-ju sa prekidima"</string>
+    <string name="mobile_data_always_on" msgid="8275958101875563572">"Mobilni podaci su uvek aktivni"</string>
+    <string name="tethering_hardware_offload" msgid="4116053719006939161">"Hardversko ubrzanje privezivanja"</string>
+    <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Prikaži Bluetooth uređaje bez naziva"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="1452342324349203434">"Onemogući glavno podešavanje jačine zvuka"</string>
+    <string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Omogući Gabeldorsche"</string>
+    <string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Verzija Bluetooth AVRCP-a"</string>
+    <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Izaberite verziju Bluetooth AVRCP-a"</string>
+    <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Verzija Bluetooth MAP-a"</string>
+    <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Izaberite verziju Bluetooth MAP-a"</string>
+    <string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth audio kodek"</string>
+    <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Izaberite Bluetooth audio kodek\n"</string>
+    <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Brzina uzorkovanja za Bluetooth audio"</string>
+    <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title" msgid="5876305103137067798">"Izaberite Bluetooth audio kodek:\n brzina uzorkovanja"</string>
+    <string name="bluetooth_select_a2dp_codec_type_help_info" msgid="8647200416514412338">"Ako je neka stavka zasivljena, to znači da je telefon ili slušalice ne podržavaju"</string>
+    <string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="6253965294594390806">"Bitova po uzorku za Bluetooth audio"</string>
+    <string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="4898693684282596143">"Izaberite Bluetooth audio kodek:\n broj bitova po uzorku"</string>
+    <string name="bluetooth_select_a2dp_codec_channel_mode" msgid="364277285688014427">"Režim kanala za Bluetooth audio"</string>
+    <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="2076949781460359589">"Izaberite Bluetooth audio kodek:\n režim kanala"</string>
+    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3233402355917446304">"Bluetooth audio kodek LDAC: kvalitet reprodukcije"</string>
+    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"Izaberite Bluetooth audio LDAC kodek:\n kvalitet snimka"</string>
+    <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"Strimovanje: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
+    <string name="select_private_dns_configuration_title" msgid="7887550926056143018">"Privatni DNS"</string>
+    <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"Izaberite režim privatnog DNS-a"</string>
+    <string name="private_dns_mode_off" msgid="7065962499349997041">"Isključeno"</string>
+    <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"Automatski"</string>
+    <string name="private_dns_mode_provider" msgid="3619040641762557028">"Ime hosta dobavljača usluge privatnog DNS-a"</string>
+    <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"Unesite ime hosta dobavljača usluge DNS-a"</string>
+    <string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"Povezivanje nije uspelo"</string>
+    <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Prikazuje opcije za sertifikaciju bežičnog ekrana"</string>
+    <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Povećava nivo evidentiranja za Wi‑Fi. Prikaz po SSID RSSI-u u biraču Wi‑Fi mreže"</string>
+    <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Smanjuje potrošnju baterije i poboljšava učinak mreže"</string>
+    <string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Kada je ovaj režim omogućen, MAC adresa ovog uređaja može da se promeni svaki put kada se poveže sa mrežom na kojoj je omogućeno nasumično razvrstavanje MAC adresa."</string>
+    <string name="wifi_metered_label" msgid="8737187690304098638">"Sa ograničenjem"</string>
+    <string name="wifi_unmetered_label" msgid="6174142840934095093">"Bez ograničenja"</string>
+    <string name="select_logd_size_title" msgid="1604578195914595173">"Veličine bafera podataka u programu za evidentiranje"</string>
+    <string name="select_logd_size_dialog_title" msgid="2105401994681013578">"Izaberite veličine po baferu evidencije"</string>
+    <string name="dev_logpersist_clear_warning_title" msgid="8631859265777337991">"Želite li da obrišete stalni memorijski prostor programa za evidentiranje?"</string>
+    <string name="dev_logpersist_clear_warning_message" msgid="6447590867594287413">"Kada ih više ne nadgledamo pomoću stalnog programa za evidentiranje, dužni smo da obrišemo podatke iz programa za evidentiranje koji su trajno smešteni na uređaju."</string>
+    <string name="select_logpersist_title" msgid="447071974007104196">"Čuvaj evidentirane podatke na uređaju"</string>
+    <string name="select_logpersist_dialog_title" msgid="7745193591195485594">"Izaberite međumemorije evidencije koje ćete stalno čuvati na uređaju."</string>
+    <string name="select_usb_configuration_title" msgid="6339801314922294586">"Izaberite konfiguraciju USB-a"</string>
+    <string name="select_usb_configuration_dialog_title" msgid="3579567144722589237">"Izaberite konfiguraciju USB-a"</string>
+    <string name="allow_mock_location" msgid="2102650981552527884">"Dozvoli lažne lokacije"</string>
+    <string name="allow_mock_location_summary" msgid="179780881081354579">"Dozvoli lažne lokacije"</string>
+    <string name="debug_view_attributes" msgid="3539609843984208216">"Omogući proveru atributa za pregled"</string>
+    <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Mobilni podaci su uvek aktivni, čak i kada je Wi‑Fi aktivan (radi brze promene mreže)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Koristi se hardversko ubrzanje privezivanja ako je dostupno"</string>
+    <string name="adb_warning_title" msgid="7708653449506485728">"Dozvoli otklanjanje USB grešaka?"</string>
+    <string name="adb_warning_message" msgid="8145270656419669221">"Otklanjanje USB grešaka namenjeno je samo za svrhe programiranja. Koristite ga za kopiranje podataka sa računara na uređaj i obratno, instaliranje aplikacija na uređaju bez obaveštenja i čitanje podataka iz evidencije."</string>
+    <string name="adbwifi_warning_title" msgid="727104571653031865">"Želite da dozvolite bežično otklanjanje grešaka?"</string>
+    <string name="adbwifi_warning_message" msgid="8005936574322702388">"Bežično otklanjanje grešaka namenjeno je samo programiranju. Koristite ga za kopiranje podataka sa računara na uređaj i obratno, instaliranje aplikacija na uređaju bez obaveštenja i čitanje podataka iz evidencije."</string>
+    <string name="adb_keys_warning_message" msgid="2968555274488101220">"Želite li da opozovete pristup otklanjanju USB grešaka sa svih računara koje ste prethodno odobrili?"</string>
+    <string name="dev_settings_warning_title" msgid="8251234890169074553">"Želite li da omogućite programerska podešavanja?"</string>
+    <string name="dev_settings_warning_message" msgid="37741686486073668">"Ova podešavanja su namenjena samo za programiranje. Mogu da izazovu prestanak funkcionisanja ili neočekivano ponašanje uređaja i aplikacija na njemu."</string>
+    <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Verifikuj aplikacije preko USB-a"</string>
+    <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Proverava da li su aplikacije instalirane preko ADB-a/ADT-a štetne."</string>
+    <string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Prikazuje Bluetooth uređaje bez naziva (samo MAC adrese)"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Onemogućava glavno podešavanje jačine zvuka na Bluetooth uređaju u slučaju problema sa jačinom zvuka na daljinskim uređajima, kao što su izuzetno velika jačina zvuka ili nedostatak kontrole."</string>
+    <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Omogućava grupu Bluetooth Gabeldorsche funkcija."</string>
+    <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Omogućava funkciju Poboljšano povezivanje."</string>
+    <string name="enable_terminal_title" msgid="3834790541986303654">"Lokalni terminal"</string>
+    <string name="enable_terminal_summary" msgid="2481074834856064500">"Omogući apl. terminala za pristup lokalnom komandnom okruženju"</string>
+    <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP provera"</string>
+    <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Podešavanje ponašanja HDCP provere"</string>
+    <string name="debug_debugging_category" msgid="535341063709248842">"Otklanjanje grešaka"</string>
+    <string name="debug_app" msgid="8903350241392391766">"Izaberite aplikaciju za otklanjanje grešaka"</string>
+    <string name="debug_app_not_set" msgid="1934083001283807188">"Nema podešenih aplikacija za otklanjanje grešaka"</string>
+    <string name="debug_app_set" msgid="6599535090477753651">"Aplikacija za otklanjanje grešaka: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="select_application" msgid="2543228890535466325">"Biranje aplikacije"</string>
+    <string name="no_application" msgid="9038334538870247690">"Nijedna"</string>
+    <string name="wait_for_debugger" msgid="7461199843335409809">"Sačekaj program za otklanjanje grešaka"</string>
+    <string name="wait_for_debugger_summary" msgid="6846330006113363286">"Aplikacija čeka program za otklanjanje grešaka da priloži pre izvršavanja"</string>
+    <string name="debug_input_category" msgid="7349460906970849771">"Unos"</string>
+    <string name="debug_drawing_category" msgid="5066171112313666619">"Crtanje"</string>
+    <string name="debug_hw_drawing_category" msgid="5830815169336975162">"Hardverski ubrzano prikazivanje"</string>
+    <string name="media_category" msgid="8122076702526144053">"Mediji"</string>
+    <string name="debug_monitoring_category" msgid="1597387133765424994">"Nadgledanje"</string>
+    <string name="strict_mode" msgid="889864762140862437">"Omogućen je strogi režim"</string>
+    <string name="strict_mode_summary" msgid="1838248687233554654">"Ekran treperi kada aplikacije obavljaju duge operacije na glavnoj niti"</string>
+    <string name="pointer_location" msgid="7516929526199520173">"Lokacija pokazivača"</string>
+    <string name="pointer_location_summary" msgid="957120116989798464">"Preklopni element sa trenutnim podacima o dodiru"</string>
+    <string name="show_touches" msgid="8437666942161289025">"Prikazuj dodire"</string>
+    <string name="show_touches_summary" msgid="3692861665994502193">"Prikazuje vizuelne povratne informacije za dodire"</string>
+    <string name="show_screen_updates" msgid="2078782895825535494">"Prikaži ažuriranja površine"</string>
+    <string name="show_screen_updates_summary" msgid="2126932969682087406">"Osvetljava sve površine prozora kada se ažuriraju"</string>
+    <string name="show_hw_screen_updates" msgid="2021286231267747506">"Prikaži ažuriranja prikaza"</string>
+    <string name="show_hw_screen_updates_summary" msgid="3539770072741435691">"Osvetljava prikaze u prozorima kada se crta"</string>
+    <string name="show_hw_layers_updates" msgid="5268370750002509767">"Prikaži ažuriranja hardverskih slojeva"</string>
+    <string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"Hardverski slojevi trepere zeleno kada se ažuriraju"</string>
+    <string name="debug_hw_overdraw" msgid="8944851091008756796">"Otkloni greške GPU preklapanja"</string>
+    <string name="disable_overlays" msgid="4206590799671557143">"Onemogući HW postavljene elemente"</string>
+    <string name="disable_overlays_summary" msgid="1954852414363338166">"Uvek se koristi GPU za komponovanje ekrana"</string>
+    <string name="simulate_color_space" msgid="1206503300335835151">"Simuliraj prostor boje"</string>
+    <string name="enable_opengl_traces_title" msgid="4638773318659125196">"Omogući OpenGL tragove"</string>
+    <string name="usb_audio_disable_routing" msgid="3367656923544254975">"Onemogući USB preusm. zvuka"</string>
+    <string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"Onemogućava automatsko preusmeravanje na USB audio periferne uređaje"</string>
+    <string name="debug_layout" msgid="1659216803043339741">"Prikaži granice rasporeda"</string>
+    <string name="debug_layout_summary" msgid="8825829038287321978">"Prikazuje granice klipa, margine itd."</string>
+    <string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Nametni smer rasporeda zdesna nalevo"</string>
+    <string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Nameće smer rasporeda ekrana zdesna nalevo za sve lokalitete"</string>
+    <string name="window_blurs" msgid="6831008984828425106">"Dozvoli zamagljenja prozora"</string>
+    <string name="force_msaa" msgid="4081288296137775550">"Nametni 4x MSAA"</string>
+    <string name="force_msaa_summary" msgid="9070437493586769500">"Omogućava 4x MSAA u OpenGL ES 2.0 aplikacijama"</string>
+    <string name="show_non_rect_clip" msgid="7499758654867881817">"Otkloni greške isecanja oblasti nepravougaonog oblika"</string>
+    <string name="track_frame_time" msgid="522674651937771106">"Renderuj pomoću HWUI-a"</string>
+    <string name="enable_gpu_debug_layers" msgid="4986675516188740397">"Omogući slojeve za otklanjanje grešaka GPU-a"</string>
+    <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Učitava otklanjanje grešaka GPU-a u apl. za otklanjanje grešaka"</string>
+    <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Opširne evidencije prodavca"</string>
+    <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Uvrštava u izveštaje o greškama dodatne posebne evidencije prodavca za uređaje, koje mogu da sadrže privatne podatke, da troše više baterije i/ili da koriste više memorije."</string>
+    <string name="window_animation_scale_title" msgid="5236381298376812508">"Razmera animacije prozora"</string>
+    <string name="transition_animation_scale_title" msgid="1278477690695439337">"Razmera animacije prelaza"</string>
+    <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animatorova razmera trajanja"</string>
+    <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simuliraj sekundarne ekrane"</string>
+    <string name="debug_applications_category" msgid="5394089406638954196">"Aplikacije"</string>
+    <string name="immediately_destroy_activities" msgid="1826287490705167403">"Ne čuvaj aktivnosti"</string>
+    <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Uništava svaku aktivnost čim je korisnik napusti"</string>
+    <string name="app_process_limit_title" msgid="8361367869453043007">"Ograničenje pozadinskih procesa"</string>
+    <string name="show_all_anrs" msgid="9160563836616468726">"Prikaži ANR-ove u pozadini"</string>
+    <string name="show_all_anrs_summary" msgid="8562788834431971392">"Prikazuje dijalog Aplikacija ne reaguje za aplikacije u pozadini"</string>
+    <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Prikazuj upozorenja zbog kanala za obaveštenja"</string>
+    <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Prikazuje upozorenje na ekranu kada aplikacija postavi obaveštenje bez važećeg kanala"</string>
+    <string name="force_allow_on_external" msgid="9187902444231637880">"Prinudno dozvoli aplikacije u spoljnoj"</string>
+    <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Omogućava upisivanje svih aplikacija u spoljnu memoriju, bez obzira na vrednosti manifesta"</string>
+    <string name="force_resizable_activities" msgid="7143612144399959606">"Prinudno omogući promenu veličine aktivnosti"</string>
+    <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Omogućava promenu veličine svih aktivnosti za režim sa više prozora, bez obzira na vrednosti manifesta."</string>
+    <string name="enable_freeform_support" msgid="7599125687603914253">"Omogući prozore proizvoljnog formata"</string>
+    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Omogućava podršku za eksperimentalne prozore proizvoljnog formata."</string>
+    <string name="desktop_mode" msgid="2389067840550544462">"Režim za računare"</string>
+    <string name="local_backup_password_title" msgid="4631017948933578709">"Lozinka rezervne kopije za računar"</string>
+    <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Rezervne kopije čitavog sistema trenutno nisu zaštićene"</string>
+    <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Dodirnite da biste promenili ili uklonili lozinku za pravljenje rezervnih kopija čitavog sistema na računaru"</string>
+    <string name="local_backup_password_toast_success" msgid="4891666204428091604">"Postavljena je nova lozinka rezervne kopije"</string>
+    <string name="local_backup_password_toast_confirmation_mismatch" msgid="2994718182129097733">"Nova lozinka i njena potvrda se ne podudaraju"</string>
+    <string name="local_backup_password_toast_validation_failure" msgid="714669442363647122">"Postavljanje lozinke rezervne kopije nije uspelo"</string>
+    <string name="loading_injected_setting_summary" msgid="8394446285689070348">"Učitava se…"</string>
   <string-array name="color_mode_names">
-    <item msgid="3836559907767149216">"Живописан (подразумевано)"</item>
-    <item msgid="9112200311983078311">"Природан"</item>
-    <item msgid="6564241960833766170">"Стандардан"</item>
+    <item msgid="3836559907767149216">"Živopisan (podrazumevano)"</item>
+    <item msgid="9112200311983078311">"Prirodan"</item>
+    <item msgid="6564241960833766170">"Standardan"</item>
   </string-array>
   <string-array name="color_mode_descriptions">
-    <item msgid="6828141153199944847">"Побољшане боје"</item>
-    <item msgid="4548987861791236754">"Природне боје налик онима које региструје око"</item>
-    <item msgid="1282170165150762976">"Боје оптимизоване за дигитални садржај"</item>
+    <item msgid="6828141153199944847">"Poboljšane boje"</item>
+    <item msgid="4548987861791236754">"Prirodne boje nalik onima koje registruje oko"</item>
+    <item msgid="1282170165150762976">"Boje optimizovane za digitalni sadržaj"</item>
   </string-array>
-    <string name="inactive_apps_title" msgid="5372523625297212320">"Апликације у стању приправности"</string>
-    <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"Неактивна. Додирните да бисте је активирали."</string>
-    <string name="inactive_app_active_summary" msgid="8047630990208722344">"Активна. Додирните да бисте је деактивирали."</string>
-    <string name="standby_bucket_summary" msgid="5128193447550429600">"Стање приправности апликације: <xliff:g id="BUCKET"> %s</xliff:g>"</string>
-    <string name="transcode_settings_title" msgid="2581975870429850549">"Подешавања транскодирања медија"</string>
-    <string name="transcode_user_control" msgid="6176368544817731314">"Замени подразумевана подешавања транскодирања"</string>
-    <string name="transcode_enable_all" msgid="2411165920039166710">"Омогући транскодирање"</string>
-    <string name="transcode_default" msgid="3784803084573509491">"Подразумевај да апликације подржавају модерне формате"</string>
-    <string name="transcode_notification" msgid="5560515979793436168">"Приказуј обавештења о транскодирању"</string>
-    <string name="transcode_disable_cache" msgid="3160069309377467045">"Онемогући кеш транскодирања"</string>
-    <string name="runningservices_settings_title" msgid="6460099290493086515">"Покренуте услуге"</string>
-    <string name="runningservices_settings_summary" msgid="1046080643262665743">"Приказ и контрола тренутно покренутих услуга"</string>
-    <string name="select_webview_provider_title" msgid="3917815648099445503">"Примена WebView-а"</string>
-    <string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Подесите примену WebView-а"</string>
-    <string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Овај избор више није важећи. Пробајте поново."</string>
-    <string name="picture_color_mode" msgid="1013807330552931903">"Режим боја слика"</string>
-    <string name="picture_color_mode_desc" msgid="151780973768136200">"Користи sRGB"</string>
-    <string name="daltonizer_mode_disabled" msgid="403424372812399228">"Онемогућено је"</string>
-    <string name="daltonizer_mode_monochromacy" msgid="362060873835885014">"Једнобојност"</string>
-    <string name="daltonizer_mode_deuteranomaly" msgid="3507284319584683963">"Деутераномалија (црвено-зелено)"</string>
-    <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Протаномалија (црвено-зелено)"</string>
-    <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Тританомалија (плаво-жуто)"</string>
-    <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Корекција боја"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Корекција боја може да буде корисна када желите:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Прецизније да видите боје&lt;/li&gt; &lt;li&gt;&amp;nbsp;Да уклоните боје како бисте се фокусирали&lt;/li&gt; &lt;/ol&gt;"</string>
-    <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Замењује га <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="inactive_apps_title" msgid="5372523625297212320">"Aplikacije u stanju pripravnosti"</string>
+    <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"Neaktivna. Dodirnite da biste je aktivirali."</string>
+    <string name="inactive_app_active_summary" msgid="8047630990208722344">"Aktivna. Dodirnite da biste je deaktivirali."</string>
+    <string name="standby_bucket_summary" msgid="5128193447550429600">"Stanje pripravnosti aplikacije: <xliff:g id="BUCKET"> %s</xliff:g>"</string>
+    <string name="transcode_settings_title" msgid="2581975870429850549">"Podešavanja transkodiranja medija"</string>
+    <string name="transcode_user_control" msgid="6176368544817731314">"Zameni podrazumevana podešavanja transkodiranja"</string>
+    <string name="transcode_enable_all" msgid="2411165920039166710">"Omogući transkodiranje"</string>
+    <string name="transcode_default" msgid="3784803084573509491">"Podrazumevaj da aplikacije podržavaju moderne formate"</string>
+    <string name="transcode_notification" msgid="5560515979793436168">"Prikazuj obaveštenja o transkodiranju"</string>
+    <string name="transcode_disable_cache" msgid="3160069309377467045">"Onemogući keš transkodiranja"</string>
+    <string name="runningservices_settings_title" msgid="6460099290493086515">"Pokrenute usluge"</string>
+    <string name="runningservices_settings_summary" msgid="1046080643262665743">"Prikaz i kontrola trenutno pokrenutih usluga"</string>
+    <string name="select_webview_provider_title" msgid="3917815648099445503">"Primena WebView-a"</string>
+    <string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Podesite primenu WebView-a"</string>
+    <string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Ovaj izbor više nije važeći. Probajte ponovo."</string>
+    <string name="picture_color_mode" msgid="1013807330552931903">"Režim boja slika"</string>
+    <string name="picture_color_mode_desc" msgid="151780973768136200">"Koristi sRGB"</string>
+    <string name="daltonizer_mode_disabled" msgid="403424372812399228">"Onemogućeno je"</string>
+    <string name="daltonizer_mode_monochromacy" msgid="362060873835885014">"Jednobojnost"</string>
+    <string name="daltonizer_mode_deuteranomaly" msgid="3507284319584683963">"Deuteranomalija (crveno-zeleno)"</string>
+    <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomalija (crveno-zeleno)"</string>
+    <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalija (plavo-žuto)"</string>
+    <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Korekcija boja"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Korekcija boja može da bude korisna kada želite:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Preciznije da vidite boje&lt;/li&gt; &lt;li&gt;&amp;nbsp;Da uklonite boje kako biste se fokusirali&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Zamenjuje ga <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g>–<xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="8264199158671531431">"Преостало је око <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration" msgid="1076561255466053220">"Преостало је око <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
-    <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Преостало је око <xliff:g id="TIME_REMAINING">%1$s</xliff:g> на основу коришћења"</string>
-    <string name="power_discharging_duration_enhanced" msgid="1800465736237672323">"Преостало је око <xliff:g id="TIME_REMAINING">%1$s</xliff:g> на основу коришћења (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_remaining_duration_only" msgid="8264199158671531431">"Preostalo je oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1076561255466053220">"Preostalo je oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Preostalo je oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g> na osnovu korišćenja"</string>
+    <string name="power_discharging_duration_enhanced" msgid="1800465736237672323">"Preostalo je oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g> na osnovu korišćenja (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
     <!-- no translation found for power_remaining_duration_only_short (7438846066602840588) -->
     <skip />
-    <string name="power_discharge_by_enhanced" msgid="563438403581662942">"Трајаће приближно до <xliff:g id="TIME">%1$s</xliff:g> на основу коришћења (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
-    <string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"Трајаће приближно до <xliff:g id="TIME">%1$s</xliff:g> на основу коришћења"</string>
-    <string name="power_discharge_by" msgid="4113180890060388350">"Трајаће приближно до <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
-    <string name="power_discharge_by_only" msgid="92545648425937000">"Трајаће приближно до <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharge_by_only_short" msgid="5883041507426914446">"До <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Батерија ће се можда испразнити до <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Још мање од <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
-    <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Још мање од <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
-    <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Још више од <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
-    <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Још више од <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Телефон ће се ускоро искључити"</string>
-    <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Таблет ће се ускоро искључити"</string>
-    <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Уређај ће се ускоро искључити"</string>
-    <string name="power_remaining_duration_shutdown_imminent" product="default" msgid="4429259621177089719">"Телефон ће се ускоро искључити (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
-    <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7703677921000858479">"Таблет ће се ускоро искључити (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
-    <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"Уређај ће се ускоро искључити (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
+    <string name="power_discharge_by_enhanced" msgid="563438403581662942">"Trajaće približno do <xliff:g id="TIME">%1$s</xliff:g> na osnovu korišćenja (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"Trajaće približno do <xliff:g id="TIME">%1$s</xliff:g> na osnovu korišćenja"</string>
+    <string name="power_discharge_by" msgid="4113180890060388350">"Trajaće približno do <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_discharge_by_only" msgid="92545648425937000">"Trajaće približno do <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Baterija će se možda isprazniti do <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Još manje od <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+    <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Još manje od <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Još više od <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Još više od <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon će se uskoro isključiti"</string>
+    <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet će se uskoro isključiti"</string>
+    <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Uređaj će se uskoro isključiti"</string>
+    <string name="power_remaining_duration_shutdown_imminent" product="default" msgid="4429259621177089719">"Telefon će se uskoro isključiti (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
+    <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7703677921000858479">"Tablet će se uskoro isključiti (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
+    <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"Uređaj će se uskoro isključiti (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> до краја пуњења"</string>
-    <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до краја пуњења"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
-    <string name="battery_info_status_unknown" msgid="268625384868401114">"Непознато"</string>
-    <string name="battery_info_status_charging" msgid="4279958015430387405">"Пуни се"</string>
-    <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Брзо се пуни"</string>
-    <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Споро се пуни"</string>
-    <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Бежично пуњење"</string>
-    <string name="battery_info_status_charging_dock" msgid="8573274094093364791">"Пуњење"</string>
-    <string name="battery_info_status_discharging" msgid="6962689305413556485">"Не пуни се"</string>
-    <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Повезано, не пуни се"</string>
-    <string name="battery_info_status_full" msgid="1339002294876531312">"Напуњено"</string>
-    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Напуњено до краја"</string>
-    <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Контролише администратор"</string>
-    <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Контролишу ограничена подешавања"</string>
-    <string name="disabled" msgid="8017887509554714950">"Онемогућено"</string>
-    <string name="external_source_trusted" msgid="1146522036773132905">"Дозвољено"</string>
-    <string name="external_source_untrusted" msgid="5037891688911672227">"Није дозвољено"</string>
-    <string name="install_other_apps" msgid="3232595082023199454">"Инсталирање непознатих апликација"</string>
-    <string name="home" msgid="973834627243661438">"Почетна за Подешавања"</string>
+    <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> do kraja punjenja"</string>
+    <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do kraja punjenja"</string>
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – punjenje je optimizovano"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – punjenje je optimizovano"</string>
+    <string name="battery_info_status_unknown" msgid="268625384868401114">"Nepoznato"</string>
+    <string name="battery_info_status_charging" msgid="4279958015430387405">"Puni se"</string>
+    <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Brzo se puni"</string>
+    <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Sporo se puni"</string>
+    <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Bežično punjenje"</string>
+    <string name="battery_info_status_charging_dock" msgid="8573274094093364791">"Punjenje"</string>
+    <string name="battery_info_status_discharging" msgid="6962689305413556485">"Ne puni se"</string>
+    <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Povezano, ne puni se"</string>
+    <string name="battery_info_status_full" msgid="1339002294876531312">"Napunjeno"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Napunjeno do kraja"</string>
+    <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Kontroliše administrator"</string>
+    <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrolišu ograničena podešavanja"</string>
+    <string name="disabled" msgid="8017887509554714950">"Onemogućeno"</string>
+    <string name="external_source_trusted" msgid="1146522036773132905">"Dozvoljeno"</string>
+    <string name="external_source_untrusted" msgid="5037891688911672227">"Nije dozvoljeno"</string>
+    <string name="install_other_apps" msgid="3232595082023199454">"Instaliranje nepoznatih aplikacija"</string>
+    <string name="home" msgid="973834627243661438">"Početna za Podešavanja"</string>
   <string-array name="battery_labels">
     <item msgid="7878690469765357158">"0%"</item>
     <item msgid="8894873528875953317">"50%"</item>
     <item msgid="7529124349186240216">"100%"</item>
   </string-array>
-    <string name="charge_length_format" msgid="6941645744588690932">"Пре <xliff:g id="ID_1">%1$s</xliff:g>"</string>
-    <string name="remaining_length_format" msgid="4310625772926171089">"Још <xliff:g id="ID_1">%1$s</xliff:g>"</string>
-    <string name="screen_zoom_summary_small" msgid="6050633151263074260">"Мали"</string>
-    <string name="screen_zoom_summary_default" msgid="1888865694033865408">"Подразумевано"</string>
-    <string name="screen_zoom_summary_large" msgid="4706951482598978984">"Велики"</string>
-    <string name="screen_zoom_summary_very_large" msgid="7317423942896999029">"Већи"</string>
-    <string name="screen_zoom_summary_extremely_large" msgid="1438045624562358554">"Највећи"</string>
-    <string name="screen_zoom_summary_custom" msgid="3468154096832912210">"Прилагођени (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
-    <string name="content_description_menu_button" msgid="6254844309171779931">"Мени"</string>
-    <string name="retail_demo_reset_message" msgid="5392824901108195463">"Унесите лозинку да бисте обавили ресетовање на фабричка подешавања у режиму демонстрације"</string>
-    <string name="retail_demo_reset_next" msgid="3688129033843885362">"Даље"</string>
-    <string name="retail_demo_reset_title" msgid="1866911701095959800">"Потребна је лозинка"</string>
-    <string name="active_input_method_subtypes" msgid="4232680535471633046">"Методе активног уноса"</string>
-    <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"Користи језике система"</string>
-    <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"Отварање подешавања за апликацију <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> није успело"</string>
-    <string name="ime_security_warning" msgid="6547562217880551450">"Овај метод уноса можда може да прикупља сав текст који уносите, укључујући личне податке, као што су лозинке и бројеви кредитних картица. Потиче од апликације <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Желите ли да користите овај метод уноса?"</string>
-    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Напомена: После рестартовања ова апликација не може да се покрене док не откључате телефон"</string>
-    <string name="ims_reg_title" msgid="8197592958123671062">"Статус IMS регистрације"</string>
-    <string name="ims_reg_status_registered" msgid="884916398194885457">"Регистрован je"</string>
-    <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"Није регистрован"</string>
-    <string name="status_unavailable" msgid="5279036186589861608">"Недоступно"</string>
-    <string name="wifi_status_mac_randomized" msgid="466382542497832189">"MAC адреса је насумично изабрана"</string>
-    <string name="wifi_tether_connected_summary" msgid="5282919920463340158">"{count,plural, =0{0 уређаја је повезано}=1{1 уређај је повезан}one{# уређај је повезан}few{# уређаја су повезана}other{# уређаја је повезано}}"</string>
-    <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Више времена."</string>
-    <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Мање времена."</string>
-    <string name="cancel" msgid="5665114069455378395">"Откажи"</string>
-    <string name="okay" msgid="949938843324579502">"Потврди"</string>
-    <string name="done" msgid="381184316122520313">"Готово"</string>
-    <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Аларми и подсетници"</string>
-    <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Омогући подешавање аларма и подсетника"</string>
-    <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Аларми и подсетници"</string>
-    <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Омогућите овој апликацији да подешава аларме и заказује временски осетљиве радње. То омогућава да апликација буде покренута у позадини, што може да троши више батерије.\n\nАко је ова дозвола искључена, постојећи аларми и догађаји засновани на времену заказани помоћу ове апликације неће радити."</string>
-    <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"заказати, аларм, подсетник, сат"</string>
-    <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Укључи"</string>
-    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Укључите режим Не узнемиравај"</string>
-    <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Никад"</string>
-    <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Само приоритетни прекиди"</string>
+    <string name="charge_length_format" msgid="6941645744588690932">"Pre <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="4310625772926171089">"Još <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="6050633151263074260">"Mali"</string>
+    <string name="screen_zoom_summary_default" msgid="1888865694033865408">"Podrazumevano"</string>
+    <string name="screen_zoom_summary_large" msgid="4706951482598978984">"Veliki"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7317423942896999029">"Veći"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="1438045624562358554">"Najveći"</string>
+    <string name="screen_zoom_summary_custom" msgid="3468154096832912210">"Prilagođeni (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
+    <string name="content_description_menu_button" msgid="6254844309171779931">"Meni"</string>
+    <string name="retail_demo_reset_message" msgid="5392824901108195463">"Unesite lozinku da biste obavili resetovanje na fabrička podešavanja u režimu demonstracije"</string>
+    <string name="retail_demo_reset_next" msgid="3688129033843885362">"Dalje"</string>
+    <string name="retail_demo_reset_title" msgid="1866911701095959800">"Potrebna je lozinka"</string>
+    <string name="active_input_method_subtypes" msgid="4232680535471633046">"Metode aktivnog unosa"</string>
+    <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"Koristi jezike sistema"</string>
+    <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"Otvaranje podešavanja za aplikaciju <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> nije uspelo"</string>
+    <string name="ime_security_warning" msgid="6547562217880551450">"Ovaj metod unosa možda može da prikuplja sav tekst koji unosite, uključujući lične podatke, kao što su lozinke i brojevi kreditnih kartica. Potiče od aplikacije <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Želite li da koristite ovaj metod unosa?"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Napomena: Posle restartovanja ova aplikacija ne može da se pokrene dok ne otključate telefon"</string>
+    <string name="ims_reg_title" msgid="8197592958123671062">"Status IMS registracije"</string>
+    <string name="ims_reg_status_registered" msgid="884916398194885457">"Registrovan je"</string>
+    <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"Nije registrovan"</string>
+    <string name="status_unavailable" msgid="5279036186589861608">"Nedostupno"</string>
+    <string name="wifi_status_mac_randomized" msgid="466382542497832189">"MAC adresa je nasumično izabrana"</string>
+    <string name="wifi_tether_connected_summary" msgid="5282919920463340158">"{count,plural, =0{0 uređaja je povezano}=1{1 uređaj je povezan}one{# uređaj je povezan}few{# uređaja su povezana}other{# uređaja je povezano}}"</string>
+    <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Više vremena."</string>
+    <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Manje vremena."</string>
+    <string name="cancel" msgid="5665114069455378395">"Otkaži"</string>
+    <string name="okay" msgid="949938843324579502">"Potvrdi"</string>
+    <string name="done" msgid="381184316122520313">"Gotovo"</string>
+    <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmi i podsetnici"</string>
+    <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Omogući podešavanje alarma i podsetnika"</string>
+    <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmi i podsetnici"</string>
+    <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Omogućite ovoj aplikaciji da podešava alarme i zakazuje vremenski osetljive radnje. To omogućava da aplikacija bude pokrenuta u pozadini, što može da troši više baterije.\n\nAko je ova dozvola isključena, postojeći alarmi i događaji zasnovani na vremenu zakazani pomoću ove aplikacije neće raditi."</string>
+    <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"zakazati, alarm, podsetnik, sat"</string>
+    <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Uključi"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Uključite režim Ne uznemiravaj"</string>
+    <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nikad"</string>
+    <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Samo prioritetni prekidi"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="zen_alarm_warning_indef" msgid="4146527909616457163">"Нећете чути следећи аларм у <xliff:g id="WHEN">%1$s</xliff:g> ако не искључите ово пре тога"</string>
-    <string name="zen_alarm_warning" msgid="245729928048586280">"Нећете чути следећи аларм у <xliff:g id="WHEN">%1$s</xliff:g>"</string>
-    <string name="alarm_template" msgid="3346777418136233330">"у <xliff:g id="WHEN">%1$s</xliff:g>"</string>
+    <string name="zen_alarm_warning_indef" msgid="4146527909616457163">"Nećete čuti sledeći alarm u <xliff:g id="WHEN">%1$s</xliff:g> ako ne isključite ovo pre toga"</string>
+    <string name="zen_alarm_warning" msgid="245729928048586280">"Nećete čuti sledeći alarm u <xliff:g id="WHEN">%1$s</xliff:g>"</string>
+    <string name="alarm_template" msgid="3346777418136233330">"u <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template_far" msgid="6382760514842998629">"<xliff:g id="WHEN">%1$s</xliff:g>"</string>
-    <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Трајање"</string>
-    <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Питај сваки пут"</string>
-    <string name="zen_mode_forever" msgid="3339224497605461291">"Док не искључите"</string>
-    <string name="time_unit_just_now" msgid="3006134267292728099">"Управо"</string>
-    <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Овај телефон"</string>
-    <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Овај таблет"</string>
-    <string name="media_transfer_this_phone" msgid="7194341457812151531">"Овај телефон"</string>
-    <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Проблем при повезивању. Искључите уређај, па га поново укључите"</string>
-    <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Жичани аудио уређај"</string>
-    <string name="help_label" msgid="3528360748637781274">"Помоћ и повратне информације"</string>
-    <string name="storage_category" msgid="2287342585424631813">"Меморијски простор"</string>
-    <string name="shared_data_title" msgid="1017034836800864953">"Дељени подаци"</string>
-    <string name="shared_data_summary" msgid="5516326713822885652">"Прегледајте и измените дељене податке"</string>
-    <string name="shared_data_no_blobs_text" msgid="3108114670341737434">"Нема дељених података за овог корисника."</string>
-    <string name="shared_data_query_failure_text" msgid="3489828881998773687">"Дошло је до грешке при преузимању дељених података. Пробајте поново."</string>
-    <string name="blob_id_text" msgid="8680078988996308061">"ИД дељених података: <xliff:g id="BLOB_ID">%d</xliff:g>"</string>
-    <string name="blob_expires_text" msgid="7882727111491739331">"Истиче: <xliff:g id="DATE">%s</xliff:g>"</string>
-    <string name="shared_data_delete_failure_text" msgid="3842701391009628947">"Дошло је до грешке при брисању дељених података."</string>
-    <string name="shared_data_no_accessors_dialog_text" msgid="8903738462570715315">"Нема купљених закупа за ове дељене податке. Желите ли да их избришете?"</string>
-    <string name="accessor_info_title" msgid="8289823651512477787">"Апликације које деле податке"</string>
-    <string name="accessor_no_description_text" msgid="7510967452505591456">"У апликацији није наведен ниједан опис."</string>
-    <string name="accessor_expires_text" msgid="4625619273236786252">"Изнајмљивање истиче: <xliff:g id="DATE">%s</xliff:g>"</string>
-    <string name="delete_blob_text" msgid="2819192607255625697">"Избриши дељене податке"</string>
-    <string name="delete_blob_confirmation_text" msgid="7807446938920827280">"Желите ли стварно да избришете ове дељене податке?"</string>
-    <string name="user_add_user_item_summary" msgid="5748424612724703400">"Корисници имају сопствене апликације и садржај"</string>
-    <string name="user_add_profile_item_summary" msgid="5418602404308968028">"Можете да ограничите приступ на апликације и садржај са налога"</string>
-    <string name="user_add_user_item_title" msgid="2394272381086965029">"Корисник"</string>
-    <string name="user_add_profile_item_title" msgid="3111051717414643029">"Ограничени профил"</string>
-    <string name="user_add_user_title" msgid="5457079143694924885">"Додајете новог корисника?"</string>
-    <string name="user_add_user_message_long" msgid="1527434966294733380">"Овај уређај можете да делите са другим људима ако направите још корисника. Сваки корисник има сопствени простор, који може да прилагођава помоћу апликација, позадине и слично. Корисници могу да прилагођавају и подешавања уређаја која утичу на свакога, попут Wi‑Fi-ја.\n\nКада додате новог корисника, та особа треба да подеси сопствени простор.\n\nСваки корисник може да ажурира апликације за све остале кориснике. Подешавања и услуге приступачности не могу да се преносе на новог корисника."</string>
-    <string name="user_add_user_message_short" msgid="3295959985795716166">"Када додате новог корисника, та особа треба да подеси сопствени простор.\n\nСваки корисник може да ажурира апликације за све остале кориснике."</string>
-    <string name="user_setup_dialog_title" msgid="8037342066381939995">"Подешавате корисника?"</string>
-    <string name="user_setup_dialog_message" msgid="269931619868102841">"Та особа треба да узме уређај и подеси свој простор"</string>
-    <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Желите ли да одмах подесите профил?"</string>
-    <string name="user_setup_button_setup_now" msgid="1708269547187760639">"Подеси"</string>
-    <string name="user_setup_button_setup_later" msgid="8712980133555493516">"Не сада"</string>
-    <string name="user_add_user_type_title" msgid="551279664052914497">"Додавање"</string>
-    <string name="user_new_user_name" msgid="60979820612818840">"Нови корисник"</string>
-    <string name="user_new_profile_name" msgid="2405500423304678841">"Нови профил"</string>
-    <string name="user_info_settings_title" msgid="6351390762733279907">"Подаци о кориснику"</string>
-    <string name="profile_info_settings_title" msgid="105699672534365099">"Подаци о профилу"</string>
-    <string name="user_need_lock_message" msgid="4311424336209509301">"Да бисте могли да направите ограничени профил, треба да подесите закључавање екрана да бисте заштитили апликације и личне податке."</string>
-    <string name="user_set_lock_button" msgid="1427128184982594856">"Подеси закључавање"</string>
-    <string name="user_switch_to_user" msgid="6975428297154968543">"Пређи на корисника <xliff:g id="USER_NAME">%s</xliff:g>"</string>
-    <string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Прави се нови корисник…"</string>
-    <string name="creating_new_guest_dialog_message" msgid="1114905602181350690">"Прави се нови гост…"</string>
-    <string name="add_user_failed" msgid="4809887794313944872">"Прављење новог корисника није успело"</string>
-    <string name="add_guest_failed" msgid="8074548434469843443">"Прављење новог госта није успело"</string>
-    <string name="user_nickname" msgid="262624187455825083">"Надимак"</string>
-    <string name="user_add_user" msgid="7876449291500212468">"Додај корисника"</string>
-    <string name="guest_new_guest" msgid="3482026122932643557">"Додај госта"</string>
-    <string name="guest_exit_guest" msgid="5908239569510734136">"Уклони госта"</string>
-    <string name="guest_reset_guest" msgid="6110013010356013758">"Ресетуј сесију госта"</string>
-    <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Желите ли да ресетујете сесију госта?"</string>
-    <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Желите да уклоните госта?"</string>
-    <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Ресетуј"</string>
-    <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Уклони"</string>
-    <string name="guest_resetting" msgid="7822120170191509566">"Сесија госта се ресетује…"</string>
-    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Желите да ресетујете сесију госта?"</string>
-    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Тиме ћете покренути нову сесију госта и избрисати све апликације и податке из актуелне сесије"</string>
-    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Излазите из режима госта?"</string>
-    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Тиме ћете избрисати све апликације и податке из актуелне сесије госта"</string>
-    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Изађи"</string>
-    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Сачуваћете активности госта?"</string>
-    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Сачувајте активности из актуелне сесије или избришите све апликације и податке"</string>
-    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Избриши"</string>
-    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Сачувај"</string>
-    <string name="guest_exit_button" msgid="5774985819191803960">"Изађи из режима госта"</string>
-    <string name="guest_reset_button" msgid="2515069346223503479">"Ресетуј сесију госта"</string>
-    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Затвори режим госта"</string>
-    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Све активности ће бити избрисане при излазу"</string>
-    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Можете да сачувате или избришете активности при излазу"</string>
-    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Ресетујете за брисање активности сесије, или сачувајте или избришите активности при излазу"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Сликај"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Одабери слику"</string>
-    <string name="user_image_photo_selector" msgid="433658323306627093">"Изаберите слику"</string>
-    <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Превише нетачних покушаја. Избрисаћемо податке са овог уређаја."</string>
-    <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Превише нетачних покушаја. Избрисаћемо овог корисника."</string>
-    <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Превише нетачних покушаја. Избрисаћемо овај пословни профил и његове податке."</string>
-    <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Одбаци"</string>
-    <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Подразумевано за уређај"</string>
-    <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Онемогућено"</string>
-    <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Омогућено"</string>
-    <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Морате да рестартујете уређај да би се ова промена применила. Рестартујте га одмах или откажите."</string>
-    <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Жичане слушалице"</string>
-    <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Укључено"</string>
-    <string name="wifi_hotspot_switch_off_text" msgid="7245567251496959764">"Искључено"</string>
-    <string name="carrier_network_change_mode" msgid="4257621815706644026">"Промена мреже мобилног оператера"</string>
+    <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Trajanje"</string>
+    <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Pitaj svaki put"</string>
+    <string name="zen_mode_forever" msgid="3339224497605461291">"Dok ne isključite"</string>
+    <string name="time_unit_just_now" msgid="3006134267292728099">"Upravo"</string>
+    <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ovaj telefon"</string>
+    <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Ovaj tablet"</string>
+    <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ovaj telefon"</string>
+    <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem pri povezivanju. Isključite uređaj, pa ga ponovo uključite"</string>
+    <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Žičani audio uređaj"</string>
+    <string name="help_label" msgid="3528360748637781274">"Pomoć i povratne informacije"</string>
+    <string name="storage_category" msgid="2287342585424631813">"Memorijski prostor"</string>
+    <string name="shared_data_title" msgid="1017034836800864953">"Deljeni podaci"</string>
+    <string name="shared_data_summary" msgid="5516326713822885652">"Pregledajte i izmenite deljene podatke"</string>
+    <string name="shared_data_no_blobs_text" msgid="3108114670341737434">"Nema deljenih podataka za ovog korisnika."</string>
+    <string name="shared_data_query_failure_text" msgid="3489828881998773687">"Došlo je do greške pri preuzimanju deljenih podataka. Probajte ponovo."</string>
+    <string name="blob_id_text" msgid="8680078988996308061">"ID deljenih podataka: <xliff:g id="BLOB_ID">%d</xliff:g>"</string>
+    <string name="blob_expires_text" msgid="7882727111491739331">"Ističe: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="shared_data_delete_failure_text" msgid="3842701391009628947">"Došlo je do greške pri brisanju deljenih podataka."</string>
+    <string name="shared_data_no_accessors_dialog_text" msgid="8903738462570715315">"Nema kupljenih zakupa za ove deljene podatke. Želite li da ih izbrišete?"</string>
+    <string name="accessor_info_title" msgid="8289823651512477787">"Aplikacije koje dele podatke"</string>
+    <string name="accessor_no_description_text" msgid="7510967452505591456">"U aplikaciji nije naveden nijedan opis."</string>
+    <string name="accessor_expires_text" msgid="4625619273236786252">"Iznajmljivanje ističe: <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="delete_blob_text" msgid="2819192607255625697">"Izbriši deljene podatke"</string>
+    <string name="delete_blob_confirmation_text" msgid="7807446938920827280">"Želite li stvarno da izbrišete ove deljene podatke?"</string>
+    <string name="user_add_user_item_summary" msgid="5748424612724703400">"Korisnici imaju sopstvene aplikacije i sadržaj"</string>
+    <string name="user_add_profile_item_summary" msgid="5418602404308968028">"Možete da ograničite pristup na aplikacije i sadržaj sa naloga"</string>
+    <string name="user_add_user_item_title" msgid="2394272381086965029">"Korisnik"</string>
+    <string name="user_add_profile_item_title" msgid="3111051717414643029">"Ograničeni profil"</string>
+    <string name="user_add_user_title" msgid="5457079143694924885">"Dodajete novog korisnika?"</string>
+    <string name="user_add_user_message_long" msgid="1527434966294733380">"Ovaj uređaj možete da delite sa drugim ljudima ako napravite još korisnika. Svaki korisnik ima sopstveni prostor, koji može da prilagođava pomoću aplikacija, pozadine i slično. Korisnici mogu da prilagođavaju i podešavanja uređaja koja utiču na svakoga, poput Wi‑Fi-ja.\n\nKada dodate novog korisnika, ta osoba treba da podesi sopstveni prostor.\n\nSvaki korisnik može da ažurira aplikacije za sve ostale korisnike. Podešavanja i usluge pristupačnosti ne mogu da se prenose na novog korisnika."</string>
+    <string name="user_add_user_message_short" msgid="3295959985795716166">"Kada dodate novog korisnika, ta osoba treba da podesi sopstveni prostor.\n\nSvaki korisnik može da ažurira aplikacije za sve ostale korisnike."</string>
+    <string name="user_setup_dialog_title" msgid="8037342066381939995">"Podešavate korisnika?"</string>
+    <string name="user_setup_dialog_message" msgid="269931619868102841">"Ta osoba treba da uzme uređaj i podesi svoj prostor"</string>
+    <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Želite li da odmah podesite profil?"</string>
+    <string name="user_setup_button_setup_now" msgid="1708269547187760639">"Podesi"</string>
+    <string name="user_setup_button_setup_later" msgid="8712980133555493516">"Ne sada"</string>
+    <string name="user_add_user_type_title" msgid="551279664052914497">"Dodavanje"</string>
+    <string name="user_new_user_name" msgid="60979820612818840">"Novi korisnik"</string>
+    <string name="user_new_profile_name" msgid="2405500423304678841">"Novi profil"</string>
+    <string name="user_info_settings_title" msgid="6351390762733279907">"Podaci o korisniku"</string>
+    <string name="profile_info_settings_title" msgid="105699672534365099">"Podaci o profilu"</string>
+    <string name="user_need_lock_message" msgid="4311424336209509301">"Da biste mogli da napravite ograničeni profil, treba da podesite zaključavanje ekrana da biste zaštitili aplikacije i lične podatke."</string>
+    <string name="user_set_lock_button" msgid="1427128184982594856">"Podesi zaključavanje"</string>
+    <string name="user_switch_to_user" msgid="6975428297154968543">"Pređi na korisnika <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Pravi se novi korisnik…"</string>
+    <string name="creating_new_guest_dialog_message" msgid="1114905602181350690">"Pravi se novi gost…"</string>
+    <string name="add_user_failed" msgid="4809887794313944872">"Pravljenje novog korisnika nije uspelo"</string>
+    <string name="add_guest_failed" msgid="8074548434469843443">"Pravljenje novog gosta nije uspelo"</string>
+    <string name="user_nickname" msgid="262624187455825083">"Nadimak"</string>
+    <string name="user_add_user" msgid="7876449291500212468">"Dodaj korisnika"</string>
+    <string name="guest_new_guest" msgid="3482026122932643557">"Dodaj gosta"</string>
+    <string name="guest_exit_guest" msgid="5908239569510734136">"Ukloni gosta"</string>
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Resetuj sesiju gosta"</string>
+    <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Želite li da resetujete sesiju gosta?"</string>
+    <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Želite da uklonite gosta?"</string>
+    <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Resetuj"</string>
+    <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Ukloni"</string>
+    <string name="guest_resetting" msgid="7822120170191509566">"Sesija gosta se resetuje…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Želite da resetujete sesiju gosta?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Time ćete pokrenuti novu sesiju gosta i izbrisati sve aplikacije i podatke iz aktuelne sesije"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Izlazite iz režima gosta?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Time ćete izbrisati sve aplikacije i podatke iz aktuelne sesije gosta"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Izađi"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Sačuvaćete aktivnosti gosta?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Sačuvajte aktivnosti iz aktuelne sesije ili izbrišite sve aplikacije i podatke"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Izbriši"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Sačuvaj"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Izađi iz režima gosta"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Resetuj sesiju gosta"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Zatvori režim gosta"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Sve aktivnosti će biti izbrisane pri izlazu"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Možete da sačuvate ili izbrišete aktivnosti pri izlazu"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Resetujete za brisanje aktivnosti sesije, ili sačuvajte ili izbrišite aktivnosti pri izlazu"</string>
+    <string name="user_image_take_photo" msgid="467512954561638530">"Slikaj"</string>
+    <string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberi sliku"</string>
+    <string name="user_image_photo_selector" msgid="433658323306627093">"Izaberite sliku"</string>
+    <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Previše netačnih pokušaja. Izbrisaćemo podatke sa ovog uređaja."</string>
+    <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Previše netačnih pokušaja. Izbrisaćemo ovog korisnika."</string>
+    <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Previše netačnih pokušaja. Izbrisaćemo ovaj poslovni profil i njegove podatke."</string>
+    <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Odbaci"</string>
+    <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Podrazumevano za uređaj"</string>
+    <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Onemogućeno"</string>
+    <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Omogućeno"</string>
+    <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Morate da restartujete uređaj da bi se ova promena primenila. Restartujte ga odmah ili otkažite."</string>
+    <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Žičane slušalice"</string>
+    <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Uključeno"</string>
+    <string name="wifi_hotspot_switch_off_text" msgid="7245567251496959764">"Isključeno"</string>
+    <string name="carrier_network_change_mode" msgid="4257621815706644026">"Promena mreže mobilnog operatera"</string>
     <string name="data_connection_3g" msgid="931852552688157407">"3G"</string>
     <string name="data_connection_edge" msgid="4625509456544797637">"EDGE"</string>
     <string name="data_connection_cdma" msgid="9098161966701934334">"1X"</string>
@@ -644,34 +642,34 @@
     <string name="data_connection_lte" msgid="7675461204366364124">"LTE"</string>
     <string name="data_connection_lte_plus" msgid="6643158654804916653">"LTE+"</string>
     <string name="data_connection_carrier_wifi" msgid="8932949159370130465">"W+"</string>
-    <string name="cell_data_off_content_description" msgid="2280700839891636498">"Мобилни подаци су искључени"</string>
-    <string name="not_default_data_content_description" msgid="6517068332106592887">"Није подешено за коришћење података"</string>
-    <string name="accessibility_no_phone" msgid="2687419663127582503">"Нема телефона."</string>
-    <string name="accessibility_phone_one_bar" msgid="5719721147018970063">"Сигнал телефона има једну црту."</string>
-    <string name="accessibility_phone_two_bars" msgid="2531458337458953263">"Сигнал телефона од две црте."</string>
-    <string name="accessibility_phone_three_bars" msgid="1523967995996696619">"Сигнал телефона од три црте."</string>
-    <string name="accessibility_phone_signal_full" msgid="4302338883816077134">"Сигнал телефона је пун."</string>
-    <string name="accessibility_no_data" msgid="4563181886936931008">"Нема података."</string>
-    <string name="accessibility_data_one_bar" msgid="6892888138070752480">"Сигнал за податке има једну црту."</string>
-    <string name="accessibility_data_two_bars" msgid="9202641507241802499">"Сигнал за податке од две црте."</string>
-    <string name="accessibility_data_three_bars" msgid="2813876214466722413">"Сигнал за податке од три црте."</string>
-    <string name="accessibility_data_signal_full" msgid="1808301899314382337">"Сигнал за податке је најјачи."</string>
-    <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Веза са етернетом је прекинута."</string>
-    <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Етернет."</string>
-    <string name="accessibility_no_calling" msgid="3540827068323895748">"Без позивања."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Одаберите слику профила"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Подразумевана икона корисника"</string>
-    <string name="physical_keyboard_title" msgid="4811935435315835220">"Физичка тастатура"</string>
-    <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Одаберите распоред тастатуре"</string>
-    <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Подразумевано"</string>
-    <string name="turn_screen_on_title" msgid="3266937298097573424">"Укључите екран"</string>
-    <string name="allow_turn_screen_on" msgid="6194845766392742639">"Дозволи укључивање екрана"</string>
-    <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Дозвољава апликацији да укључи екран. Ако се омогући, апликација може да укључи екран у било ком тренутку без ваше експлицитне намере."</string>
-    <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Желите да зауставите емитовање апликације <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Ако емитујете апликацију <xliff:g id="SWITCHAPP">%1$s</xliff:g> или промените излаз, актуелно емитовање ће се зауставити"</string>
-    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Емитујте апликацију <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
-    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Промените излаз"</string>
-    <string name="back_navigation_animation" msgid="8105467568421689484">"Анимације за покрет повратка са предвиђањем"</string>
-    <string name="back_navigation_animation_summary" msgid="741292224121599456">"Омогућите анимације система за покрет повратка са предвиђањем."</string>
-    <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ово подешавање омогућава анимације система за покрет повратка са предвиђањем. Захтева подешавање дозволе enableOnBackInvokedCallback по апликацији на true у фајлу манифеста."</string>
+    <string name="cell_data_off_content_description" msgid="2280700839891636498">"Mobilni podaci su isključeni"</string>
+    <string name="not_default_data_content_description" msgid="6517068332106592887">"Nije podešeno za korišćenje podataka"</string>
+    <string name="accessibility_no_phone" msgid="2687419663127582503">"Nema telefona."</string>
+    <string name="accessibility_phone_one_bar" msgid="5719721147018970063">"Signal telefona ima jednu crtu."</string>
+    <string name="accessibility_phone_two_bars" msgid="2531458337458953263">"Signal telefona od dve crte."</string>
+    <string name="accessibility_phone_three_bars" msgid="1523967995996696619">"Signal telefona od tri crte."</string>
+    <string name="accessibility_phone_signal_full" msgid="4302338883816077134">"Signal telefona je pun."</string>
+    <string name="accessibility_no_data" msgid="4563181886936931008">"Nema podataka."</string>
+    <string name="accessibility_data_one_bar" msgid="6892888138070752480">"Signal za podatke ima jednu crtu."</string>
+    <string name="accessibility_data_two_bars" msgid="9202641507241802499">"Signal za podatke od dve crte."</string>
+    <string name="accessibility_data_three_bars" msgid="2813876214466722413">"Signal za podatke od tri crte."</string>
+    <string name="accessibility_data_signal_full" msgid="1808301899314382337">"Signal za podatke je najjači."</string>
+    <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Veza sa eternetom je prekinuta."</string>
+    <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Eternet."</string>
+    <string name="accessibility_no_calling" msgid="3540827068323895748">"Bez pozivanja."</string>
+    <string name="avatar_picker_title" msgid="8492884172713170652">"Odaberite sliku profila"</string>
+    <string name="default_user_icon_description" msgid="6554047177298972638">"Podrazumevana ikona korisnika"</string>
+    <string name="physical_keyboard_title" msgid="4811935435315835220">"Fizička tastatura"</string>
+    <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Odaberite raspored tastature"</string>
+    <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Podrazumevano"</string>
+    <string name="turn_screen_on_title" msgid="3266937298097573424">"Uključite ekran"</string>
+    <string name="allow_turn_screen_on" msgid="6194845766392742639">"Dozvoli uključivanje ekrana"</string>
+    <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Dozvoljava aplikaciji da uključi ekran. Ako se omogući, aplikacija može da uključi ekran u bilo kom trenutku bez vaše eksplicitne namere."</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Želite da zaustavite emitovanje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Ako emitujete aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promenite izlaz, aktuelno emitovanje će se zaustaviti"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Emitujte aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Promenite izlaz"</string>
+    <string name="back_navigation_animation" msgid="8105467568421689484">"Animacije za pokret povratka sa predviđanjem"</string>
+    <string name="back_navigation_animation_summary" msgid="741292224121599456">"Omogućite animacije sistema za pokret povratka sa predviđanjem."</string>
+    <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ovo podešavanje omogućava animacije sistema za pokret povratka sa predviđanjem. Zahteva podešavanje dozvole enableOnBackInvokedCallback po aplikaciji na true u fajlu manifesta."</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 1fccad9..0d89e92 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Да поўнай зарадкі засталося <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – да поўнай зарадкі засталося: <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – Зарадка аптымізавана"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – Зарадка аптымізавана"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Невядома"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Зарадка"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Хуткая зарадка"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 5ce9cba..0e331c8 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -182,7 +182,7 @@
     <string name="unknown" msgid="3544487229740637809">"Неизвестно"</string>
     <string name="running_process_item_user_label" msgid="3988506293099805796">"Потребител: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
     <string name="launch_defaults_some" msgid="3631650616557252926">"Зададени са някои стандартни настройки"</string>
-    <string name="launch_defaults_none" msgid="8049374306261262709">"Няма зададени стандартни настройки"</string>
+    <string name="launch_defaults_none" msgid="8049374306261262709">"Няма зададени стандартни действия"</string>
     <string name="tts_settings" msgid="8130616705989351312">"Настройки за синтезиран говор"</string>
     <string name="tts_settings_title" msgid="7602210956640483039">"Синтезиран говор"</string>
     <string name="tts_default_rate_title" msgid="3964187817364304022">"Скорост на речта"</string>
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Оставащо време до пълно зареждане: <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – Оставащо време до пълно зареждане: <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – Зареждането е оптимизирано"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – Зареждането е оптимизирано"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Неизвестно"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Зарежда се"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Зарежда се бързо"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index bca3eb1..080e700 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g>-এ ব্যাটারি পুরো চার্জ হয়ে যাবে"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>-এ ব্যাটারি পুরো চার্জ হয়ে যাবে"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - চার্জিং অপ্টিমাইজ করা হয়েছে"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - চার্জিং অপ্টিমাইজ করা হয়েছে"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"অজানা"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"চার্জ হচ্ছে"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"দ্রুত চার্জ হচ্ছে"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index b5e75e4..f39f7fc 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> do potpune napunjenosti"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do potpune napunjenosti"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – punjenje je optimizirano"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – punjenje je optimizirano"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Nepoznato"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Punjenje"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Brzo punjenje"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index cff34e3..516a864 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> per completar la càrrega"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g>: càrrega optimitzada"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g>: càrrega optimitzada"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Desconegut"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"S\'està carregant"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carregant ràpidament"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index f5b7600..2683f9e 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> do úplného nabití"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabití"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – optimalizované nabíjení"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – optimalizované nabíjení"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Neznámé"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Nabíjí se"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Rychlé nabíjení"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 1f3d5f9..8fd740f 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Fuldt opladet om <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – fuldt opladet om <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – opladning er optimeret"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – opladning optimeres"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Ukendt"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Oplader"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Oplader hurtigt"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 35e8637..9f50140 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Voll in <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – voll in <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – Laden wird optimiert"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – Laden wird optimiert"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Unbekannt"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Wird aufgeladen"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Schnelles Aufladen"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 200c640..0a89ed1 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -317,7 +317,7 @@
     <string name="wifi_unmetered_label" msgid="6174142840934095093">"Χωρίς μέτρηση με βάση τη χρήση"</string>
     <string name="select_logd_size_title" msgid="1604578195914595173">"Μέγεθος προσωρινής μνήμης για τη λειτουργία καταγραφής"</string>
     <string name="select_logd_size_dialog_title" msgid="2105401994681013578">"Μέγεθος αρχείων κατ/φής ανά προ/νή μνήμη αρχείου κατ/φής"</string>
-    <string name="dev_logpersist_clear_warning_title" msgid="8631859265777337991">"Διαγραφή αποθηκευτικού χώρου μόνιμων αρχείων καταγραφής;"</string>
+    <string name="dev_logpersist_clear_warning_title" msgid="8631859265777337991">"Εκκαθάριση αποθηκευτικού χώρου μόνιμων αρχείων καταγραφής;"</string>
     <string name="dev_logpersist_clear_warning_message" msgid="6447590867594287413">"Όταν δεν γίνεται πλέον παρακολούθηση με μόνιμο αρχείο καταγραφής, θα πρέπει να διαγραφούν τα δεδομένα του αρχείου καταγραφής στη συσκευή σας."</string>
     <string name="select_logpersist_title" msgid="447071974007104196">"Αποθ.δεδ.αρχείων κατ.μόνιμα στη συσκ."</string>
     <string name="select_logpersist_dialog_title" msgid="7745193591195485594">"Επιλογή αρχείων καταγραφής προσωρινής μνήμης για αποθήκευση μόνιμα στη συσκευή"</string>
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Απομένουν <xliff:g id="TIME">%1$s</xliff:g> για πλήρη φόρτιση"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - Απομένουν <xliff:g id="TIME">%2$s</xliff:g> για πλήρη φόρτιση"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Η φόρτιση βελτιστοποιήθηκε"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Η φόρτιση βελτιστοποιήθηκε"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Άγνωστο"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Φόρτιση"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Ταχεία φόρτιση"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 000cd8a..ba64e85 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> left until full"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> left until full"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Charging optimised"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Charging optimised"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Unknown"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Charging"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Charging rapidly"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 000cd8a..ba64e85 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> left until full"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> left until full"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Charging optimised"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Charging optimised"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Unknown"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Charging"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Charging rapidly"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 000cd8a..ba64e85 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> left until full"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> left until full"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Charging optimised"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Charging optimised"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Unknown"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Charging"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Charging rapidly"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index d89aff6..b23f883 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> para completar"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carga optimizada"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carga optimizada"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Desconocido"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Cargando"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Cargando rápidamente"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 794d64f..ff04270 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -182,7 +182,7 @@
     <string name="unknown" msgid="3544487229740637809">"Desconocido"</string>
     <string name="running_process_item_user_label" msgid="3988506293099805796">"Usuario: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
     <string name="launch_defaults_some" msgid="3631650616557252926">"Se han establecido algunos valores predeterminados"</string>
-    <string name="launch_defaults_none" msgid="8049374306261262709">"No se han establecido opciones predeterminadas"</string>
+    <string name="launch_defaults_none" msgid="8049374306261262709">"No se han establecido valores predeterminados"</string>
     <string name="tts_settings" msgid="8130616705989351312">"Ajustes de conversión de texto a voz"</string>
     <string name="tts_settings_title" msgid="7602210956640483039">"Salida de conversión de texto a voz"</string>
     <string name="tts_default_rate_title" msgid="3964187817364304022">"Velocidad de la voz"</string>
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> hasta la carga completa"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> hasta la carga completa"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carga optimizada"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carga optimizada"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Desconocido"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Cargando"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carga rápida"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 4204320..574743e 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Täislaadimiseks kulub <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – täislaadimiseks kulub <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – laadimine on optimeeritud"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – laadimine on optimeeritud"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Tundmatu"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Laadimine"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Kiirlaadimine"</string>
diff --git a/packages/SettingsLib/res/values-eu/arrays.xml b/packages/SettingsLib/res/values-eu/arrays.xml
index 9c12e95..d15712a 100644
--- a/packages/SettingsLib/res/values-eu/arrays.xml
+++ b/packages/SettingsLib/res/values-eu/arrays.xml
@@ -267,7 +267,7 @@
     <item msgid="3358668781763928157">"Kargatzen"</item>
     <item msgid="7804797564616858506">"MTP (multimedia-edukia transferitzeko protokoloa)"</item>
     <item msgid="910925519184248772">"PTP (irudiak transferitzeko protokoloa)"</item>
-    <item msgid="3825132913289380004">"RNDIS (USB bidezko Ethernet konexioa)"</item>
+    <item msgid="3825132913289380004">"RNDIS (USB bidezko Ethernet-konexioa)"</item>
     <item msgid="8828567335701536560">"Audio-iturburua"</item>
     <item msgid="8688681727755534982">"MIDI"</item>
   </string-array>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 92eaf2b..34e59f3 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> guztiz kargatu arte"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> guztiz kargatu arte"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Kargatze optimizatua"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Kargatze optimizatua"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Ezezaguna"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Kargatzen"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Bizkor kargatzen"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 6bdbc0e..1bf56c0 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - ‏<xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> تا شارژ کامل باقی مانده است"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> تا شارژ کامل باقی مانده است"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - شارژ بهینه شده است"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - شارژ بهینه شده است"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"ناشناس"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"در حال شارژ شدن"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"درحال شارژ شدن سریع"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index a6eb736..28df1ea 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> kunnes täynnä"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kunnes täynnä"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – Lataus optimoitu"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – Lataus optimoitu"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Tuntematon"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Ladataan"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Nopea lataus"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 477e2de1..c5d37da 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> jusqu\'à la recharge complète"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g> jusqu\'à la recharge complète)"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Recharge optimisée"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Recharge optimisée"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Inconnu"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Charge en cours…"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Recharge rapide"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index fe1744e..e9dc12f 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Chargée à 100 %% dans <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - chargée à 100 %% dans <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Recharge optimisée"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Recharge optimisée"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Inconnu"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Batterie en charge"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Charge rapide"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 2f4eb5b..d69f0cb 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> para completar a carga"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g> para completar a carga)"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> (carga optimizada)"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> (carga optimizada)"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Descoñecido"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Cargando"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Cargando rapidamente"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 267c468..e54d098 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"પૂર્ણ ચાર્જ થવામાં <xliff:g id="TIME">%1$s</xliff:g> બાકી છે"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - પૂર્ણ ચાર્જ થવામાં <xliff:g id="TIME">%2$s</xliff:g> બાકી છે"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - ચાર્જિંગ ઑપ્ટિમાઇઝ કરવામાં આવ્યું છે"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - ચાર્જિંગ ઑપ્ટિમાઇઝ કરવામાં આવ્યું છે"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"અજાણ્યું"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"ચાર્જ થઈ રહ્યું છે"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ઝડપથી ચાર્જ થાય છે"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 0ad754c..d4ef7ea 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> में बैटरी पूरी चार्ज हो जाएगी"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> में बैटरी पूरी चार्ज हो जाएगी"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - चार्जिंग को ऑप्टिमाइज़ किया गया"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - चार्जिंग को ऑप्टिमाइज़ किया गया"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"अज्ञात"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"चार्ज हो रही है"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"तेज़ चार्ज हो रही है"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 34c82b1..59039b4 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> do napunjenosti"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napunjenosti"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – punjenje se optimizira"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – punjenje se optimizira"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Nepoznato"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Punjenje"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Brzo punjenje"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 2a43d15..016a0e8 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> a teljes töltöttségig"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> a teljes töltöttségig"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – Optimalizált töltés"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – Optimalizált töltés"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Ismeretlen"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Töltés"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Gyorstöltés"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 8442bf5..518161a 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> մինչև լրիվ լիցքավորումը"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> մինչև լրիվ լիցքավորումը"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – Լիցքավորումն օպտիմալացված է"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – Լիցքավորումն օպտիմալացված է"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Անհայտ"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Լիցքավորում"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Արագ լիցքավորում"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index d1e490f..abdbf06 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> lagi sampai penuh"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lagi sampai penuh"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Pengisian daya dioptimalkan"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Pengisian daya dioptimalkan"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Tidak diketahui"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Mengisi daya"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Mengisi daya cepat"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index b011b2d..05a6779 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> fram að fullri hleðslu"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> fram að fullri hleðslu"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – Hleðsla fínstillt"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – Hleðsla fínstillt"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Óþekkt"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Í hleðslu"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Hröð hleðsla"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index b659443..23e54c3 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> alla ricarica completa"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla ricarica completa"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Ricarica ottimizzata"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Ricarica ottimizzata"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Sconosciuta"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"In carica"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Ricarica veloce"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 7303a2d..6db4ebb 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g>‏ – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"הזמן הנותר לטעינה מלאה: <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – הזמן הנותר לטעינה מלאה: <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – הטעינה עברה אופטימיזציה"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – הטעינה עברה אופטימיזציה"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"לא ידוע"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"בטעינה"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"הסוללה נטענת מהר"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 1f80d48..e93b87c 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"完了まであと <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - 完了まであと <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - 充電最適化済み"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - 充電最適化済み"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"不明"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"充電中"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"急速充電中"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index fd37a860..14e82ea 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"სრულ დატენვამდე დარჩენილია <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> — სრულ დატენვამდე დარჩენილია <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - დატენვა ოპტიმიზირებულია"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - დატენვა ოპტიმიზირებულია"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"უცნობი"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"იტენება"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"სწრაფად იტენება"</string>
diff --git a/packages/SettingsLib/res/values-kk/arrays.xml b/packages/SettingsLib/res/values-kk/arrays.xml
index 9971f86..3fd1b50 100644
--- a/packages/SettingsLib/res/values-kk/arrays.xml
+++ b/packages/SettingsLib/res/values-kk/arrays.xml
@@ -50,13 +50,13 @@
   </string-array>
   <string-array name="hdcp_checking_titles">
     <item msgid="2377230797542526134">"Ешқашан тексермеу"</item>
-    <item msgid="3919638466823112484">"DRM (авторлық құқықты техникалық қорғау) мазмұнын ғана тексеру"</item>
+    <item msgid="3919638466823112484">"DRM (авторлық құқықты техникалық қорғау) контентін ғана тексеру"</item>
     <item msgid="9048424957228926377">"Әрқашан тексеру"</item>
   </string-array>
   <string-array name="hdcp_checking_summaries">
-    <item msgid="4045840870658484038">"Ешқашан HDCP (жоғары кең жолақты цифрлық мазмұн қорғаушы) тексерулерін қолданбаңыз"</item>
-    <item msgid="8254225038262324761">"HDCP тексерісін DRM мазмұны үшін ғана қолдану"</item>
-    <item msgid="6421717003037072581">"Әрқашан HDCP (жоғары кең жолақты цифрлық мазмұн қорғаушы) тексерулерін қолданыңыз"</item>
+    <item msgid="4045840870658484038">"Ешқашан HDCP (жоғары кең жолақты цифрлық контент қорғаушы) тексерулерін қолданбаңыз"</item>
+    <item msgid="8254225038262324761">"HDCP тексерісін DRM контенті үшін ғана қолдану"</item>
+    <item msgid="6421717003037072581">"Әрқашан HDCP (жоғары кең жолақты цифрлық контент қорғаушы) тексерулерін қолданыңыз"</item>
   </string-array>
   <string-array name="bt_hci_snoop_log_entries">
     <item msgid="695678520785580527">"Өшірулі"</item>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index dea3570..e8092d0 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -344,7 +344,7 @@
     <string name="enable_terminal_title" msgid="3834790541986303654">"Жергілікті терминал"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Жергілікті шелл-код қол жетімділігін ұсынатын терминалды қолданбаны қосу"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP тексерісі"</string>
-    <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP (кең жолақты цифрлық мазмұн қорғау) тексеру мүмкіндігін орнату"</string>
+    <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP (кең жолақты цифрлық контент қорғау) тексеру мүмкіндігін орнату"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Түзету"</string>
     <string name="debug_app" msgid="8903350241392391766">"Түзету қолданбасын таңдау"</string>
     <string name="debug_app_not_set" msgid="1934083001283807188">"Түзету қолданбалары орнатылмаған."</string>
@@ -424,7 +424,7 @@
   <string-array name="color_mode_descriptions">
     <item msgid="6828141153199944847">"Жақсартылған түстер"</item>
     <item msgid="4548987861791236754">"Көзбен көргендегі табиғи түстер"</item>
-    <item msgid="1282170165150762976">"Сандық мазмұн үшін оңтайландырылған түстер"</item>
+    <item msgid="1282170165150762976">"Сандық контент үшін оңтайландырылған түстер"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="5372523625297212320">"Күту режиміндегі қолданбалар"</string>
     <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"Белсенді емес. Ауыстырып қосу үшін түртіңіз."</string>
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Толық зарядталғанға дейін <xliff:g id="TIME">%1$s</xliff:g> қалды."</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – толық зарядталғанға дейін <xliff:g id="TIME">%2$s</xliff:g> қалды."</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – зарядтау оңтайландырылды."</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – зарядтау оңтайландырылды."</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Белгісіз"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Зарядталуда"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Жылдам зарядталуда"</string>
@@ -569,8 +567,8 @@
     <string name="accessor_expires_text" msgid="4625619273236786252">"Рұқсаттың аяқталу мерзімі: <xliff:g id="DATE">%s</xliff:g>"</string>
     <string name="delete_blob_text" msgid="2819192607255625697">"Ортақ деректерді жою"</string>
     <string name="delete_blob_confirmation_text" msgid="7807446938920827280">"Осы ортақ деректерді шынымен жойғыңыз келе ме?"</string>
-    <string name="user_add_user_item_summary" msgid="5748424612724703400">"Пайдаланушылардың өздерінің қолданбалары мен мазмұны болады"</string>
-    <string name="user_add_profile_item_summary" msgid="5418602404308968028">"Өз аккаунтыңыздан қолданбалар мен мазмұнға қол жетімділікті шектеуіңізге болады"</string>
+    <string name="user_add_user_item_summary" msgid="5748424612724703400">"Пайдаланушылардың өздерінің қолданбалары мен контенті болады"</string>
+    <string name="user_add_profile_item_summary" msgid="5418602404308968028">"Өз аккаунтыңыздан қолданбалар мен контентке қол жетімділікті шектеуіңізге болады"</string>
     <string name="user_add_user_item_title" msgid="2394272381086965029">"Пайдаланушы"</string>
     <string name="user_add_profile_item_title" msgid="3111051717414643029">"Шектелген профайл"</string>
     <string name="user_add_user_title" msgid="5457079143694924885">"Жаңа пайдаланушы қосылсын ба?"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 4ed0952..f8c1ffa 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> ទៀតទើបពេញ"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - នៅសល់ <xliff:g id="TIME">%2$s</xliff:g> ទៀតទើបពេញ"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - បានបង្កើនប្រសិទ្ធភាពនៃការសាក"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - បានបង្កើនប្រសិទ្ធភាពនៃការសាក"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"មិន​ស្គាល់"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"កំពុងសាក​ថ្ម"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"កំពុងសាកថ្មយ៉ាងឆាប់រហ័ស"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index e18a3f1..5f7c596 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> - ಸಮಯದಲ್ಲಿ ಪೂರ್ತಿ ಚಾರ್ಜ್ ಆಗುತ್ತದೆ"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ಸಮಯದಲ್ಲಿ ಪೂರ್ತಿ ಚಾರ್ಜ್ ಆಗುತ್ತದೆ"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - ಚಾರ್ಜಿಂಗ್ ಅನ್ನು ಆಪ್ಟಿಮೈಸ್ ಮಾಡಲಾಗಿದೆ"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - ಚಾರ್ಜಿಂಗ್ ಅನ್ನು ಆಪ್ಟಿಮೈಸ್ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"ಅಪರಿಚಿತ"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ವೇಗದ ಚಾರ್ಜಿಂಗ್"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 42ec09c9..270b04f 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> 후 충전 완료"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> 후 충전 완료"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - 충전 최적화됨"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - 충전 최적화됨"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"알 수 없음"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"충전 중"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"고속 충전 중"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 1e3453b..a904fb2 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> кийин толук кубатталат"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> кийин толук кубатталат"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> — Кубаттоо жакшыртылды"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> — Кубаттоо жакшыртылды"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Белгисиз"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Кубатталууда"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Ыкчам кубатталууда"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 63ff4df..ee6c02f 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"ຍັງເຫຼືອອີກ <xliff:g id="TIME">%1$s</xliff:g> ຈຶ່ງຈະສາກເຕັມ"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"ຍັງເຫຼືອອີກ <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ຈຶ່ງຈະສາກເຕັມ"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - ການສາກຖືກປັບໃຫ້ເໝາະສົມແລ້ວ"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - ການສາກຖືກປັບໃຫ້ເໝາະສົມແລ້ວ"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"ບໍ່ຮູ້ຈັກ"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"ກຳລັງສາກໄຟ"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ກຳລັງສາກໄຟດ່ວນ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 765fb10..1314771 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Liko <xliff:g id="TIME">%1$s</xliff:g>, kol bus visiškai įkrauta"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – liko <xliff:g id="TIME">%2$s</xliff:g>, kol bus visiškai įkrauta"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – įkrovimas optimizuotas"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – įkrovimas optimizuotas"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Nežinomas"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Kraunasi..."</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Greitai įkraunama"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 222e41a..69cef9d 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> līdz pilnai uzlādei"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g> līdz pilnai uzlādei"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> — uzlāde optimizēta"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> — uzlāde optimizēta"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Nezināms"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Uzlāde"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Notiek ātrā uzlāde"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index f672c60..729d9fd 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> до полна батерија"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> до полна батерија"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Полнењето е оптимизирано"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Полнењето е оптимизирано"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Непознато"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Се полни"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Брзо полнење"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index e6ccc5a..b07ff67 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"പൂർണ്ണമാകാൻ <xliff:g id="TIME">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - പൂർണ്ണമാകാൻ <xliff:g id="TIME">%2$s</xliff:g> ശേഷിക്കുന്നു"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - ചാർജിംഗ് ഒപ്റ്റിമൈസ് ചെയ്തു"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - ചാർജിംഗ് ഒപ്റ്റിമൈസ് ചെയ്തു"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"അജ്ഞാതം"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"ചാർജ് ചെയ്യുന്നു"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"അതിവേഗ ചാർജിംഗ്"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 71630d4..e388366 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Дүүрэх хүртэл <xliff:g id="TIME">%1$s</xliff:g> үлдсэн"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - дүүрэх хүртэл <xliff:g id="TIME">%2$s</xliff:g> үлдсэн"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Цэнэглэх явцыг оновчилсон"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Цэнэглэх явцыг оновчилсон"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Тодорхойгүй"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Цэнэглэж байна"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Хурдан цэнэглэж байна"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 0493ffe..b611ae1 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"पूर्ण चार्ज होण्यासाठी <xliff:g id="TIME">%1$s</xliff:g> शिल्लक आहेत"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - पूर्ण चार्ज होण्यासाठी <xliff:g id="TIME">%2$s</xliff:g> शिल्लक आहे"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - चार्जिंग ऑप्टिमाइझ केले"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - चार्जिंग ऑप्टिमाइझ केले"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"अज्ञात"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"चार्ज होत आहे"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"वेगाने चार्ज होत आहे"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index bb3b65b..16edeb9 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> lagi sebelum penuh"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lagi sebelum penuh"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Pengecasan dioptimumkan"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Pengecasan dioptimumkan"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Tidak diketahui"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Mengecas"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Mengecas dgn cepat"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 5bcaa27..91ab024 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"အားပြည့်ရန် <xliff:g id="TIME">%1$s</xliff:g> လိုသည်"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"အားပြည့်ရန် <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> လိုသည်"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - အားသွင်းခြင်းကို အကောင်းဆုံးပြင်ဆင်ထားသည်"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - အားသွင်းခြင်းကို အကောင်းဆုံးပြင်ဆင်ထားသည်"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"မသိ"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"အားသွင်းနေပါသည်"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"အမြန် အားသွင်းနေသည်"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index e42e939..aede28a 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Fulladet om <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – Fulladet om <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – Ladingen er optimalisert"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – Ladingen er optimalisert"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Ukjent"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Lader"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Lader raskt"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 8c5171b..7795158 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -94,7 +94,7 @@
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"विच्छेदन गरियो"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"जडान हटाइँदै ..."</string>
     <string name="bluetooth_connecting" msgid="5871702668260192755">"जडान हुँदै..."</string>
-    <string name="bluetooth_connected" msgid="8065345572198502293">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> सँग जडान गरियो"</string>
+    <string name="bluetooth_connected" msgid="8065345572198502293">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> सँग कनेक्ट भएको छ"</string>
     <string name="bluetooth_pairing" msgid="4269046942588193600">"कनेक्ट गरिँदै छ..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"जडान गरियो (फोनबाहेेक) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"जडान गरियो (मिडियाबाहेक) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
@@ -182,7 +182,7 @@
     <string name="unknown" msgid="3544487229740637809">"अज्ञात"</string>
     <string name="running_process_item_user_label" msgid="3988506293099805796">"प्रयोगकर्ता: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
     <string name="launch_defaults_some" msgid="3631650616557252926">"केही पूर्वनिर्धारितहरू सेट गरिएका छन्"</string>
-    <string name="launch_defaults_none" msgid="8049374306261262709">"कुनै डिफल्ट सेट गरिएको छैन"</string>
+    <string name="launch_defaults_none" msgid="8049374306261262709">"कुनै डिफल्ट मान सेट गरिएको छैन"</string>
     <string name="tts_settings" msgid="8130616705989351312">"पाठ-वाचन सेटिङहरू"</string>
     <string name="tts_settings_title" msgid="7602210956640483039">"टेक्स्ट टु स्पिच आउटपुट"</string>
     <string name="tts_default_rate_title" msgid="3964187817364304022">"बोलीको गति"</string>
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"पूरा चार्ज हुन <xliff:g id="TIME">%1$s</xliff:g> लाग्ने छ"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - पूरा चार्ज हुन <xliff:g id="TIME">%2$s</xliff:g> लाग्ने छ"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - चार्ज गर्ने प्रक्रिया अप्टिमाइज गरिएको छ"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - चार्ज गर्ने प्रक्रिया अप्टिमाइज गरिएको छ"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"अज्ञात"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"चार्ज हुँदै छ"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"द्रुत गतिमा चार्ज गरिँदै छ"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index aa70f9b..8ee274b 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Vol over <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - vol over <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Opladen geoptimaliseerd"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Opladen geoptimaliseerd"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Onbekend"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Opladen"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Snel opladen"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index a39e0ec..b18c53b 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"ପୂର୍ଣ୍ଣ ହେବାକୁ ଆଉ <xliff:g id="TIME">%1$s</xliff:g> ବାକି ଅଛି"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - ପୂର୍ଣ୍ଣ ହେବାକୁ ଆଉ <xliff:g id="TIME">%2$s</xliff:g> ବାକି ଅଛି"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - ଚାର୍ଜିଂକୁ ଅପ୍ଟିମାଇଜ କରାଯାଇଛି"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - ଚାର୍ଜିଂକୁ ଅପ୍ଟିମାଇଜ କରାଯାଇଛି"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"ଅଜ୍ଞାତ"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"ଚାର୍ଜ ହେଉଛି"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ଶୀଘ୍ର ଚାର୍ଜ ହେଉଛି"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 4a729c9..2d376b6 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"ਬੈਟਰੀ ਪੂਰੀ ਚਾਰਜ ਹੋਣ ਵਿੱਚ <xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਬੈਟਰੀ ਪੂਰੀ ਚਾਰਜ ਹੋਣ ਵਿੱਚ <xliff:g id="TIME">%2$s</xliff:g> ਬਾਕੀ"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਚਾਰਜਿੰਗ ਨੂੰ ਸੁਯੋਗ ਬਣਾਇਆ ਗਿਆ"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਚਾਰਜਿੰਗ ਨੂੰ ਸੁਯੋਗ ਬਣਾਇਆ ਗਿਆ"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"ਅਗਿਆਤ"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"ਚਾਰਜ ਹੋ ਰਹੀ ਹੈ"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ਤੇਜ਼ ਚਾਰਜ ਹੋ ਰਹੀ ਹੈ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 935ac2d..b18d819 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> do pełnego naładowania"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – ładowanie zoptymalizowane"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – ładowanie zoptymalizowane"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Nieznane"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Ładowanie"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Szybkie ładowanie"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 0ada85c..816108e 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> até a conclusão"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> até a conclusão"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carregamento otimizado"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carregamento otimizado"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Desconhecido"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Carregando"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carregando rápido"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index fca397d..d241f38 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> até à carga máxima"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até à carga máxima"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g>: carregamento otimizado"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g>: carregamento otimizado"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Desconhecido"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"A carregar"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carregamento rápido"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 0ada85c..816108e 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> até a conclusão"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> até a conclusão"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carregamento otimizado"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carregamento otimizado"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Desconhecido"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Carregando"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carregando rápido"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 0ce8f46..ea5faa8 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> până la finalizare"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> până la finalizare"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – Încărcare optimizată"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – Încărcare optimizată"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Necunoscut"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Se încarcă"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Se încarcă rapid"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index ac97cb8..9e4f23c 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> до полной зарядки"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – зарядка оптимизирована"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – зарядка оптимизирована"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Неизвестно"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Идет зарядка"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Быстрая зарядка"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 099202c..0fb7ebf 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"සම්පූර්ණ වීමට <xliff:g id="TIME">%1$s</xliff:g>ක් ඉතිරියි"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - සම්පූර්ණ වීමට <xliff:g id="TIME">%2$s</xliff:g>ක් ඉතිරියි"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - ආරෝපණය ප්‍රශස්ත කර ඇත"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - ආරෝපණය ප්‍රශස්ත කර ඇත"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"නොදනී"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"ආරෝපණය වෙමින්"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ශීඝ්‍ර ආරෝපණය"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 06e822e..1d18703 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> do úplného nabitia"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Nabíjanie je optimalizované"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Nabíjanie je optimalizované"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Neznáme"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Nabíja sa"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Rýchle nabíjanie"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 4e4d540..f3ad4a3 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Še <xliff:g id="TIME">%1$s</xliff:g> do napolnjenosti"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – še <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – polnjenje je optimizirano"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – polnjenje je optimizirano"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Neznano"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Polnjenje"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Hitro polnjenje"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 86aaf6a..b8f3dc2 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> derisa të mbushet"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> derisa të mbushet"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Karikimi u optimizua"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Karikimi u optimizua"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"I panjohur"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Po karikohet"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Karikim i shpejtë"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 68af019..361826c 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> до краја пуњења"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до краја пуњења"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – пуњење је оптимизовано"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – пуњење је оптимизовано"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Непознато"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Пуни се"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Брзо се пуни"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 0b2939e..ae1cab3 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> kvar tills fulladdat"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kvar tills fulladdat"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Laddningen har optimerats"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Laddningen har optimerats"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Okänd"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Laddar"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Laddas snabbt"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 49486670..84c7dd3 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -182,7 +182,7 @@
     <string name="unknown" msgid="3544487229740637809">"Haijulikani"</string>
     <string name="running_process_item_user_label" msgid="3988506293099805796">"Mtumiaji: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
     <string name="launch_defaults_some" msgid="3631650616557252926">"Baadhi ya chaguomsingi zimewekwa"</string>
-    <string name="launch_defaults_none" msgid="8049374306261262709">"Hakuna chaguo-misingi zilizowekwa"</string>
+    <string name="launch_defaults_none" msgid="8049374306261262709">"Hakuna machaguomsingi yaliyowekwa"</string>
     <string name="tts_settings" msgid="8130616705989351312">"Mipangilio ya kusoma maandishi kwa sauti"</string>
     <string name="tts_settings_title" msgid="7602210956640483039">"Kusoma maandishi kwa sauti"</string>
     <string name="tts_default_rate_title" msgid="3964187817364304022">"Kasi ya kutamka"</string>
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Zimesalia <xliff:g id="TIME">%1$s</xliff:g> ijae chaji"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> zimesalia ijae chaji"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Hali ya kuchaji imeboreshwa"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Hali ya kuchaji imeboreshwa"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Haijulikani"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Inachaji"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Inachaji kwa kasi"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 9b22973..6af4df8 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"முழுவதும் சார்ஜாக <xliff:g id="TIME">%1$s</xliff:g> ஆகும்"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - முழுவதும் சார்ஜாக <xliff:g id="TIME">%2$s</xliff:g> ஆகும்"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - சார்ஜிங் மேம்படுத்தப்பட்டது"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - சார்ஜிங் மேம்படுத்தப்பட்டது"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"அறியப்படாத"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"சார்ஜ் ஆகிறது"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"வேகமாக சார்ஜாகிறது"</string>
diff --git a/packages/SettingsLib/res/values-te/arrays.xml b/packages/SettingsLib/res/values-te/arrays.xml
index d4361e5..fb4cff1 100644
--- a/packages/SettingsLib/res/values-te/arrays.xml
+++ b/packages/SettingsLib/res/values-te/arrays.xml
@@ -56,7 +56,7 @@
   <string-array name="hdcp_checking_summaries">
     <item msgid="4045840870658484038">"ఎప్పటికీ HDCP తనిఖీని ఉపయోగించవద్దు"</item>
     <item msgid="8254225038262324761">"DRM కంటెంట్‌కు మాత్రమే HDCP చెకింగ్‌ను ఉపయోగించండి"</item>
-    <item msgid="6421717003037072581">"ఎప్పటికీ HDCP తనిఖీని ఉపయోగించు"</item>
+    <item msgid="6421717003037072581">"ఎప్పటికీ HDCP తనిఖీని ఉపయోగించండి"</item>
   </string-array>
   <string-array name="bt_hci_snoop_log_entries">
     <item msgid="695678520785580527">"డిజేబుల్ చేయబడింది"</item>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 311d3c9..d56fb62 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -137,13 +137,13 @@
     <string name="bluetooth_hid_profile_summary_connected" msgid="3923653977051684833">"ఇన్‌పుట్ పరికరానికి కనెక్ట్ చేయబడింది"</string>
     <string name="bluetooth_pan_user_profile_summary_connected" msgid="380469653827505727">"ఇంటర్నెట్ యాక్సెస్ కోసం పరికరానికి కనెక్ట్ చేయబడింది"</string>
     <string name="bluetooth_pan_nap_profile_summary_connected" msgid="3744773111299503493">"స్థానిక ఇంటర్నెట్ కనెక్షన్‌ను పరికరంతో షేర్ చేయడం"</string>
-    <string name="bluetooth_pan_profile_summary_use_for" msgid="7422039765025340313">"ఇంటర్నెట్ యాక్సెస్ కోసం ఉపయోగించు"</string>
-    <string name="bluetooth_map_profile_summary_use_for" msgid="4453622103977592583">"మ్యాప్ కోసం ఉపయోగించు"</string>
+    <string name="bluetooth_pan_profile_summary_use_for" msgid="7422039765025340313">"ఇంటర్నెట్ యాక్సెస్ కోసం ఉపయోగించండి"</string>
+    <string name="bluetooth_map_profile_summary_use_for" msgid="4453622103977592583">"మ్యాప్ కోసం ఉపయోగించండి"</string>
     <string name="bluetooth_sap_profile_summary_use_for" msgid="6204902866176714046">"SIM యాక్సెస్ కోసం ఉపయోగించబడుతుంది"</string>
-    <string name="bluetooth_a2dp_profile_summary_use_for" msgid="7324694226276491807">"మీడియా ఆడియో కోసం ఉపయోగించు"</string>
-    <string name="bluetooth_headset_profile_summary_use_for" msgid="808970643123744170">"ఫోన్ ఆడియో కోసం ఉపయోగించు"</string>
-    <string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"ఫైల్ బదిలీ కోసం ఉపయోగించు"</string>
-    <string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"ఇన్‌పుట్ కోసం ఉపయోగించు"</string>
+    <string name="bluetooth_a2dp_profile_summary_use_for" msgid="7324694226276491807">"మీడియా ఆడియో కోసం ఉపయోగించండి"</string>
+    <string name="bluetooth_headset_profile_summary_use_for" msgid="808970643123744170">"ఫోన్ ఆడియో కోసం ఉపయోగించండి"</string>
+    <string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"ఫైల్ బదిలీ కోసం ఉపయోగించండి"</string>
+    <string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"ఇన్‌పుట్ కోసం ఉపయోగించండి"</string>
     <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"వినికిడి మద్దతు ఉపకరణాలకు ఉపయోగించండి"</string>
     <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"LE_AUDIO కోసం ఉపయోగించండి"</string>
     <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"జత చేయి"</string>
@@ -190,7 +190,7 @@
     <string name="tts_default_pitch_title" msgid="6988592215554485479">"పిచ్"</string>
     <string name="tts_default_pitch_summary" msgid="9132719475281551884">"సమన్వయం చేసిన ప్రసంగం యొక్క టోన్‌ను ప్రభావితం చేస్తుంది"</string>
     <string name="tts_default_lang_title" msgid="4698933575028098940">"భాష"</string>
-    <string name="tts_lang_use_system" msgid="6312945299804012406">"సిస్టమ్ భాషను ఉపయోగించు"</string>
+    <string name="tts_lang_use_system" msgid="6312945299804012406">"సిస్టమ్ భాషను ఉపయోగించండి"</string>
     <string name="tts_lang_not_selected" msgid="7927823081096056147">"భాష ఎంచుకోబడలేదు"</string>
     <string name="tts_default_lang_summary" msgid="9042620014800063470">"టెక్స్ట్‌ను చదివి వినిపించేటప్పుడు, ఒక్కో భాషకు వాడాల్సిన నిర్దిష్ట వాయిస్‌ను సెట్ చేస్తుంది"</string>
     <string name="tts_play_example_title" msgid="1599468547216481684">"ఒక ఉదాహరణ వినండి"</string>
@@ -372,7 +372,7 @@
     <string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"హార్డ్‌వేర్ లేయర్‌లు అప్‌డేట్‌ చేయబడినప్పుడు వాటిని ఆకుపచ్చ రంగులో ఫ్లాష్ చేయి"</string>
     <string name="debug_hw_overdraw" msgid="8944851091008756796">"GPU ఓవర్‌డ్రాను డీబగ్ చేయండి"</string>
     <string name="disable_overlays" msgid="4206590799671557143">"డిజేబుల్-  HW ఓవర్‌లేలు"</string>
-    <string name="disable_overlays_summary" msgid="1954852414363338166">"స్క్రీన్ కంపాజిటింగ్‌కు ఎల్లప్పుడూ GPUని ఉపయోగించు"</string>
+    <string name="disable_overlays_summary" msgid="1954852414363338166">"స్క్రీన్ కంపాజిటింగ్‌కు ఎల్లప్పుడూ GPUని ఉపయోగించండి"</string>
     <string name="simulate_color_space" msgid="1206503300335835151">"రంగుల‌ను సిమ్యులేట్ చేయి"</string>
     <string name="enable_opengl_traces_title" msgid="4638773318659125196">"OpenGL ట్రేస్‌లను ప్రారంభించండి"</string>
     <string name="usb_audio_disable_routing" msgid="3367656923544254975">"USB ఆడియో రూటింగ్ నిలిపివేయి"</string>
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g>లో పూర్తిగా ఛార్జ్ అవుతుంది"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>లో పూర్తిగా ఛార్జ్ అవుతుంది"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - ఛార్జింగ్ ఆప్టిమైజ్ చేయబడింది"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - ఛార్జింగ్ ఆప్టిమైజ్ చేయబడింది"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"తెలియదు"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"ఛార్జ్ అవుతోంది"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"వేగవంతమైన ఛార్జింగ్"</string>
@@ -516,7 +514,7 @@
     <string name="retail_demo_reset_next" msgid="3688129033843885362">"తర్వాత"</string>
     <string name="retail_demo_reset_title" msgid="1866911701095959800">"పాస్‌వర్డ్ అవసరం"</string>
     <string name="active_input_method_subtypes" msgid="4232680535471633046">"సక్రియ ఇన్‌పుట్ పద్ధతులు"</string>
-    <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"సిస్టమ్ భాషలను ఉపయోగించు"</string>
+    <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"సిస్టమ్ భాషలను ఉపయోగించండి"</string>
     <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> యొక్క సెట్టింగ్‌లను తెరవడం విఫలమైంది"</string>
     <string name="ime_security_warning" msgid="6547562217880551450">"ఈ ఇన్‌పుట్ పద్ధతి మీరు టైప్ చేసే మొత్తం వచనాన్ని అలాగే పాస్‌వర్డ్‌లు మరియు క్రెడిట్ కార్డు నంబర్‌ల వంటి వ్యక్తిగత డేటాను సేకరించగలదు. ఇది <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> యాప్‌లో అందించబడుతుంది. ఈ ఇన్‌పుట్ పద్ధతిని ఉపయోగించాలా?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"గమనిక: రీబూట్ చేసాక, మీరు మీ ఫోన్‌ను అన్‌లాక్ చేసే వరకు ఈ యాప్ ప్రారంభం కాదు"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 680e7d6..c308c7f 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"อีก <xliff:g id="TIME">%1$s</xliff:g>จึงจะเต็ม"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - อีก <xliff:g id="TIME">%2$s</xliff:g> จึงจะเต็ม"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - ปรับการชาร์จให้เหมาะสมแล้ว"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - ปรับการชาร์จให้เหมาะสมแล้ว"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"ไม่ทราบ"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"กำลังชาร์จ"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"กำลังชาร์จอย่างเร็ว"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index f4bf11d9..883a592 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -58,7 +58,7 @@
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Problema sa pag-authenticate"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Hindi makakonekta"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Hindi makakonekta sa \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
-    <string name="wifi_check_password_try_again" msgid="8817789642851605628">"Suriin ang password at subukang muli"</string>
+    <string name="wifi_check_password_try_again" msgid="8817789642851605628">"Suriin ang password at subukan ulit"</string>
     <string name="wifi_not_in_range" msgid="1541760821805777772">"Wala sa sakop"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Hindi awtomatikong kokonekta"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Walang access sa internet"</string>
@@ -81,7 +81,7 @@
     <string name="osu_opening_provider" msgid="4318105381295178285">"Binubuksan ang <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Hindi makakonekta"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Kinukumpleto ang pag-sign up…"</string>
-    <string name="osu_sign_up_failed" msgid="5605453599586001793">"Hindi makumpleto ang pag-sign up. I-tap para subukang muli."</string>
+    <string name="osu_sign_up_failed" msgid="5605453599586001793">"Hindi makumpleto ang pag-sign up. I-tap para subukan ulit."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Kumpleto na ang pag-sign up. Kumokonekta…"</string>
     <string name="speed_label_very_slow" msgid="8526005255731597666">"Napakabagal"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Mabagal"</string>
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> na lang bago mapuno"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> na lang bago mapuno"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Naka-optimize ang pag-charge"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Naka-optimize ang pag-charge"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Hindi Kilala"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Nagcha-charge"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Mabilis na charge"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 74762a6..738e97e 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Tamamen şarj olmasına <xliff:g id="TIME">%1$s</xliff:g> kaldı"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tamamen şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Şarj işlemi optimize edildi"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Şarj işlemi optimize edildi"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Bilinmiyor"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Şarj oluyor"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Hızlı şarj oluyor"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 19b2496..41fd9f7 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> до повного заряду"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного заряду"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – заряджання оптимізовано"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – заряджання оптимізовано"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Невідомо"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Заряджається"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Швидке заряджання"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 112217d..ecd55ea 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"‎<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>‎"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"مکمل چارج ہونے میں <xliff:g id="TIME">%1$s</xliff:g> باقی ہے"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"مکمل چارج ہونے میں <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> باقی ہے"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - چارجنگ کو بہتر بنایا گیا"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - چارجنگ کو بہتر بنایا گیا"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"نامعلوم"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"چارج ہو رہا ہے"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"تیزی سے چارج ہو رہا ہے"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 6ce7053..4cc1d21 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -244,7 +244,7 @@
     <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR kod skaneri yordamida yangi qurilmalarni ulang"</string>
     <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Qurilmani ulanish kodi orqali ulash"</string>
     <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Olti xonali kod yordamida yangi qurilmalarni ulash mumkin"</string>
-    <string name="adb_paired_devices_title" msgid="5268997341526217362">"Ulangan qurilmalar"</string>
+    <string name="adb_paired_devices_title" msgid="5268997341526217362">"Juftlangan qurilmalar"</string>
     <string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"Hozirda ulangan"</string>
     <string name="adb_wireless_device_details_title" msgid="7129369670526565786">"Qurilma tafsilotlari"</string>
     <string name="adb_device_forget" msgid="193072400783068417">"Olib tashlash"</string>
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Toʻlishiga <xliff:g id="TIME">%1$s</xliff:g> qoldi"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – Toʻlishiga <xliff:g id="TIME">%2$s</xliff:g> qoldi"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Quvvatlash optimallashtirildi"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Quvvatlash optimallashtirildi"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Noma’lum"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Quvvat olmoqda"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Tezkor quvvat olmoqda"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index b9121ab..7f9d858 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> nữa là pin đầy"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> nữa là pin đầy"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – Quá trình sạc được tối ưu hoá"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – Quá trình sạc được tối ưu hoá"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Không xác định"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Đang sạc"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Đang sạc nhanh"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index d59aba1..676309d 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"还需<xliff:g id="TIME">%1$s</xliff:g>充满"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需<xliff:g id="TIME">%2$s</xliff:g>充满"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - 充电方式已优化"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - 充电方式已优化"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"未知"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"正在充电"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"正在快速充电"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index fd607226..23c0203 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g>後充滿電"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充滿電"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - 已優化充電"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - 已優化充電"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"未知"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"充電中"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"快速充電中"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/arrays.xml b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
index 66aaa56b..b69fd53 100644
--- a/packages/SettingsLib/res/values-zh-rTW/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
@@ -247,7 +247,7 @@
   </string-array>
   <string-array name="track_frame_time_entries">
     <item msgid="634406443901014984">"關閉"</item>
-    <item msgid="1288760936356000927">"在螢幕上以列顯示"</item>
+    <item msgid="1288760936356000927">"在螢幕上顯示長條圖"</item>
     <item msgid="5023908510820531131">"在「<xliff:g id="AS_TYPED_COMMAND">adb shell dumpsys gfxinfo</xliff:g>」指令中"</item>
   </string-array>
   <string-array name="debug_hw_overdraw_entries">
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 3ae32b4..50d2921 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -259,7 +259,7 @@
     <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"正在配對裝置…"</string>
     <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"無法配對裝置。可能是QR 圖碼錯誤,或是裝置未連上相同的網路。"</string>
     <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP 位址和通訊埠"</string>
-    <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"掃描 QR 圖碼"</string>
+    <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"掃描 QR code"</string>
     <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"掃描 QR 圖碼即可透過 Wi-Fi 配對裝置"</string>
     <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"請連上 Wi-Fi 網路"</string>
     <string name="keywords_adb_wireless" msgid="6507505581882171240">"ADB, 偵錯, 開發"</string>
@@ -351,7 +351,7 @@
     <string name="debug_app_set" msgid="6599535090477753651">"偵錯應用程式:<xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="select_application" msgid="2543228890535466325">"選取應用程式"</string>
     <string name="no_application" msgid="9038334538870247690">"無"</string>
-    <string name="wait_for_debugger" msgid="7461199843335409809">"等待偵錯程式"</string>
+    <string name="wait_for_debugger" msgid="7461199843335409809">"等待偵錯工具"</string>
     <string name="wait_for_debugger_summary" msgid="6846330006113363286">"執行受偵錯的應用程式之前,先等待偵錯程序附加完成"</string>
     <string name="debug_input_category" msgid="7349460906970849771">"輸入"</string>
     <string name="debug_drawing_category" msgid="5066171112313666619">"繪圖"</string>
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g>後充飽"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - 充電效能已最佳化"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - 充電效能將最佳化"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"不明"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"充電中"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"快速充電中"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 57de713..3898831 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -477,10 +477,8 @@
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> okusele kuze kugcwale"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> okusele kuze kugcwale"</string>
-    <!-- no translation found for power_charging_limited (8202147604844938236) -->
-    <skip />
-    <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
-    <skip />
+    <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Ukushaja kuthuthukisiwe"</string>
+    <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Ukushaja kuthuthukisiwe"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Akwaziwa"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Iyashaja"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Ishaja ngokushesha"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
index 6bc1160..2f821d5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
@@ -383,7 +383,10 @@
         Log.d(TAG, "Bond " + device.getAnonymizedAddress() + " by CSIP");
         mOngoingSetMemberPair = device;
         syncConfigFromMainDevice(device, groupId);
-        device.createBond(BluetoothDevice.TRANSPORT_LE);
+        if (!device.createBond(BluetoothDevice.TRANSPORT_LE)) {
+            Log.d(TAG, "Bonding could not be started");
+            mOngoingSetMemberPair = null;
+        }
     }
 
     private void syncConfigFromMainDevice(BluetoothDevice device, int groupId) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java b/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java
index 44a37f4..d4d2b48 100644
--- a/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.content.res.Resources;
+import android.hardware.display.DisplayManager;
 import android.os.AsyncTask;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -32,6 +33,9 @@
 import com.android.settingslib.R;
 
 import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Predicate;
 
 /**
  * Utility methods for working with display density.
@@ -70,120 +74,169 @@
      */
     private static final int MIN_DIMENSION_DP = 320;
 
-    private final String[] mEntries;
-    private final int[] mValues;
+    private static final Predicate<DisplayInfo> INTERNAL_ONLY =
+            (info) -> info.type == Display.TYPE_INTERNAL;
 
-    private final int mDefaultDensity;
-    private final int mCurrentIndex;
+    private final Predicate<DisplayInfo> mPredicate;
+
+    private final DisplayManager mDisplayManager;
+
+    /**
+     * The text description of the density values of the default display.
+     */
+    private String[] mDefaultDisplayDensityEntries;
+
+    /**
+     * The density values of the default display.
+     */
+    private int[] mDefaultDisplayDensityValues;
+
+    /**
+     * The density values, indexed by display unique ID.
+     */
+    private final Map<String, int[]> mValuesPerDisplay = new HashMap();
+
+    private int mDefaultDensityForDefaultDisplay;
+    private int mCurrentIndex = -1;
 
     public DisplayDensityUtils(Context context) {
-        final int defaultDensity = DisplayDensityUtils.getDefaultDisplayDensity(
-                Display.DEFAULT_DISPLAY);
-        if (defaultDensity <= 0) {
-            mEntries = null;
-            mValues = null;
-            mDefaultDensity = 0;
-            mCurrentIndex = -1;
-            return;
-        }
+        this(context, INTERNAL_ONLY);
+    }
 
-        final Resources res = context.getResources();
-        DisplayInfo info = new DisplayInfo();
-        context.getDisplayNoVerify().getDisplayInfo(info);
+    /**
+     * Creates an instance that stores the density values for the displays that satisfy
+     * the predicate.
+     * @param context The context
+     * @param predicate Determines what displays the density should be set for. The default display
+     *                  must satisfy this predicate.
+     */
+    public DisplayDensityUtils(Context context, Predicate predicate) {
+        mPredicate = predicate;
+        mDisplayManager = context.getSystemService(DisplayManager.class);
 
-        final int currentDensity = info.logicalDensityDpi;
-        int currentDensityIndex = -1;
-
-        // Compute number of "larger" and "smaller" scales for this display.
-        final int minDimensionPx = Math.min(info.logicalWidth, info.logicalHeight);
-        final int maxDensity = DisplayMetrics.DENSITY_MEDIUM * minDimensionPx / MIN_DIMENSION_DP;
-        final float maxScaleDimen = context.getResources().getFraction(
-                R.fraction.display_density_max_scale, 1, 1);
-        final float maxScale = Math.min(maxScaleDimen, maxDensity / (float) defaultDensity);
-        final float minScale = context.getResources().getFraction(
-                R.fraction.display_density_min_scale, 1, 1);
-        final float minScaleInterval = context.getResources().getFraction(
-                R.fraction.display_density_min_scale_interval, 1, 1);
-        final int numLarger = (int) MathUtils.constrain((maxScale - 1) / minScaleInterval,
-                0, SUMMARIES_LARGER.length);
-        final int numSmaller = (int) MathUtils.constrain((1 - minScale) / minScaleInterval,
-                0, SUMMARIES_SMALLER.length);
-
-        String[] entries = new String[1 + numSmaller + numLarger];
-        int[] values = new int[entries.length];
-        int curIndex = 0;
-
-        if (numSmaller > 0) {
-            final float interval = (1 - minScale) / numSmaller;
-            for (int i = numSmaller - 1; i >= 0; i--) {
-                // Round down to a multiple of 2 by truncating the low bit.
-                final int density = ((int) (defaultDensity * (1 - (i + 1) * interval))) & ~1;
-                if (currentDensity == density) {
-                    currentDensityIndex = curIndex;
-                }
-                entries[curIndex] = res.getString(SUMMARIES_SMALLER[i]);
-                values[curIndex] = density;
-                curIndex++;
+        for (Display display : mDisplayManager.getDisplays(
+                DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED)) {
+            DisplayInfo info = new DisplayInfo();
+            if (!display.getDisplayInfo(info)) {
+                Log.w(LOG_TAG, "Cannot fetch display info for display " + display.getDisplayId());
+                continue;
             }
-        }
-
-        if (currentDensity == defaultDensity) {
-            currentDensityIndex = curIndex;
-        }
-        values[curIndex] = defaultDensity;
-        entries[curIndex] = res.getString(SUMMARY_DEFAULT);
-        curIndex++;
-
-        if (numLarger > 0) {
-            final float interval = (maxScale - 1) / numLarger;
-            for (int i = 0; i < numLarger; i++) {
-                // Round down to a multiple of 2 by truncating the low bit.
-                final int density = ((int) (defaultDensity * (1 + (i + 1) * interval))) & ~1;
-                if (currentDensity == density) {
-                    currentDensityIndex = curIndex;
+            if (!mPredicate.test(info)) {
+                if (display.getDisplayId() == Display.DEFAULT_DISPLAY) {
+                    throw new IllegalArgumentException("Predicate must not filter out the default "
+                            + "display.");
                 }
-                values[curIndex] = density;
-                entries[curIndex] = res.getString(SUMMARIES_LARGER[i]);
-                curIndex++;
+                continue;
             }
+
+            final int defaultDensity = DisplayDensityUtils.getDefaultDensityForDisplay(
+                    display.getDisplayId());
+            if (defaultDensity <= 0) {
+                Log.w(LOG_TAG, "Cannot fetch default density for display "
+                        + display.getDisplayId());
+                continue;
+            }
+
+            final Resources res = context.getResources();
+
+            final int currentDensity = info.logicalDensityDpi;
+            int currentDensityIndex = -1;
+
+            // Compute number of "larger" and "smaller" scales for this display.
+            final int minDimensionPx = Math.min(info.logicalWidth, info.logicalHeight);
+            final int maxDensity =
+                    DisplayMetrics.DENSITY_MEDIUM * minDimensionPx / MIN_DIMENSION_DP;
+            final float maxScaleDimen = context.getResources().getFraction(
+                    R.fraction.display_density_max_scale, 1, 1);
+            final float maxScale = Math.min(maxScaleDimen, maxDensity / (float) defaultDensity);
+            final float minScale = context.getResources().getFraction(
+                    R.fraction.display_density_min_scale, 1, 1);
+            final float minScaleInterval = context.getResources().getFraction(
+                    R.fraction.display_density_min_scale_interval, 1, 1);
+            final int numLarger = (int) MathUtils.constrain((maxScale - 1) / minScaleInterval,
+                    0, SUMMARIES_LARGER.length);
+            final int numSmaller = (int) MathUtils.constrain((1 - minScale) / minScaleInterval,
+                    0, SUMMARIES_SMALLER.length);
+
+            String[] entries = new String[1 + numSmaller + numLarger];
+            int[] values = new int[entries.length];
+            int curIndex = 0;
+
+            if (numSmaller > 0) {
+                final float interval = (1 - minScale) / numSmaller;
+                for (int i = numSmaller - 1; i >= 0; i--) {
+                    // Round down to a multiple of 2 by truncating the low bit.
+                    final int density = ((int) (defaultDensity * (1 - (i + 1) * interval))) & ~1;
+                    if (currentDensity == density) {
+                        currentDensityIndex = curIndex;
+                    }
+                    entries[curIndex] = res.getString(SUMMARIES_SMALLER[i]);
+                    values[curIndex] = density;
+                    curIndex++;
+                }
+            }
+
+            if (currentDensity == defaultDensity) {
+                currentDensityIndex = curIndex;
+            }
+            values[curIndex] = defaultDensity;
+            entries[curIndex] = res.getString(SUMMARY_DEFAULT);
+            curIndex++;
+
+            if (numLarger > 0) {
+                final float interval = (maxScale - 1) / numLarger;
+                for (int i = 0; i < numLarger; i++) {
+                    // Round down to a multiple of 2 by truncating the low bit.
+                    final int density = ((int) (defaultDensity * (1 + (i + 1) * interval))) & ~1;
+                    if (currentDensity == density) {
+                        currentDensityIndex = curIndex;
+                    }
+                    values[curIndex] = density;
+                    entries[curIndex] = res.getString(SUMMARIES_LARGER[i]);
+                    curIndex++;
+                }
+            }
+
+            final int displayIndex;
+            if (currentDensityIndex >= 0) {
+                displayIndex = currentDensityIndex;
+            } else {
+                // We don't understand the current density. Must have been set by
+                // someone else. Make room for another entry...
+                int newLength = values.length + 1;
+                values = Arrays.copyOf(values, newLength);
+                values[curIndex] = currentDensity;
+
+                entries = Arrays.copyOf(entries, newLength);
+                entries[curIndex] = res.getString(SUMMARY_CUSTOM, currentDensity);
+
+                displayIndex = curIndex;
+            }
+
+            if (display.getDisplayId() == Display.DEFAULT_DISPLAY) {
+                mDefaultDensityForDefaultDisplay = defaultDensity;
+                mCurrentIndex = displayIndex;
+                mDefaultDisplayDensityEntries = entries;
+                mDefaultDisplayDensityValues = values;
+            }
+            mValuesPerDisplay.put(info.uniqueId, values);
         }
-
-        final int displayIndex;
-        if (currentDensityIndex >= 0) {
-            displayIndex = currentDensityIndex;
-        } else {
-            // We don't understand the current density. Must have been set by
-            // someone else. Make room for another entry...
-            int newLength = values.length + 1;
-            values = Arrays.copyOf(values, newLength);
-            values[curIndex] = currentDensity;
-
-            entries = Arrays.copyOf(entries, newLength);
-            entries[curIndex] = res.getString(SUMMARY_CUSTOM, currentDensity);
-
-            displayIndex = curIndex;
-        }
-
-        mDefaultDensity = defaultDensity;
-        mCurrentIndex = displayIndex;
-        mEntries = entries;
-        mValues = values;
     }
 
-    public String[] getEntries() {
-        return mEntries;
+    public String[] getDefaultDisplayDensityEntries() {
+        return mDefaultDisplayDensityEntries;
     }
 
-    public int[] getValues() {
-        return mValues;
+    public int[] getDefaultDisplayDensityValues() {
+        return mDefaultDisplayDensityValues;
     }
 
-    public int getCurrentIndex() {
+    public int getCurrentIndexForDefaultDisplay() {
         return mCurrentIndex;
     }
 
-    public int getDefaultDensity() {
-        return mDefaultDensity;
+    public int getDefaultDensityForDefaultDisplay() {
+        return mDefaultDensityForDefaultDisplay;
     }
 
     /**
@@ -193,7 +246,7 @@
      * @return the default density of the specified display, or {@code -1} if
      *         the display does not exist or the density could not be obtained
      */
-    private static int getDefaultDisplayDensity(int displayId) {
+    private static int getDefaultDensityForDisplay(int displayId) {
        try {
            final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
            return wm.getInitialDisplayDensity(displayId);
@@ -203,19 +256,31 @@
     }
 
     /**
-     * Asynchronously applies display density changes to the specified display.
+     * Asynchronously applies display density changes to the displays that satisfy the predicate.
      * <p>
      * The change will be applied to the user specified by the value of
      * {@link UserHandle#myUserId()} at the time the method is called.
-     *
-     * @param displayId the identifier of the display to modify
      */
-    public static void clearForcedDisplayDensity(final int displayId) {
+    public void clearForcedDisplayDensity() {
         final int userId = UserHandle.myUserId();
         AsyncTask.execute(() -> {
             try {
-                final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
-                wm.clearForcedDisplayDensityForUser(displayId, userId);
+                for (Display display : mDisplayManager.getDisplays(
+                        DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED)) {
+                    int displayId = display.getDisplayId();
+                    DisplayInfo info = new DisplayInfo();
+                    if (!display.getDisplayInfo(info)) {
+                        Log.w(LOG_TAG, "Unable to clear forced display density setting "
+                                + "for display " + displayId);
+                        continue;
+                    }
+                    if (!mPredicate.test(info)) {
+                        continue;
+                    }
+
+                    final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
+                    wm.clearForcedDisplayDensityForUser(displayId, userId);
+                }
             } catch (RemoteException exc) {
                 Log.w(LOG_TAG, "Unable to clear forced display density setting");
             }
@@ -223,20 +288,39 @@
     }
 
     /**
-     * Asynchronously applies display density changes to the specified display.
+     * Asynchronously applies display density changes to the displays that satisfy the predicate.
      * <p>
      * The change will be applied to the user specified by the value of
      * {@link UserHandle#myUserId()} at the time the method is called.
      *
-     * @param displayId the identifier of the display to modify
-     * @param density the density to force for the specified display
+     * @param index The index of the density value
      */
-    public static void setForcedDisplayDensity(final int displayId, final int density) {
+    public void setForcedDisplayDensity(final int index) {
         final int userId = UserHandle.myUserId();
         AsyncTask.execute(() -> {
             try {
-                final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
-                wm.setForcedDisplayDensityForUser(displayId, density, userId);
+                for (Display display : mDisplayManager.getDisplays(
+                        DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED)) {
+                    int displayId = display.getDisplayId();
+                    DisplayInfo info = new DisplayInfo();
+                    if (!display.getDisplayInfo(info)) {
+                        Log.w(LOG_TAG, "Unable to save forced display density setting "
+                                + "for display " + displayId);
+                        continue;
+                    }
+                    if (!mPredicate.test(info)) {
+                        continue;
+                    }
+                    if (!mValuesPerDisplay.containsKey(info.uniqueId)) {
+                        Log.w(LOG_TAG, "Unable to save forced display density setting "
+                                + "for display " + info.uniqueId);
+                        continue;
+                    }
+
+                    final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
+                    wm.setForcedDisplayDensityForUser(displayId,
+                            mValuesPerDisplay.get(info.uniqueId)[index], userId);
+                }
             } catch (RemoteException exc) {
                 Log.w(LOG_TAG, "Unable to save forced display density setting");
             }
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
index 7ec0fcd..d2e615a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
@@ -190,6 +190,10 @@
         return !isGroup;
     }
 
+    boolean preferRouteListingOrdering() {
+        return false;
+    }
+
     /**
      * Remove a {@code device} from current media.
      *
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
index f4355c3..7458f010 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
@@ -213,6 +213,15 @@
     }
 
     /**
+     * Returns if media app establishes a preferred route listing order.
+     *
+     * @return True if route list ordering exist and not using system ordering, false otherwise.
+     */
+    public boolean isPreferenceRouteListingExist() {
+        return mInfoMediaManager.preferRouteListingOrdering();
+    }
+
+    /**
      * Start scan connected MediaDevice
      */
     public void startScan() {
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
index c829bc3..d6586db 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
@@ -184,6 +184,15 @@
      */
     public abstract String getId();
 
+    /**
+     * Checks if device is suggested device from application
+     *
+     * @return true if device is suggested device
+     */
+    public boolean isSuggestedDevice() {
+        return false;
+    }
+
     void setConnectedRecord() {
         mConnectedRecord++;
         ConnectionRecordManager.getInstance().setConnectionRecord(mContext, getId(),
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java
index 1f2297b..fc2bf0a 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java
@@ -21,10 +21,10 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyLong;
+import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageUtilsTest.java
index 95f7ef4..508dffc 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageUtilsTest.java
@@ -18,7 +18,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java
index f28572f..cf07c6b 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java
@@ -22,7 +22,7 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoInteractions;
 import static org.mockito.Mockito.when;
 
 import android.app.Activity;
@@ -143,7 +143,7 @@
         dialog.show();
         dialog.cancel();
 
-        verifyZeroInteractions(successCallback);
+        verifyNoInteractions(successCallback);
         verify(cancelCallback, times(1))
                 .run();
     }
@@ -159,7 +159,7 @@
         dialog.show();
         dialog.getButton(Dialog.BUTTON_NEGATIVE).performClick();
 
-        verifyZeroInteractions(successCallback);
+        verifyNoInteractions(successCallback);
         verify(cancelCallback, times(1))
                 .run();
     }
@@ -180,7 +180,7 @@
 
         verify(successCallback, times(1))
                 .accept("test", oldUserIcon);
-        verifyZeroInteractions(cancelCallback);
+        verifyNoInteractions(cancelCallback);
     }
 
     @Test
@@ -198,7 +198,7 @@
 
         verify(successCallback, times(1))
                 .accept("test", null);
-        verifyZeroInteractions(cancelCallback);
+        verifyNoInteractions(cancelCallback);
     }
 
     @Test
@@ -219,7 +219,7 @@
 
         verify(successCallback, times(1))
                 .accept(expectedNewName, mCurrentIcon);
-        verifyZeroInteractions(cancelCallback);
+        verifyNoInteractions(cancelCallback);
     }
 
     @Test
@@ -238,7 +238,7 @@
 
         verify(successCallback, times(1))
                 .accept("test", newPhoto);
-        verifyZeroInteractions(cancelCallback);
+        verifyNoInteractions(cancelCallback);
     }
 
     @Test
@@ -257,7 +257,7 @@
 
         verify(successCallback, times(1))
                 .accept("test", newPhoto);
-        verifyZeroInteractions(cancelCallback);
+        verifyNoInteractions(cancelCallback);
     }
 
     @Test
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java
index 29549d9..103512d 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java
@@ -61,6 +61,8 @@
     private PreferenceViewHolder mViewHolder;
     private FrameLayout mMiddleGroundLayout;
     private final Context mContext = ApplicationProvider.getApplicationContext();
+    private IllustrationPreference.OnBindListener mOnBindListener;
+    private LottieAnimationView mOnBindListenerAnimationView;
 
     @Before
     public void setUp() {
@@ -82,6 +84,12 @@
 
         final AttributeSet attributeSet = Robolectric.buildAttributeSet().build();
         mPreference = new IllustrationPreference(mContext, attributeSet);
+        mOnBindListener = new IllustrationPreference.OnBindListener() {
+            @Override
+            public void onBind(LottieAnimationView animationView) {
+                mOnBindListenerAnimationView = animationView;
+            }
+        };
     }
 
     @Test
@@ -186,4 +194,25 @@
         assertThat(mBackgroundView.getMaxHeight()).isEqualTo(restrictedHeight);
         assertThat(mAnimationView.getMaxHeight()).isEqualTo(restrictedHeight);
     }
+
+    @Test
+    public void setOnBindListener_isNotified() {
+        mOnBindListenerAnimationView = null;
+        mPreference.setOnBindListener(mOnBindListener);
+
+        mPreference.onBindViewHolder(mViewHolder);
+
+        assertThat(mOnBindListenerAnimationView).isNotNull();
+        assertThat(mOnBindListenerAnimationView).isEqualTo(mAnimationView);
+    }
+
+    @Test
+    public void setOnBindListener_notNotified() {
+        mOnBindListenerAnimationView = null;
+        mPreference.setOnBindListener(null);
+
+        mPreference.onBindViewHolder(mViewHolder);
+
+        assertThat(mOnBindListenerAnimationView).isNull();
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/UpdatableListPreferenceDialogFragmentTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/UpdatableListPreferenceDialogFragmentTest.java
index 0b3495d..ca0aa0d 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/UpdatableListPreferenceDialogFragmentTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/UpdatableListPreferenceDialogFragmentTest.java
@@ -56,7 +56,7 @@
 
         mUpdatableListPrefDlgFragment = spy(UpdatableListPreferenceDialogFragment
                 .newInstance(KEY, MetricsProto.MetricsEvent.DIALOG_SWITCH_A2DP_DEVICES));
-        mEntries = spy(new ArrayList<>());
+        mEntries = new ArrayList<>();
         mUpdatableListPrefDlgFragment.setEntries(mEntries);
         mUpdatableListPrefDlgFragment
                 .setMetricsCategory(mUpdatableListPrefDlgFragment.getArguments());
diff --git a/packages/SettingsProvider/res/values-b+sr+Latn/strings.xml b/packages/SettingsProvider/res/values-b+sr+Latn/strings.xml
index 4d05762..def4b68 100644
--- a/packages/SettingsProvider/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsProvider/res/values-b+sr+Latn/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="4567566098528588863">"Подешавања складишта"</string>
-    <string name="wifi_softap_config_change" msgid="5688373762357941645">"Подешавања хотспота су промењена"</string>
-    <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Додирните да бисте видели детаље"</string>
+    <string name="app_label" msgid="4567566098528588863">"Podešavanja skladišta"</string>
+    <string name="wifi_softap_config_change" msgid="5688373762357941645">"Podešavanja hotspota su promenjena"</string>
+    <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Dodirnite da biste videli detalje"</string>
 </resources>
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 1b0b6b4..211030a 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -123,7 +123,7 @@
         Settings.Secure.FINGERPRINT_SIDE_FPS_BP_POWER_WINDOW,
         Settings.Secure.FINGERPRINT_SIDE_FPS_ENROLL_TAP_WINDOW,
         Settings.Secure.FINGERPRINT_SIDE_FPS_AUTH_DOWNTIME,
-        Settings.Secure.SFPS_REQUIRE_SCREEN_ON_TO_AUTH_ENABLED,
+        Settings.Secure.SFPS_PERFORMANT_AUTH_ENABLED,
         Settings.Secure.ACTIVE_UNLOCK_ON_WAKE,
         Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT,
         Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 4fa490f..0539f09 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -178,7 +178,7 @@
         VALIDATORS.put(Secure.FINGERPRINT_SIDE_FPS_ENROLL_TAP_WINDOW,
                 NON_NEGATIVE_INTEGER_VALIDATOR);
         VALIDATORS.put(Secure.FINGERPRINT_SIDE_FPS_AUTH_DOWNTIME, NON_NEGATIVE_INTEGER_VALIDATOR);
-        VALIDATORS.put(Secure.SFPS_REQUIRE_SCREEN_ON_TO_AUTH_ENABLED, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Secure.SFPS_PERFORMANT_AUTH_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.SHOW_MEDIA_WHEN_BYPASSING, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.FACE_UNLOCK_APP_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, BOOLEAN_VALIDATOR);
diff --git a/packages/Shell/res/values-b+sr+Latn/strings.xml b/packages/Shell/res/values-b+sr+Latn/strings.xml
index 3513afc..805aed6 100644
--- a/packages/Shell/res/values-b+sr+Latn/strings.xml
+++ b/packages/Shell/res/values-b+sr+Latn/strings.xml
@@ -17,31 +17,31 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_notification_channel" msgid="2574150205913861141">"Извештаји о грешкама"</string>
-    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Извештај о грешци <xliff:g id="ID">#%d</xliff:g> се генерише"</string>
-    <string name="bugreport_finished_title" msgid="4429132808670114081">"Извештај о грешци <xliff:g id="ID">#%d</xliff:g> је снимљен"</string>
-    <string name="bugreport_updating_title" msgid="4423539949559634214">"Додају се детаљи у извештај о грешци"</string>
-    <string name="bugreport_updating_wait" msgid="3322151947853929470">"Сачекајте..."</string>
-    <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"Извештај о грешци ће се ускоро појавити на телефону"</string>
-    <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Изаберите да бисте делили извештај о грешци"</string>
-    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Додирните да бисте делили извештај о грешци"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Изаберите да бисте делили извештај о грешци без снимка екрана или сачекајте да се направи снимак екрана"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Додирните за дељење извештаја о грешци без снимка екрана или сачекајте да се направи снимак екрана"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Додирните за дељење извештаја о грешци без снимка екрана или сачекајте да се направи снимак екрана"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"Извештаји о грешкама садрже податке из различитих системских датотека евиденције, који обухватају личне и приватне податке (попут коришћења апликацијa и података о локацији). Делите извештаје о грешкама само са апликацијама и људима у које имате поверења."</string>
-    <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Не приказуј поново"</string>
-    <string name="bugreport_storage_title" msgid="5332488144740527109">"Извештаји о грешкама"</string>
-    <string name="bugreport_unreadable_text" msgid="586517851044535486">"Датотека извештаја о грешци не може да се прочита"</string>
-    <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"Додавање детаља извештаја о грешци у zip датотеку није успело"</string>
-    <string name="bugreport_unnamed" msgid="2800582406842092709">"неименовано"</string>
-    <string name="bugreport_info_action" msgid="2158204228510576227">"Детаљи"</string>
-    <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Снимци екрана"</string>
-    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Снимак екрана је направљен."</string>
-    <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Снимање екрана није успело."</string>
-    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Детаљи извештаја о грешци <xliff:g id="ID">#%d</xliff:g>"</string>
-    <string name="bugreport_info_name" msgid="4414036021935139527">"Назив датотеке"</string>
-    <string name="bugreport_info_title" msgid="2306030793918239804">"Наслов грешке"</string>
-    <string name="bugreport_info_description" msgid="5072835127481627722">"Резиме грешке"</string>
-    <string name="save" msgid="4781509040564835759">"Сачувај"</string>
-    <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"Дели извештај о грешци"</string>
+    <string name="bugreport_notification_channel" msgid="2574150205913861141">"Izveštaji o greškama"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Izveštaj o grešci <xliff:g id="ID">#%d</xliff:g> se generiše"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Izveštaj o grešci <xliff:g id="ID">#%d</xliff:g> je snimljen"</string>
+    <string name="bugreport_updating_title" msgid="4423539949559634214">"Dodaju se detalji u izveštaj o grešci"</string>
+    <string name="bugreport_updating_wait" msgid="3322151947853929470">"Sačekajte..."</string>
+    <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"Izveštaj o grešci će se uskoro pojaviti na telefonu"</string>
+    <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Izaberite da biste delili izveštaj o grešci"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Dodirnite da biste delili izveštaj o grešci"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Izaberite da biste delili izveštaj o grešci bez snimka ekrana ili sačekajte da se napravi snimak ekrana"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Dodirnite za deljenje izveštaja o grešci bez snimka ekrana ili sačekajte da se napravi snimak ekrana"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Dodirnite za deljenje izveštaja o grešci bez snimka ekrana ili sačekajte da se napravi snimak ekrana"</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"Izveštaji o greškama sadrže podatke iz različitih sistemskih datoteka evidencije, koji obuhvataju lične i privatne podatke (poput korišćenja aplikacija i podataka o lokaciji). Delite izveštaje o greškama samo sa aplikacijama i ljudima u koje imate poverenja."</string>
+    <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Ne prikazuj ponovo"</string>
+    <string name="bugreport_storage_title" msgid="5332488144740527109">"Izveštaji o greškama"</string>
+    <string name="bugreport_unreadable_text" msgid="586517851044535486">"Datoteka izveštaja o grešci ne može da se pročita"</string>
+    <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"Dodavanje detalja izveštaja o grešci u zip datoteku nije uspelo"</string>
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"neimenovano"</string>
+    <string name="bugreport_info_action" msgid="2158204228510576227">"Detalji"</string>
+    <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Snimci ekrana"</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Snimak ekrana je napravljen."</string>
+    <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Snimanje ekrana nije uspelo."</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Detalji izveštaja o grešci <xliff:g id="ID">#%d</xliff:g>"</string>
+    <string name="bugreport_info_name" msgid="4414036021935139527">"Naziv datoteke"</string>
+    <string name="bugreport_info_title" msgid="2306030793918239804">"Naslov greške"</string>
+    <string name="bugreport_info_description" msgid="5072835127481627722">"Rezime greške"</string>
+    <string name="save" msgid="4781509040564835759">"Sačuvaj"</string>
+    <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"Deli izveštaj o grešci"</string>
 </resources>
diff --git a/packages/Shell/res/values-te/strings.xml b/packages/Shell/res/values-te/strings.xml
index 2f86232..f99800e 100644
--- a/packages/Shell/res/values-te/strings.xml
+++ b/packages/Shell/res/values-te/strings.xml
@@ -42,6 +42,6 @@
     <string name="bugreport_info_name" msgid="4414036021935139527">"ఫైల్ పేరు"</string>
     <string name="bugreport_info_title" msgid="2306030793918239804">"బగ్ శీర్షిక"</string>
     <string name="bugreport_info_description" msgid="5072835127481627722">"బగ్ సారాంశం"</string>
-    <string name="save" msgid="4781509040564835759">"సేవ్ చేయి"</string>
+    <string name="save" msgid="4781509040564835759">"సేవ్ చేయండి"</string>
     <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"బగ్ రిపోర్ట్‌ షేర్ చేయండి"</string>
 </resources>
diff --git a/packages/SimAppDialog/res/values-b+sr+Latn/strings.xml b/packages/SimAppDialog/res/values-b+sr+Latn/strings.xml
index 5d5921e4..f7771c5 100644
--- a/packages/SimAppDialog/res/values-b+sr+Latn/strings.xml
+++ b/packages/SimAppDialog/res/values-b+sr+Latn/strings.xml
@@ -18,9 +18,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string>
-    <string name="install_carrier_app_title" msgid="334729104862562585">"Активирајте мобилну услугу"</string>
-    <string name="install_carrier_app_description" msgid="4014303558674923797">"Да би нова SIM картица исправно радила, треба да инсталирате апликацију <xliff:g id="ID_1">%1$s</xliff:g>"</string>
-    <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Да би нова SIM картица исправно радила, треба да инсталирате апликацију мобилног оператера"</string>
-    <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Не сада"</string>
-    <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Преузми апликацију"</string>
+    <string name="install_carrier_app_title" msgid="334729104862562585">"Aktivirajte mobilnu uslugu"</string>
+    <string name="install_carrier_app_description" msgid="4014303558674923797">"Da bi nova SIM kartica ispravno radila, treba da instalirate aplikaciju <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Da bi nova SIM kartica ispravno radila, treba da instalirate aplikaciju mobilnog operatera"</string>
+    <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Ne sada"</string>
+    <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Preuzmi aplikaciju"</string>
 </resources>
diff --git a/packages/SoundPicker/res/values-b+sr+Latn/strings.xml b/packages/SoundPicker/res/values-b+sr+Latn/strings.xml
index bc573f5..947c85c 100644
--- a/packages/SoundPicker/res/values-b+sr+Latn/strings.xml
+++ b/packages/SoundPicker/res/values-b+sr+Latn/strings.xml
@@ -16,14 +16,14 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="ringtone_default" msgid="798836092118824500">"Подразумевани звук звона"</string>
-    <string name="notification_sound_default" msgid="8133121186242636840">"Подразумевани звук обавештења"</string>
-    <string name="alarm_sound_default" msgid="4787646764557462649">"Подразумевани звук аларма"</string>
-    <string name="add_ringtone_text" msgid="6642389991738337529">"Додај мелодију звона"</string>
-    <string name="add_alarm_text" msgid="3545497316166999225">"Додајте аларм"</string>
-    <string name="add_notification_text" msgid="4431129543300614788">"Додајте обавештење"</string>
-    <string name="delete_ringtone_text" msgid="201443984070732499">"Избриши"</string>
-    <string name="unable_to_add_ringtone" msgid="4583511263449467326">"Додавање прилагођене мелодије звона није успело"</string>
-    <string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Брисање прилагођене мелодије звона није успело"</string>
-    <string name="app_label" msgid="3091611356093417332">"Звукови"</string>
+    <string name="ringtone_default" msgid="798836092118824500">"Podrazumevani zvuk zvona"</string>
+    <string name="notification_sound_default" msgid="8133121186242636840">"Podrazumevani zvuk obaveštenja"</string>
+    <string name="alarm_sound_default" msgid="4787646764557462649">"Podrazumevani zvuk alarma"</string>
+    <string name="add_ringtone_text" msgid="6642389991738337529">"Dodaj melodiju zvona"</string>
+    <string name="add_alarm_text" msgid="3545497316166999225">"Dodajte alarm"</string>
+    <string name="add_notification_text" msgid="4431129543300614788">"Dodajte obaveštenje"</string>
+    <string name="delete_ringtone_text" msgid="201443984070732499">"Izbriši"</string>
+    <string name="unable_to_add_ringtone" msgid="4583511263449467326">"Dodavanje prilagođene melodije zvona nije uspelo"</string>
+    <string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Brisanje prilagođene melodije zvona nije uspelo"</string>
+    <string name="app_label" msgid="3091611356093417332">"Zvukovi"</string>
 </resources>
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 6b4d5ae..2529157 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -60,7 +60,7 @@
             // except for SystemUI-core.
             // Copied from compose/features/Android.bp.
             static_libs: [
-                "SystemUIComposeCore",
+                "PlatformComposeCore",
 
                 "androidx.compose.runtime_runtime",
                 "androidx.compose.material3_material3",
@@ -271,6 +271,7 @@
         "LowLightDreamLib",
         "motion_tool_lib",
         "androidx.core_core-animation-testing-nodeps",
+        "androidx.compose.ui_ui",
     ],
 }
 
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 2f5b42f..b6e006f 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -193,7 +193,7 @@
     <permission android:name="com.android.systemui.permission.FLAGS"
                 android:protectionLevel="signature" />
 
-    <permission android:name="android.permission.ACCESS_KEYGUARD_QUICK_AFFORDANCES"
+    <permission android:name="android.permission.CUSTOMIZE_SYSTEM_UI"
         android:protectionLevel="signature|privileged" />
 
     <!-- Adding Quick Settings tiles -->
@@ -292,7 +292,7 @@
 
     <queries>
         <intent>
-            <action android:name="android.intent.action.NOTES" />
+            <action android:name="android.intent.action.CREATE_NOTE" />
         </intent>
     </queries>
 
@@ -411,7 +411,6 @@
 
         <service android:name=".screenshot.ScreenshotCrossProfileService"
                  android:permission="com.android.systemui.permission.SELF"
-                 android:process=":screenshot_cross_profile"
                  android:exported="false" />
 
         <service android:name=".screenrecord.RecordingService" />
@@ -664,6 +663,20 @@
             android:excludeFromRecents="true"
             android:exported="true" />
 
+        <!-- started from Telecomm(CallsManager) -->
+        <activity
+            android:name=".telephony.ui.activity.SwitchToManagedProfileForCallActivity"
+            android:excludeFromRecents="true"
+            android:exported="true"
+            android:finishOnCloseSystemDialogs="true"
+            android:permission="android.permission.MODIFY_PHONE_STATE"
+            android:theme="@style/Theme.SystemUI.Dialog.Alert">
+            <intent-filter>
+                <action android:name="android.telecom.action.SHOW_SWITCH_TO_WORK_PROFILE_FOR_CALL_DIALOG" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
         <!-- platform logo easter egg activity -->
         <activity
             android:name=".DessertCase"
@@ -908,7 +921,7 @@
             android:excludeFromRecents="true"
             android:theme="@android:style/Theme.NoDisplay"
             android:label="@string/note_task_button_label"
-            android:icon="@drawable/ic_note_task_button">
+            android:icon="@drawable/ic_note_task_shortcut_widget">
 
             <intent-filter>
                 <action android:name="android.intent.action.CREATE_SHORTCUT" />
@@ -1003,10 +1016,10 @@
         </receiver>
 
         <provider
-            android:authorities="com.android.systemui.keyguard.quickaffordance"
-            android:name="com.android.systemui.keyguard.KeyguardQuickAffordanceProvider"
+            android:authorities="com.android.systemui.customization"
+            android:name="com.android.systemui.keyguard.CustomizationProvider"
             android:exported="true"
-            android:permission="android.permission.ACCESS_KEYGUARD_QUICK_AFFORDANCES"
+            android:permission="android.permission.CUSTOMIZE_SYSTEM_UI"
             />
     </application>
 </manifest>
diff --git a/packages/SystemUI/README.md b/packages/SystemUI/README.md
index ee8d023..2910bba 100644
--- a/packages/SystemUI/README.md
+++ b/packages/SystemUI/README.md
@@ -5,46 +5,72 @@
 SystemUI is a persistent process that provides UI for the system but outside
 of the system_server process.
 
-The starting point for most of sysui code is a list of services that extend
-SystemUI that are started up by SystemUIApplication. These services then depend
-on some custom dependency injection provided by Dependency.
-
 Inputs directed at sysui (as opposed to general listeners) generally come in
 through IStatusBar. Outputs from sysui are through a variety of private APIs to
 the android platform all over.
 
 ## SystemUIApplication
 
-When SystemUIApplication starts up, it will start up the services listed in
-config_systemUIServiceComponents or config_systemUIServiceComponentsPerUser.
+When SystemUIApplication starts up, it instantiates a Dagger graph from which
+various pieces of the application are built.
 
-Each of these services extend SystemUI. SystemUI provides them with a Context
-and gives them callbacks for onConfigurationChanged (this historically was
-the main path for onConfigurationChanged, now also happens through
-ConfigurationController). They also receive a callback for onBootCompleted
+To support customization, SystemUIApplication relies on the AndroidManifest.xml
+having an `android.app.AppComponentFactory` specified. Specifically, it relies
+on an `AppComponentFactory` that subclases `SystemUIAppComponentFactoryBase`.
+Implementations of this abstract base class must override
+`#createSystemUIInitializer(Context)` which returns a `SystemUIInitializer`.
+`SystemUIInitializer` primary job in turn is to intialize and return the Dagger
+root component back to the `SystemUIApplication`.
+
+Writing a custom `SystemUIAppComponentFactoryBase` and `SystemUIInitializer`,
+should be enough for most implementations to stand up a customized Dagger
+graph, and launch a custom version of SystemUI.
+
+## Dagger / Dependency Injection
+
+See [dagger.md](docs/dagger.md) and https://dagger.dev/.
+
+## CoreStartable
+
+The starting point for most of SystemUI code is a list of classes that
+implement `CoreStartable` that are started up by SystemUIApplication.
+CoreStartables are like miniature services. They have their `#start` method
+called after being instantiated, and a reference to them is stored inside
+SystemUIApplication. They are in charge of their own behavior beyond this,
+registering and unregistering with the rest of the system as needed.
+
+`CoreStartable` also receives a callback for `#onBootCompleted`
 since these objects may be started before the device has finished booting.
 
-Each SystemUI service is expected to be a major part of system ui and the
-goal is to minimize communication between them. So in general they should be
-relatively silo'd.
+`CoreStartable` is an ideal place to add new features and functionality
+that does not belong directly under the umbrella of an existing feature.
+It is better to define a new `CoreStartable` than to stick unrelated
+initialization code together in catch-all methods.
 
-## Dependencies
+CoreStartables are tied to application startup via Dagger:
 
-The first SystemUI service that is started should always be Dependency.
-Dependency provides a static method for getting a hold of dependencies that
-have a lifecycle that spans sysui. Dependency has code for how to create all
-dependencies manually added. SystemUIFactory is also capable of
-adding/replacing these dependencies.
+```kotlin
+class FeatureStartable
+@Inject
+constructor(
+    /* ... */
+) : CoreStartable {
+    override fun start() {
+        // ...
+    }
+}
 
-Dependencies are lazily initialized, so if a Dependency is never referenced at
-runtime, it will never be created.
+@Module
+abstract class FeatureModule {
+    @Binds
+    @IntoMap
+    @ClassKey(FeatureStartable::class)
+    abstract fun bind(impl: FeatureStartable): CoreStartable
+}
+```
 
-If an instantiated dependency implements Dumpable it will be included in dumps
-of sysui (and bug reports), allowing it to include current state information.
-This is how \*Controllers dump state to bug reports.
-
-If an instantiated dependency implements ConfigurationChangeReceiver it will
-receive onConfigurationChange callbacks when the configuration changes.
+Including `FeatureModule` in the Dagger graph such as this will ensure that
+`FeatureStartable` gets constructed and that its `#start` method is called.
 
 ## IStatusBar
 
@@ -64,12 +90,6 @@
 This is generally used a shortcut to directly trigger CommandQueue rather than
 calling StatusManager and waiting for the call to come back to IStatusBar.
 
-## Default SystemUI services list
-
-### [com.android.systemui.Dependency](/packages/SystemUI/src/com/android/systemui/Dependency.java)
-
-Provides custom dependency injection.
-
 ### [com.android.systemui.util.NotificationChannels](/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java)
 
 Creates/initializes the channels sysui uses when posting notifications.
@@ -88,11 +108,11 @@
 Registers all the callbacks/listeners required to show the Volume dialog when
 it should be shown.
 
-### [com.android.systemui.status.phone.StatusBar](/packages/SystemUI/src/com/android/systemui/status/phone/StatusBar.java)
+### [com.android.systemui.status.phone.CentralSurfaces](/packages/SystemUI/src/com/android/systemui/status/phone/CentralSurfaces.java)
 
 This shows the UI for the status bar and the notification shade it contains.
 It also contains a significant amount of other UI that interacts with these
-surfaces (keyguard, AOD, etc.). StatusBar also contains a notification listener
+surfaces (keyguard, AOD, etc.). CentralSurfaces also contains a notification listener
 to receive notification callbacks.
 
 ### [com.android.systemui.usb.StorageNotification](/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java)
diff --git a/packages/SystemUI/TEST_MAPPING b/packages/SystemUI/TEST_MAPPING
index cd45b8ea..60bfdb2 100644
--- a/packages/SystemUI/TEST_MAPPING
+++ b/packages/SystemUI/TEST_MAPPING
@@ -16,6 +16,9 @@
         },
         {
             "exclude-annotation": "android.platform.test.annotations.Postsubmit"
+        },
+        {
+            "exclude-annotation": "android.platform.test.annotations.FlakyTest"
         }
       ]
     }
@@ -72,16 +75,16 @@
   // Curious where your @Scenario tests will run?
   //
   // @Ignore: nowhere
-  // @Staging or @FlakyTest: in staged-postsubmit, but not postsubmit or
-  // 	presubmit
+  // @FlakyTest: in staged-postsubmit, but not blocking postsubmit or
+  // presubmit
   // @Postsubmit: in postsubmit and staged-postsubmit, but not presubmit
   // none of the above: in presubmit, postsubmit, and staged-postsubmit
   //
-  // Therefore, please annotate new tests with @Staging, then with @Postsubmit
-  // once they're ready for postsubmit, then with neither once they're ready
-  // for presubmit.
+  // Ideally, please annotate new tests with @FlakyTest, then with @Postsubmit
+  // once they're ready for postsubmit as they will immediately block go/android-platinum,
+  // then with neither once they're ready for presubmit.
   //
-  // If you don't use @Staging or @Postsubmit, your new test will immediately
+  // If you don't use @Postsubmit, your new test will immediately
   // block presubmit, which is probably not what you want!
   "sysui-platinum-postsubmit": [
     {
@@ -98,6 +101,9 @@
         },
         {
             "exclude-annotation": "androidx.test.filters.FlakyTest"
+        },
+        {
+            "exclude-annotation": "android.platform.test.annotations.FlakyTest"
         }
       ]
     }
@@ -130,6 +136,9 @@
         },
         {
             "include-filter": "android.platform.test.scenario.sysui"
+        },
+        {
+            "exclude-annotation": "android.platform.test.annotations.FlakyTest"
         }
       ]
     }
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
index fe349f2..c729b09 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
@@ -37,6 +37,8 @@
 import android.view.WindowManager
 import android.view.animation.Interpolator
 import android.view.animation.PathInterpolator
+import androidx.annotation.BinderThread
+import androidx.annotation.UiThread
 import com.android.internal.annotations.VisibleForTesting
 import com.android.internal.policy.ScreenDecorationsUtils
 import kotlin.math.roundToInt
@@ -226,7 +228,7 @@
         // If we expect an animation, post a timeout to cancel it in case the remote animation is
         // never started.
         if (willAnimate) {
-            runner.postTimeout()
+            runner.delegate.postTimeout()
 
             // Hide the keyguard using the launch animation instead of the default unlock animation.
             if (hideKeyguardWithAnimation) {
@@ -299,10 +301,13 @@
 
     interface Callback {
         /** Whether we are currently on the keyguard or not. */
-        fun isOnKeyguard(): Boolean
+        @JvmDefault fun isOnKeyguard(): Boolean = false
 
         /** Hide the keyguard and animate using [runner]. */
-        fun hideKeyguardWithAnimation(runner: IRemoteAnimationRunner)
+        @JvmDefault
+        fun hideKeyguardWithAnimation(runner: IRemoteAnimationRunner) {
+            throw UnsupportedOperationException()
+        }
 
         /* Get the background color of [task]. */
         fun getBackgroundColor(task: TaskInfo): Int
@@ -389,14 +394,51 @@
         fun onLaunchAnimationCancelled(newKeyguardOccludedState: Boolean? = null) {}
     }
 
-    class Runner(
+    @VisibleForTesting
+    inner class Runner(
+        controller: Controller,
+        callback: Callback,
+        /** The animator to use to animate the window launch. */
+        launchAnimator: LaunchAnimator = DEFAULT_LAUNCH_ANIMATOR,
+        /** Listener for animation lifecycle events. */
+        listener: Listener? = null
+    ) : IRemoteAnimationRunner.Stub() {
+        private val context = controller.launchContainer.context
+        internal val delegate: AnimationDelegate
+
+        init {
+            delegate = AnimationDelegate(controller, callback, launchAnimator, listener)
+        }
+
+        @BinderThread
+        override fun onAnimationStart(
+            transit: Int,
+            apps: Array<out RemoteAnimationTarget>?,
+            wallpapers: Array<out RemoteAnimationTarget>?,
+            nonApps: Array<out RemoteAnimationTarget>?,
+            finishedCallback: IRemoteAnimationFinishedCallback?
+        ) {
+            context.mainExecutor.execute {
+                delegate.onAnimationStart(transit, apps, wallpapers, nonApps, finishedCallback)
+            }
+        }
+
+        @BinderThread
+        override fun onAnimationCancelled(isKeyguardOccluded: Boolean) {
+            context.mainExecutor.execute { delegate.onAnimationCancelled(isKeyguardOccluded) }
+        }
+    }
+
+    class AnimationDelegate
+    @JvmOverloads
+    constructor(
         private val controller: Controller,
         private val callback: Callback,
         /** The animator to use to animate the window launch. */
         private val launchAnimator: LaunchAnimator = DEFAULT_LAUNCH_ANIMATOR,
         /** Listener for animation lifecycle events. */
         private val listener: Listener? = null
-    ) : IRemoteAnimationRunner.Stub() {
+    ) : RemoteAnimationDelegate<IRemoteAnimationFinishedCallback> {
         private val launchContainer = controller.launchContainer
         private val context = launchContainer.context
         private val transactionApplierView =
@@ -419,6 +461,7 @@
         // posting it.
         private var onTimeout = Runnable { onAnimationTimedOut() }
 
+        @UiThread
         internal fun postTimeout() {
             launchContainer.postDelayed(onTimeout, LAUNCH_TIMEOUT)
         }
@@ -427,19 +470,20 @@
             launchContainer.removeCallbacks(onTimeout)
         }
 
+        @UiThread
         override fun onAnimationStart(
             @WindowManager.TransitionOldType transit: Int,
             apps: Array<out RemoteAnimationTarget>?,
             wallpapers: Array<out RemoteAnimationTarget>?,
             nonApps: Array<out RemoteAnimationTarget>?,
-            iCallback: IRemoteAnimationFinishedCallback?
+            callback: IRemoteAnimationFinishedCallback?
         ) {
             removeTimeout()
 
             // The animation was started too late and we already notified the controller that it
             // timed out.
             if (timedOut) {
-                iCallback?.invoke()
+                callback?.invoke()
                 return
             }
 
@@ -449,7 +493,7 @@
                 return
             }
 
-            context.mainExecutor.execute { startAnimation(apps, nonApps, iCallback) }
+            startAnimation(apps, nonApps, callback)
         }
 
         private fun startAnimation(
@@ -687,6 +731,7 @@
             controller.onLaunchAnimationCancelled()
         }
 
+        @UiThread
         override fun onAnimationCancelled(isKeyguardOccluded: Boolean) {
             if (timedOut) {
                 return
@@ -695,10 +740,9 @@
             Log.i(TAG, "Remote animation was cancelled")
             cancelled = true
             removeTimeout()
-            context.mainExecutor.execute {
-                animation?.cancel()
-                controller.onLaunchAnimationCancelled(newKeyguardOccludedState = isKeyguardOccluded)
-            }
+
+            animation?.cancel()
+            controller.onLaunchAnimationCancelled(newKeyguardOccludedState = isKeyguardOccluded)
         }
 
         private fun IRemoteAnimationFinishedCallback.invoke() {
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
index 54aa351..a3ed085 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
@@ -237,13 +237,17 @@
             openedDialogs.firstOrNull {
                 it.dialog.window.decorView.viewRootImpl == controller.viewRoot
             }
-        val animateFrom =
+        val controller =
             animatedParent?.dialogContentWithBackground?.let {
                 Controller.fromView(it, controller.cuj)
             }
                 ?: controller
 
-        if (animatedParent == null && animateFrom !is LaunchableView) {
+        if (
+            animatedParent == null &&
+                controller is ViewDialogLaunchAnimatorController &&
+                controller.source !is LaunchableView
+        ) {
             // Make sure the View we launch from implements LaunchableView to avoid visibility
             // issues. Given that we don't own dialog decorViews so we can't enforce it for launches
             // from a dialog.
@@ -272,7 +276,7 @@
                 launchAnimator,
                 callback,
                 interactionJankMonitor,
-                animateFrom,
+                controller,
                 onDialogDismissed = { openedDialogs.remove(it) },
                 dialog = dialog,
                 animateBackgroundBoundsChange,
@@ -366,7 +370,7 @@
         val dialog = animatedDialog.dialog
 
         // Don't animate if the dialog is not showing or if we are locked and going to show the
-        // bouncer.
+        // primary bouncer.
         if (
             !dialog.isShowing ||
                 (!callback.isUnlocked() && !callback.isShowingAlternateAuthOnUnlock())
@@ -791,13 +795,13 @@
         // Move the drawing of the source in the overlay of this dialog, then animate. We trigger a
         // one-off synchronization to make sure that this is done in sync between the two different
         // windows.
+        controller.startDrawingInOverlayOf(decorView)
         synchronizeNextDraw(
             then = {
                 isSourceDrawnInDialog = true
                 maybeStartLaunchAnimation()
             }
         )
-        controller.startDrawingInOverlayOf(decorView)
     }
 
     /**
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt
index 3d341af..2903288 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt
@@ -33,9 +33,7 @@
 private const val FONT_ITALIC_ANIMATION_STEP = 0.1f
 private const val FONT_ITALIC_DEFAULT_VALUE = 0f
 
-/**
- * Provide interpolation of two fonts by adjusting font variation settings.
- */
+/** Provide interpolation of two fonts by adjusting font variation settings. */
 class FontInterpolator {
 
     /**
@@ -61,11 +59,14 @@
         var index: Int,
         val sortedAxes: MutableList<FontVariationAxis>
     ) {
-        constructor(font: Font, axes: List<FontVariationAxis>) :
-                this(font.sourceIdentifier,
-                        font.ttcIndex,
-                        axes.toMutableList().apply { sortBy { it.tag } }
-                )
+        constructor(
+            font: Font,
+            axes: List<FontVariationAxis>
+        ) : this(
+            font.sourceIdentifier,
+            font.ttcIndex,
+            axes.toMutableList().apply { sortBy { it.tag } }
+        )
 
         fun set(font: Font, axes: List<FontVariationAxis>) {
             sourceId = font.sourceIdentifier
@@ -86,9 +87,7 @@
     private val tmpInterpKey = InterpKey(null, null, 0f)
     private val tmpVarFontKey = VarFontKey(0, 0, mutableListOf())
 
-    /**
-     * Linear interpolate the font variation settings.
-     */
+    /** Linear interpolate the font variation settings. */
     fun lerp(start: Font, end: Font, progress: Float): Font {
         if (progress == 0f) {
             return start
@@ -115,27 +114,34 @@
         // this doesn't take much time since the variation axes is usually up to 5. If we need to
         // support more number of axes, we may want to preprocess the font and store the sorted axes
         // and also pre-fill the missing axes value with default value from 'fvar' table.
-        val newAxes = lerp(startAxes, endAxes) { tag, startValue, endValue ->
-            when (tag) {
-                // TODO: Good to parse 'fvar' table for retrieving default value.
-                TAG_WGHT -> adjustWeight(
-                        MathUtils.lerp(
+        val newAxes =
+            lerp(startAxes, endAxes) { tag, startValue, endValue ->
+                when (tag) {
+                    // TODO: Good to parse 'fvar' table for retrieving default value.
+                    TAG_WGHT ->
+                        adjustWeight(
+                            MathUtils.lerp(
                                 startValue ?: FONT_WEIGHT_DEFAULT_VALUE,
                                 endValue ?: FONT_WEIGHT_DEFAULT_VALUE,
-                                progress))
-                TAG_ITAL -> adjustItalic(
-                        MathUtils.lerp(
+                                progress
+                            )
+                        )
+                    TAG_ITAL ->
+                        adjustItalic(
+                            MathUtils.lerp(
                                 startValue ?: FONT_ITALIC_DEFAULT_VALUE,
                                 endValue ?: FONT_ITALIC_DEFAULT_VALUE,
-                                progress))
-                else -> {
-                    require(startValue != null && endValue != null) {
-                        "Unable to interpolate due to unknown default axes value : $tag"
+                                progress
+                            )
+                        )
+                    else -> {
+                        require(startValue != null && endValue != null) {
+                            "Unable to interpolate due to unknown default axes value : $tag"
+                        }
+                        MathUtils.lerp(startValue, endValue, progress)
                     }
-                    MathUtils.lerp(startValue, endValue, progress)
                 }
             }
-        }
 
         // Check if we already make font for this axes. This is typically happens if the animation
         // happens backward.
@@ -149,9 +155,7 @@
         // This is the first time to make the font for the axes. Build and store it to the cache.
         // Font.Builder#build won't throw IOException since creating fonts from existing fonts will
         // not do any IO work.
-        val newFont = Font.Builder(start)
-                .setFontVariationSettings(newAxes.toTypedArray())
-                .build()
+        val newFont = Font.Builder(start).setFontVariationSettings(newAxes.toTypedArray()).build()
         interpCache[InterpKey(start, end, progress)] = newFont
         verFontCache[VarFontKey(start, newAxes)] = newFont
         return newFont
@@ -173,26 +177,28 @@
             val tagA = if (i < start.size) start[i].tag else null
             val tagB = if (j < end.size) end[j].tag else null
 
-            val comp = when {
-                tagA == null -> 1
-                tagB == null -> -1
-                else -> tagA.compareTo(tagB)
-            }
+            val comp =
+                when {
+                    tagA == null -> 1
+                    tagB == null -> -1
+                    else -> tagA.compareTo(tagB)
+                }
 
-            val axis = when {
-                comp == 0 -> {
-                    val v = filter(tagA!!, start[i++].styleValue, end[j++].styleValue)
-                    FontVariationAxis(tagA, v)
+            val axis =
+                when {
+                    comp == 0 -> {
+                        val v = filter(tagA!!, start[i++].styleValue, end[j++].styleValue)
+                        FontVariationAxis(tagA, v)
+                    }
+                    comp < 0 -> {
+                        val v = filter(tagA!!, start[i++].styleValue, null)
+                        FontVariationAxis(tagA, v)
+                    }
+                    else -> { // comp > 0
+                        val v = filter(tagB!!, null, end[j++].styleValue)
+                        FontVariationAxis(tagB, v)
+                    }
                 }
-                comp < 0 -> {
-                    val v = filter(tagA!!, start[i++].styleValue, null)
-                    FontVariationAxis(tagA, v)
-                }
-                else -> { // comp > 0
-                    val v = filter(tagB!!, null, end[j++].styleValue)
-                    FontVariationAxis(tagB, v)
-                }
-            }
 
             result.add(axis)
         }
@@ -202,21 +208,21 @@
     // For the performance reasons, we animate weight with FONT_WEIGHT_ANIMATION_STEP. This helps
     // Cache hit ratio in the Skia glyph cache.
     private fun adjustWeight(value: Float) =
-            coerceInWithStep(value, FONT_WEIGHT_MIN, FONT_WEIGHT_MAX, FONT_WEIGHT_ANIMATION_STEP)
+        coerceInWithStep(value, FONT_WEIGHT_MIN, FONT_WEIGHT_MAX, FONT_WEIGHT_ANIMATION_STEP)
 
     // For the performance reasons, we animate italic with FONT_ITALIC_ANIMATION_STEP. This helps
     // Cache hit ratio in the Skia glyph cache.
     private fun adjustItalic(value: Float) =
-            coerceInWithStep(value, FONT_ITALIC_MIN, FONT_ITALIC_MAX, FONT_ITALIC_ANIMATION_STEP)
+        coerceInWithStep(value, FONT_ITALIC_MIN, FONT_ITALIC_MAX, FONT_ITALIC_ANIMATION_STEP)
 
     private fun coerceInWithStep(v: Float, min: Float, max: Float, step: Float) =
-            (v.coerceIn(min, max) / step).toInt() * step
+        (v.coerceIn(min, max) / step).toInt() * step
 
     companion object {
         private val EMPTY_AXES = arrayOf<FontVariationAxis>()
 
         // Returns true if given two font instance can be interpolated.
         fun canInterpolate(start: Font, end: Font) =
-                start.ttcIndex == end.ttcIndex && start.sourceIdentifier == end.sourceIdentifier
+            start.ttcIndex == end.ttcIndex && start.sourceIdentifier == end.sourceIdentifier
     }
 }
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
index 0028d13..26aa0e8 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
@@ -26,6 +26,7 @@
 import android.graphics.drawable.GradientDrawable
 import android.graphics.drawable.InsetDrawable
 import android.graphics.drawable.LayerDrawable
+import android.graphics.drawable.StateListDrawable
 import android.util.Log
 import android.view.GhostView
 import android.view.View
@@ -35,6 +36,7 @@
 import com.android.internal.jank.InteractionJankMonitor
 import java.util.LinkedList
 import kotlin.math.min
+import kotlin.math.roundToInt
 
 private const val TAG = "GhostedViewLaunchAnimatorController"
 
@@ -49,7 +51,9 @@
  * Note: Avoid instantiating this directly and call [ActivityLaunchAnimator.Controller.fromView]
  * whenever possible instead.
  */
-open class GhostedViewLaunchAnimatorController @JvmOverloads constructor(
+open class GhostedViewLaunchAnimatorController
+@JvmOverloads
+constructor(
     /** The view that will be ghosted and from which the background will be extracted. */
     private val ghostedView: View,
 
@@ -145,7 +149,8 @@
         val gradient = findGradientDrawable(drawable) ?: return 0f
 
         // TODO(b/184121838): Support more than symmetric top & bottom radius.
-        return gradient.cornerRadii?.get(CORNER_RADIUS_TOP_INDEX) ?: gradient.cornerRadius
+        val radius = gradient.cornerRadii?.get(CORNER_RADIUS_TOP_INDEX) ?: gradient.cornerRadius
+        return radius * ghostedView.scaleX
     }
 
     /** Return the current bottom corner radius of the background. */
@@ -154,7 +159,8 @@
         val gradient = findGradientDrawable(drawable) ?: return 0f
 
         // TODO(b/184121838): Support more than symmetric top & bottom radius.
-        return gradient.cornerRadii?.get(CORNER_RADIUS_BOTTOM_INDEX) ?: gradient.cornerRadius
+        val radius = gradient.cornerRadii?.get(CORNER_RADIUS_BOTTOM_INDEX) ?: gradient.cornerRadius
+        return radius * ghostedView.scaleX
     }
 
     override fun createAnimatorState(): LaunchAnimator.State {
@@ -173,9 +179,13 @@
         ghostedView.getLocationOnScreen(ghostedViewLocation)
         val insets = backgroundInsets
         state.top = ghostedViewLocation[1] + insets.top
-        state.bottom = ghostedViewLocation[1] + ghostedView.height - insets.bottom
+        state.bottom =
+            ghostedViewLocation[1] + (ghostedView.height * ghostedView.scaleY).roundToInt() -
+                insets.bottom
         state.left = ghostedViewLocation[0] + insets.left
-        state.right = ghostedViewLocation[0] + ghostedView.width - insets.right
+        state.right =
+            ghostedViewLocation[0] + (ghostedView.width * ghostedView.scaleX).roundToInt() -
+                insets.right
     }
 
     override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
@@ -195,14 +205,16 @@
         backgroundDrawable = WrappedDrawable(background)
         backgroundView?.background = backgroundDrawable
 
+        // Delay the calls to `ghostedView.setVisibility()` during the animation. This must be
+        // called before `GhostView.addGhost()` is called because the latter will change the
+        // *transition* visibility, which won't be blocked and will affect the normal View
+        // visibility that is saved by `setShouldBlockVisibilityChanges()` for a later restoration.
+        (ghostedView as? LaunchableView)?.setShouldBlockVisibilityChanges(true)
+
         // Create a ghost of the view that will be moving and fading out. This allows to fade out
         // the content before fading out the background.
         ghostView = GhostView.addGhost(ghostedView, launchContainer)
 
-        // The ghost was just created, so ghostedView is currently invisible. We need to make sure
-        // that it stays invisible as long as we are animating.
-        (ghostedView as? LaunchableView)?.setShouldBlockVisibilityChanges(true)
-
         val matrix = ghostView?.animationMatrix ?: Matrix.IDENTITY_MATRIX
         matrix.getValues(initialGhostViewMatrixValues)
 
@@ -297,14 +309,19 @@
         backgroundDrawable?.wrapped?.alpha = startBackgroundAlpha
 
         GhostView.removeGhost(ghostedView)
-        (ghostedView as? LaunchableView)?.setShouldBlockVisibilityChanges(false)
         launchContainerOverlay.remove(backgroundView)
 
-        // Make sure that the view is considered VISIBLE by accessibility by first making it
-        // INVISIBLE then VISIBLE (see b/204944038#comment17 for more info).
-        ghostedView.visibility = View.INVISIBLE
-        ghostedView.visibility = View.VISIBLE
-        ghostedView.invalidate()
+        if (ghostedView is LaunchableView) {
+            // Restore the ghosted view visibility.
+            ghostedView.setShouldBlockVisibilityChanges(false)
+        } else {
+            // Make the ghosted view visible. We ensure that the view is considered VISIBLE by
+            // accessibility by first making it INVISIBLE then VISIBLE (see b/204944038#comment17
+            // for more info).
+            ghostedView.visibility = View.INVISIBLE
+            ghostedView.visibility = View.VISIBLE
+            ghostedView.invalidate()
+        }
     }
 
     companion object {
@@ -334,6 +351,10 @@
                 }
             }
 
+            if (drawable is StateListDrawable) {
+                return findGradientDrawable(drawable.current)
+            }
+
             return null
         }
     }
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableView.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableView.kt
index 67b59e0..774255b 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableView.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableView.kt
@@ -21,15 +21,19 @@
 /** A view that can expand/launch into an app or a dialog. */
 interface LaunchableView {
     /**
-     * Set whether this view should block/postpone all visibility changes. This ensures that this
-     * view:
+     * Set whether this view should block/postpone all calls to [View.setVisibility]. This ensures
+     * that this view:
      * - remains invisible during the launch animation given that it is ghosted and already drawn
      * somewhere else.
      * - remains invisible as long as a dialog expanded from it is shown.
      * - restores its expected visibility once the dialog expanded from it is dismissed.
      *
-     * Note that when this is set to true, both the [normal][android.view.View.setVisibility] and
-     * [transition][android.view.View.setTransitionVisibility] visibility changes must be blocked.
+     * When `setShouldBlockVisibilityChanges(false)` is called, then visibility of the View should
+     * be restored to its expected value, i.e. it should have the visibility of the last call to
+     * `View.setVisibility()` that was made after `setShouldBlockVisibilityChanges(true)`, if any,
+     * or the original view visibility otherwise.
+     *
+     * Note that calls to [View.setTransitionVisibility] shouldn't be blocked.
      *
      * @param block whether we should block/postpone all calls to `setVisibility` and
      * `setTransitionVisibility`.
@@ -46,27 +50,31 @@
      * super.setVisibility(visibility).
      */
     private val superSetVisibility: (Int) -> Unit,
-
-    /**
-     * The lambda that should set the actual transition visibility of [view], usually by calling
-     * super.setTransitionVisibility(visibility).
-     */
-    private val superSetTransitionVisibility: (Int) -> Unit,
-) {
+) : LaunchableView {
     private var blockVisibilityChanges = false
     private var lastVisibility = view.visibility
 
     /** Call this when [LaunchableView.setShouldBlockVisibilityChanges] is called. */
-    fun setShouldBlockVisibilityChanges(block: Boolean) {
+    override fun setShouldBlockVisibilityChanges(block: Boolean) {
         if (block == blockVisibilityChanges) {
             return
         }
 
         blockVisibilityChanges = block
         if (block) {
+            // Save the current visibility for later.
             lastVisibility = view.visibility
         } else {
-            superSetVisibility(lastVisibility)
+            // Restore the visibility. To avoid accessibility issues, we change the visibility twice
+            // which makes sure that we trigger a visibility flag change (see b/204944038#comment17
+            // for more info).
+            if (lastVisibility == View.VISIBLE) {
+                superSetVisibility(View.INVISIBLE)
+                superSetVisibility(View.VISIBLE)
+            } else {
+                superSetVisibility(View.VISIBLE)
+                superSetVisibility(lastVisibility)
+            }
         }
     }
 
@@ -79,16 +87,4 @@
 
         superSetVisibility(visibility)
     }
-
-    /** Call this when [View.setTransitionVisibility] is called. */
-    fun setTransitionVisibility(visibility: Int) {
-        if (blockVisibilityChanges) {
-            // View.setTransitionVisibility just sets the visibility flag, so we don't have to save
-            // the transition visibility separately from the normal visibility.
-            lastVisibility = visibility
-            return
-        }
-
-        superSetTransitionVisibility(visibility)
-    }
 }
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationDelegate.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationDelegate.kt
new file mode 100644
index 0000000..337408b
--- /dev/null
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationDelegate.kt
@@ -0,0 +1,30 @@
+package com.android.systemui.animation
+
+import android.annotation.UiThread
+import android.view.IRemoteAnimationFinishedCallback
+import android.view.RemoteAnimationTarget
+import android.view.WindowManager
+
+/**
+ * A component capable of running remote animations.
+ *
+ * Expands the IRemoteAnimationRunner API by allowing for different types of more specialized
+ * callbacks.
+ */
+interface RemoteAnimationDelegate<in T : IRemoteAnimationFinishedCallback> {
+    /**
+     * Called on the UI thread when the animation targets are received. Sets up and kicks off the
+     * animation.
+     */
+    @UiThread
+    fun onAnimationStart(
+        @WindowManager.TransitionOldType transit: Int,
+        apps: Array<out RemoteAnimationTarget>?,
+        wallpapers: Array<out RemoteAnimationTarget>?,
+        nonApps: Array<out RemoteAnimationTarget>?,
+        callback: T?
+    )
+
+    /** Called on the UI thread when a signal is received to cancel the animation. */
+    @UiThread fun onAnimationCancelled(isKeyguardOccluded: Boolean)
+}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
index 5f1bb83..fdab749 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
@@ -36,8 +36,8 @@
  * Currently this class can provide text style animation for text weight and text size. For example
  * the simple view that draws text with animating text size is like as follows:
  *
- * <pre>
- * <code>
+ * <pre> <code>
+ * ```
  *     class SimpleTextAnimation : View {
  *         @JvmOverloads constructor(...)
  *
@@ -53,83 +53,63 @@
  *             animator.setTextStyle(-1 /* unchanged weight */, sizePx, animate)
  *         }
  *     }
- * </code>
- * </pre>
+ * ```
+ * </code> </pre>
  */
-class TextAnimator(
-    layout: Layout,
-    private val invalidateCallback: () -> Unit
-) {
+class TextAnimator(layout: Layout, private val invalidateCallback: () -> Unit) {
     // Following two members are for mutable for testing purposes.
     public var textInterpolator: TextInterpolator = TextInterpolator(layout)
-    public var animator: ValueAnimator = ValueAnimator.ofFloat(1f).apply {
-        duration = DEFAULT_ANIMATION_DURATION
-        addUpdateListener {
-            textInterpolator.progress = it.animatedValue as Float
-            invalidateCallback()
-        }
-        addListener(object : AnimatorListenerAdapter() {
-            override fun onAnimationEnd(animation: Animator?) {
-                textInterpolator.rebase()
+    public var animator: ValueAnimator =
+        ValueAnimator.ofFloat(1f).apply {
+            duration = DEFAULT_ANIMATION_DURATION
+            addUpdateListener {
+                textInterpolator.progress = it.animatedValue as Float
+                invalidateCallback()
             }
-            override fun onAnimationCancel(animation: Animator?) = textInterpolator.rebase()
-        })
-    }
+            addListener(
+                object : AnimatorListenerAdapter() {
+                    override fun onAnimationEnd(animation: Animator?) {
+                        textInterpolator.rebase()
+                    }
+                    override fun onAnimationCancel(animation: Animator?) = textInterpolator.rebase()
+                }
+            )
+        }
 
     sealed class PositionedGlyph {
 
-        /**
-         * Mutable X coordinate of the glyph position relative from drawing offset.
-         */
+        /** Mutable X coordinate of the glyph position relative from drawing offset. */
         var x: Float = 0f
 
-        /**
-         * Mutable Y coordinate of the glyph position relative from the baseline.
-         */
+        /** Mutable Y coordinate of the glyph position relative from the baseline. */
         var y: Float = 0f
 
-        /**
-         * The current line of text being drawn, in a multi-line TextView.
-         */
+        /** The current line of text being drawn, in a multi-line TextView. */
         var lineNo: Int = 0
 
-        /**
-         * Mutable text size of the glyph in pixels.
-         */
+        /** Mutable text size of the glyph in pixels. */
         var textSize: Float = 0f
 
-        /**
-         * Mutable color of the glyph.
-         */
+        /** Mutable color of the glyph. */
         var color: Int = 0
 
-        /**
-         * Immutable character offset in the text that the current font run start.
-         */
+        /** Immutable character offset in the text that the current font run start. */
         abstract var runStart: Int
             protected set
 
-        /**
-         * Immutable run length of the font run.
-         */
+        /** Immutable run length of the font run. */
         abstract var runLength: Int
             protected set
 
-        /**
-         * Immutable glyph index of the font run.
-         */
+        /** Immutable glyph index of the font run. */
         abstract var glyphIndex: Int
             protected set
 
-        /**
-         * Immutable font instance for this font run.
-         */
+        /** Immutable font instance for this font run. */
         abstract var font: Font
             protected set
 
-        /**
-         * Immutable glyph ID for this glyph.
-         */
+        /** Immutable glyph ID for this glyph. */
         abstract var glyphId: Int
             protected set
     }
@@ -147,20 +127,18 @@
     /**
      * GlyphFilter applied just before drawing to canvas for tweaking positions and text size.
      *
-     * This callback is called for each glyphs just before drawing the glyphs. This function will
-     * be called with the intrinsic position, size, color, glyph ID and font instance. You can
-     * mutate the position, size and color for tweaking animations.
-     * Do not keep the reference of passed glyph object. The interpolator reuses that object for
-     * avoiding object allocations.
+     * This callback is called for each glyphs just before drawing the glyphs. This function will be
+     * called with the intrinsic position, size, color, glyph ID and font instance. You can mutate
+     * the position, size and color for tweaking animations. Do not keep the reference of passed
+     * glyph object. The interpolator reuses that object for avoiding object allocations.
      *
-     * Details:
-     * The text is drawn with font run units. The font run is a text segment that draws with the
-     * same font. The {@code runStart} and {@code runLimit} is a range of the font run in the text
-     * that current glyph is in. Once the font run is determined, the system will convert characters
-     * into glyph IDs. The {@code glyphId} is the glyph identifier in the font and
-     * {@code glyphIndex} is the offset of the converted glyph array. Please note that the
-     * {@code glyphIndex} is not a character index, because the character will not be converted to
-     * glyph one-by-one. If there are ligatures including emoji sequence, etc, the glyph ID may be
+     * Details: The text is drawn with font run units. The font run is a text segment that draws
+     * with the same font. The {@code runStart} and {@code runLimit} is a range of the font run in
+     * the text that current glyph is in. Once the font run is determined, the system will convert
+     * characters into glyph IDs. The {@code glyphId} is the glyph identifier in the font and {@code
+     * glyphIndex} is the offset of the converted glyph array. Please note that the {@code
+     * glyphIndex} is not a character index, because the character will not be converted to glyph
+     * one-by-one. If there are ligatures including emoji sequence, etc, the glyph ID may be
      * composed from multiple characters.
      *
      * Here is an example of font runs: "fin. 終わり"
@@ -193,7 +171,9 @@
      */
     var glyphFilter: GlyphCallback?
         get() = textInterpolator.glyphFilter
-        set(value) { textInterpolator.glyphFilter = value }
+        set(value) {
+            textInterpolator.glyphFilter = value
+        }
 
     fun draw(c: Canvas) = textInterpolator.draw(c)
 
@@ -208,7 +188,7 @@
      * @param weight an optional text weight.
      * @param textSize an optional font size.
      * @param colors an optional colors array that must be the same size as numLines passed to
-     *  the TextInterpolator
+     *               the TextInterpolator
      * @param animate an optional boolean indicating true for showing style transition as animation,
      *                false for immediate style transition. True by default.
      * @param duration an optional animation duration in milliseconds. This is ignored if animate is
@@ -237,10 +217,11 @@
         if (weight >= 0) {
             // Paint#setFontVariationSettings creates Typeface instance from scratch. To reduce the
             // memory impact, cache the typeface result.
-            textInterpolator.targetPaint.typeface = typefaceCache.getOrElse(weight) {
-                textInterpolator.targetPaint.fontVariationSettings = "'$TAG_WGHT' $weight"
-                textInterpolator.targetPaint.typeface
-            }
+            textInterpolator.targetPaint.typeface =
+                typefaceCache.getOrElse(weight) {
+                    textInterpolator.targetPaint.fontVariationSettings = "'$TAG_WGHT' $weight"
+                    textInterpolator.targetPaint.typeface
+                }
         }
         if (color != null) {
             textInterpolator.targetPaint.color = color
@@ -249,22 +230,24 @@
 
         if (animate) {
             animator.startDelay = delay
-            animator.duration = if (duration == -1L) {
-                DEFAULT_ANIMATION_DURATION
-            } else {
-                duration
-            }
+            animator.duration =
+                if (duration == -1L) {
+                    DEFAULT_ANIMATION_DURATION
+                } else {
+                    duration
+                }
             interpolator?.let { animator.interpolator = it }
             if (onAnimationEnd != null) {
-                val listener = object : AnimatorListenerAdapter() {
-                    override fun onAnimationEnd(animation: Animator?) {
-                        onAnimationEnd.run()
-                        animator.removeListener(this)
+                val listener =
+                    object : AnimatorListenerAdapter() {
+                        override fun onAnimationEnd(animation: Animator?) {
+                            onAnimationEnd.run()
+                            animator.removeListener(this)
+                        }
+                        override fun onAnimationCancel(animation: Animator?) {
+                            animator.removeListener(this)
+                        }
                     }
-                    override fun onAnimationCancel(animation: Animator?) {
-                        animator.removeListener(this)
-                    }
-                }
                 animator.addListener(listener)
             }
             animator.start()
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
index 0448c81..341784e 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
@@ -26,12 +26,8 @@
 import com.android.internal.graphics.ColorUtils
 import java.lang.Math.max
 
-/**
- * Provide text style linear interpolation for plain text.
- */
-class TextInterpolator(
-    layout: Layout
-) {
+/** Provide text style linear interpolation for plain text. */
+class TextInterpolator(layout: Layout) {
 
     /**
      * Returns base paint used for interpolation.
@@ -64,12 +60,11 @@
         var baseFont: Font,
         var targetFont: Font
     ) {
-        val length: Int get() = end - start
+        val length: Int
+            get() = end - start
     }
 
-    /**
-     * A class represents text layout of a single run.
-     */
+    /** A class represents text layout of a single run. */
     private class Run(
         val glyphIds: IntArray,
         val baseX: FloatArray, // same length as glyphIds
@@ -79,12 +74,8 @@
         val fontRuns: List<FontRun>
     )
 
-    /**
-     * A class represents text layout of a single line.
-     */
-    private class Line(
-        val runs: List<Run>
-    )
+    /** A class represents text layout of a single line. */
+    private class Line(val runs: List<Run>)
 
     private var lines = listOf<Line>()
     private val fontInterpolator = FontInterpolator()
@@ -106,8 +97,8 @@
     /**
      * The layout used for drawing text.
      *
-     * Only non-styled text is supported. Even if the given layout is created from Spanned, the
-     * span information is not used.
+     * Only non-styled text is supported. Even if the given layout is created from Spanned, the span
+     * information is not used.
      *
      * The paint objects used for interpolation are not changed by this method call.
      *
@@ -122,6 +113,9 @@
             shapeText(value)
         }
 
+    var shapedText: String = ""
+        private set
+
     init {
         // shapeText needs to be called after all members are initialized.
         shapeText(layout)
@@ -130,8 +124,8 @@
     /**
      * Recalculate internal text layout for interpolation.
      *
-     * Whenever the target paint is modified, call this method to recalculate internal
-     * text layout used for interpolation.
+     * Whenever the target paint is modified, call this method to recalculate internal text layout
+     * used for interpolation.
      */
     fun onTargetPaintModified() {
         updatePositionsAndFonts(shapeText(layout, targetPaint), updateBase = false)
@@ -140,8 +134,8 @@
     /**
      * Recalculate internal text layout for interpolation.
      *
-     * Whenever the base paint is modified, call this method to recalculate internal
-     * text layout used for interpolation.
+     * Whenever the base paint is modified, call this method to recalculate internal text layout
+     * used for interpolation.
      */
     fun onBasePaintModified() {
         updatePositionsAndFonts(shapeText(layout, basePaint), updateBase = true)
@@ -152,11 +146,11 @@
      *
      * The text interpolator does not calculate all the text position by text shaper due to
      * performance reasons. Instead, the text interpolator shape the start and end state and
-     * calculate text position of the middle state by linear interpolation. Due to this trick,
-     * the text positions of the middle state is likely different from the text shaper result.
-     * So, if you want to start animation from the middle state, you will see the glyph jumps due to
-     * this trick, i.e. the progress 0.5 of interpolation between weight 400 and 700 is different
-     * from text shape result of weight 550.
+     * calculate text position of the middle state by linear interpolation. Due to this trick, the
+     * text positions of the middle state is likely different from the text shaper result. So, if
+     * you want to start animation from the middle state, you will see the glyph jumps due to this
+     * trick, i.e. the progress 0.5 of interpolation between weight 400 and 700 is different from
+     * text shape result of weight 550.
      *
      * After calling this method, do not call onBasePaintModified() since it reshape the text and
      * update the base state. As in above notice, the text shaping result at current progress is
@@ -168,8 +162,8 @@
      * animate weight from 200 to 400, then if you want to move back to 200 at the half of the
      * animation, it will look like
      *
-     * <pre>
-     * <code>
+     * <pre> <code>
+     * ```
      *     val interp = TextInterpolator(layout)
      *
      *     // Interpolate between weight 200 to 400.
@@ -199,9 +193,8 @@
      *         // progress is 0.5
      *         animator.start()
      *     }
-     * </code>
-     * </pre>
-     *
+     * ```
+     * </code> </pre>
      */
     fun rebase() {
         if (progress == 0f) {
@@ -263,69 +256,73 @@
         }
 
         var maxRunLength = 0
-        lines = baseLayout.zip(targetLayout) { baseLine, targetLine ->
-            val runs = baseLine.zip(targetLine) { base, target ->
-
-                require(base.glyphCount() == target.glyphCount()) {
-                    "Inconsistent glyph count at line ${lines.size}"
-                }
-
-                val glyphCount = base.glyphCount()
-
-                // Good to recycle the array if the existing array can hold the new layout result.
-                val glyphIds = IntArray(glyphCount) {
-                    base.getGlyphId(it).also { baseGlyphId ->
-                        require(baseGlyphId == target.getGlyphId(it)) {
-                            "Inconsistent glyph ID at $it in line ${lines.size}"
+        lines =
+            baseLayout.zip(targetLayout) { baseLine, targetLine ->
+                val runs =
+                    baseLine.zip(targetLine) { base, target ->
+                        require(base.glyphCount() == target.glyphCount()) {
+                            "Inconsistent glyph count at line ${lines.size}"
                         }
-                    }
-                }
 
-                val baseX = FloatArray(glyphCount) { base.getGlyphX(it) }
-                val baseY = FloatArray(glyphCount) { base.getGlyphY(it) }
-                val targetX = FloatArray(glyphCount) { target.getGlyphX(it) }
-                val targetY = FloatArray(glyphCount) { target.getGlyphY(it) }
+                        val glyphCount = base.glyphCount()
 
-                // Calculate font runs
-                val fontRun = mutableListOf<FontRun>()
-                if (glyphCount != 0) {
-                    var start = 0
-                    var baseFont = base.getFont(start)
-                    var targetFont = target.getFont(start)
-                    require(FontInterpolator.canInterpolate(baseFont, targetFont)) {
-                        "Cannot interpolate font at $start ($baseFont vs $targetFont)"
-                    }
-
-                    for (i in 1 until glyphCount) {
-                        val nextBaseFont = base.getFont(i)
-                        val nextTargetFont = target.getFont(i)
-
-                        if (baseFont !== nextBaseFont) {
-                            require(targetFont !== nextTargetFont) {
-                                "Base font has changed at $i but target font has not changed."
+                        // Good to recycle the array if the existing array can hold the new layout
+                        // result.
+                        val glyphIds =
+                            IntArray(glyphCount) {
+                                base.getGlyphId(it).also { baseGlyphId ->
+                                    require(baseGlyphId == target.getGlyphId(it)) {
+                                        "Inconsistent glyph ID at $it in line ${lines.size}"
+                                    }
+                                }
                             }
-                            // Font transition point. push run and reset context.
-                            fontRun.add(FontRun(start, i, baseFont, targetFont))
-                            maxRunLength = max(maxRunLength, i - start)
-                            baseFont = nextBaseFont
-                            targetFont = nextTargetFont
-                            start = i
+
+                        val baseX = FloatArray(glyphCount) { base.getGlyphX(it) }
+                        val baseY = FloatArray(glyphCount) { base.getGlyphY(it) }
+                        val targetX = FloatArray(glyphCount) { target.getGlyphX(it) }
+                        val targetY = FloatArray(glyphCount) { target.getGlyphY(it) }
+
+                        // Calculate font runs
+                        val fontRun = mutableListOf<FontRun>()
+                        if (glyphCount != 0) {
+                            var start = 0
+                            var baseFont = base.getFont(start)
+                            var targetFont = target.getFont(start)
                             require(FontInterpolator.canInterpolate(baseFont, targetFont)) {
                                 "Cannot interpolate font at $start ($baseFont vs $targetFont)"
                             }
-                        } else { // baseFont === nextBaseFont
-                            require(targetFont === nextTargetFont) {
-                                "Base font has not changed at $i but target font has changed."
+
+                            for (i in 1 until glyphCount) {
+                                val nextBaseFont = base.getFont(i)
+                                val nextTargetFont = target.getFont(i)
+
+                                if (baseFont !== nextBaseFont) {
+                                    require(targetFont !== nextTargetFont) {
+                                        "Base font has changed at $i but target font is unchanged."
+                                    }
+                                    // Font transition point. push run and reset context.
+                                    fontRun.add(FontRun(start, i, baseFont, targetFont))
+                                    maxRunLength = max(maxRunLength, i - start)
+                                    baseFont = nextBaseFont
+                                    targetFont = nextTargetFont
+                                    start = i
+                                    require(FontInterpolator.canInterpolate(baseFont, targetFont)) {
+                                        "Cannot interpolate font at $start" +
+                                            " ($baseFont vs $targetFont)"
+                                    }
+                                } else { // baseFont === nextBaseFont
+                                    require(targetFont === nextTargetFont) {
+                                        "Base font is unchanged at $i but target font has changed."
+                                    }
+                                }
                             }
+                            fontRun.add(FontRun(start, glyphCount, baseFont, targetFont))
+                            maxRunLength = max(maxRunLength, glyphCount - start)
                         }
+                        Run(glyphIds, baseX, baseY, targetX, targetY, fontRun)
                     }
-                    fontRun.add(FontRun(start, glyphCount, baseFont, targetFont))
-                    maxRunLength = max(maxRunLength, glyphCount - start)
-                }
-                Run(glyphIds, baseX, baseY, targetX, targetY, fontRun)
+                Line(runs)
             }
-            Line(runs)
-        }
 
         // Update float array used for drawing.
         if (tmpPositionArray.size < maxRunLength * 2) {
@@ -357,9 +354,9 @@
         if (glyphFilter == null) {
             for (i in run.start until run.end) {
                 tmpPositionArray[arrayIndex++] =
-                        MathUtils.lerp(line.baseX[i], line.targetX[i], progress)
+                    MathUtils.lerp(line.baseX[i], line.targetX[i], progress)
                 tmpPositionArray[arrayIndex++] =
-                        MathUtils.lerp(line.baseY[i], line.targetY[i], progress)
+                    MathUtils.lerp(line.baseY[i], line.targetY[i], progress)
             }
             c.drawGlyphs(line.glyphIds, run.start, tmpPositionArray, 0, run.length, font, paint)
             return
@@ -388,13 +385,14 @@
                 tmpPaintForGlyph.color = tmpGlyph.color
 
                 c.drawGlyphs(
-                        line.glyphIds,
-                        prevStart,
-                        tmpPositionArray,
-                        0,
-                        i - prevStart,
-                        font,
-                        tmpPaintForGlyph)
+                    line.glyphIds,
+                    prevStart,
+                    tmpPositionArray,
+                    0,
+                    i - prevStart,
+                    font,
+                    tmpPaintForGlyph
+                )
                 prevStart = i
                 arrayIndex = 0
             }
@@ -404,13 +402,14 @@
         }
 
         c.drawGlyphs(
-                line.glyphIds,
-                prevStart,
-                tmpPositionArray,
-                0,
-                run.end - prevStart,
-                font,
-                tmpPaintForGlyph)
+            line.glyphIds,
+            prevStart,
+            tmpPositionArray,
+            0,
+            run.end - prevStart,
+            font,
+            tmpPaintForGlyph
+        )
     }
 
     private fun updatePositionsAndFonts(
@@ -418,9 +417,7 @@
         updateBase: Boolean
     ) {
         // Update target positions with newly calculated text layout.
-        check(layoutResult.size == lines.size) {
-            "The new layout result has different line count."
-        }
+        check(layoutResult.size == lines.size) { "The new layout result has different line count." }
 
         lines.zip(layoutResult) { line, runs ->
             line.runs.zip(runs) { lineRun, newGlyphs ->
@@ -436,7 +433,7 @@
                         }
                         require(newFont === newGlyphs.getFont(i)) {
                             "The new layout has different font run." +
-                                    " $newFont vs ${newGlyphs.getFont(i)} at $i"
+                                " $newFont vs ${newGlyphs.getFont(i)} at $i"
                         }
                     }
 
@@ -444,7 +441,7 @@
                     // check new font can be interpolatable with base font.
                     require(FontInterpolator.canInterpolate(newFont, run.baseFont)) {
                         "New font cannot be interpolated with existing font. $newFont," +
-                                " ${run.baseFont}"
+                            " ${run.baseFont}"
                     }
 
                     if (updateBase) {
@@ -480,14 +477,13 @@
     }
 
     // Shape the text and stores the result to out argument.
-    private fun shapeText(
-        layout: Layout,
-        paint: TextPaint
-    ): List<List<PositionedGlyphs>> {
+    private fun shapeText(layout: Layout, paint: TextPaint): List<List<PositionedGlyphs>> {
+        var text = StringBuilder()
         val out = mutableListOf<List<PositionedGlyphs>>()
         for (lineNo in 0 until layout.lineCount) { // Shape all lines.
             val lineStart = layout.getLineStart(lineNo)
-            var count = layout.getLineEnd(lineNo) - lineStart
+            val lineEnd = layout.getLineEnd(lineNo)
+            var count = lineEnd - lineStart
             // Do not render the last character in the line if it's a newline and unprintable
             val last = lineStart + count - 1
             if (last > lineStart && last < layout.text.length && layout.text[last] == '\n') {
@@ -495,19 +491,28 @@
             }
 
             val runs = mutableListOf<PositionedGlyphs>()
-            TextShaper.shapeText(layout.text, lineStart, count, layout.textDirectionHeuristic,
-                    paint) { _, _, glyphs, _ ->
-                runs.add(glyphs)
-            }
+            TextShaper.shapeText(
+                layout.text,
+                lineStart,
+                count,
+                layout.textDirectionHeuristic,
+                paint
+            ) { _, _, glyphs, _ -> runs.add(glyphs) }
             out.add(runs)
+
+            if (lineNo > 0) {
+                text.append("\n")
+            }
+            text.append(layout.text.substring(lineStart, lineEnd))
         }
+        shapedText = text.toString()
         return out
     }
 }
 
 private fun Layout.getDrawOrigin(lineNo: Int) =
-        if (getParagraphDirection(lineNo) == Layout.DIR_LEFT_TO_RIGHT) {
-            getLineLeft(lineNo)
-        } else {
-            getLineRight(lineNo)
-        }
+    if (getParagraphDirection(lineNo) == Layout.DIR_LEFT_TO_RIGHT) {
+        getLineLeft(lineNo)
+    } else {
+        getLineRight(lineNo)
+    }
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewDialogLaunchAnimatorController.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewDialogLaunchAnimatorController.kt
index 964ef8c..9257f99 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewDialogLaunchAnimatorController.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewDialogLaunchAnimatorController.kt
@@ -25,7 +25,7 @@
 /** A [DialogLaunchAnimator.Controller] that can animate a [View] from/to a dialog. */
 class ViewDialogLaunchAnimatorController
 internal constructor(
-    private val source: View,
+    internal val source: View,
     override val cuj: DialogCuj?,
 ) : DialogLaunchAnimator.Controller {
     override val viewRoot: ViewRootImpl?
@@ -34,23 +34,29 @@
     override val sourceIdentity: Any = source
 
     override fun startDrawingInOverlayOf(viewGroup: ViewGroup) {
+        // Delay the calls to `source.setVisibility()` during the animation. This must be called
+        // before `GhostView.addGhost()` is called because the latter will change the *transition*
+        // visibility, which won't be blocked and will affect the normal View visibility that is
+        // saved by `setShouldBlockVisibilityChanges()` for a later restoration.
+        (source as? LaunchableView)?.setShouldBlockVisibilityChanges(true)
+
         // Create a temporary ghost of the source (which will make it invisible) and add it
         // to the host dialog.
         GhostView.addGhost(source, viewGroup)
-
-        // The ghost of the source was just created, so the source is currently invisible.
-        // We need to make sure that it stays invisible as long as the dialog is shown or
-        // animating.
-        (source as? LaunchableView)?.setShouldBlockVisibilityChanges(true)
     }
 
     override fun stopDrawingInOverlay() {
         // Note: here we should remove the ghost from the overlay, but in practice this is
-        // already done by the launch controllers created below.
+        // already done by the launch controller created below.
 
-        // Make sure we allow the source to change its visibility again.
-        (source as? LaunchableView)?.setShouldBlockVisibilityChanges(false)
-        source.visibility = View.VISIBLE
+        if (source is LaunchableView) {
+            // Make sure we allow the source to change its visibility again and restore its previous
+            // value.
+            source.setShouldBlockVisibilityChanges(false)
+        } else {
+            // We made the source invisible earlier, so let's make it visible again.
+            source.visibility = View.VISIBLE
+        }
     }
 
     override fun createLaunchController(): LaunchAnimator.Controller {
@@ -67,10 +73,14 @@
             override fun onLaunchAnimationEnd(isExpandingFullyAbove: Boolean) {
                 delegate.onLaunchAnimationEnd(isExpandingFullyAbove)
 
-                // We hide the source when the dialog is showing. We will make this view
-                // visible again when dismissing the dialog. This does nothing if the source
-                // implements [LaunchableView], as it's already INVISIBLE in that case.
-                source.visibility = View.INVISIBLE
+                // At this point the view visibility is restored by the delegate, so we delay the
+                // visibility changes again and make it invisible while the dialog is shown.
+                if (source is LaunchableView) {
+                    source.setShouldBlockVisibilityChanges(true)
+                    source.setTransitionVisibility(View.INVISIBLE)
+                } else {
+                    source.visibility = View.INVISIBLE
+                }
             }
         }
     }
@@ -90,13 +100,15 @@
     }
 
     override fun onExitAnimationCancelled() {
-        // Make sure we allow the source to change its visibility again.
-        (source as? LaunchableView)?.setShouldBlockVisibilityChanges(false)
-
-        // If the view is invisible it's probably because of us, so we make it visible
-        // again.
-        if (source.visibility == View.INVISIBLE) {
-            source.visibility = View.VISIBLE
+        if (source is LaunchableView) {
+            // Make sure we allow the source to change its visibility again.
+            source.setShouldBlockVisibilityChanges(false)
+        } else {
+            // If the view is invisible it's probably because of us, so we make it visible
+            // again.
+            if (source.visibility == View.INVISIBLE) {
+                source.visibility = View.VISIBLE
+            }
         }
     }
 
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseAnimationConfig.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseAnimationConfig.kt
index 5ac3aad7..79bc2f4 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseAnimationConfig.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseAnimationConfig.kt
@@ -49,13 +49,16 @@
     val opacity: Int = DEFAULT_OPACITY,
     val width: Float = 0f,
     val height: Float = 0f,
-    val duration: Float = DEFAULT_NOISE_DURATION_IN_MILLIS,
+    val maxDuration: Float = DEFAULT_MAX_DURATION_IN_MILLIS,
+    val easeInDuration: Float = DEFAULT_EASING_DURATION_IN_MILLIS,
+    val easeOutDuration: Float = DEFAULT_EASING_DURATION_IN_MILLIS,
     val pixelDensity: Float = 1f,
     val blendMode: BlendMode = DEFAULT_BLEND_MODE,
     val onAnimationEnd: Runnable? = null
 ) {
     companion object {
-        const val DEFAULT_NOISE_DURATION_IN_MILLIS = 7500F
+        const val DEFAULT_MAX_DURATION_IN_MILLIS = 30_000f // Max 30 sec
+        const val DEFAULT_EASING_DURATION_IN_MILLIS = 750f
         const val DEFAULT_LUMINOSITY_MULTIPLIER = 1f
         const val DEFAULT_NOISE_GRID_COUNT = 1.2f
         const val DEFAULT_NOISE_SPEED_Z = 0.3f
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseController.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseController.kt
index 4c7e5f4..b8f4b27 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseController.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseController.kt
@@ -15,16 +15,106 @@
  */
 package com.android.systemui.surfaceeffects.turbulencenoise
 
-/** A controller that plays [TurbulenceNoiseView]. */
+import android.view.View
+import androidx.annotation.VisibleForTesting
+import java.util.Random
+
+/** Plays [TurbulenceNoiseView] in ease-in, main (no easing), and ease-out order. */
 class TurbulenceNoiseController(private val turbulenceNoiseView: TurbulenceNoiseView) {
+
+    companion object {
+        /**
+         * States of the turbulence noise animation.
+         *
+         * <p>The state is designed to be follow the order below: [AnimationState.EASE_IN],
+         * [AnimationState.MAIN], [AnimationState.EASE_OUT].
+         */
+        enum class AnimationState {
+            EASE_IN,
+            MAIN,
+            EASE_OUT,
+            NOT_PLAYING
+        }
+    }
+
+    private val random = Random()
+
+    /** Current state of the animation. */
+    @VisibleForTesting
+    var state: AnimationState = AnimationState.NOT_PLAYING
+        set(value) {
+            field = value
+            if (state == AnimationState.NOT_PLAYING) {
+                turbulenceNoiseView.visibility = View.INVISIBLE
+                turbulenceNoiseView.clearConfig()
+            } else {
+                turbulenceNoiseView.visibility = View.VISIBLE
+            }
+        }
+
+    init {
+        turbulenceNoiseView.visibility = View.INVISIBLE
+    }
+
     /** Updates the color of the noise. */
     fun updateNoiseColor(color: Int) {
+        if (state == AnimationState.NOT_PLAYING) {
+            return
+        }
         turbulenceNoiseView.updateColor(color)
     }
 
-    // TODO: add cancel and/ or pause once design requirements become clear.
-    /** Plays [TurbulenceNoiseView] with the given config. */
-    fun play(turbulenceNoiseAnimationConfig: TurbulenceNoiseAnimationConfig) {
-        turbulenceNoiseView.play(turbulenceNoiseAnimationConfig)
+    /**
+     * Plays [TurbulenceNoiseView] with the given config.
+     *
+     * <p>It plays ease-in, main, and ease-out animations in sequence.
+     */
+    fun play(config: TurbulenceNoiseAnimationConfig) {
+        if (state != AnimationState.NOT_PLAYING) {
+            return // Ignore if any of the animation is playing.
+        }
+
+        turbulenceNoiseView.applyConfig(config)
+        playEaseInAnimation()
+    }
+
+    // TODO(b/237282226): Support force finish.
+    /** Finishes the main animation, which triggers the ease-out animation. */
+    fun finish() {
+        if (state == AnimationState.MAIN) {
+            turbulenceNoiseView.finish(nextAnimation = this::playEaseOutAnimation)
+        }
+    }
+
+    private fun playEaseInAnimation() {
+        if (state != AnimationState.NOT_PLAYING) {
+            return
+        }
+        state = AnimationState.EASE_IN
+
+        // Add offset to avoid repetitive noise.
+        turbulenceNoiseView.playEaseIn(
+            offsetX = random.nextFloat(),
+            offsetY = random.nextFloat(),
+            this::playMainAnimation
+        )
+    }
+
+    private fun playMainAnimation() {
+        if (state != AnimationState.EASE_IN) {
+            return
+        }
+        state = AnimationState.MAIN
+
+        turbulenceNoiseView.play(this::playEaseOutAnimation)
+    }
+
+    private fun playEaseOutAnimation() {
+        if (state != AnimationState.MAIN) {
+            return
+        }
+        state = AnimationState.EASE_OUT
+
+        turbulenceNoiseView.playEaseOut(onAnimationEnd = { state = AnimationState.NOT_PLAYING })
     }
 }
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt
index 19c114d..7456c43 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt
@@ -114,8 +114,19 @@
         setFloatUniform("in_aspectRatio", width / max(height, 0.001f))
     }
 
-    /** Sets noise move speed in x, y, and z direction. */
+    /** Current noise movements in x, y, and z axes. */
+    var noiseOffsetX: Float = 0f
+        private set
+    var noiseOffsetY: Float = 0f
+        private set
+    var noiseOffsetZ: Float = 0f
+        private set
+
+    /** Sets noise move offset in x, y, and z direction. */
     fun setNoiseMove(x: Float, y: Float, z: Float) {
-        setFloatUniform("in_noiseMove", x, y, z)
+        noiseOffsetX = x
+        noiseOffsetY = y
+        noiseOffsetZ = z
+        setFloatUniform("in_noiseMove", noiseOffsetX, noiseOffsetY, noiseOffsetZ)
     }
 }
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseView.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseView.kt
index 68712c6..e1e515d 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseView.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseView.kt
@@ -25,38 +25,29 @@
 import android.view.View
 import androidx.annotation.VisibleForTesting
 import androidx.core.graphics.ColorUtils
-import java.util.Random
-import kotlin.math.sin
 
-/** View that renders turbulence noise effect. */
+/**
+ * View that renders turbulence noise effect.
+ *
+ * <p>Use [TurbulenceNoiseController] to control the turbulence animation. If you want to make some
+ * other turbulence noise effects, either add functionality to [TurbulenceNoiseController] or create
+ * another controller instead of extend or modify the [TurbulenceNoiseView].
+ *
+ * <p>Please keep the [TurbulenceNoiseView] (or View in general) not aware of the state.
+ *
+ * <p>Please avoid inheriting the View if possible. Instead, reconsider adding a controller for a
+ * new case.
+ */
 class TurbulenceNoiseView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
 
     companion object {
         private const val MS_TO_SEC = 0.001f
-        private const val TWO_PI = Math.PI.toFloat() * 2f
     }
 
-    @VisibleForTesting val turbulenceNoiseShader = TurbulenceNoiseShader()
+    private val turbulenceNoiseShader = TurbulenceNoiseShader()
     private val paint = Paint().apply { this.shader = turbulenceNoiseShader }
-    private val random = Random()
-    private val animator: ValueAnimator = ValueAnimator.ofFloat(0f, 1f)
-    private var config: TurbulenceNoiseAnimationConfig? = null
-
-    val isPlaying: Boolean
-        get() = animator.isRunning
-
-    init {
-        // Only visible during the animation.
-        visibility = INVISIBLE
-    }
-
-    /** Updates the color during the animation. No-op if there's no animation playing. */
-    fun updateColor(color: Int) {
-        config?.let {
-            it.color = color
-            applyConfig(it)
-        }
-    }
+    @VisibleForTesting var noiseConfig: TurbulenceNoiseAnimationConfig? = null
+    @VisibleForTesting var currentAnimator: ValueAnimator? = null
 
     override fun onDraw(canvas: Canvas?) {
         if (canvas == null || !canvas.isHardwareAccelerated) {
@@ -68,32 +59,38 @@
         canvas.drawPaint(paint)
     }
 
-    fun play(config: TurbulenceNoiseAnimationConfig) {
-        if (isPlaying) {
-            return // Ignore if the animation is playing.
+    /** Updates the color during the animation. No-op if there's no animation playing. */
+    internal fun updateColor(color: Int) {
+        noiseConfig?.let {
+            turbulenceNoiseShader.setColor(ColorUtils.setAlphaComponent(color, it.opacity))
         }
-        visibility = VISIBLE
-        applyConfig(config)
+    }
 
-        // Add random offset to avoid same patterned noise.
-        val offsetX = random.nextFloat()
-        val offsetY = random.nextFloat()
+    /** Plays the turbulence noise with no easing. */
+    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+    fun play(onAnimationEnd: Runnable? = null) {
+        if (noiseConfig == null) {
+            return
+        }
+        val config = noiseConfig!!
 
-        animator.duration = config.duration.toLong()
+        val animator = ValueAnimator.ofFloat(0f, 1f)
+        animator.duration = config.maxDuration.toLong()
+
+        // Animation should start from the initial position to avoid abrupt transition.
+        val initialX = turbulenceNoiseShader.noiseOffsetX
+        val initialY = turbulenceNoiseShader.noiseOffsetY
+        val initialZ = turbulenceNoiseShader.noiseOffsetZ
+
         animator.addUpdateListener { updateListener ->
             val timeInSec = updateListener.currentPlayTime * MS_TO_SEC
-            // Remap [0,1] to [0, 2*PI]
-            val progress = TWO_PI * updateListener.animatedValue as Float
-
             turbulenceNoiseShader.setNoiseMove(
-                offsetX + timeInSec * config.noiseMoveSpeedX,
-                offsetY + timeInSec * config.noiseMoveSpeedY,
-                timeInSec * config.noiseMoveSpeedZ
+                initialX + timeInSec * config.noiseMoveSpeedX,
+                initialY + timeInSec * config.noiseMoveSpeedY,
+                initialZ + timeInSec * config.noiseMoveSpeedZ
             )
 
-            // Fade in and out the noise as the animation progress.
-            // TODO: replace it with a better curve
-            turbulenceNoiseShader.setOpacity(sin(TWO_PI - progress) * config.luminosityMultiplier)
+            turbulenceNoiseShader.setOpacity(config.luminosityMultiplier)
 
             invalidate()
         }
@@ -101,16 +98,121 @@
         animator.addListener(
             object : AnimatorListenerAdapter() {
                 override fun onAnimationEnd(animation: Animator) {
-                    visibility = INVISIBLE
-                    config.onAnimationEnd?.run()
+                    currentAnimator = null
+                    onAnimationEnd?.run()
                 }
             }
         )
+
         animator.start()
+        currentAnimator = animator
     }
 
-    private fun applyConfig(config: TurbulenceNoiseAnimationConfig) {
-        this.config = config
+    /** Plays the turbulence noise with linear ease-in. */
+    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+    fun playEaseIn(offsetX: Float = 0f, offsetY: Float = 0f, onAnimationEnd: Runnable? = null) {
+        if (noiseConfig == null) {
+            return
+        }
+        val config = noiseConfig!!
+
+        val animator = ValueAnimator.ofFloat(0f, 1f)
+        animator.duration = config.easeInDuration.toLong()
+
+        // Animation should start from the initial position to avoid abrupt transition.
+        val initialX = turbulenceNoiseShader.noiseOffsetX
+        val initialY = turbulenceNoiseShader.noiseOffsetY
+        val initialZ = turbulenceNoiseShader.noiseOffsetZ
+
+        animator.addUpdateListener { updateListener ->
+            val timeInSec = updateListener.currentPlayTime * MS_TO_SEC
+            val progress = updateListener.animatedValue as Float
+
+            turbulenceNoiseShader.setNoiseMove(
+                offsetX + initialX + timeInSec * config.noiseMoveSpeedX,
+                offsetY + initialY + timeInSec * config.noiseMoveSpeedY,
+                initialZ + timeInSec * config.noiseMoveSpeedZ
+            )
+
+            // TODO: Replace it with a better curve.
+            turbulenceNoiseShader.setOpacity(progress * config.luminosityMultiplier)
+
+            invalidate()
+        }
+
+        animator.addListener(
+            object : AnimatorListenerAdapter() {
+                override fun onAnimationEnd(animation: Animator) {
+                    currentAnimator = null
+                    onAnimationEnd?.run()
+                }
+            }
+        )
+
+        animator.start()
+        currentAnimator = animator
+    }
+
+    /** Plays the turbulence noise with linear ease-out. */
+    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+    fun playEaseOut(onAnimationEnd: Runnable? = null) {
+        if (noiseConfig == null) {
+            return
+        }
+        val config = noiseConfig!!
+
+        val animator = ValueAnimator.ofFloat(0f, 1f)
+        animator.duration = config.easeOutDuration.toLong()
+
+        // Animation should start from the initial position to avoid abrupt transition.
+        val initialX = turbulenceNoiseShader.noiseOffsetX
+        val initialY = turbulenceNoiseShader.noiseOffsetY
+        val initialZ = turbulenceNoiseShader.noiseOffsetZ
+
+        animator.addUpdateListener { updateListener ->
+            val timeInSec = updateListener.currentPlayTime * MS_TO_SEC
+            val progress = updateListener.animatedValue as Float
+
+            turbulenceNoiseShader.setNoiseMove(
+                initialX + timeInSec * config.noiseMoveSpeedX,
+                initialY + timeInSec * config.noiseMoveSpeedY,
+                initialZ + timeInSec * config.noiseMoveSpeedZ
+            )
+
+            // TODO: Replace it with a better curve.
+            turbulenceNoiseShader.setOpacity((1f - progress) * config.luminosityMultiplier)
+
+            invalidate()
+        }
+
+        animator.addListener(
+            object : AnimatorListenerAdapter() {
+                override fun onAnimationEnd(animation: Animator) {
+                    currentAnimator = null
+                    onAnimationEnd?.run()
+                }
+            }
+        )
+
+        animator.start()
+        currentAnimator = animator
+    }
+
+    /** Finishes the current animation if playing and plays the next animation if given. */
+    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+    fun finish(nextAnimation: Runnable? = null) {
+        // Calling Animator#end sets the animation state back to the initial state. Using pause to
+        // avoid visual artifacts.
+        currentAnimator?.pause()
+        currentAnimator = null
+
+        nextAnimation?.run()
+    }
+
+    /** Applies shader uniforms. Must be called before playing animation. */
+    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+    fun applyConfig(config: TurbulenceNoiseAnimationConfig) {
+        noiseConfig = config
         with(turbulenceNoiseShader) {
             setGridCount(config.gridCount)
             setColor(ColorUtils.setAlphaComponent(config.color, config.opacity))
@@ -120,4 +222,8 @@
         }
         paint.blendMode = config.blendMode
     }
+
+    internal fun clearConfig() {
+        noiseConfig = null
+    }
 }
diff --git a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/CleanArchitectureDependencyViolationDetector.kt b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/CleanArchitectureDependencyViolationDetector.kt
new file mode 100644
index 0000000..1f6e603
--- /dev/null
+++ b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/CleanArchitectureDependencyViolationDetector.kt
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.internal.systemui.lint
+
+import com.android.tools.lint.client.api.UElementHandler
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import org.jetbrains.uast.UElement
+import org.jetbrains.uast.UFile
+import org.jetbrains.uast.UImportStatement
+
+/**
+ * Detects violations of the Dependency Rule of Clean Architecture.
+ *
+ * The rule states that code in each layer may only depend on code in the same layer or the layer
+ * directly "beneath" that layer in the layer diagram.
+ *
+ * In System UI, we have three layers; from top to bottom, they are: ui, domain, and data. As a
+ * convention, was used packages with those names to place code in the appropriate layer. We also
+ * make an exception and allow for shared models to live under a separate package named "shared" to
+ * avoid code duplication.
+ *
+ * For more information, please see go/sysui-arch.
+ */
+@Suppress("UnstableApiUsage")
+class CleanArchitectureDependencyViolationDetector : Detector(), Detector.UastScanner {
+    override fun getApplicableUastTypes(): List<Class<out UElement>> {
+        return listOf(UFile::class.java)
+    }
+
+    override fun createUastHandler(context: JavaContext): UElementHandler {
+        return object : UElementHandler() {
+            override fun visitFile(node: UFile) {
+                // Check which Clean Architecture layer this file belongs to:
+                matchingLayer(node.packageName)?.let { layer ->
+                    // The file matches with a Clean Architecture layer. Let's check all of its
+                    // imports.
+                    node.imports.forEach { importStatement ->
+                        visitImportStatement(context, layer, importStatement)
+                    }
+                }
+            }
+        }
+    }
+
+    private fun visitImportStatement(
+        context: JavaContext,
+        layer: Layer,
+        importStatement: UImportStatement,
+    ) {
+        val importText = importStatement.importReference?.asSourceString() ?: return
+        val importedLayer = matchingLayer(importText) ?: return
+
+        // Now check whether the layer of the file may depend on the layer of the import.
+        if (!layer.mayDependOn(importedLayer)) {
+            context.report(
+                issue = ISSUE,
+                scope = importStatement,
+                location = context.getLocation(importStatement),
+                message =
+                    "The ${layer.packageNamePart} layer may not depend on" +
+                        " the ${importedLayer.packageNamePart} layer.",
+            )
+        }
+    }
+
+    private fun matchingLayer(packageName: String): Layer? {
+        val packageNameParts = packageName.split(".").toSet()
+        return Layer.values()
+            .filter { layer -> packageNameParts.contains(layer.packageNamePart) }
+            .takeIf { it.size == 1 }
+            ?.first()
+    }
+
+    private enum class Layer(
+        val packageNamePart: String,
+        val canDependOn: Set<Layer>,
+    ) {
+        SHARED(
+            packageNamePart = "shared",
+            canDependOn = emptySet(), // The shared layer may not depend on any other layer.
+        ),
+        DATA(
+            packageNamePart = "data",
+            canDependOn = setOf(SHARED),
+        ),
+        DOMAIN(
+            packageNamePart = "domain",
+            canDependOn = setOf(SHARED, DATA),
+        ),
+        UI(
+            packageNamePart = "ui",
+            canDependOn = setOf(DOMAIN, SHARED),
+        ),
+        ;
+
+        fun mayDependOn(otherLayer: Layer): Boolean {
+            return this == otherLayer || canDependOn.contains(otherLayer)
+        }
+    }
+
+    companion object {
+        @JvmStatic
+        val ISSUE =
+            Issue.create(
+                id = "CleanArchitectureDependencyViolation",
+                briefDescription = "Violation of the Clean Architecture Dependency Rule.",
+                explanation =
+                    """
+                    Following the \"Dependency Rule\" from Clean Architecture, every layer of code \
+                    can only depend code in its own layer or code in the layer directly \
+                    \"beneath\" it. Therefore, the UI layer can only depend on the" Domain layer \
+                    and the Domain layer can only depend on the Data layer. We" do make an \
+                    exception to allow shared models to exist and be shared across layers by \
+                    placing them under shared/model, which should be done with care. For more \
+                    information about Clean Architecture in System UI, please see go/sysui-arch. \
+                    NOTE: if your code is not using Clean Architecture, please feel free to ignore \
+                    this warning.
+                """,
+                category = Category.CORRECTNESS,
+                priority = 8,
+                severity = Severity.WARNING,
+                implementation =
+                    Implementation(
+                        CleanArchitectureDependencyViolationDetector::class.java,
+                        Scope.JAVA_FILE_SCOPE,
+                    ),
+            )
+    }
+}
diff --git a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt
index 3f334c1c..254a6fb 100644
--- a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt
+++ b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt
@@ -27,9 +27,11 @@
 class SystemUIIssueRegistry : IssueRegistry() {
 
     override val issues: List<Issue>
-        get() = listOf(
+        get() =
+            listOf(
                 BindServiceOnMainThreadDetector.ISSUE,
                 BroadcastSentViaContextDetector.ISSUE,
+                CleanArchitectureDependencyViolationDetector.ISSUE,
                 SlowUserQueryDetector.ISSUE_SLOW_USER_ID_QUERY,
                 SlowUserQueryDetector.ISSUE_SLOW_USER_INFO_QUERY,
                 NonInjectedMainThreadDetector.ISSUE,
@@ -37,7 +39,7 @@
                 SoftwareBitmapDetector.ISSUE,
                 NonInjectedServiceDetector.ISSUE,
                 StaticSettingsProviderDetector.ISSUE
-        )
+            )
 
     override val api: Int
         get() = CURRENT_API
@@ -45,9 +47,9 @@
         get() = 8
 
     override val vendor: Vendor =
-            Vendor(
-                    vendorName = "Android",
-                    feedbackUrl = "http://b/issues/new?component=78010",
-                    contact = "jernej@google.com"
-            )
+        Vendor(
+            vendorName = "Android",
+            feedbackUrl = "http://b/issues/new?component=78010",
+            contact = "jernej@google.com"
+        )
 }
diff --git a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/CleanArchitectureDependencyViolationDetectorTest.kt b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/CleanArchitectureDependencyViolationDetectorTest.kt
new file mode 100644
index 0000000..a4b59fd
--- /dev/null
+++ b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/CleanArchitectureDependencyViolationDetectorTest.kt
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *            http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.internal.systemui.lint
+
+import com.android.tools.lint.checks.infrastructure.TestFiles
+import com.android.tools.lint.checks.infrastructure.TestMode
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+import org.junit.Ignore
+import org.junit.Test
+
+@Suppress("UnstableApiUsage")
+@Ignore("b/254533331")
+class CleanArchitectureDependencyViolationDetectorTest : SystemUILintDetectorTest() {
+    override fun getDetector(): Detector {
+        return CleanArchitectureDependencyViolationDetector()
+    }
+
+    override fun getIssues(): List<Issue> {
+        return listOf(
+            CleanArchitectureDependencyViolationDetector.ISSUE,
+        )
+    }
+
+    @Test
+    fun `No violations`() {
+        lint()
+            .files(
+                *LEGITIMATE_FILES,
+            )
+            .issues(
+                CleanArchitectureDependencyViolationDetector.ISSUE,
+            )
+            .run()
+            .expectWarningCount(0)
+    }
+
+    @Test
+    fun `Violation - domain depends on ui`() {
+        lint()
+            .files(
+                *LEGITIMATE_FILES,
+                TestFiles.kotlin(
+                    """
+                        package test.domain.interactor
+
+                        import test.ui.viewmodel.ViewModel
+
+                        class BadClass(
+                            private val viewModel: ViewModel,
+                        )
+                    """.trimIndent()
+                )
+            )
+            .issues(
+                CleanArchitectureDependencyViolationDetector.ISSUE,
+            )
+            .testModes(TestMode.DEFAULT)
+            .run()
+            .expectWarningCount(1)
+            .expect(
+                expectedText =
+                    """
+                    src/test/domain/interactor/BadClass.kt:3: Warning: The domain layer may not depend on the ui layer. [CleanArchitectureDependencyViolation]
+                    import test.ui.viewmodel.ViewModel
+                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                    0 errors, 1 warnings
+                """,
+            )
+    }
+
+    @Test
+    fun `Violation - ui depends on data`() {
+        lint()
+            .files(
+                *LEGITIMATE_FILES,
+                TestFiles.kotlin(
+                    """
+                        package test.ui.viewmodel
+
+                        import test.data.repository.Repository
+
+                        class BadClass(
+                            private val repository: Repository,
+                        )
+                    """.trimIndent()
+                )
+            )
+            .issues(
+                CleanArchitectureDependencyViolationDetector.ISSUE,
+            )
+            .testModes(TestMode.DEFAULT)
+            .run()
+            .expectWarningCount(1)
+            .expect(
+                expectedText =
+                    """
+                    src/test/ui/viewmodel/BadClass.kt:3: Warning: The ui layer may not depend on the data layer. [CleanArchitectureDependencyViolation]
+                    import test.data.repository.Repository
+                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                    0 errors, 1 warnings
+                """,
+            )
+    }
+
+    @Test
+    fun `Violation - shared depends on all other layers`() {
+        lint()
+            .files(
+                *LEGITIMATE_FILES,
+                TestFiles.kotlin(
+                    """
+                        package test.shared.model
+
+                        import test.data.repository.Repository
+                        import test.domain.interactor.Interactor
+                        import test.ui.viewmodel.ViewModel
+
+                        class BadClass(
+                            private val repository: Repository,
+                            private val interactor: Interactor,
+                            private val viewmodel: ViewModel,
+                        )
+                    """.trimIndent()
+                )
+            )
+            .issues(
+                CleanArchitectureDependencyViolationDetector.ISSUE,
+            )
+            .testModes(TestMode.DEFAULT)
+            .run()
+            .expectWarningCount(3)
+            .expect(
+                expectedText =
+                    """
+                    src/test/shared/model/BadClass.kt:3: Warning: The shared layer may not depend on the data layer. [CleanArchitectureDependencyViolation]
+                    import test.data.repository.Repository
+                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                    src/test/shared/model/BadClass.kt:4: Warning: The shared layer may not depend on the domain layer. [CleanArchitectureDependencyViolation]
+                    import test.domain.interactor.Interactor
+                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                    src/test/shared/model/BadClass.kt:5: Warning: The shared layer may not depend on the ui layer. [CleanArchitectureDependencyViolation]
+                    import test.ui.viewmodel.ViewModel
+                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                    0 errors, 3 warnings
+                """,
+            )
+    }
+
+    @Test
+    fun `Violation - data depends on domain`() {
+        lint()
+            .files(
+                *LEGITIMATE_FILES,
+                TestFiles.kotlin(
+                    """
+                        package test.data.repository
+
+                        import test.domain.interactor.Interactor
+
+                        class BadClass(
+                            private val interactor: Interactor,
+                        )
+                    """.trimIndent()
+                )
+            )
+            .issues(
+                CleanArchitectureDependencyViolationDetector.ISSUE,
+            )
+            .testModes(TestMode.DEFAULT)
+            .run()
+            .expectWarningCount(1)
+            .expect(
+                expectedText =
+                    """
+                    src/test/data/repository/BadClass.kt:3: Warning: The data layer may not depend on the domain layer. [CleanArchitectureDependencyViolation]
+                    import test.domain.interactor.Interactor
+                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                    0 errors, 1 warnings
+                """,
+            )
+    }
+
+    companion object {
+        private val MODEL_FILE =
+            TestFiles.kotlin(
+                """
+                    package test.shared.model
+
+                    import test.some.other.thing.SomeOtherThing
+
+                    data class Model(
+                        private val name: String,
+                    )
+                """.trimIndent()
+            )
+        private val REPOSITORY_FILE =
+            TestFiles.kotlin(
+                """
+                    package test.data.repository
+
+                    import test.shared.model.Model
+                    import test.some.other.thing.SomeOtherThing
+
+                    class Repository {
+                        private val models = listOf(
+                            Model("one"),
+                            Model("two"),
+                            Model("three"),
+                        )
+
+                        fun getModels(): List<Model> {
+                            return models
+                        }
+                    }
+                """.trimIndent()
+            )
+        private val INTERACTOR_FILE =
+            TestFiles.kotlin(
+                """
+                    package test.domain.interactor
+
+                    import test.data.repository.Repository
+                    import test.shared.model.Model
+
+                    class Interactor(
+                        private val repository: Repository,
+                    ) {
+                        fun getModels(): List<Model> {
+                            return repository.getModels()
+                        }
+                    }
+                """.trimIndent()
+            )
+        private val VIEW_MODEL_FILE =
+            TestFiles.kotlin(
+                """
+                    package test.ui.viewmodel
+
+                    import test.domain.interactor.Interactor
+                    import test.some.other.thing.SomeOtherThing
+
+                    class ViewModel(
+                        private val interactor: Interactor,
+                    ) {
+                        fun getNames(): List<String> {
+                            return interactor.getModels().map { model -> model.name }
+                        }
+                    }
+                """.trimIndent()
+            )
+        private val NON_CLEAN_ARCHITECTURE_FILE =
+            TestFiles.kotlin(
+                """
+                    package test.some.other.thing
+
+                    import test.data.repository.Repository
+                    import test.domain.interactor.Interactor
+                    import test.ui.viewmodel.ViewModel
+
+                    class SomeOtherThing {
+                        init {
+                            val viewModel = ViewModel(
+                                interactor = Interactor(
+                                    repository = Repository(),
+                                ),
+                            )
+                        }
+                    }
+                """.trimIndent()
+            )
+        private val LEGITIMATE_FILES =
+            arrayOf(
+                MODEL_FILE,
+                REPOSITORY_FILE,
+                INTERACTOR_FILE,
+                VIEW_MODEL_FILE,
+                NON_CLEAN_ARCHITECTURE_FILE,
+            )
+    }
+}
diff --git a/packages/SystemUI/compose/core/Android.bp b/packages/SystemUI/compose/core/Android.bp
index fbdb526..ab3efb8 100644
--- a/packages/SystemUI/compose/core/Android.bp
+++ b/packages/SystemUI/compose/core/Android.bp
@@ -22,7 +22,7 @@
 }
 
 android_library {
-    name: "SystemUIComposeCore",
+    name: "PlatformComposeCore",
     manifest: "AndroidManifest.xml",
 
     srcs: [
diff --git a/packages/SystemUI/compose/core/AndroidManifest.xml b/packages/SystemUI/compose/core/AndroidManifest.xml
index 83c442d..20543db 100644
--- a/packages/SystemUI/compose/core/AndroidManifest.xml
+++ b/packages/SystemUI/compose/core/AndroidManifest.xml
@@ -16,7 +16,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.systemui.compose.core">
+    package="com.android.compose.core">
 
 
 </manifest>
diff --git a/packages/SystemUI/compose/core/TEST_MAPPING b/packages/SystemUI/compose/core/TEST_MAPPING
index dc243d2..ee95f73 100644
--- a/packages/SystemUI/compose/core/TEST_MAPPING
+++ b/packages/SystemUI/compose/core/TEST_MAPPING
@@ -1,7 +1,7 @@
 {
   "presubmit": [
     {
-      "name": "SystemUIComposeCoreTests",
+      "name": "PlatformComposeCoreTests",
       "options": [
         {
           "exclude-annotation": "org.junit.Ignore"
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/SystemUiButtons.kt b/packages/SystemUI/compose/core/src/com/android/compose/PlatformButtons.kt
similarity index 94%
rename from packages/SystemUI/compose/core/src/com/android/systemui/compose/SystemUiButtons.kt
rename to packages/SystemUI/compose/core/src/com/android/compose/PlatformButtons.kt
index 496f4b3..d1ee18a 100644
--- a/packages/SystemUI/compose/core/src/com/android/systemui/compose/SystemUiButtons.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/PlatformButtons.kt
@@ -15,7 +15,7 @@
  *
  */
 
-package com.android.systemui.compose
+package com.android.compose
 
 import androidx.compose.foundation.BorderStroke
 import androidx.compose.foundation.layout.PaddingValues
@@ -27,10 +27,10 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.dp
-import com.android.systemui.compose.theme.LocalAndroidColorScheme
+import com.android.compose.theme.LocalAndroidColorScheme
 
 @Composable
-fun SysUiButton(
+fun PlatformButton(
     onClick: () -> Unit,
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
@@ -48,7 +48,7 @@
 }
 
 @Composable
-fun SysUiOutlinedButton(
+fun PlatformOutlinedButton(
     onClick: () -> Unit,
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
@@ -67,7 +67,7 @@
 }
 
 @Composable
-fun SysUiTextButton(
+fun PlatformTextButton(
     onClick: () -> Unit,
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/SystemUiController.kt b/packages/SystemUI/compose/core/src/com/android/compose/SystemUiController.kt
similarity index 99%
rename from packages/SystemUI/compose/core/src/com/android/systemui/compose/SystemUiController.kt
rename to packages/SystemUI/compose/core/src/com/android/compose/SystemUiController.kt
index c9470c8..a02954a 100644
--- a/packages/SystemUI/compose/core/src/com/android/systemui/compose/SystemUiController.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/SystemUiController.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.compose
+package com.android.compose
 
 import android.app.Activity
 import android.content.Context
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/animation/Expandable.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/Expandable.kt
similarity index 93%
rename from packages/SystemUI/compose/core/src/com/android/systemui/compose/animation/Expandable.kt
rename to packages/SystemUI/compose/core/src/com/android/compose/animation/Expandable.kt
index d31ca51..4e96dda 100644
--- a/packages/SystemUI/compose/core/src/com/android/systemui/compose/animation/Expandable.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/Expandable.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.compose.animation
+package com.android.compose.animation
 
 import android.content.Context
 import android.view.View
@@ -41,6 +41,7 @@
 import androidx.compose.runtime.State
 import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.movableContentOf
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberCompositionContext
@@ -73,6 +74,7 @@
 import androidx.compose.ui.unit.dp
 import androidx.lifecycle.ViewTreeLifecycleOwner
 import androidx.lifecycle.ViewTreeViewModelStoreOwner
+import com.android.compose.runtime.movableContentOf
 import com.android.systemui.animation.Expandable
 import com.android.systemui.animation.LaunchAnimator
 import kotlin.math.max
@@ -170,25 +172,25 @@
     val contentColor = controller.contentColor
     val shape = controller.shape
 
-    // TODO(b/230830644): Use movableContentOf to preserve the content state instead once the
-    // Compose libraries have been updated and include aosp/2163631.
     val wrappedContent =
-        @Composable { controller: ExpandableController ->
-            CompositionLocalProvider(
-                LocalContentColor provides contentColor,
-            ) {
-                // We make sure that the content itself (wrapped by the background) is at least
-                // 40.dp, which is the same as the M3 buttons. This applies even if onClick is
-                // null, to make it easier to write expandables that are sometimes clickable and
-                // sometimes not. There shouldn't be any Expandable smaller than 40dp because if
-                // the expandable is not clickable directly, then something in its content should
-                // be (and with a size >= 40dp).
-                val minSize = 40.dp
-                Box(
-                    Modifier.defaultMinSize(minWidth = minSize, minHeight = minSize),
-                    contentAlignment = Alignment.Center,
+        remember(content) {
+            movableContentOf { expandable: Expandable ->
+                CompositionLocalProvider(
+                    LocalContentColor provides contentColor,
                 ) {
-                    content(controller.expandable)
+                    // We make sure that the content itself (wrapped by the background) is at least
+                    // 40.dp, which is the same as the M3 buttons. This applies even if onClick is
+                    // null, to make it easier to write expandables that are sometimes clickable and
+                    // sometimes not. There shouldn't be any Expandable smaller than 40dp because if
+                    // the expandable is not clickable directly, then something in its content
+                    // should be (and with a size >= 40dp).
+                    val minSize = 40.dp
+                    Box(
+                        Modifier.defaultMinSize(minWidth = minSize, minHeight = minSize),
+                        contentAlignment = Alignment.Center,
+                    ) {
+                        content(expandable)
+                    }
                 }
             }
         }
@@ -270,7 +272,7 @@
                     .onGloballyPositioned {
                         controller.boundsInComposeViewRoot.value = it.boundsInRoot()
                     }
-            ) { wrappedContent(controller) }
+            ) { wrappedContent(controller.expandable) }
         }
         else -> {
             val clickModifier =
@@ -301,7 +303,7 @@
                         controller.boundsInComposeViewRoot.value = it.boundsInRoot()
                     },
             ) {
-                wrappedContent(controller)
+                wrappedContent(controller.expandable)
             }
         }
     }
@@ -315,7 +317,7 @@
     animatorState: State<LaunchAnimator.State?>,
     overlay: ViewGroupOverlay,
     controller: ExpandableControllerImpl,
-    content: @Composable (ExpandableController) -> Unit,
+    content: @Composable (Expandable) -> Unit,
     composeViewRoot: View,
     onOverlayComposeViewChanged: (View?) -> Unit,
     density: Density,
@@ -370,7 +372,7 @@
                             // We center the content in the expanding container.
                             contentAlignment = Alignment.Center,
                         ) {
-                            Box(contentModifier) { content(controller) }
+                            Box(contentModifier) { content(controller.expandable) }
                         }
                     }
                 }
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/animation/ExpandableController.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt
similarity index 99%
rename from packages/SystemUI/compose/core/src/com/android/systemui/compose/animation/ExpandableController.kt
rename to packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt
index f75b3a8..edb10c7d 100644
--- a/packages/SystemUI/compose/core/src/com/android/systemui/compose/animation/ExpandableController.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.compose.animation
+package com.android.compose.animation
 
 import android.view.View
 import android.view.ViewGroup
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/animation/ViewTreeSavedStateRegistryOwner.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/ViewTreeSavedStateRegistryOwner.kt
similarity index 96%
rename from packages/SystemUI/compose/core/src/com/android/systemui/compose/animation/ViewTreeSavedStateRegistryOwner.kt
rename to packages/SystemUI/compose/core/src/com/android/compose/animation/ViewTreeSavedStateRegistryOwner.kt
index 79f1cad1..d400f77 100644
--- a/packages/SystemUI/compose/core/src/com/android/systemui/compose/animation/ViewTreeSavedStateRegistryOwner.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/ViewTreeSavedStateRegistryOwner.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.compose.animation
+package com.android.compose.animation
 
 import android.view.View
 import androidx.savedstate.SavedStateRegistryOwner
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/modifiers/FadingBackground.kt b/packages/SystemUI/compose/core/src/com/android/compose/modifiers/FadingBackground.kt
similarity index 98%
rename from packages/SystemUI/compose/core/src/com/android/systemui/compose/modifiers/FadingBackground.kt
rename to packages/SystemUI/compose/core/src/com/android/compose/modifiers/FadingBackground.kt
index 121bf2c..13c2464 100644
--- a/packages/SystemUI/compose/core/src/com/android/systemui/compose/modifiers/FadingBackground.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/modifiers/FadingBackground.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.compose.modifiers
+package com.android.compose.modifiers
 
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.DrawModifier
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/modifiers/Padding.kt b/packages/SystemUI/compose/core/src/com/android/compose/modifiers/Padding.kt
similarity index 98%
rename from packages/SystemUI/compose/core/src/com/android/systemui/compose/modifiers/Padding.kt
rename to packages/SystemUI/compose/core/src/com/android/compose/modifiers/Padding.kt
index 3b13c0b..d9bc9c9 100644
--- a/packages/SystemUI/compose/core/src/com/android/systemui/compose/modifiers/Padding.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/modifiers/Padding.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.compose.modifiers
+package com.android.compose.modifiers
 
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.layout.LayoutModifier
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/modifiers/Size.kt b/packages/SystemUI/compose/core/src/com/android/compose/modifiers/Size.kt
similarity index 99%
rename from packages/SystemUI/compose/core/src/com/android/systemui/compose/modifiers/Size.kt
rename to packages/SystemUI/compose/core/src/com/android/compose/modifiers/Size.kt
index 570d2431..ec1b966 100644
--- a/packages/SystemUI/compose/core/src/com/android/systemui/compose/modifiers/Size.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/modifiers/Size.kt
@@ -15,7 +15,7 @@
  *
  */
 
-package com.android.systemui.compose.modifiers
+package com.android.compose.modifiers
 
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.layout.IntrinsicMeasurable
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/layout/pager/Pager.kt b/packages/SystemUI/compose/core/src/com/android/compose/pager/Pager.kt
similarity index 99%
rename from packages/SystemUI/compose/core/src/com/android/systemui/compose/layout/pager/Pager.kt
rename to packages/SystemUI/compose/core/src/com/android/compose/pager/Pager.kt
index 19624e6..eb9d625 100644
--- a/packages/SystemUI/compose/core/src/com/android/systemui/compose/layout/pager/Pager.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/pager/Pager.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.compose.layout.pager
+package com.android.compose.pager
 
 import androidx.compose.animation.core.AnimationSpec
 import androidx.compose.animation.core.DecayAnimationSpec
@@ -40,7 +40,6 @@
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.Velocity
 import androidx.compose.ui.unit.dp
-import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.flow.filter
 
 /** Library-wide switch to turn on debug logging. */
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/layout/pager/PagerState.kt b/packages/SystemUI/compose/core/src/com/android/compose/pager/PagerState.kt
similarity index 99%
rename from packages/SystemUI/compose/core/src/com/android/systemui/compose/layout/pager/PagerState.kt
rename to packages/SystemUI/compose/core/src/com/android/compose/pager/PagerState.kt
index 288c26e..2e6ae78 100644
--- a/packages/SystemUI/compose/core/src/com/android/systemui/compose/layout/pager/PagerState.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/pager/PagerState.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.compose.layout.pager
+package com.android.compose.pager
 
 import androidx.annotation.FloatRange
 import androidx.annotation.IntRange
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/layout/pager/SnappingFlingBehavior.kt b/packages/SystemUI/compose/core/src/com/android/compose/pager/SnappingFlingBehavior.kt
similarity index 99%
rename from packages/SystemUI/compose/core/src/com/android/systemui/compose/layout/pager/SnappingFlingBehavior.kt
rename to packages/SystemUI/compose/core/src/com/android/compose/pager/SnappingFlingBehavior.kt
index 0b53f532..23122de 100644
--- a/packages/SystemUI/compose/core/src/com/android/systemui/compose/layout/pager/SnappingFlingBehavior.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/pager/SnappingFlingBehavior.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.compose.layout.pager
+package com.android.compose.pager
 
 import androidx.compose.animation.core.AnimationSpec
 import androidx.compose.animation.core.AnimationState
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/runtime/MovableContent.kt b/packages/SystemUI/compose/core/src/com/android/compose/runtime/MovableContent.kt
similarity index 96%
rename from packages/SystemUI/compose/core/src/com/android/systemui/compose/runtime/MovableContent.kt
rename to packages/SystemUI/compose/core/src/com/android/compose/runtime/MovableContent.kt
index 3f2f96b..228ba3d 100644
--- a/packages/SystemUI/compose/core/src/com/android/systemui/compose/runtime/MovableContent.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/runtime/MovableContent.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.compose.runtime
+package com.android.compose.runtime
 
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.InternalComposeApi
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/AndroidColorScheme.kt b/packages/SystemUI/compose/core/src/com/android/compose/theme/AndroidColorScheme.kt
similarity index 96%
rename from packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/AndroidColorScheme.kt
rename to packages/SystemUI/compose/core/src/com/android/compose/theme/AndroidColorScheme.kt
index caa7e5f..4f1657f 100644
--- a/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/AndroidColorScheme.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/theme/AndroidColorScheme.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.compose.theme
+package com.android.compose.theme
 
 import android.annotation.ColorInt
 import android.content.Context
@@ -27,7 +27,7 @@
     staticCompositionLocalOf<AndroidColorScheme> {
         throw IllegalStateException(
             "No AndroidColorScheme configured. Make sure to use LocalAndroidColorScheme in a " +
-                "Composable surrounded by a SystemUITheme {}."
+                "Composable surrounded by a PlatformTheme {}."
         )
     }
 
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/Color.kt b/packages/SystemUI/compose/core/src/com/android/compose/theme/Color.kt
similarity index 95%
rename from packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/Color.kt
rename to packages/SystemUI/compose/core/src/com/android/compose/theme/Color.kt
index de47cce..5dbaff6 100644
--- a/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/Color.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/theme/Color.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.compose.theme
+package com.android.compose.theme
 
 import android.annotation.AttrRes
 import androidx.compose.runtime.Composable
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/SystemUITheme.kt b/packages/SystemUI/compose/core/src/com/android/compose/theme/PlatformTheme.kt
similarity index 77%
rename from packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/SystemUITheme.kt
rename to packages/SystemUI/compose/core/src/com/android/compose/theme/PlatformTheme.kt
index 00532f4..b4e90d6 100644
--- a/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/SystemUITheme.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/theme/PlatformTheme.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.compose.theme
+package com.android.compose.theme
 
 import androidx.compose.foundation.isSystemInDarkTheme
 import androidx.compose.material3.MaterialTheme
@@ -24,15 +24,15 @@
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.remember
 import androidx.compose.ui.platform.LocalContext
-import com.android.systemui.compose.theme.typography.TypeScaleTokens
-import com.android.systemui.compose.theme.typography.TypefaceNames
-import com.android.systemui.compose.theme.typography.TypefaceTokens
-import com.android.systemui.compose.theme.typography.TypographyTokens
-import com.android.systemui.compose.theme.typography.systemUITypography
+import com.android.compose.theme.typography.TypeScaleTokens
+import com.android.compose.theme.typography.TypefaceNames
+import com.android.compose.theme.typography.TypefaceTokens
+import com.android.compose.theme.typography.TypographyTokens
+import com.android.compose.theme.typography.platformTypography
 
-/** The Material 3 theme that should wrap all SystemUI Composables. */
+/** The Material 3 theme that should wrap all Platform Composables. */
 @Composable
-fun SystemUITheme(
+fun PlatformTheme(
     isDarkTheme: Boolean = isSystemInDarkTheme(),
     content: @Composable () -> Unit,
 ) {
@@ -49,7 +49,7 @@
     val typefaceNames = remember(context) { TypefaceNames.get(context) }
     val typography =
         remember(typefaceNames) {
-            systemUITypography(TypographyTokens(TypeScaleTokens(TypefaceTokens(typefaceNames))))
+            platformTypography(TypographyTokens(TypeScaleTokens(TypefaceTokens(typefaceNames))))
         }
 
     MaterialTheme(colorScheme, typography = typography) {
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/typography/SystemUITypography.kt b/packages/SystemUI/compose/core/src/com/android/compose/theme/typography/PlatformTypography.kt
similarity index 91%
rename from packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/typography/SystemUITypography.kt
rename to packages/SystemUI/compose/core/src/com/android/compose/theme/typography/PlatformTypography.kt
index 365f4bb..1ce1ae3 100644
--- a/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/typography/SystemUITypography.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/theme/typography/PlatformTypography.kt
@@ -14,18 +14,18 @@
  * limitations under the License.
  */
 
-package com.android.systemui.compose.theme.typography
+package com.android.compose.theme.typography
 
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Typography
 
 /**
- * The SystemUI typography.
+ * The typography for Platform Compose code.
  *
  * Do not use directly and call [MaterialTheme.typography] instead to access the different text
  * styles.
  */
-internal fun systemUITypography(typographyTokens: TypographyTokens): Typography {
+internal fun platformTypography(typographyTokens: TypographyTokens): Typography {
     return Typography(
         displayLarge = typographyTokens.displayLarge,
         displayMedium = typographyTokens.displayMedium,
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/typography/TypeScaleTokens.kt b/packages/SystemUI/compose/core/src/com/android/compose/theme/typography/TypeScaleTokens.kt
similarity index 98%
rename from packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/typography/TypeScaleTokens.kt
rename to packages/SystemUI/compose/core/src/com/android/compose/theme/typography/TypeScaleTokens.kt
index 537ba0b..78fcf5c 100644
--- a/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/typography/TypeScaleTokens.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/theme/typography/TypeScaleTokens.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.compose.theme.typography
+package com.android.compose.theme.typography
 
 import androidx.compose.ui.unit.sp
 
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/typography/TypefaceTokens.kt b/packages/SystemUI/compose/core/src/com/android/compose/theme/typography/TypefaceTokens.kt
similarity index 97%
rename from packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/typography/TypefaceTokens.kt
rename to packages/SystemUI/compose/core/src/com/android/compose/theme/typography/TypefaceTokens.kt
index f3d554f..13acfd6 100644
--- a/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/typography/TypefaceTokens.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/theme/typography/TypefaceTokens.kt
@@ -16,7 +16,7 @@
 
 @file:OptIn(ExperimentalTextApi::class)
 
-package com.android.systemui.compose.theme.typography
+package com.android.compose.theme.typography
 
 import android.content.Context
 import androidx.compose.ui.text.ExperimentalTextApi
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/typography/TypographyTokens.kt b/packages/SystemUI/compose/core/src/com/android/compose/theme/typography/TypographyTokens.kt
similarity index 98%
rename from packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/typography/TypographyTokens.kt
rename to packages/SystemUI/compose/core/src/com/android/compose/theme/typography/TypographyTokens.kt
index 55f3d1f..38aadb8 100644
--- a/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/typography/TypographyTokens.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/theme/typography/TypographyTokens.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.compose.theme.typography
+package com.android.compose.theme.typography
 
 import androidx.compose.ui.text.TextStyle
 
diff --git a/packages/SystemUI/compose/core/tests/Android.bp b/packages/SystemUI/compose/core/tests/Android.bp
index f8023e2..6119e96 100644
--- a/packages/SystemUI/compose/core/tests/Android.bp
+++ b/packages/SystemUI/compose/core/tests/Android.bp
@@ -23,7 +23,7 @@
 
 // TODO(b/230606318): Make those host tests instead of device tests.
 android_test {
-    name: "SystemUIComposeCoreTests",
+    name: "PlatformComposeCoreTests",
     manifest: "AndroidManifest.xml",
     test_suites: ["device-tests"],
     sdk_version: "current",
@@ -34,7 +34,7 @@
     ],
 
     static_libs: [
-        "SystemUIComposeCore",
+        "PlatformComposeCore",
 
         "androidx.test.runner",
         "androidx.test.ext.junit",
diff --git a/packages/SystemUI/compose/core/tests/AndroidManifest.xml b/packages/SystemUI/compose/core/tests/AndroidManifest.xml
index 729ab98..1016340 100644
--- a/packages/SystemUI/compose/core/tests/AndroidManifest.xml
+++ b/packages/SystemUI/compose/core/tests/AndroidManifest.xml
@@ -15,14 +15,14 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.systemui.compose.core.tests" >
+    package="com.android.compose.core.tests" >
 
     <application>
         <uses-library android:name="android.test.runner" />
     </application>
 
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.systemui.compose.core.tests"
-                     android:label="Tests for SystemUIComposeCore"/>
+                     android:targetPackage="com.android.compose.core.tests"
+                     android:label="Tests for PlatformComposeCore"/>
 
 </manifest>
\ No newline at end of file
diff --git a/packages/SystemUI/compose/core/tests/src/com/android/systemui/compose/theme/SystemUIThemeTest.kt b/packages/SystemUI/compose/core/tests/src/com/android/compose/theme/SystemUIThemeTest.kt
similarity index 90%
rename from packages/SystemUI/compose/core/tests/src/com/android/systemui/compose/theme/SystemUIThemeTest.kt
rename to packages/SystemUI/compose/core/tests/src/com/android/compose/theme/SystemUIThemeTest.kt
index 20249f6..9bc6856 100644
--- a/packages/SystemUI/compose/core/tests/src/com/android/systemui/compose/theme/SystemUIThemeTest.kt
+++ b/packages/SystemUI/compose/core/tests/src/com/android/compose/theme/SystemUIThemeTest.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.compose.theme
+package com.android.compose.theme
 
 import androidx.compose.material3.Text
 import androidx.compose.ui.test.assertIsDisplayed
@@ -32,7 +32,7 @@
 
     @Test
     fun testThemeShowsContent() {
-        composeRule.setContent { SystemUITheme { Text("foo") } }
+        composeRule.setContent { PlatformTheme { Text("foo") } }
 
         composeRule.onNodeWithText("foo").assertIsDisplayed()
     }
@@ -40,7 +40,7 @@
     @Test
     fun testAndroidColorsAreAvailableInsideTheme() {
         composeRule.setContent {
-            SystemUITheme { Text("foo", color = LocalAndroidColorScheme.current.colorAccent) }
+            PlatformTheme { Text("foo", color = LocalAndroidColorScheme.current.colorAccent) }
         }
 
         composeRule.onNodeWithText("foo").assertIsDisplayed()
diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt
index 6e728ce..e253fb9 100644
--- a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt
+++ b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt
@@ -17,13 +17,21 @@
 
 package com.android.systemui.compose
 
+import android.content.Context
+import android.view.View
 import androidx.activity.ComponentActivity
+import androidx.lifecycle.LifecycleOwner
 import com.android.systemui.people.ui.viewmodel.PeopleViewModel
+import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
 
 /** The Compose facade, when Compose is *not* available. */
 object ComposeFacade : BaseComposeFacade {
     override fun isComposeAvailable(): Boolean = false
 
+    override fun composeInitializer(): ComposeInitializer {
+        throwComposeUnavailableError()
+    }
+
     override fun setPeopleSpaceActivityContent(
         activity: ComponentActivity,
         viewModel: PeopleViewModel,
@@ -32,7 +40,15 @@
         throwComposeUnavailableError()
     }
 
-    private fun throwComposeUnavailableError() {
+    override fun createFooterActionsView(
+        context: Context,
+        viewModel: FooterActionsViewModel,
+        qsVisibilityLifecycleOwner: LifecycleOwner
+    ): View {
+        throwComposeUnavailableError()
+    }
+
+    private fun throwComposeUnavailableError(): Nothing {
         error(
             "Compose is not available. Make sure to check isComposeAvailable() before calling any" +
                 " other function on ComposeFacade."
diff --git a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt
index 16294d9..1ea18fe 100644
--- a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt
+++ b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt
@@ -16,21 +16,39 @@
 
 package com.android.systemui.compose
 
+import android.content.Context
+import android.view.View
 import androidx.activity.ComponentActivity
 import androidx.activity.compose.setContent
-import com.android.systemui.compose.theme.SystemUITheme
+import androidx.compose.ui.platform.ComposeView
+import androidx.lifecycle.LifecycleOwner
+import com.android.compose.theme.PlatformTheme
 import com.android.systemui.people.ui.compose.PeopleScreen
 import com.android.systemui.people.ui.viewmodel.PeopleViewModel
+import com.android.systemui.qs.footer.ui.compose.FooterActions
+import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
 
 /** The Compose facade, when Compose is available. */
 object ComposeFacade : BaseComposeFacade {
     override fun isComposeAvailable(): Boolean = true
 
+    override fun composeInitializer(): ComposeInitializer = ComposeInitializerImpl
+
     override fun setPeopleSpaceActivityContent(
         activity: ComponentActivity,
         viewModel: PeopleViewModel,
         onResult: (PeopleViewModel.Result) -> Unit,
     ) {
-        activity.setContent { SystemUITheme { PeopleScreen(viewModel, onResult) } }
+        activity.setContent { PlatformTheme { PeopleScreen(viewModel, onResult) } }
+    }
+
+    override fun createFooterActionsView(
+        context: Context,
+        viewModel: FooterActionsViewModel,
+        qsVisibilityLifecycleOwner: LifecycleOwner,
+    ): View {
+        return ComposeView(context).apply {
+            setContent { PlatformTheme { FooterActions(viewModel, qsVisibilityLifecycleOwner) } }
+        }
     }
 }
diff --git a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeInitializerImpl.kt b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeInitializerImpl.kt
new file mode 100644
index 0000000..772c891
--- /dev/null
+++ b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeInitializerImpl.kt
@@ -0,0 +1,78 @@
+/*
+ * 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.compose
+
+import android.view.View
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.ViewTreeLifecycleOwner
+import androidx.savedstate.SavedStateRegistry
+import androidx.savedstate.SavedStateRegistryController
+import androidx.savedstate.SavedStateRegistryOwner
+import com.android.compose.animation.ViewTreeSavedStateRegistryOwner
+import com.android.systemui.lifecycle.ViewLifecycleOwner
+
+internal object ComposeInitializerImpl : ComposeInitializer {
+    override fun onAttachedToWindow(root: View) {
+        if (ViewTreeLifecycleOwner.get(root) != null) {
+            error("root $root already has a LifecycleOwner")
+        }
+
+        val parent = root.parent
+        if (parent is View && parent.id != android.R.id.content) {
+            error(
+                "ComposeInitializer.onAttachedToWindow(View) must be called on the content child." +
+                    "Outside of activities and dialogs, this is usually the top-most View of a " +
+                    "window."
+            )
+        }
+
+        // The lifecycle owner, which is STARTED when [root] is visible and RESUMED when [root] is
+        // both visible and focused.
+        val lifecycleOwner = ViewLifecycleOwner(root)
+
+        // We create a trivial implementation of [SavedStateRegistryOwner] that does not do any save
+        // or restore because SystemUI process is always running and top-level windows using this
+        // initializer are created once, when the process is started.
+        val savedStateRegistryOwner =
+            object : SavedStateRegistryOwner {
+                private val savedStateRegistry =
+                    SavedStateRegistryController.create(this).apply { performRestore(null) }
+
+                override fun getLifecycle(): Lifecycle = lifecycleOwner.lifecycle
+
+                override fun getSavedStateRegistry(): SavedStateRegistry {
+                    return savedStateRegistry.savedStateRegistry
+                }
+            }
+
+        // We must call [ViewLifecycleOwner.onCreate] after creating the [SavedStateRegistryOwner]
+        // because `onCreate` might move the lifecycle state to STARTED which will make
+        // [SavedStateRegistryController.performRestore] throw.
+        lifecycleOwner.onCreate()
+
+        // Set the owners on the root. They will be reused by any ComposeView inside the root
+        // hierarchy.
+        ViewTreeLifecycleOwner.set(root, lifecycleOwner)
+        ViewTreeSavedStateRegistryOwner.set(root, savedStateRegistryOwner)
+    }
+
+    override fun onDetachedFromWindow(root: View) {
+        (ViewTreeLifecycleOwner.get(root) as ViewLifecycleOwner).onDestroy()
+        ViewTreeLifecycleOwner.set(root, null)
+        ViewTreeSavedStateRegistryOwner.set(root, null)
+    }
+}
diff --git a/packages/SystemUI/compose/features/Android.bp b/packages/SystemUI/compose/features/Android.bp
index 4533330..8f8bb1b 100644
--- a/packages/SystemUI/compose/features/Android.bp
+++ b/packages/SystemUI/compose/features/Android.bp
@@ -31,7 +31,7 @@
 
     static_libs: [
         "SystemUI-core",
-        "SystemUIComposeCore",
+        "PlatformComposeCore",
 
         "androidx.compose.runtime_runtime",
         "androidx.compose.material3_material3",
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/compose/modifiers/SysuiTestTag.kt b/packages/SystemUI/compose/features/src/com/android/systemui/compose/modifiers/SysuiTestTag.kt
new file mode 100644
index 0000000..9eb78e1
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/compose/modifiers/SysuiTestTag.kt
@@ -0,0 +1,32 @@
+/*
+ * 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.compose.modifiers
+
+import androidx.compose.ui.ExperimentalComposeUiApi
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.semantics.testTagsAsResourceId
+
+/**
+ * Set a test tag on this node so that it is associated with [resId]. This node will then be
+ * accessible by integration tests using `sysuiResSelector(resId)`.
+ */
+@OptIn(ExperimentalComposeUiApi::class)
+fun Modifier.sysuiResTag(resId: String): Modifier {
+    return this.semantics { testTagsAsResourceId = true }.testTag("com.android.systemui:id/$resId")
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt
index 4a56b02..3eeadae 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt
@@ -49,8 +49,9 @@
 import androidx.compose.ui.unit.dp
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
+import com.android.compose.theme.LocalAndroidColorScheme
 import com.android.systemui.R
-import com.android.systemui.compose.theme.LocalAndroidColorScheme
+import com.android.systemui.compose.modifiers.sysuiResTag
 import com.android.systemui.people.ui.viewmodel.PeopleTileViewModel
 import com.android.systemui.people.ui.viewmodel.PeopleViewModel
 
@@ -110,7 +111,9 @@
     recentTiles: List<PeopleTileViewModel>,
     onTileClicked: (PeopleTileViewModel) -> Unit,
 ) {
-    Column {
+    Column(
+        Modifier.sysuiResTag("top_level_with_conversations"),
+    ) {
         Column(
             Modifier.fillMaxWidth().padding(PeopleSpacePadding),
             horizontalAlignment = Alignment.CenterHorizontally,
@@ -132,7 +135,7 @@
         }
 
         LazyColumn(
-            Modifier.fillMaxWidth(),
+            Modifier.fillMaxWidth().sysuiResTag("scroll_view"),
             contentPadding =
                 PaddingValues(
                     top = 16.dp,
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreenEmpty.kt b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreenEmpty.kt
index 5c9358f..3f590df 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreenEmpty.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreenEmpty.kt
@@ -41,8 +41,8 @@
 import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.text.style.TextOverflow
 import androidx.compose.ui.unit.dp
+import com.android.compose.theme.LocalAndroidColorScheme
 import com.android.systemui.R
-import com.android.systemui.compose.theme.LocalAndroidColorScheme
 
 @Composable
 internal fun PeopleScreenEmpty(
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt
index 654b723..349f5c3 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt
@@ -65,14 +65,15 @@
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.LifecycleOwner
 import androidx.lifecycle.repeatOnLifecycle
+import com.android.compose.animation.Expandable
+import com.android.compose.modifiers.background
+import com.android.compose.theme.LocalAndroidColorScheme
+import com.android.compose.theme.colorAttr
 import com.android.systemui.R
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.common.ui.compose.Icon
-import com.android.systemui.compose.animation.Expandable
-import com.android.systemui.compose.modifiers.background
-import com.android.systemui.compose.theme.LocalAndroidColorScheme
-import com.android.systemui.compose.theme.colorAttr
+import com.android.systemui.compose.modifiers.sysuiResTag
 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsButtonViewModel
 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsForegroundServicesButtonViewModel
 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsSecurityButtonViewModel
@@ -180,9 +181,9 @@
 
             security?.let { SecurityButton(it, Modifier.weight(1f)) }
             foregroundServices?.let { ForegroundServicesButton(it) }
-            userSwitcher?.let { IconButton(it) }
-            IconButton(viewModel.settings)
-            viewModel.power?.let { IconButton(it) }
+            userSwitcher?.let { IconButton(it, Modifier.sysuiResTag("multi_user_switch")) }
+            IconButton(viewModel.settings, Modifier.sysuiResTag("settings_button_container"))
+            viewModel.power?.let { IconButton(it, Modifier.sysuiResTag("pm_lite")) }
         }
     }
 }
diff --git a/packages/SystemUI/compose/features/tests/AndroidManifest.xml b/packages/SystemUI/compose/features/tests/AndroidManifest.xml
index 2fa475d..2f41ea9 100644
--- a/packages/SystemUI/compose/features/tests/AndroidManifest.xml
+++ b/packages/SystemUI/compose/features/tests/AndroidManifest.xml
@@ -35,7 +35,7 @@
             android:enabled="false"
             tools:replace="android:authorities"
             tools:node="remove" />
-        <provider android:name="com.android.systemui.keyguard.KeyguardQuickAffordanceProvider"
+        <provider android:name="com.android.systemui.keyguard.CustomizationProvider"
             android:authorities="com.android.systemui.test.keyguard.quickaffordance.disabled"
             android:enabled="false"
             tools:replace="android:authorities"
diff --git a/packages/SystemUI/compose/testing/Android.bp b/packages/SystemUI/compose/testing/Android.bp
index 293e51f..555f42e 100644
--- a/packages/SystemUI/compose/testing/Android.bp
+++ b/packages/SystemUI/compose/testing/Android.bp
@@ -30,7 +30,7 @@
     ],
 
     static_libs: [
-        "SystemUIComposeCore",
+        "PlatformComposeCore",
         "SystemUIScreenshotLib",
 
         "androidx.compose.runtime_runtime",
diff --git a/packages/SystemUI/compose/testing/src/com/android/systemui/testing/compose/ComposeScreenshotTestRule.kt b/packages/SystemUI/compose/testing/src/com/android/systemui/testing/compose/ComposeScreenshotTestRule.kt
index 979e1a0..cb9e53c 100644
--- a/packages/SystemUI/compose/testing/src/com/android/systemui/testing/compose/ComposeScreenshotTestRule.kt
+++ b/packages/SystemUI/compose/testing/src/com/android/systemui/testing/compose/ComposeScreenshotTestRule.kt
@@ -22,7 +22,7 @@
 import androidx.compose.ui.platform.ViewRootForTest
 import androidx.compose.ui.test.junit4.createAndroidComposeRule
 import androidx.compose.ui.test.onRoot
-import com.android.systemui.compose.theme.SystemUITheme
+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
@@ -79,7 +79,7 @@
         // Set the content using the AndroidComposeRule to make sure that the Activity is set up
         // correctly.
         composeRule.setContent {
-            SystemUITheme {
+            PlatformTheme {
                 Surface(
                     color = MaterialTheme.colorScheme.background,
                 ) {
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 462b90a..86bd5f2 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
@@ -54,7 +54,6 @@
     defStyleAttr: Int = 0,
     defStyleRes: Int = 0
 ) : TextView(context, attrs, defStyleAttr, defStyleRes) {
-    var tag: String = "UnnamedClockView"
     var logBuffer: LogBuffer? = null
 
     private val time = Calendar.getInstance()
@@ -132,7 +131,7 @@
 
     override fun onAttachedToWindow() {
         super.onAttachedToWindow()
-        logBuffer?.log(tag, DEBUG, "onAttachedToWindow")
+        logBuffer?.log(TAG, DEBUG, "onAttachedToWindow")
         refreshFormat()
     }
 
@@ -148,7 +147,7 @@
         time.timeInMillis = timeOverrideInMillis ?: System.currentTimeMillis()
         contentDescription = DateFormat.format(descFormat, time)
         val formattedText = DateFormat.format(format, time)
-        logBuffer?.log(tag, DEBUG,
+        logBuffer?.log(TAG, DEBUG,
                 { str1 = formattedText?.toString() },
                 { "refreshTime: new formattedText=$str1" }
         )
@@ -157,7 +156,7 @@
         // relayout if the text didn't actually change.
         if (!TextUtils.equals(text, formattedText)) {
             text = formattedText
-            logBuffer?.log(tag, DEBUG,
+            logBuffer?.log(TAG, DEBUG,
                     { str1 = formattedText?.toString() },
                     { "refreshTime: done setting new time text to: $str1" }
             )
@@ -167,17 +166,17 @@
             // without being notified TextInterpolator being notified.
             if (layout != null) {
                 textAnimator?.updateLayout(layout)
-                logBuffer?.log(tag, DEBUG, "refreshTime: done updating textAnimator layout")
+                logBuffer?.log(TAG, DEBUG, "refreshTime: done updating textAnimator layout")
             }
             requestLayout()
-            logBuffer?.log(tag, DEBUG, "refreshTime: after requestLayout")
+            logBuffer?.log(TAG, DEBUG, "refreshTime: after requestLayout")
         }
     }
 
     fun onTimeZoneChanged(timeZone: TimeZone?) {
         time.timeZone = timeZone
         refreshFormat()
-        logBuffer?.log(tag, DEBUG,
+        logBuffer?.log(TAG, DEBUG,
                 { str1 = timeZone?.toString() },
                 { "onTimeZoneChanged newTimeZone=$str1" }
         )
@@ -194,7 +193,7 @@
         } else {
             animator.updateLayout(layout)
         }
-        logBuffer?.log(tag, DEBUG, "onMeasure")
+        logBuffer?.log(TAG, DEBUG, "onMeasure")
     }
 
     override fun onDraw(canvas: Canvas) {
@@ -206,12 +205,12 @@
         } else {
             super.onDraw(canvas)
         }
-        logBuffer?.log(tag, DEBUG, "onDraw lastDraw")
+        logBuffer?.log(TAG, DEBUG, "onDraw")
     }
 
     override fun invalidate() {
         super.invalidate()
-        logBuffer?.log(tag, DEBUG, "invalidate")
+        logBuffer?.log(TAG, DEBUG, "invalidate")
     }
 
     override fun onTextChanged(
@@ -221,7 +220,7 @@
             lengthAfter: Int
     ) {
         super.onTextChanged(text, start, lengthBefore, lengthAfter)
-        logBuffer?.log(tag, DEBUG,
+        logBuffer?.log(TAG, DEBUG,
                 { str1 = text.toString() },
                 { "onTextChanged text=$str1" }
         )
@@ -238,7 +237,7 @@
     }
 
     fun animateColorChange() {
-        logBuffer?.log(tag, DEBUG, "animateColorChange")
+        logBuffer?.log(TAG, DEBUG, "animateColorChange")
         setTextStyle(
             weight = lockScreenWeight,
             textSize = -1f,
@@ -260,7 +259,7 @@
     }
 
     fun animateAppearOnLockscreen() {
-        logBuffer?.log(tag, DEBUG, "animateAppearOnLockscreen")
+        logBuffer?.log(TAG, DEBUG, "animateAppearOnLockscreen")
         setTextStyle(
             weight = dozingWeight,
             textSize = -1f,
@@ -285,7 +284,7 @@
         if (isAnimationEnabled && textAnimator == null) {
             return
         }
-        logBuffer?.log(tag, DEBUG, "animateFoldAppear")
+        logBuffer?.log(TAG, DEBUG, "animateFoldAppear")
         setTextStyle(
             weight = lockScreenWeightInternal,
             textSize = -1f,
@@ -312,7 +311,7 @@
             // Skip charge animation if dozing animation is already playing.
             return
         }
-        logBuffer?.log(tag, DEBUG, "animateCharge")
+        logBuffer?.log(TAG, DEBUG, "animateCharge")
         val startAnimPhase2 = Runnable {
             setTextStyle(
                 weight = if (isDozing()) dozingWeight else lockScreenWeight,
@@ -336,7 +335,7 @@
     }
 
     fun animateDoze(isDozing: Boolean, animate: Boolean) {
-        logBuffer?.log(tag, DEBUG, "animateDoze")
+        logBuffer?.log(TAG, DEBUG, "animateDoze")
         setTextStyle(
             weight = if (isDozing) dozingWeight else lockScreenWeight,
             textSize = -1f,
@@ -455,7 +454,7 @@
             isSingleLineInternal && !use24HourFormat -> Patterns.sClockView12
             else -> DOUBLE_LINE_FORMAT_12_HOUR
         }
-        logBuffer?.log(tag, DEBUG,
+        logBuffer?.log(TAG, DEBUG,
                 { str1 = format?.toString() },
                 { "refreshFormat format=$str1" }
         )
@@ -466,6 +465,7 @@
 
     fun dump(pw: PrintWriter) {
         pw.println("$this")
+        pw.println("    alpha=$alpha")
         pw.println("    measuredWidth=$measuredWidth")
         pw.println("    measuredHeight=$measuredHeight")
         pw.println("    singleLineInternal=$isSingleLineInternal")
@@ -626,7 +626,7 @@
     }
 
     companion object {
-        private val TAG = AnimatableClockView::class.simpleName
+        private val TAG = AnimatableClockView::class.simpleName!!
         const val ANIMATION_DURATION_FOLD_TO_AOD: Int = 600
         private const val DOUBLE_LINE_FORMAT_12_HOUR = "hh\nmm"
         private const val DOUBLE_LINE_FORMAT_24_HOUR = "HH\nmm"
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 e138ef8..7645dec 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
@@ -88,13 +88,6 @@
         events.onTimeTick()
     }
 
-    override fun setLogBuffer(logBuffer: LogBuffer) {
-        smallClock.view.tag = "smallClockView"
-        largeClock.view.tag = "largeClockView"
-        smallClock.view.logBuffer = logBuffer
-        largeClock.view.logBuffer = logBuffer
-    }
-
     open inner class DefaultClockFaceController(
         override val view: AnimatableClockView,
     ) : ClockFaceController {
@@ -104,6 +97,12 @@
         private var isRegionDark = false
         protected var targetRegion: Rect? = null
 
+        override var logBuffer: LogBuffer?
+            get() = view.logBuffer
+            set(value) {
+                view.logBuffer = value
+            }
+
         init {
             view.setColors(currentColor, currentColor)
         }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/KeyguardQuickAffordanceProviderClient.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderClient.kt
similarity index 70%
rename from packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/KeyguardQuickAffordanceProviderClient.kt
rename to packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderClient.kt
index 3213b2e..cd9fb88 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/KeyguardQuickAffordanceProviderClient.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderClient.kt
@@ -15,17 +15,20 @@
  *
  */
 
-package com.android.systemui.shared.quickaffordance.data.content
+package com.android.systemui.shared.customization.data.content
 
 import android.annotation.SuppressLint
 import android.content.ContentValues
 import android.content.Context
+import android.content.Intent
 import android.database.ContentObserver
 import android.graphics.Color
 import android.graphics.drawable.Drawable
 import android.net.Uri
+import android.util.Log
 import androidx.annotation.DrawableRes
-import com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderContract as Contract
+import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
+import java.net.URISyntaxException
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.flow.Flow
@@ -35,7 +38,7 @@
 import kotlinx.coroutines.withContext
 
 /** Client for using a content provider implementing the [Contract]. */
-interface KeyguardQuickAffordanceProviderClient {
+interface CustomizationProviderClient {
 
     /**
      * Selects an affordance with the given ID for a slot on the lock screen with the given ID.
@@ -169,6 +172,8 @@
          * If `null`, the button should not be shown.
          */
         val enablementActionComponentName: String? = null,
+        /** Optional [Intent] to use to start an activity to configure this affordance. */
+        val configureIntent: Intent? = null,
     )
 
     /** Models a selection of a quick affordance on a slot. */
@@ -190,10 +195,10 @@
     )
 }
 
-class KeyguardQuickAffordanceProviderClientImpl(
+class CustomizationProviderClientImpl(
     private val context: Context,
     private val backgroundDispatcher: CoroutineDispatcher,
-) : KeyguardQuickAffordanceProviderClient {
+) : CustomizationProviderClient {
 
     override suspend fun insertSelection(
         slotId: String,
@@ -201,20 +206,23 @@
     ) {
         withContext(backgroundDispatcher) {
             context.contentResolver.insert(
-                Contract.SelectionTable.URI,
+                Contract.LockScreenQuickAffordances.SelectionTable.URI,
                 ContentValues().apply {
-                    put(Contract.SelectionTable.Columns.SLOT_ID, slotId)
-                    put(Contract.SelectionTable.Columns.AFFORDANCE_ID, affordanceId)
+                    put(Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID, slotId)
+                    put(
+                        Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_ID,
+                        affordanceId
+                    )
                 }
             )
         }
     }
 
-    override suspend fun querySlots(): List<KeyguardQuickAffordanceProviderClient.Slot> {
+    override suspend fun querySlots(): List<CustomizationProviderClient.Slot> {
         return withContext(backgroundDispatcher) {
             context.contentResolver
                 .query(
-                    Contract.SlotTable.URI,
+                    Contract.LockScreenQuickAffordances.SlotTable.URI,
                     null,
                     null,
                     null,
@@ -222,16 +230,21 @@
                 )
                 ?.use { cursor ->
                     buildList {
-                        val idColumnIndex = cursor.getColumnIndex(Contract.SlotTable.Columns.ID)
+                        val idColumnIndex =
+                            cursor.getColumnIndex(
+                                Contract.LockScreenQuickAffordances.SlotTable.Columns.ID
+                            )
                         val capacityColumnIndex =
-                            cursor.getColumnIndex(Contract.SlotTable.Columns.CAPACITY)
+                            cursor.getColumnIndex(
+                                Contract.LockScreenQuickAffordances.SlotTable.Columns.CAPACITY
+                            )
                         if (idColumnIndex == -1 || capacityColumnIndex == -1) {
                             return@buildList
                         }
 
                         while (cursor.moveToNext()) {
                             add(
-                                KeyguardQuickAffordanceProviderClient.Slot(
+                                CustomizationProviderClient.Slot(
                                     id = cursor.getString(idColumnIndex),
                                     capacity = cursor.getInt(capacityColumnIndex),
                                 )
@@ -243,7 +256,7 @@
             ?: emptyList()
     }
 
-    override suspend fun queryFlags(): List<KeyguardQuickAffordanceProviderClient.Flag> {
+    override suspend fun queryFlags(): List<CustomizationProviderClient.Flag> {
         return withContext(backgroundDispatcher) {
             context.contentResolver
                 .query(
@@ -265,7 +278,7 @@
 
                         while (cursor.moveToNext()) {
                             add(
-                                KeyguardQuickAffordanceProviderClient.Flag(
+                                CustomizationProviderClient.Flag(
                                     name = cursor.getString(nameColumnIndex),
                                     value = cursor.getInt(valueColumnIndex) == 1,
                                 )
@@ -277,20 +290,19 @@
             ?: emptyList()
     }
 
-    override fun observeSlots(): Flow<List<KeyguardQuickAffordanceProviderClient.Slot>> {
-        return observeUri(Contract.SlotTable.URI).map { querySlots() }
+    override fun observeSlots(): Flow<List<CustomizationProviderClient.Slot>> {
+        return observeUri(Contract.LockScreenQuickAffordances.SlotTable.URI).map { querySlots() }
     }
 
-    override fun observeFlags(): Flow<List<KeyguardQuickAffordanceProviderClient.Flag>> {
+    override fun observeFlags(): Flow<List<CustomizationProviderClient.Flag>> {
         return observeUri(Contract.FlagsTable.URI).map { queryFlags() }
     }
 
-    override suspend fun queryAffordances():
-        List<KeyguardQuickAffordanceProviderClient.Affordance> {
+    override suspend fun queryAffordances(): List<CustomizationProviderClient.Affordance> {
         return withContext(backgroundDispatcher) {
             context.contentResolver
                 .query(
-                    Contract.AffordanceTable.URI,
+                    Contract.LockScreenQuickAffordances.AffordanceTable.URI,
                     null,
                     null,
                     null,
@@ -299,24 +311,41 @@
                 ?.use { cursor ->
                     buildList {
                         val idColumnIndex =
-                            cursor.getColumnIndex(Contract.AffordanceTable.Columns.ID)
+                            cursor.getColumnIndex(
+                                Contract.LockScreenQuickAffordances.AffordanceTable.Columns.ID
+                            )
                         val nameColumnIndex =
-                            cursor.getColumnIndex(Contract.AffordanceTable.Columns.NAME)
+                            cursor.getColumnIndex(
+                                Contract.LockScreenQuickAffordances.AffordanceTable.Columns.NAME
+                            )
                         val iconColumnIndex =
-                            cursor.getColumnIndex(Contract.AffordanceTable.Columns.ICON)
+                            cursor.getColumnIndex(
+                                Contract.LockScreenQuickAffordances.AffordanceTable.Columns.ICON
+                            )
                         val isEnabledColumnIndex =
-                            cursor.getColumnIndex(Contract.AffordanceTable.Columns.IS_ENABLED)
+                            cursor.getColumnIndex(
+                                Contract.LockScreenQuickAffordances.AffordanceTable.Columns
+                                    .IS_ENABLED
+                            )
                         val enablementInstructionsColumnIndex =
                             cursor.getColumnIndex(
-                                Contract.AffordanceTable.Columns.ENABLEMENT_INSTRUCTIONS
+                                Contract.LockScreenQuickAffordances.AffordanceTable.Columns
+                                    .ENABLEMENT_INSTRUCTIONS
                             )
                         val enablementActionTextColumnIndex =
                             cursor.getColumnIndex(
-                                Contract.AffordanceTable.Columns.ENABLEMENT_ACTION_TEXT
+                                Contract.LockScreenQuickAffordances.AffordanceTable.Columns
+                                    .ENABLEMENT_ACTION_TEXT
                             )
                         val enablementComponentNameColumnIndex =
                             cursor.getColumnIndex(
-                                Contract.AffordanceTable.Columns.ENABLEMENT_COMPONENT_NAME
+                                Contract.LockScreenQuickAffordances.AffordanceTable.Columns
+                                    .ENABLEMENT_COMPONENT_NAME
+                            )
+                        val configureIntentColumnIndex =
+                            cursor.getColumnIndex(
+                                Contract.LockScreenQuickAffordances.AffordanceTable.Columns
+                                    .CONFIGURE_INTENT
                             )
                         if (
                             idColumnIndex == -1 ||
@@ -325,15 +354,17 @@
                                 isEnabledColumnIndex == -1 ||
                                 enablementInstructionsColumnIndex == -1 ||
                                 enablementActionTextColumnIndex == -1 ||
-                                enablementComponentNameColumnIndex == -1
+                                enablementComponentNameColumnIndex == -1 ||
+                                configureIntentColumnIndex == -1
                         ) {
                             return@buildList
                         }
 
                         while (cursor.moveToNext()) {
+                            val affordanceId = cursor.getString(idColumnIndex)
                             add(
-                                KeyguardQuickAffordanceProviderClient.Affordance(
-                                    id = cursor.getString(idColumnIndex),
+                                CustomizationProviderClient.Affordance(
+                                    id = affordanceId,
                                     name = cursor.getString(nameColumnIndex),
                                     iconResourceId = cursor.getInt(iconColumnIndex),
                                     isEnabled = cursor.getInt(isEnabledColumnIndex) == 1,
@@ -341,13 +372,17 @@
                                         cursor
                                             .getString(enablementInstructionsColumnIndex)
                                             ?.split(
-                                                Contract.AffordanceTable
+                                                Contract.LockScreenQuickAffordances.AffordanceTable
                                                     .ENABLEMENT_INSTRUCTIONS_DELIMITER
                                             ),
                                     enablementActionText =
                                         cursor.getString(enablementActionTextColumnIndex),
                                     enablementActionComponentName =
                                         cursor.getString(enablementComponentNameColumnIndex),
+                                    configureIntent =
+                                        cursor
+                                            .getString(configureIntentColumnIndex)
+                                            ?.toIntent(affordanceId = affordanceId),
                                 )
                             )
                         }
@@ -357,16 +392,17 @@
             ?: emptyList()
     }
 
-    override fun observeAffordances():
-        Flow<List<KeyguardQuickAffordanceProviderClient.Affordance>> {
-        return observeUri(Contract.AffordanceTable.URI).map { queryAffordances() }
+    override fun observeAffordances(): Flow<List<CustomizationProviderClient.Affordance>> {
+        return observeUri(Contract.LockScreenQuickAffordances.AffordanceTable.URI).map {
+            queryAffordances()
+        }
     }
 
-    override suspend fun querySelections(): List<KeyguardQuickAffordanceProviderClient.Selection> {
+    override suspend fun querySelections(): List<CustomizationProviderClient.Selection> {
         return withContext(backgroundDispatcher) {
             context.contentResolver
                 .query(
-                    Contract.SelectionTable.URI,
+                    Contract.LockScreenQuickAffordances.SelectionTable.URI,
                     null,
                     null,
                     null,
@@ -375,11 +411,19 @@
                 ?.use { cursor ->
                     buildList {
                         val slotIdColumnIndex =
-                            cursor.getColumnIndex(Contract.SelectionTable.Columns.SLOT_ID)
+                            cursor.getColumnIndex(
+                                Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID
+                            )
                         val affordanceIdColumnIndex =
-                            cursor.getColumnIndex(Contract.SelectionTable.Columns.AFFORDANCE_ID)
+                            cursor.getColumnIndex(
+                                Contract.LockScreenQuickAffordances.SelectionTable.Columns
+                                    .AFFORDANCE_ID
+                            )
                         val affordanceNameColumnIndex =
-                            cursor.getColumnIndex(Contract.SelectionTable.Columns.AFFORDANCE_NAME)
+                            cursor.getColumnIndex(
+                                Contract.LockScreenQuickAffordances.SelectionTable.Columns
+                                    .AFFORDANCE_NAME
+                            )
                         if (
                             slotIdColumnIndex == -1 ||
                                 affordanceIdColumnIndex == -1 ||
@@ -390,7 +434,7 @@
 
                         while (cursor.moveToNext()) {
                             add(
-                                KeyguardQuickAffordanceProviderClient.Selection(
+                                CustomizationProviderClient.Selection(
                                     slotId = cursor.getString(slotIdColumnIndex),
                                     affordanceId = cursor.getString(affordanceIdColumnIndex),
                                     affordanceName = cursor.getString(affordanceNameColumnIndex),
@@ -403,8 +447,10 @@
             ?: emptyList()
     }
 
-    override fun observeSelections(): Flow<List<KeyguardQuickAffordanceProviderClient.Selection>> {
-        return observeUri(Contract.SelectionTable.URI).map { querySelections() }
+    override fun observeSelections(): Flow<List<CustomizationProviderClient.Selection>> {
+        return observeUri(Contract.LockScreenQuickAffordances.SelectionTable.URI).map {
+            querySelections()
+        }
     }
 
     override suspend fun deleteSelection(
@@ -413,9 +459,10 @@
     ) {
         withContext(backgroundDispatcher) {
             context.contentResolver.delete(
-                Contract.SelectionTable.URI,
-                "${Contract.SelectionTable.Columns.SLOT_ID} = ? AND" +
-                    " ${Contract.SelectionTable.Columns.AFFORDANCE_ID} = ?",
+                Contract.LockScreenQuickAffordances.SelectionTable.URI,
+                "${Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID} = ? AND" +
+                    " ${Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_ID}" +
+                    " = ?",
                 arrayOf(
                     slotId,
                     affordanceId,
@@ -429,8 +476,8 @@
     ) {
         withContext(backgroundDispatcher) {
             context.contentResolver.delete(
-                Contract.SelectionTable.URI,
-                Contract.SelectionTable.Columns.SLOT_ID,
+                Contract.LockScreenQuickAffordances.SelectionTable.URI,
+                Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID,
                 arrayOf(
                     slotId,
                 ),
@@ -473,7 +520,19 @@
             .onStart { emit(Unit) }
     }
 
+    private fun String.toIntent(
+        affordanceId: String,
+    ): Intent? {
+        return try {
+            Intent.parseUri(this, 0)
+        } catch (e: URISyntaxException) {
+            Log.w(TAG, "Cannot parse Uri into Intent for affordance with ID \"$affordanceId\"!")
+            null
+        }
+    }
+
     companion object {
+        private const val TAG = "CustomizationProviderClient"
         private const val SYSTEM_UI_PACKAGE_NAME = "com.android.systemui"
     }
 }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt
new file mode 100644
index 0000000..e4e9c46
--- /dev/null
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.shared.customization.data.content
+
+import android.content.ContentResolver
+import android.net.Uri
+
+/** Contract definitions for querying content about keyguard quick affordances. */
+object CustomizationProviderContract {
+
+    const val AUTHORITY = "com.android.systemui.customization"
+    const val PERMISSION = "android.permission.CUSTOMIZE_SYSTEM_UI"
+
+    private val BASE_URI: Uri =
+        Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(AUTHORITY).build()
+
+    /** Namespace for lock screen shortcut (quick affordance) tables. */
+    object LockScreenQuickAffordances {
+
+        const val NAMESPACE = "lockscreen_quickaffordance"
+
+        private val LOCK_SCREEN_QUICK_AFFORDANCE_BASE_URI: Uri =
+            BASE_URI.buildUpon().path(NAMESPACE).build()
+
+        fun qualifiedTablePath(tableName: String): String {
+            return "$NAMESPACE/$tableName"
+        }
+
+        /**
+         * Table for slots.
+         *
+         * Slots are positions where affordances can be placed on the lock screen. Affordances that
+         * are placed on slots are said to be "selected". The system supports the idea of multiple
+         * affordances per slot, though the implementation may limit the number of affordances on
+         * each slot.
+         *
+         * Supported operations:
+         * - Query - to know which slots are available, query the [SlotTable.URI] [Uri]. The result
+         * set will contain rows with the [SlotTable.Columns] columns.
+         */
+        object SlotTable {
+            const val TABLE_NAME = "slots"
+            val URI: Uri =
+                LOCK_SCREEN_QUICK_AFFORDANCE_BASE_URI.buildUpon().appendPath(TABLE_NAME).build()
+
+            object Columns {
+                /** String. Unique ID for this slot. */
+                const val ID = "id"
+                /** Integer. The maximum number of affordances that can be placed in the slot. */
+                const val CAPACITY = "capacity"
+            }
+        }
+
+        /**
+         * Table for affordances.
+         *
+         * Affordances are actions/buttons that the user can execute. They are placed on slots on
+         * the lock screen.
+         *
+         * Supported operations:
+         * - Query - to know about all the affordances that are available on the device, regardless
+         * of which ones are currently selected, query the [AffordanceTable.URI] [Uri]. The result
+         * set will contain rows, each with the columns specified in [AffordanceTable.Columns].
+         */
+        object AffordanceTable {
+            const val TABLE_NAME = "affordances"
+            val URI: Uri =
+                LOCK_SCREEN_QUICK_AFFORDANCE_BASE_URI.buildUpon().appendPath(TABLE_NAME).build()
+            const val ENABLEMENT_INSTRUCTIONS_DELIMITER = "]["
+            const val COMPONENT_NAME_SEPARATOR = "/"
+
+            object Columns {
+                /** String. Unique ID for this affordance. */
+                const val ID = "id"
+                /** String. User-visible name for this affordance. */
+                const val NAME = "name"
+                /**
+                 * Integer. Resource ID for the drawable to load for this affordance. This is a
+                 * resource ID from the system UI package.
+                 */
+                const val ICON = "icon"
+                /** Integer. `1` if the affordance is enabled or `0` if it disabled. */
+                const val IS_ENABLED = "is_enabled"
+                /**
+                 * String. List of strings, delimited by [ENABLEMENT_INSTRUCTIONS_DELIMITER] to be
+                 * shown to the user if the affordance is disabled and the user selects the
+                 * affordance.
+                 */
+                const val ENABLEMENT_INSTRUCTIONS = "enablement_instructions"
+                /**
+                 * String. Optional label for a button that, when clicked, opens a destination
+                 * activity where the user can re-enable the disabled affordance.
+                 */
+                const val ENABLEMENT_ACTION_TEXT = "enablement_action_text"
+                /**
+                 * String. Optional package name and activity action string, delimited by
+                 * [COMPONENT_NAME_SEPARATOR] to use with an `Intent` to start an activity that
+                 * opens a destination where the user can re-enable the disabled affordance.
+                 */
+                const val ENABLEMENT_COMPONENT_NAME = "enablement_action_intent"
+                /**
+                 * Byte array. Optional parcelled `Intent` to use to start an activity that can be
+                 * used to configure the affordance.
+                 */
+                const val CONFIGURE_INTENT = "configure_intent"
+            }
+        }
+
+        /**
+         * Table for selections.
+         *
+         * Selections are pairs of slot and affordance IDs.
+         *
+         * Supported operations:
+         * - Insert - to insert an affordance and place it in a slot, insert values for the columns
+         * into the [SelectionTable.URI] [Uri]. The maximum capacity rule is enforced by the system.
+         * Selecting a new affordance for a slot that is already full will automatically remove the
+         * oldest affordance from the slot.
+         * - Query - to know which affordances are set on which slots, query the
+         * [SelectionTable.URI] [Uri]. The result set will contain rows, each of which with the
+         * columns from [SelectionTable.Columns].
+         * - Delete - to unselect an affordance, removing it from a slot, delete from the
+         * [SelectionTable.URI] [Uri], passing in values for each column.
+         */
+        object SelectionTable {
+            const val TABLE_NAME = "selections"
+            val URI: Uri =
+                LOCK_SCREEN_QUICK_AFFORDANCE_BASE_URI.buildUpon().appendPath(TABLE_NAME).build()
+
+            object Columns {
+                /** String. Unique ID for the slot. */
+                const val SLOT_ID = "slot_id"
+                /** String. Unique ID for the selected affordance. */
+                const val AFFORDANCE_ID = "affordance_id"
+                /** String. Human-readable name for the affordance. */
+                const val AFFORDANCE_NAME = "affordance_name"
+            }
+        }
+    }
+
+    /**
+     * Table for flags.
+     *
+     * Flags are key-value pairs.
+     *
+     * Supported operations:
+     * - Query - to know the values of flags, query the [FlagsTable.URI] [Uri]. The result set will
+     * contain rows, each of which with the columns from [FlagsTable.Columns].
+     */
+    object FlagsTable {
+        const val TABLE_NAME = "flags"
+        val URI: Uri = BASE_URI.buildUpon().path(TABLE_NAME).build()
+
+        /** Flag denoting whether the Wallpaper Picker should use the new, revamped UI. */
+        const val FLAG_NAME_REVAMPED_WALLPAPER_UI = "revamped_wallpaper_ui"
+
+        /**
+         * Flag denoting whether the customizable lock screen quick affordances feature is enabled.
+         */
+        const val FLAG_NAME_CUSTOM_LOCK_SCREEN_QUICK_AFFORDANCES_ENABLED =
+            "is_custom_lock_screen_quick_affordances_feature_enabled"
+
+        /** Flag denoting whether the customizable clocks feature is enabled. */
+        const val FLAG_NAME_CUSTOM_CLOCKS_ENABLED = "is_custom_clocks_feature_enabled"
+
+        /** Flag denoting whether the Wallpaper preview should use the full screen UI. */
+        const val FLAG_NAME_WALLPAPER_FULLSCREEN_PREVIEW = "wallpaper_fullscreen_preview"
+
+        object Columns {
+            /** String. Unique ID for the flag. */
+            const val NAME = "name"
+            /** Int. Value of the flag. `1` means `true` and `0` means `false`. */
+            const val VALUE = "value"
+        }
+    }
+}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/FakeKeyguardQuickAffordanceProviderClient.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/FakeCustomizationProviderClient.kt
similarity index 71%
rename from packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/FakeKeyguardQuickAffordanceProviderClient.kt
rename to packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/FakeCustomizationProviderClient.kt
index ec5e703..f5a955d 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/FakeKeyguardQuickAffordanceProviderClient.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/FakeCustomizationProviderClient.kt
@@ -15,7 +15,7 @@
  *
  */
 
-package com.android.systemui.shared.quickaffordance.data.content
+package com.android.systemui.shared.customization.data.content
 
 import android.graphics.drawable.BitmapDrawable
 import android.graphics.drawable.Drawable
@@ -25,46 +25,46 @@
 import kotlinx.coroutines.flow.asStateFlow
 import kotlinx.coroutines.flow.combine
 
-class FakeKeyguardQuickAffordanceProviderClient(
-    slots: List<KeyguardQuickAffordanceProviderClient.Slot> =
+class FakeCustomizationProviderClient(
+    slots: List<CustomizationProviderClient.Slot> =
         listOf(
-            KeyguardQuickAffordanceProviderClient.Slot(
+            CustomizationProviderClient.Slot(
                 id = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
                 capacity = 1,
             ),
-            KeyguardQuickAffordanceProviderClient.Slot(
+            CustomizationProviderClient.Slot(
                 id = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
                 capacity = 1,
             ),
         ),
-    affordances: List<KeyguardQuickAffordanceProviderClient.Affordance> =
+    affordances: List<CustomizationProviderClient.Affordance> =
         listOf(
-            KeyguardQuickAffordanceProviderClient.Affordance(
+            CustomizationProviderClient.Affordance(
                 id = AFFORDANCE_1,
                 name = AFFORDANCE_1,
                 iconResourceId = 1,
             ),
-            KeyguardQuickAffordanceProviderClient.Affordance(
+            CustomizationProviderClient.Affordance(
                 id = AFFORDANCE_2,
                 name = AFFORDANCE_2,
                 iconResourceId = 2,
             ),
-            KeyguardQuickAffordanceProviderClient.Affordance(
+            CustomizationProviderClient.Affordance(
                 id = AFFORDANCE_3,
                 name = AFFORDANCE_3,
                 iconResourceId = 3,
             ),
         ),
-    flags: List<KeyguardQuickAffordanceProviderClient.Flag> =
+    flags: List<CustomizationProviderClient.Flag> =
         listOf(
-            KeyguardQuickAffordanceProviderClient.Flag(
+            CustomizationProviderClient.Flag(
                 name =
-                    KeyguardQuickAffordanceProviderContract.FlagsTable
+                    CustomizationProviderContract.FlagsTable
                         .FLAG_NAME_CUSTOM_LOCK_SCREEN_QUICK_AFFORDANCES_ENABLED,
                 value = true,
             )
         ),
-) : KeyguardQuickAffordanceProviderClient {
+) : CustomizationProviderClient {
 
     private val slots = MutableStateFlow(slots)
     private val affordances = MutableStateFlow(affordances)
@@ -85,37 +85,35 @@
         selections.value = selections.value.toMutableMap().apply { this[slotId] = affordances }
     }
 
-    override suspend fun querySlots(): List<KeyguardQuickAffordanceProviderClient.Slot> {
+    override suspend fun querySlots(): List<CustomizationProviderClient.Slot> {
         return slots.value
     }
 
-    override suspend fun queryFlags(): List<KeyguardQuickAffordanceProviderClient.Flag> {
+    override suspend fun queryFlags(): List<CustomizationProviderClient.Flag> {
         return flags.value
     }
 
-    override fun observeSlots(): Flow<List<KeyguardQuickAffordanceProviderClient.Slot>> {
+    override fun observeSlots(): Flow<List<CustomizationProviderClient.Slot>> {
         return slots.asStateFlow()
     }
 
-    override fun observeFlags(): Flow<List<KeyguardQuickAffordanceProviderClient.Flag>> {
+    override fun observeFlags(): Flow<List<CustomizationProviderClient.Flag>> {
         return flags.asStateFlow()
     }
 
-    override suspend fun queryAffordances():
-        List<KeyguardQuickAffordanceProviderClient.Affordance> {
+    override suspend fun queryAffordances(): List<CustomizationProviderClient.Affordance> {
         return affordances.value
     }
 
-    override fun observeAffordances():
-        Flow<List<KeyguardQuickAffordanceProviderClient.Affordance>> {
+    override fun observeAffordances(): Flow<List<CustomizationProviderClient.Affordance>> {
         return affordances.asStateFlow()
     }
 
-    override suspend fun querySelections(): List<KeyguardQuickAffordanceProviderClient.Selection> {
+    override suspend fun querySelections(): List<CustomizationProviderClient.Selection> {
         return toSelectionList(selections.value, affordances.value)
     }
 
-    override fun observeSelections(): Flow<List<KeyguardQuickAffordanceProviderClient.Selection>> {
+    override fun observeSelections(): Flow<List<CustomizationProviderClient.Selection>> {
         return combine(selections, affordances) { selections, affordances ->
             toSelectionList(selections, affordances)
         }
@@ -148,7 +146,7 @@
         flags.value =
             flags.value.toMutableList().apply {
                 removeIf { it.name == name }
-                add(KeyguardQuickAffordanceProviderClient.Flag(name = name, value = value))
+                add(CustomizationProviderClient.Flag(name = name, value = value))
             }
     }
 
@@ -157,29 +155,26 @@
             slots.value.toMutableList().apply {
                 val index = indexOfFirst { it.id == slotId }
                 check(index != -1) { "Slot with ID \"$slotId\" doesn't exist!" }
-                set(
-                    index,
-                    KeyguardQuickAffordanceProviderClient.Slot(id = slotId, capacity = capacity)
-                )
+                set(index, CustomizationProviderClient.Slot(id = slotId, capacity = capacity))
             }
     }
 
-    fun addAffordance(affordance: KeyguardQuickAffordanceProviderClient.Affordance): Int {
+    fun addAffordance(affordance: CustomizationProviderClient.Affordance): Int {
         affordances.value = affordances.value + listOf(affordance)
         return affordances.value.size - 1
     }
 
     private fun toSelectionList(
         selections: Map<String, List<String>>,
-        affordances: List<KeyguardQuickAffordanceProviderClient.Affordance>,
-    ): List<KeyguardQuickAffordanceProviderClient.Selection> {
+        affordances: List<CustomizationProviderClient.Affordance>,
+    ): List<CustomizationProviderClient.Selection> {
         return selections
             .map { (slotId, affordanceIds) ->
                 affordanceIds.map { affordanceId ->
                     val affordanceName =
                         affordances.find { it.id == affordanceId }?.name
                             ?: error("No affordance with ID of \"$affordanceId\"!")
-                    KeyguardQuickAffordanceProviderClient.Selection(
+                    CustomizationProviderClient.Selection(
                         slotId = slotId,
                         affordanceId = affordanceId,
                         affordanceName = affordanceName,
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/KeyguardQuickAffordanceProviderContract.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/KeyguardQuickAffordanceProviderContract.kt
deleted file mode 100644
index e197752..0000000
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/KeyguardQuickAffordanceProviderContract.kt
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package com.android.systemui.shared.quickaffordance.data.content
-
-import android.content.ContentResolver
-import android.net.Uri
-
-/** Contract definitions for querying content about keyguard quick affordances. */
-object KeyguardQuickAffordanceProviderContract {
-
-    const val AUTHORITY = "com.android.systemui.keyguard.quickaffordance"
-    const val PERMISSION = "android.permission.ACCESS_KEYGUARD_QUICK_AFFORDANCES"
-
-    private val BASE_URI: Uri =
-        Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(AUTHORITY).build()
-
-    /**
-     * Table for slots.
-     *
-     * Slots are positions where affordances can be placed on the lock screen. Affordances that are
-     * placed on slots are said to be "selected". The system supports the idea of multiple
-     * affordances per slot, though the implementation may limit the number of affordances on each
-     * slot.
-     *
-     * Supported operations:
-     * - Query - to know which slots are available, query the [SlotTable.URI] [Uri]. The result set
-     * will contain rows with the [SlotTable.Columns] columns.
-     */
-    object SlotTable {
-        const val TABLE_NAME = "slots"
-        val URI: Uri = BASE_URI.buildUpon().path(TABLE_NAME).build()
-
-        object Columns {
-            /** String. Unique ID for this slot. */
-            const val ID = "id"
-            /** Integer. The maximum number of affordances that can be placed in the slot. */
-            const val CAPACITY = "capacity"
-        }
-    }
-
-    /**
-     * Table for affordances.
-     *
-     * Affordances are actions/buttons that the user can execute. They are placed on slots on the
-     * lock screen.
-     *
-     * Supported operations:
-     * - Query - to know about all the affordances that are available on the device, regardless of
-     * which ones are currently selected, query the [AffordanceTable.URI] [Uri]. The result set will
-     * contain rows, each with the columns specified in [AffordanceTable.Columns].
-     */
-    object AffordanceTable {
-        const val TABLE_NAME = "affordances"
-        val URI: Uri = BASE_URI.buildUpon().path(TABLE_NAME).build()
-        const val ENABLEMENT_INSTRUCTIONS_DELIMITER = "]["
-        const val COMPONENT_NAME_SEPARATOR = "/"
-
-        object Columns {
-            /** String. Unique ID for this affordance. */
-            const val ID = "id"
-            /** String. User-visible name for this affordance. */
-            const val NAME = "name"
-            /**
-             * Integer. Resource ID for the drawable to load for this affordance. This is a resource
-             * ID from the system UI package.
-             */
-            const val ICON = "icon"
-            /** Integer. `1` if the affordance is enabled or `0` if it disabled. */
-            const val IS_ENABLED = "is_enabled"
-            /**
-             * String. List of strings, delimited by [ENABLEMENT_INSTRUCTIONS_DELIMITER] to be shown
-             * to the user if the affordance is disabled and the user selects the affordance. The
-             * first one is a title while the rest are the steps needed to re-enable the affordance.
-             */
-            const val ENABLEMENT_INSTRUCTIONS = "enablement_instructions"
-            /**
-             * String. Optional label for a button that, when clicked, opens a destination activity
-             * where the user can re-enable the disabled affordance.
-             */
-            const val ENABLEMENT_ACTION_TEXT = "enablement_action_text"
-            /**
-             * String. Optional package name and activity action string, delimited by
-             * [COMPONENT_NAME_SEPARATOR] to use with an `Intent` to start an activity that opens a
-             * destination where the user can re-enable the disabled affordance.
-             */
-            const val ENABLEMENT_COMPONENT_NAME = "enablement_action_intent"
-        }
-    }
-
-    /**
-     * Table for selections.
-     *
-     * Selections are pairs of slot and affordance IDs.
-     *
-     * Supported operations:
-     * - Insert - to insert an affordance and place it in a slot, insert values for the columns into
-     * the [SelectionTable.URI] [Uri]. The maximum capacity rule is enforced by the system.
-     * Selecting a new affordance for a slot that is already full will automatically remove the
-     * oldest affordance from the slot.
-     * - Query - to know which affordances are set on which slots, query the [SelectionTable.URI]
-     * [Uri]. The result set will contain rows, each of which with the columns from
-     * [SelectionTable.Columns].
-     * - Delete - to unselect an affordance, removing it from a slot, delete from the
-     * [SelectionTable.URI] [Uri], passing in values for each column.
-     */
-    object SelectionTable {
-        const val TABLE_NAME = "selections"
-        val URI: Uri = BASE_URI.buildUpon().path(TABLE_NAME).build()
-
-        object Columns {
-            /** String. Unique ID for the slot. */
-            const val SLOT_ID = "slot_id"
-            /** String. Unique ID for the selected affordance. */
-            const val AFFORDANCE_ID = "affordance_id"
-            /** String. Human-readable name for the affordance. */
-            const val AFFORDANCE_NAME = "affordance_name"
-        }
-    }
-
-    /**
-     * Table for flags.
-     *
-     * Flags are key-value pairs.
-     *
-     * Supported operations:
-     * - Query - to know the values of flags, query the [FlagsTable.URI] [Uri]. The result set will
-     * contain rows, each of which with the columns from [FlagsTable.Columns].
-     */
-    object FlagsTable {
-        const val TABLE_NAME = "flags"
-        val URI: Uri = BASE_URI.buildUpon().path(TABLE_NAME).build()
-
-        /** Flag denoting whether the Wallpaper Picker should use the new, revamped UI. */
-        const val FLAG_NAME_REVAMPED_WALLPAPER_UI = "revamped_wallpaper_ui"
-
-        /**
-         * Flag denoting whether the customizable lock screen quick affordances feature is enabled.
-         */
-        const val FLAG_NAME_CUSTOM_LOCK_SCREEN_QUICK_AFFORDANCES_ENABLED =
-            "is_custom_lock_screen_quick_affordances_feature_enabled"
-
-        /** Flag denoting whether the customizable clocks feature is enabled. */
-        const val FLAG_NAME_CUSTOM_CLOCKS_ENABLED = "is_custom_clocks_feature_enabled"
-
-        object Columns {
-            /** String. Unique ID for the flag. */
-            const val NAME = "name"
-            /** Int. Value of the flag. `1` means `true` and `0` means `false`. */
-            const val VALUE = "value"
-        }
-    }
-}
diff --git a/packages/SystemUI/docs/dagger.md b/packages/SystemUI/docs/dagger.md
index 8917013..9b4c21e 100644
--- a/packages/SystemUI/docs/dagger.md
+++ b/packages/SystemUI/docs/dagger.md
@@ -8,105 +8,110 @@
 
  - [User's guide](https://google.github.io/dagger/users-guide)
 
-TODO: Add some links.
-
 ## State of the world
 
-Dagger 2 has been turned on for SystemUI and a early first pass has been taken
-for converting everything in [Dependency.java](packages/systemui/src/com/android/systemui/Dependency.java)
-to use Dagger. Since a lot of SystemUI depends on Dependency, stubs have been added to Dependency 
-to proxy any gets through to the instances provided by dagger, this will allow migration of SystemUI 
-through a number of CLs.
+Dagger 2 has been turned on for SystemUI and much of
+[Dependency.java](../src/com/android/systemui/Dependency.java)
+has been converted to use Dagger. Since a lot of SystemUI depends on Dependency,
+stubs have been added to Dependency to proxy any gets through to the instances
+provided by dagger, this will allow migration of SystemUI through a number of CLs.
 
 ### How it works in SystemUI
 
+There are three high level "scopes" of concern in SystemUI. They all represent
+singleton scopes, but serve different purposes.
+
+* `@Singleton` - Instances that are shared everywhere. There isn't a  lot of
+   code in this scope. Things like the main thread, and Android Framework
+   provided instances mostly.
+* `@WMShell` - WindowManager related code in the SystemUI process. We don't
+   want this code relying on the rest of SystemUI, and we don't want the rest
+   of SystemUI peeking into its internals, so it runs in its own Subcomponent.
+* `@SysUISingleton` - Most of what would be considered "SystemUI". Most feature
+   work by SystemUI developers goes into this scope. Useful interfaces from
+   WindowManager are made available inside this Subcomponent.
+
+The root dagger graph is created by an instance of `SystemUIInitializer`.
+See [README.md](../README.md) for more details.
 For the classes that we're using in Dependency and are switching to dagger, the
 equivalent dagger version is using `@Singleton` and therefore only has one instance.
 To have the single instance span all of SystemUI and be easily accessible for
 other components, there is a single root `@Component` that exists that generates
-these. The component lives in [SystemUIFactory](packages/systemui/src/com/android/systemui/SystemUIFactory.java)
-and is called `SystemUIRootComponent`.
-
-```java
-
-@Singleton
-@Component(modules = {SystemUIFactory.class, DependencyProvider.class, DependencyBinder.class,
-        ContextHolder.class})
-public interface SystemUIRootComponent {
-    @Singleton
-    Dependency.DependencyInjector createDependency();
-}
-```
-
-The root component is composed of root modules, which in turn provide the global singleton 
-dependencies across all of SystemUI.
-
-- `SystemUIFactory` `@Provides` dependencies that need to be overridden by SystemUI
-variants (like other form factors e.g. Car). 
-
-- `DependencyBinder` creates the mapping from interfaces to implementation classes. 
-
-- `DependencyProvider` provides or binds any remaining depedencies required.
-
-### Adding injection to a new SystemUI object
-
-SystemUI object are made injectable by adding an entry in `SystemUIBinder`. SystemUIApplication uses
-information in that file to locate and construct an instance of the requested SystemUI class.
+these. The component lives in
+[ReferenceGlobalRootComponent.java](../src/com/android/systemui/dagger/ReferenceGlobalRootComponent.java).
 
 ### Adding a new injectable object
 
-First tag the constructor with `@Inject`. Also tag it with `@Singleton` if only one
-instance should be created.
+First annotate the constructor with `@Inject`. Also annotate it with
+`@SysUISingleton` if only one instance should be created.
 
-```java
-@Singleton
-public class SomethingController {
-  @Inject
-  public SomethingController(Context context,
-    @Named(MAIN_HANDLER_NAME) Handler mainHandler) {
-      // context and mainHandler will be automatically populated.
-  }
+```kotlin
+@SysUISingleton
+class FeatureStartable
+@Inject
+constructor(
+/* ... */
+) {
+    // ...
 }
 ```
 
-If you have an interface class and an implementation class, dagger needs to know
-how to map it. The simplest way to do this is to add an `@Provides` method to
-DependencyProvider. The type of the return value tells dagger which dependency it's providing.
+If you have an interface class and an implementation class, Dagger needs to
+know how to map it. The simplest way to do this is to add an `@Binds` method
+in a module. The type of the return value tells dagger which dependency it's
+providing:
 
-```java
-public class DependencyProvider {
-  //...
-  @Singleton
-  @Provides
-  public SomethingController provideSomethingController(Context context,
-      @Named(MAIN_HANDLER_NAME) Handler mainHandler) {
-    return new SomethingControllerImpl(context, mainHandler);
-  }
+```kotlin
+@Module
+abstract class FeatureModule {
+    @Binds
+    abstract fun bindsFeature(impl: FeatureImpl): Feature
 }
 ```
 
-If you need to access this from Dependency#get, then add an adapter to Dependency
-that maps to the instance provided by Dagger. The changes should be similar
-to the following diff.
+If you have a class that you want to make injectable that has can not
+be easily constructed by Dagger, write a `@Provides` method for it:
 
-```java
-public class Dependency {
-  //...
-  @Inject Lazy<SomethingController> mSomethingController;
-  //...
-  public void start() {
-    //...
-    mProviders.put(SomethingController.class, mSomethingController::get);
-  }
+```kotlin
+@Module
+abstract class FeatureModule {
+    @Module
+    companion object {
+        @Provides
+        fun providesFeature(ctx: Context): Feature {
+            return FeatureImpl.constructFromContext(ctx)
+        }
+    }
 }
 ```
 
+### Module Organization
+
+Please define your modules on _at least_ per-package level. If the scope of a
+package grows to encompass a great number of features, create per-feature
+modules.
+
+**Do not create catch-all modules.** Those quickly grow unwieldy and
+unmaintainable. Any that exist today should be refactored into obsolescence.
+
+You can then include your module in one of three places:
+
+1) Within another module that depends on it. Ideally, this creates a clean
+   dependency graph between features and utilities.
+2) For features that should exist in all versions of SystemUI (AOSP and
+   any variants), include the module in
+   [SystemUIModule.java](../src/com/android/systemui/dagger/SystemUIModule.java).
+3) For features that should exist only in AOSP, include the module in
+   [ReferenceSystemUIModule.java](../src/com/android/systemui/dagger/ReferenceSystemUIModule.java).
+   Similarly, if you are working on a custom version of SystemUI and have code
+   specific to your version, include it in a module specific to your version.
+
 ### Using injection with Fragments
 
 Fragments are created as part of the FragmentManager, so they need to be
 setup so the manager knows how to create them. To do that, add a method
 to com.android.systemui.fragments.FragmentService$FragmentCreator that
-returns your fragment class. Thats all thats required, once the method
+returns your fragment class. That is all that is required, once the method
 exists, FragmentService will automatically pick it up and use injection
 whenever your fragment needs to be created.
 
@@ -123,48 +128,11 @@
 FragmentHostManager.get(view).create(NavigationBarFragment.class);
 ```
 
-### Using injection with Views
-
-DO NOT ADD NEW VIEW INJECTION. VIEW INJECTION IS BEING ACTIVELY DEPRECATED.
-
-Needing to inject objects into your View's constructor generally implies you
-are doing more work in your presentation layer than is advisable.
-Instead, create an injected controller for you view, inject into the
-controller, and then attach the view to the controller after inflation.
-
-View injection generally causes headaches while testing, as inflating a view
-(which may in turn inflate other views) implicitly causes a Dagger graph to 
-be stood up, which may or may not contain the appropriately 
-faked/mocked/stubbed objects. It is a hard to control process.
-
 ## Updating Dagger2
 
 We depend on the Dagger source found in external/dagger2. We should automatically pick up on updates
 when that repository is updated.
-
-*Deprecated:*
-
-Binaries can be downloaded from https://repo1.maven.org/maven2/com/google/dagger/ and then loaded
-into
-[/prebuilts/tools/common/m2/repository/com/google/dagger/](http://cs/android/prebuilts/tools/common/m2/repository/com/google/dagger/)
-
-The following commands should work, substituting in the version that you are looking for:
-
-````
-cd prebuilts/tools/common/m2/repository/com/google/dagger/
-
-wget -r -np -nH --cut-dirs=4 -erobots=off -R "index.html*" -U "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" https://repo1.maven.org/maven2/com/google/dagger/dagger/2.28.1/
-
-wget -r -np -nH --cut-dirs=4 -erobots=off -R "index.html*" -U "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" https://repo1.maven.org/maven2/com/google/dagger/dagger-compiler/2.28.1/
-
-wget -r -np -nH --cut-dirs=4 -erobots=off -R "index.html*" -U "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" https://repo1.maven.org/maven2/com/google/dagger/dagger-spi/2.28.1/
-
-wget -r -np -nH --cut-dirs=4 -erobots=off -R "index.html*" -U "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" https://repo1.maven.org/maven2/com/google/dagger/dagger-producers/2.28.1/
-````
-
-Then update `prebuilts/tools/common/m2/Android.bp` to point at your new jars.
  
 ## TODO List
 
- - Eliminate usages of Dependency#get
- - Add links in above TODO
+ - Eliminate usages of Dependency#get: http://b/hotlists/3940788
diff --git a/packages/SystemUI/docs/demo_mode.md b/packages/SystemUI/docs/demo_mode.md
index 6cf7060..b2424f4 100644
--- a/packages/SystemUI/docs/demo_mode.md
+++ b/packages/SystemUI/docs/demo_mode.md
@@ -22,42 +22,42 @@
 <br/>
 Commands are sent as string extras with key ```command``` (required). Possible values are:
 
-Command              | Subcommand                 | Argument       | Description
----                  | ---                        | ---            | ---
-```enter```          |                            |                | Enters demo mode, bar state allowed to be modified (for convenience, any of the other non-exit commands will automatically flip demo mode on, no need to call this explicitly in practice)
-```exit```           |                            |                | Exits demo mode, bars back to their system-driven state
-```battery```        |                            |                | Control the battery display
-                     | ```level```                |                | Sets the battery level (0 - 100)
-                     | ```plugged```              |                | Sets charging state (```true```, ```false```)
-                     | ```powersave```            |                | Sets power save mode (```true```, ```anything else```)
-```network```        |                            |                | Control the RSSI display
-                     | ```airplane```             |                | ```show``` to show icon, any other value to hide
-                     | ```fully```                |                | Sets MCS state to fully connected (```true```, ```false```)
-                     | ```wifi```                 |                | ```show``` to show icon, any other value to hide
-                     |                            | ```level```    | Sets wifi level (null or 0-4)
-                     | ```mobile```               |                | ```show``` to show icon, any other value to hide
-                     |                            | ```datatype``` | Values: ```1x```, ```3g```, ```4g```, ```e```, ```g```, ```h```, ```lte```, ```roam```, any other value to hide
-                     |                            | ```level```    | Sets mobile signal strength level (null or 0-4)
-                     | ```carriernetworkchange``` |                | Sets mobile signal icon to carrier network change UX when disconnected (```show``` to show icon, any other value to hide)
-                     | ```sims```                 |                | Sets the number of sims (1-8)
-                     | ```nosim```                |                | ```show``` to show icon, any other value to hide
-```bars```           |                            |                | Control the visual style of the bars (opaque, translucent, etc)
-                     | ```mode```                 |                | Sets the bars visual style (opaque, translucent, semi-transparent)
-```status```         |                            |                | Control the system status icons
-                     | ```volume```               |                | Sets the icon in the volume slot (```silent```, ```vibrate```, any other value to hide)
-                     | ```bluetooth```            |                | Sets the icon in the bluetooth slot (```connected```, ```disconnected```, any other value to hide)
-                     | ```location```             |                | Sets the icon in the location slot (```show```, any other value to hide)
-                     | ```alarm```                |                | Sets the icon in the alarm_clock slot (```show```, any other value to hide)
-                     | ```sync```                 |                | Sets the icon in the sync_active slot (```show```, any other value to hide)
-                     | ```tty```                  |                | Sets the icon in the tty slot (```show```, any other value to hide)
-                     | ```eri```                  |                | Sets the icon in the cdma_eri slot (```show```, any other value to hide)
-                     | ```mute```                 |                | Sets the icon in the mute slot (```show```, any other value to hide)
-                     | ```speakerphone```         |                | Sets the icon in the speakerphone slot (```show```, any other value to hide)
-```notifications```  |                            |                | Control the notification icons
-                     | ```visible```              |                | ```false``` to hide the notification icons, any other value to show
-```clock```          |                            |                | Control the clock display
-                     | ```millis```               |                | Sets the time in millis
-                     | ```hhmm```                 |                | Sets the time in hh:mm
+| Command              | Subcommand                 | Argument       | Description
+| ---                  | ---                        | ---            | ---
+| ```enter```          |                            |                | Enters demo mode, bar state allowed to be modified (for convenience, any of the other non-exit commands will automatically flip demo mode on, no need to call this explicitly in practice)
+| ```exit```           |                            |                | Exits demo mode, bars back to their system-driven state
+| ```battery```        |                            |                | Control the battery display
+|                      | ```level```                |                | Sets the battery level (0 - 100)
+|                      | ```plugged```              |                | Sets charging state (```true```, ```false```)
+|                      | ```powersave```            |                | Sets power save mode (```true```, ```anything else```)
+| ```network```        |                            |                | Control the RSSI display
+|                      | ```airplane```             |                | ```show``` to show icon, any other value to hide
+|                      | ```fully```                |                | Sets MCS state to fully connected (```true```, ```false```)
+|                      | ```wifi```                 |                | ```show``` to show icon, any other value to hide
+|                      |                            | ```level```    | Sets wifi level (null or 0-4)
+|                      | ```mobile```               |                | ```show``` to show icon, any other value to hide
+|                      |                            | ```datatype``` | Values: ```1x```, ```3g```, ```4g```, ```e```, ```g```, ```h```, ```lte```, ```roam```, any other value to hide
+|                      |                            | ```level```    | Sets mobile signal strength level (null or 0-4)
+|                      | ```carriernetworkchange``` |                | Sets mobile signal icon to carrier network change UX when disconnected (```show``` to show icon, any other value to hide)
+|                      | ```sims```                 |                | Sets the number of sims (1-8)
+|                      | ```nosim```                |                | ```show``` to show icon, any other value to hide
+| ```bars```           |                            |                | Control the visual style of the bars (opaque, translucent, etc)
+|                      | ```mode```                 |                | Sets the bars visual style (opaque, translucent, semi-transparent)
+| ```status```         |                            |                | Control the system status icons
+|                      | ```volume```               |                | Sets the icon in the volume slot (```silent```, ```vibrate```, any other value to hide)
+|                      | ```bluetooth```            |                | Sets the icon in the bluetooth slot (```connected```, ```disconnected```, any other value to hide)
+|                      | ```location```             |                | Sets the icon in the location slot (```show```, any other value to hide)
+|                      | ```alarm```                |                | Sets the icon in the alarm_clock slot (```show```, any other value to hide)
+|                      | ```sync```                 |                | Sets the icon in the sync_active slot (```show```, any other value to hide)
+|                      | ```tty```                  |                | Sets the icon in the tty slot (```show```, any other value to hide)
+|                      | ```eri```                  |                | Sets the icon in the cdma_eri slot (```show```, any other value to hide)
+|                      | ```mute```                 |                | Sets the icon in the mute slot (```show```, any other value to hide)
+|                      | ```speakerphone```         |                | Sets the icon in the speakerphone slot (```show```, any other value to hide)
+| ```notifications```  |                            |                | Control the notification icons
+|                      | ```visible```              |                | ```false``` to hide the notification icons, any other value to show
+| ```clock```          |                            |                | Control the clock display
+|                      | ```millis```               |                | Sets the time in millis
+|                      | ```hhmm```                 |                | Sets the time in hh:mm
 
 ## Examples
 Enter demo mode
diff --git a/packages/SystemUI/docs/device-entry/quickaffordance.md b/packages/SystemUI/docs/device-entry/quickaffordance.md
index 01d4f00..ccb35fa 100644
--- a/packages/SystemUI/docs/device-entry/quickaffordance.md
+++ b/packages/SystemUI/docs/device-entry/quickaffordance.md
@@ -31,7 +31,7 @@
 ### Accessing Quick Affordance Data
 Quick Affordances structured data are exposed to other applications through the `KeyguardQuickAffordanceProvider` content provider which is owned by the System UI process.
 
-To access this content provider, applications must have the `android.permission.ACCESS_KEYGUARD_QUICK_AFFORDANCES` permission which is a signature and privileged permission, limiting access to system apps or apps signed by the same signature as System UI. The `KeyguardQuickAffordanceProviderContract` file defines the content provider schema for consumers.
+To access this content provider, applications must have the `android.permission.CUSTOMIZE_SYSTEM_UI` permission which is a signature and privileged permission, limiting access to system apps or apps signed by the same signature as System UI. The `KeyguardQuickAffordanceProviderContract` file defines the content provider schema for consumers.
 
 Generally speaking, there are three important tables served by the content provider: `slots`, `affordances`, and `selections`. There is also a `flags` table, but that's not important and may be ignored.
 
diff --git a/packages/SystemUI/docs/modern-architecture.png b/packages/SystemUI/docs/modern-architecture.png
new file mode 100644
index 0000000..2636362
--- /dev/null
+++ b/packages/SystemUI/docs/modern-architecture.png
Binary files differ
diff --git a/packages/SystemUI/docs/status-bar-data-pipeline.md b/packages/SystemUI/docs/status-bar-data-pipeline.md
new file mode 100644
index 0000000..9fcdce1
--- /dev/null
+++ b/packages/SystemUI/docs/status-bar-data-pipeline.md
@@ -0,0 +1,261 @@
+# Status Bar Data Pipeline
+
+## Background
+
+The status bar is the UI shown at the top of the user's screen that gives them
+information about the time, notifications, and system status like mobile
+conectivity and battery level. This document is about the implementation of the
+wifi and mobile system icons on the right side:
+
+![image of status bar](status-bar.png)
+
+In Android U, the data pipeline that determines what mobile and wifi icons to
+show in the status bar has been re-written with a new architecture. This format
+generally follows Android best practices to
+[app architecture](https://developer.android.com/topic/architecture#recommended-app-arch).
+This document serves as a guide for the new architecture, and as a guide for how
+OEMs can add customizations to the new architecture.
+
+## Architecture
+
+In the new architecture, there is a separate pipeline for each type of icon. For
+Android U, **only the wifi icon and mobile icons have been implemented in the
+new architecture**.
+
+As shown in the Android best practices guide, each new pipeline has a data
+layer, a domain layer, and a UI layer:
+
+![diagram of UI, domain, and data layers](modern-architecture.png)
+
+The classes in the data layer are `repository` instances. The classes in the
+domain layer are `interactor` instances. The classes in the UI layer are
+`viewmodel` instances and `viewbinder` instances. In this document, "repository"
+and "data layer" will be used interchangably (and the same goes for the other
+layers).
+
+The wifi logic is in `statusbar/pipeline/wifi` and the mobile logic is in
+`statusbar/pipeline/mobile`.
+
+#### Repository (data layer)
+
+System callbacks, broadcast receivers, configuration values are all defined
+here, and exposed through the appropriate interface. Where appropriate, we
+define `Model` objects at this layer so that clients do not have to rely on
+system-defined interfaces.
+
+#### Interactor (domain layer)
+
+Here is where we define the business logic and transform the data layer objects
+into something consumable by the ViewModel classes. For example,
+`MobileIconsInteractor` defines the CBRS filtering logic by exposing a
+`filteredSubscriptions` list.
+
+#### ViewModel (UI layer)
+
+View models should define the final piece of business logic mapping to UI logic.
+For example, the mobile view model checks the `IconInteractor.isRoaming` flow to
+decide whether or not to show the roaming indicator.
+
+#### ViewBinder
+
+These have already been implemented and configured. ViewBinders replace the old
+`applyMobileState` mechanism that existed in the `IconManager` classes of the
+old pipeline. A view binder associates a ViewModel with a View, and keeps the
+view up-to-date with the most recent information from the model.
+
+Any new fields added to the ViewModel classes need to be equivalently bound to
+the view here.
+
+### Putting it all together
+
+Putting that altogether, we have this overall architecture diagram for the
+icons:
+
+![diagram of wifi and mobile pipelines](status-bar-pipeline.png)
+
+### Mobile icons architecture
+
+Because there can be multiple mobile connections at the same time, the mobile
+pipeline is split up hierarchically. At each level (data, domain, and UI), there
+is a singleton parent class that manages information relevant to **all** mobile
+connections, and multiple instances of child classes that manage information for
+a **single** mobile connection.
+
+For example, `MobileConnectionsRepository` is a singleton at the data layer that
+stores information relevant to **all** mobile connections, and it also manages a
+list of child `MobileConnectionRepository` classes. `MobileConnectionRepository`
+is **not** a singleton, and each individual `MobileConnectionRepository`
+instance fully qualifies the state of a **single** connection. This pattern is
+repeated at the `Interactor` and `ViewModel` layers for mobile.
+
+![diagram of mobile parent child relationship](status-bar-mobile-pipeline.png)
+
+Note: Since there is at most one wifi connection, the wifi pipeline is not split
+up in the same way.
+
+## Customizations
+
+The new pipeline completely replaces these classes:
+
+*   `WifiStatusTracker`
+*   `MobileStatusTracker`
+*   `NetworkSignalController` and `NetworkSignalControllerImpl`
+*   `MobileSignalController`
+*   `WifiSignalController`
+*   `StatusBarSignalPolicy` (including `SignalIconState`, `MobileIconState`, and
+    `WifiIconState`)
+
+Any customizations in any of these classes will need to be migrated to the new
+pipeline. As a general rule, any change that would have gone into
+`NetworkControllerImpl` would be done in `MobileConnectionsRepository`, and any
+change for `MobileSignalController` can be done in `MobileConnectionRepository`
+(see above on the relationship between those repositories).
+
+### Sample customization: New service
+
+Some customizations require listening to additional services to get additional
+data. This new architecture makes it easy to add additional services to the
+status bar data pipeline to get icon customizations.
+
+Below is a general guide to how a new service should be added. However, there
+may be exceptions to this guide for specific use cases.
+
+1.  In the data layer (`repository` classes), add a new `StateFlow` that listens
+    to the service:
+
+    ```kotlin
+    class MobileConnectionsRepositoryImpl {
+      ...
+      val fooVal: StateFlow<Int> =
+        conflatedCallbackFlow {
+          val callback = object : FooServiceCallback(), FooListener {
+            override fun onFooChanged(foo: Int) {
+              trySend(foo)
+            }
+          }
+
+          fooService.registerCallback(callback)
+
+          awaitClose { fooService.unregisterCallback(callback) }
+        }
+          .stateIn(scope, started = SharingStarted.WhileSubscribed(), FOO_DEFAULT_VAL)
+    }
+    ```
+
+1.  In the domain layer (`interactor` classes), either use this new flow to
+    process values, or just expose the flow as-is for the UI layer.
+
+    For example, if `bar` should only be true when `foo` is positive:
+
+    ```kotlin
+    class MobileIconsInteractor {
+      ...
+      val bar: StateFlow<Boolean> =
+        mobileConnectionsRepo
+          .mapLatest { foo -> foo > 0 }
+          .stateIn(scope, SharingStarted.WhileSubscribed(), initialValue = false)
+    }
+    ```
+
+1.  In the UI layer (`viewmodel` classes), update the existing flows to process
+    the new value from the interactor.
+
+    For example, if the icon should be hidden when `bar` is true:
+
+    ```kotlin
+    class MobileIconViewModel {
+      ...
+      iconId: Flow<Int> = combine(
+        iconInteractor.level,
+        iconInteractor.numberOfLevels,
+        iconInteractor.bar,
+    ) { level, numberOfLevels, bar ->
+      if (bar) {
+        null
+      } else {
+        calcIcon(level, numberOfLevels)
+      }
+    }
+    ```
+
+## Demo mode
+
+SystemUI demo mode is a first-class citizen in the new pipeline. It is
+implemented as an entirely separate repository,
+`DemoMobileConnectionsRepository`. When the system moves into demo mode, the
+implementation of the data layer is switched to the demo repository via the
+`MobileRepositorySwitcher` class.
+
+Because the demo mode repositories implement the same interfaces as the
+production classes, any changes made above will have to be implemented for demo
+mode as well.
+
+1.  Following from above, if `fooVal` is added to the
+    `MobileConnectionsRepository` interface:
+
+    ```kotlin
+    class DemoMobileConnectionsRepository {
+      private val _fooVal = MutableStateFlow(FOO_DEFAULT_VALUE)
+      override val fooVal: StateFlow<Int> = _fooVal.asStateFlow()
+
+      // Process the state. **See below on how to add the command to the CLI**
+      fun processEnabledMobileState(state: Mobile) {
+        ...
+        _fooVal.value = state.fooVal
+      }
+    }
+    ```
+
+1.  (Optional) If you want to enable the command line interface for setting and
+    testing this value in demo mode, you can add parsing logic to
+    `DemoModeMobileConnectionDataSource` and `FakeNetworkEventModel`:
+
+    ```kotlin
+    sealed interface FakeNetworkEventModel {
+      data class Mobile(
+      ...
+      // Add new fields here
+      val fooVal: Int?
+      )
+    }
+    ```
+
+    ```kotlin
+    class DemoModeMobileConnectionDataSource {
+      // Currently, the demo commands are implemented as an extension function on Bundle
+      private fun Bundle.activeMobileEvent(): Mobile {
+        ...
+        val fooVal = getString("fooVal")?.toInt()
+        return Mobile(
+          ...
+          fooVal = fooVal,
+        )
+      }
+    }
+    ```
+
+If step 2 is implemented, then you will be able to pass demo commands via the
+command line:
+
+```
+adb shell am broadcast -a com.android.systemui.demo -e command network -e mobile show -e fooVal <test value>
+```
+
+## Migration plan
+
+For Android U, the new pipeline will be enabled and default. However, the old
+pipeline code will still be around just in case the new pipeline doesn’t do well
+in the testing phase.
+
+For Android V, the old pipeline will be completely removed and the new pipeline
+will be the one source of truth.
+
+Our ask for OEMs is to default to using the new pipeline in Android U. If there
+are customizations that seem difficult to migrate over to the new pipeline,
+please file a bug with us and we’d be more than happy to consult on the best
+solution. The new pipeline was designed with customizability in mind, so our
+hope is that working the new pipeline will be easier and faster.
+
+Note: The new pipeline currently only supports the wifi and mobile icons. The
+other system status bar icons may be migrated to a similar architecture in the
+future.
diff --git a/packages/SystemUI/docs/status-bar-mobile-pipeline.png b/packages/SystemUI/docs/status-bar-mobile-pipeline.png
new file mode 100644
index 0000000..620563d
--- /dev/null
+++ b/packages/SystemUI/docs/status-bar-mobile-pipeline.png
Binary files differ
diff --git a/packages/SystemUI/docs/status-bar-pipeline.png b/packages/SystemUI/docs/status-bar-pipeline.png
new file mode 100644
index 0000000..1c568c9
--- /dev/null
+++ b/packages/SystemUI/docs/status-bar-pipeline.png
Binary files differ
diff --git a/packages/SystemUI/docs/status-bar.png b/packages/SystemUI/docs/status-bar.png
new file mode 100644
index 0000000..3a5af0e
--- /dev/null
+++ b/packages/SystemUI/docs/status-bar.png
Binary files differ
diff --git a/packages/SystemUI/ktfmt_includes.txt b/packages/SystemUI/ktfmt_includes.txt
index b75c5c7..1f00812 100644
--- a/packages/SystemUI/ktfmt_includes.txt
+++ b/packages/SystemUI/ktfmt_includes.txt
@@ -1,8 +1,5 @@
 +packages/SystemUI
--packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt
--packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
 -packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
--packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
 -packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
 -packages/SystemUI/checks/src/com/android/internal/systemui/lint/BindServiceViaContextDetector.kt
 -packages/SystemUI/checks/src/com/android/internal/systemui/lint/BroadcastSentViaContextDetector.kt
@@ -322,8 +319,8 @@
 -packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt
 -packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
 -packages/SystemUI/src/com/android/systemui/statusbar/gesture/GenericGestureDetector.kt
--packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeStatusBarAwayGestureHandler.kt
--packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeStatusBarAwayGestureLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeUpGestureHandler.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeUpGestureLogger.kt
 -packages/SystemUI/src/com/android/systemui/statusbar/gesture/TapGestureDetector.kt
 -packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
 -packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt
@@ -460,7 +457,6 @@
 -packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt
 -packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiActivityModel.kt
 -packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt
--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
 -packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt
 -packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt
 -packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt
@@ -486,7 +482,6 @@
 -packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowStateController.kt
 -packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewInfo.kt
 -packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt
--packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
 -packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarRootView.kt
 -packages/SystemUI/src/com/android/systemui/toast/ToastDefaultAnimation.kt
 -packages/SystemUI/src/com/android/systemui/toast/ToastLogger.kt
@@ -752,7 +747,7 @@
 -packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/panelstate/ShadeExpansionStateManagerTest.kt
 -packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherControllerOldImplTest.kt
 -packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLoggerTest.kt
--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
 -packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt
 -packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
 -packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
diff --git a/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt b/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt
index dee0f5c..314c736 100644
--- a/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt
+++ b/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt
@@ -80,6 +80,7 @@
 internal class HueVibrantSecondary() : Hue {
     val hueToRotations = listOf(Pair(0, 18), Pair(41, 15), Pair(61, 10), Pair(101, 12),
             Pair(131, 15), Pair(181, 18), Pair(251, 15), Pair(301, 12), Pair(360, 12))
+
     override fun get(sourceColor: Cam): Double {
         return getHueRotation(sourceColor.hue, hueToRotations)
     }
@@ -88,6 +89,7 @@
 internal class HueVibrantTertiary() : Hue {
     val hueToRotations = listOf(Pair(0, 35), Pair(41, 30), Pair(61, 20), Pair(101, 25),
             Pair(131, 30), Pair(181, 35), Pair(251, 30), Pair(301, 25), Pair(360, 25))
+
     override fun get(sourceColor: Cam): Double {
         return getHueRotation(sourceColor.hue, hueToRotations)
     }
@@ -96,6 +98,7 @@
 internal class HueExpressiveSecondary() : Hue {
     val hueToRotations = listOf(Pair(0, 45), Pair(21, 95), Pair(51, 45), Pair(121, 20),
             Pair(151, 45), Pair(191, 90), Pair(271, 45), Pair(321, 45), Pair(360, 45))
+
     override fun get(sourceColor: Cam): Double {
         return getHueRotation(sourceColor.hue, hueToRotations)
     }
@@ -104,6 +107,7 @@
 internal class HueExpressiveTertiary() : Hue {
     val hueToRotations = listOf(Pair(0, 120), Pair(21, 120), Pair(51, 20), Pair(121, 45),
             Pair(151, 20), Pair(191, 15), Pair(271, 20), Pair(321, 120), Pair(360, 120))
+
     override fun get(sourceColor: Cam): Double {
         return getHueRotation(sourceColor.hue, hueToRotations)
     }
@@ -148,11 +152,11 @@
 }
 
 internal class CoreSpec(
-    val a1: TonalSpec,
-    val a2: TonalSpec,
-    val a3: TonalSpec,
-    val n1: TonalSpec,
-    val n2: TonalSpec
+        val a1: TonalSpec,
+        val a2: TonalSpec,
+        val a3: TonalSpec,
+        val n1: TonalSpec,
+        val n2: TonalSpec
 )
 
 enum class Style(internal val coreSpec: CoreSpec) {
@@ -214,51 +218,86 @@
     )),
 }
 
+class TonalPalette {
+    val shadeKeys = listOf(10, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000)
+    val allShades: List<Int>
+    val allShadesMapped: Map<Int, Int>
+    val baseColor: Int
+
+    internal constructor(spec: TonalSpec, seedColor: Int) {
+        val seedCam = Cam.fromInt(seedColor)
+        allShades = spec.shades(seedCam)
+        allShadesMapped = shadeKeys.zip(allShades).toMap()
+
+        val h = spec.hue.get(seedCam).toFloat()
+        val c = spec.chroma.get(seedCam).toFloat()
+        baseColor = ColorUtils.CAMToColor(h, c, CamUtils.lstarFromInt(seedColor))
+    }
+
+    val s10: Int get() = this.allShades[0]
+    val s50: Int get() = this.allShades[1]
+    val s100: Int get() = this.allShades[2]
+    val s200: Int get() = this.allShades[3]
+    val s300: Int get() = this.allShades[4]
+    val s400: Int get() = this.allShades[5]
+    val s500: Int get() = this.allShades[6]
+    val s600: Int get() = this.allShades[7]
+    val s700: Int get() = this.allShades[8]
+    val s800: Int get() = this.allShades[9]
+    val s900: Int get() = this.allShades[10]
+    val s1000: Int get() = this.allShades[11]
+}
+
 class ColorScheme(
-    @ColorInt val seed: Int,
-    val darkTheme: Boolean,
-    val style: Style = Style.TONAL_SPOT
+        @ColorInt val seed: Int,
+        val darkTheme: Boolean,
+        val style: Style = Style.TONAL_SPOT
 ) {
 
-    val accent1: List<Int>
-    val accent2: List<Int>
-    val accent3: List<Int>
-    val neutral1: List<Int>
-    val neutral2: List<Int>
+    val accent1: TonalPalette
+    val accent2: TonalPalette
+    val accent3: TonalPalette
+    val neutral1: TonalPalette
+    val neutral2: TonalPalette
 
     constructor(@ColorInt seed: Int, darkTheme: Boolean) :
             this(seed, darkTheme, Style.TONAL_SPOT)
 
     @JvmOverloads
     constructor(
-        wallpaperColors: WallpaperColors,
-        darkTheme: Boolean,
-        style: Style = Style.TONAL_SPOT
+            wallpaperColors: WallpaperColors,
+            darkTheme: Boolean,
+            style: Style = Style.TONAL_SPOT
     ) :
             this(getSeedColor(wallpaperColors, style != Style.CONTENT), darkTheme, style)
 
+    val allHues: List<TonalPalette>
+        get() {
+            return listOf(accent1, accent2, accent3, neutral1, neutral2)
+        }
+
     val allAccentColors: List<Int>
         get() {
             val allColors = mutableListOf<Int>()
-            allColors.addAll(accent1)
-            allColors.addAll(accent2)
-            allColors.addAll(accent3)
+            allColors.addAll(accent1.allShades)
+            allColors.addAll(accent2.allShades)
+            allColors.addAll(accent3.allShades)
             return allColors
         }
 
     val allNeutralColors: List<Int>
         get() {
             val allColors = mutableListOf<Int>()
-            allColors.addAll(neutral1)
-            allColors.addAll(neutral2)
+            allColors.addAll(neutral1.allShades)
+            allColors.addAll(neutral2.allShades)
             return allColors
         }
 
     val backgroundColor
-        get() = ColorUtils.setAlphaComponent(if (darkTheme) neutral1[8] else neutral1[0], 0xFF)
+        get() = ColorUtils.setAlphaComponent(if (darkTheme) neutral1.s700 else neutral1.s10, 0xFF)
 
     val accentColor
-        get() = ColorUtils.setAlphaComponent(if (darkTheme) accent1[2] else accent1[6], 0xFF)
+        get() = ColorUtils.setAlphaComponent(if (darkTheme) accent1.s100 else accent1.s500, 0xFF)
 
     init {
         val proposedSeedCam = Cam.fromInt(seed)
@@ -269,24 +308,26 @@
         } else {
             seed
         }
-        val camSeed = Cam.fromInt(seedArgb)
-        accent1 = style.coreSpec.a1.shades(camSeed)
-        accent2 = style.coreSpec.a2.shades(camSeed)
-        accent3 = style.coreSpec.a3.shades(camSeed)
-        neutral1 = style.coreSpec.n1.shades(camSeed)
-        neutral2 = style.coreSpec.n2.shades(camSeed)
+
+        accent1 = TonalPalette(style.coreSpec.a1, seedArgb)
+        accent2 = TonalPalette(style.coreSpec.a2, seedArgb)
+        accent3 = TonalPalette(style.coreSpec.a3, seedArgb)
+        neutral1 = TonalPalette(style.coreSpec.n1, seedArgb)
+        neutral2 = TonalPalette(style.coreSpec.n2, seedArgb)
     }
 
+    val shadeCount get() = this.accent1.allShades.size
+
     override fun toString(): String {
         return "ColorScheme {\n" +
                 "  seed color: ${stringForColor(seed)}\n" +
                 "  style: $style\n" +
                 "  palettes: \n" +
-                "  ${humanReadable("PRIMARY", accent1)}\n" +
-                "  ${humanReadable("SECONDARY", accent2)}\n" +
-                "  ${humanReadable("TERTIARY", accent3)}\n" +
-                "  ${humanReadable("NEUTRAL", neutral1)}\n" +
-                "  ${humanReadable("NEUTRAL VARIANT", neutral2)}\n" +
+                "  ${humanReadable("PRIMARY", accent1.allShades)}\n" +
+                "  ${humanReadable("SECONDARY", accent2.allShades)}\n" +
+                "  ${humanReadable("TERTIARY", accent3.allShades)}\n" +
+                "  ${humanReadable("NEUTRAL", neutral1.allShades)}\n" +
+                "  ${humanReadable("NEUTRAL VARIANT", neutral2.allShades)}\n" +
                 "}"
     }
 
@@ -385,7 +426,8 @@
                     val existingSeedNearby = seeds.find {
                         val hueA = intToCam[int]!!.hue
                         val hueB = intToCam[it]!!.hue
-                        hueDiff(hueA, hueB) < i } != null
+                        hueDiff(hueA, hueB) < i
+                    } != null
                     if (existingSeedNearby) {
                         continue
                     }
@@ -460,9 +502,9 @@
         }
 
         private fun huePopulations(
-            camByColor: Map<Int, Cam>,
-            populationByColor: Map<Int, Double>,
-            filter: Boolean = true
+                camByColor: Map<Int, Cam>,
+                populationByColor: Map<Int, Double>,
+                filter: Boolean = true
         ): List<Double> {
             val huePopulation = List(size = 360, init = { 0.0 }).toMutableList()
 
diff --git a/packages/SystemUI/plugin/Android.bp b/packages/SystemUI/plugin/Android.bp
index 7709f21..fb1c454 100644
--- a/packages/SystemUI/plugin/Android.bp
+++ b/packages/SystemUI/plugin/Android.bp
@@ -29,6 +29,7 @@
         "src/**/*.java",
         "src/**/*.kt",
         "bcsmartspace/src/**/*.java",
+        "bcsmartspace/src/**/*.kt",
     ],
 
     static_libs: [
diff --git a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceConfigPlugin.kt b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceConfigPlugin.kt
new file mode 100644
index 0000000..509f022
--- /dev/null
+++ b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceConfigPlugin.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.plugins
+
+// TODO(b/265360975): Evaluate this plugin approach.
+/** Plugin to provide BC smartspace configuration */
+interface BcSmartspaceConfigPlugin {
+    /** Gets default date/weather disabled status. */
+    val isDefaultDateWeatherDisabled: Boolean
+}
diff --git a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
index eac765a..bc6e5ec 100644
--- a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
+++ b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
@@ -40,6 +40,11 @@
  */
 @ProvidesInterface(action = BcSmartspaceDataPlugin.ACTION, version = BcSmartspaceDataPlugin.VERSION)
 public interface BcSmartspaceDataPlugin extends Plugin {
+    String UI_SURFACE_LOCK_SCREEN_AOD = "lockscreen";
+    String UI_SURFACE_HOME_SCREEN = "home";
+    String UI_SURFACE_MEDIA = "media_data_manager";
+    String UI_SURFACE_DREAM = "dream";
+
     String ACTION = "com.android.systemui.action.PLUGIN_BC_SMARTSPACE_DATA";
     int VERSION = 1;
     String TAG = "BcSmartspaceDataPlugin";
@@ -89,6 +94,11 @@
         void registerDataProvider(BcSmartspaceDataPlugin plugin);
 
         /**
+         * Sets {@link BcSmartspaceConfigPlugin}.
+         */
+        void registerConfigProvider(BcSmartspaceConfigPlugin configProvider);
+
+        /**
          * Primary color for unprotected text
          */
         void setPrimaryTextColor(int color);
@@ -100,6 +110,11 @@
         void setIsDreaming(boolean isDreaming);
 
         /**
+         * Set the UI surface for the cards. Should be called immediately after the view is created.
+         */
+        void setUiSurface(String uiSurface);
+
+        /**
          * Range [0.0 - 1.0] when transitioning from Lockscreen to/from AOD
          */
         void setDozeAmount(float amount);
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 66e44b9..a2a0709 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
@@ -71,9 +71,6 @@
 
     /** Optional method for dumping debug information */
     fun dump(pw: PrintWriter) {}
-
-    /** Optional method for debug logging */
-    fun setLogBuffer(logBuffer: LogBuffer) {}
 }
 
 /** Interface for a specific clock face version rendered by the clock */
@@ -83,6 +80,9 @@
 
     /** Events specific to this clock face */
     val events: ClockFaceEvents
+
+    /** Some clocks may log debug information */
+    var logBuffer: LogBuffer?
 }
 
 /** Events that should call when various rendering parameters change */
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/ConstantStringsLogger.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/ConstantStringsLogger.kt
new file mode 100644
index 0000000..f95b187
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/ConstantStringsLogger.kt
@@ -0,0 +1,33 @@
+/*
+ * 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.plugins.log
+
+import com.google.errorprone.annotations.CompileTimeConstant
+
+/**
+ * Handy for adding basic logging with CompileTimeConstant strings - so logging with no variables.
+ * Most likely you want to delegate it to [ConstantStringsLoggerImpl].
+ */
+interface ConstantStringsLogger {
+    fun v(@CompileTimeConstant msg: String)
+
+    fun d(@CompileTimeConstant msg: String)
+
+    fun w(@CompileTimeConstant msg: String)
+
+    fun e(@CompileTimeConstant msg: String)
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/ConstantStringsLoggerImpl.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/ConstantStringsLoggerImpl.kt
new file mode 100644
index 0000000..91b39e6
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/ConstantStringsLoggerImpl.kt
@@ -0,0 +1,29 @@
+/*
+ * 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.plugins.log
+
+import com.google.errorprone.annotations.CompileTimeConstant
+
+class ConstantStringsLoggerImpl(val buffer: LogBuffer, val tag: String) : ConstantStringsLogger {
+    override fun v(@CompileTimeConstant msg: String) = buffer.log(tag, LogLevel.VERBOSE, msg)
+
+    override fun d(@CompileTimeConstant msg: String) = buffer.log(tag, LogLevel.DEBUG, msg)
+
+    override fun w(@CompileTimeConstant msg: String) = buffer.log(tag, LogLevel.WARNING, msg)
+
+    override fun e(@CompileTimeConstant msg: String) = buffer.log(tag, LogLevel.ERROR, msg)
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/LogBuffer.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/LogBuffer.kt
index 6436dcb..e99b214 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/LogBuffer.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/LogBuffer.kt
@@ -159,8 +159,13 @@
      * bug report more actionable, so using the [log] with a messagePrinter to add more detail to
      * every log may do more to improve overall logging than adding more logs with this method.
      */
-    fun log(tag: String, level: LogLevel, @CompileTimeConstant message: String) =
-        log(tag, level, { str1 = message }, { str1!! })
+    @JvmOverloads
+    fun log(
+        tag: String,
+        level: LogLevel,
+        @CompileTimeConstant message: String,
+        exception: Throwable? = null,
+    ) = log(tag, level, { str1 = message }, { str1!! }, exception)
 
     /**
      * You should call [log] instead of this method.
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/LogcatEchoTrackerDebug.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/LogcatEchoTrackerDebug.kt
index d3fabac..faf1b78 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/LogcatEchoTrackerDebug.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/LogcatEchoTrackerDebug.kt
@@ -21,6 +21,7 @@
 import android.net.Uri
 import android.os.Handler
 import android.os.Looper
+import android.os.Trace
 import android.provider.Settings
 
 /**
@@ -51,14 +52,21 @@
         }
     }
 
+    private fun clearCache() {
+        Trace.beginSection("LogcatEchoTrackerDebug#clearCache")
+        cachedBufferLevels.clear()
+        Trace.endSection()
+    }
+
     private fun attach(mainLooper: Looper) {
+        Trace.beginSection("LogcatEchoTrackerDebug#attach")
         contentResolver.registerContentObserver(
             Settings.Global.getUriFor(BUFFER_PATH),
             true,
             object : ContentObserver(Handler(mainLooper)) {
                 override fun onChange(selfChange: Boolean, uri: Uri?) {
                     super.onChange(selfChange, uri)
-                    cachedBufferLevels.clear()
+                    clearCache()
                 }
             }
         )
@@ -69,10 +77,11 @@
             object : ContentObserver(Handler(mainLooper)) {
                 override fun onChange(selfChange: Boolean, uri: Uri?) {
                     super.onChange(selfChange, uri)
-                    cachedTagLevels.clear()
+                    clearCache()
                 }
             }
         )
+        Trace.endSection()
     }
 
     /** Whether [bufferName] should echo messages of [level] or higher to logcat. */
@@ -97,9 +106,12 @@
 
     private fun readSetting(path: String): LogLevel {
         return try {
+            Trace.beginSection("LogcatEchoTrackerDebug#readSetting")
             parseProp(Settings.Global.getString(contentResolver, path))
         } catch (_: Settings.SettingNotFoundException) {
             DEFAULT_LEVEL
+        } finally {
+            Trace.endSection()
         }
     }
 
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index f96644f..5fc9193 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -16,6 +16,50 @@
   public <init>();
 }
 
+# Needed to ensure callback field references are kept in their respective
+# owning classes when the downstream callback registrars only store weak refs.
+# TODO(b/264686688): Handle these cases with more targeted annotations.
+-keepclassmembers,allowaccessmodification class com.android.systemui.**, com.android.keyguard.** {
+  private com.android.keyguard.KeyguardUpdateMonitorCallback *;
+  private com.android.systemui.privacy.PrivacyConfig$Callback *;
+  private com.android.systemui.privacy.PrivacyItemController$Callback *;
+  private com.android.systemui.settings.UserTracker$Callback *;
+  private com.android.systemui.statusbar.phone.StatusBarWindowCallback *;
+  private com.android.systemui.util.service.Observer$Callback *;
+  private com.android.systemui.util.service.ObservableServiceConnection$Callback *;
+}
+# Note that these rules are temporary companions to the above rules, required
+# for cases like Kotlin where fields with anonymous types use the anonymous type
+# rather than the supertype.
+-if class * extends com.android.keyguard.KeyguardUpdateMonitorCallback
+-keepclassmembers,allowaccessmodification class com.android.systemui.**, com.android.keyguard.** {
+  <1> *;
+}
+-if class * extends com.android.systemui.privacy.PrivacyConfig$Callback
+-keepclassmembers,allowaccessmodification class com.android.systemui.**, com.android.keyguard.** {
+  <1> *;
+}
+-if class * extends com.android.systemui.privacy.PrivacyItemController$Callback
+-keepclassmembers,allowaccessmodification class com.android.systemui.**, com.android.keyguard.** {
+  <1> *;
+}
+-if class * extends com.android.systemui.settings.UserTracker$Callback
+-keepclassmembers,allowaccessmodification class com.android.systemui.**, com.android.keyguard.** {
+  <1> *;
+}
+-if class * extends com.android.systemui.statusbar.phone.StatusBarWindowCallback
+-keepclassmembers,allowaccessmodification class com.android.systemui.**, com.android.keyguard.** {
+  <1> *;
+}
+-if class * extends com.android.systemui.util.service.Observer$Callback
+-keepclassmembers,allowaccessmodification class com.android.systemui.**, com.android.keyguard.** {
+  <1> *;
+}
+-if class * extends com.android.systemui.util.service.ObservableServiceConnection$Callback
+-keepclassmembers,allowaccessmodification class com.android.systemui.**, com.android.keyguard.** {
+  <1> *;
+}
+
 -keepclasseswithmembers class * {
     public <init>(android.content.Context, android.util.AttributeSet);
 }
diff --git a/packages/SystemUI/res-keyguard/drawable/super_lock_icon.xml b/packages/SystemUI/res-keyguard/drawable/super_lock_icon.xml
index b3987f1..951d6fe 100644
--- a/packages/SystemUI/res-keyguard/drawable/super_lock_icon.xml
+++ b/packages/SystemUI/res-keyguard/drawable/super_lock_icon.xml
@@ -99,4 +99,9 @@
         android:fromId="@id/unlocked"
         android:toId="@id/locked_aod"
         android:drawable="@drawable/unlocked_to_aod_lock" />
+
+    <transition
+        android:fromId="@id/unlocked"
+        android:toId="@id/locked"
+        android:drawable="@drawable/unlocked_to_locked" />
 </animated-selector>
diff --git a/packages/SystemUI/res-keyguard/drawable/unlocked_to_locked.xml b/packages/SystemUI/res-keyguard/drawable/unlocked_to_locked.xml
new file mode 100644
index 0000000..b55abd1
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/unlocked_to_locked.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2022 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<animated-vector xmlns:aapt="http://schemas.android.com/aapt" xmlns:android="http://schemas.android.com/apk/res/android">
+    <aapt:attr name="android:drawable">
+        <vector android:height="65dp" android:width="46dp" android:viewportHeight="65" android:viewportWidth="46">
+            <group android:name="_R_G">
+                <group android:name="_R_G_L_2_G_T_1" android:translateX="22.75" android:translateY="22.25" android:scaleX="1.02" android:scaleY="1.02">
+                    <group android:name="_R_G_L_2_G" android:translateX="-8.75" android:translateY="-8.75">
+                        <path android:name="_R_G_L_2_G_D_0_P_0" android:strokeColor="#FF000000" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M27.19 14.81 C27.19,14.81 27.19,8.3 27.19,8.3 C27.19,4.92 24.44,2.88 21.19,2.75 C17.74,2.62 15,4.74 15,8.11 C15,8.11 15,15 15,15 " />
+                    </group>
+                </group>
+                <group android:name="_R_G_L_1_G_N_4_T_1" android:translateX="22.75" android:translateY="22.25" android:scaleX="1.02" android:scaleY="1.02">
+                    <group android:name="_R_G_L_1_G_N_4_T_0" android:translateX="-8.75" android:translateY="-8.75">
+                        <group android:name="_R_G_L_1_G" android:translateX="8.995" android:translateY="18.431" android:scaleX="0.98039" android:scaleY="0.98039">
+                            <path android:name="_R_G_L_1_G_D_0_P_0" android:strokeColor="#FF000000" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M11.25 -0.64 C11.25,-0.64 11.25,13.64 11.25,13.64 C11.25,15.22 9.97,16.5 8.39,16.5 C8.39,16.5 -8.39,16.5 -8.39,16.5 C-9.97,16.5 -11.25,15.22 -11.25,13.64 C-11.25,13.64 -11.25,-0.64 -11.25,-0.64 C-11.25,-2.22 -9.97,-3.5 -8.39,-3.5 C-8.39,-3.5 8.39,-3.5 8.39,-3.5 C9.97,-3.5 11.25,-2.22 11.25,-0.64c " />
+                        </group>
+                    </group>
+                </group>
+                <group android:name="_R_G_L_0_G_N_4_T_1" android:translateX="22.75" android:translateY="22.25" android:scaleX="1.02" android:scaleY="1.02">
+                    <group android:name="_R_G_L_0_G_N_4_T_0" android:translateX="-8.75" android:translateY="-8.75">
+                        <group android:name="_R_G_L_0_G" android:translateX="8.995000000000001" android:translateY="18.345000000000002" android:pivotX="-0.031" android:pivotY="4.406" android:scaleX="0.98039" android:scaleY="0.98039">
+                            <path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#FF000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-0.09 8.63 C1.2,8.63 2.25,7.57 2.25,6.28 C2.25,4.99 1.2,3.94 -0.09,3.94 C-1.39,3.94 -2.44,4.99 -2.44,6.28 C-2.44,7.57 -1.39,8.63 -0.09,8.63c " />
+                        </group>
+                    </group>
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+    <target android:name="_R_G_L_2_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="strokeWidth" android:duration="333" android:startOffset="0" android:valueFrom="2" android:valueTo="2" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0.833,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_2_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="pathData" android:duration="83" android:startOffset="0" android:valueFrom="M27.19 14.81 C27.19,14.81 27.19,8.3 27.19,8.3 C27.19,4.92 24.44,2.88 21.19,2.75 C17.74,2.62 15,4.74 15,8.11 C15,8.11 15,15 15,15 " android:valueTo="M27.13 10.19 C27.13,10.19 27.13,3.67 27.13,3.67 C27.13,0.3 24.38,-1.75 21.13,-1.87 C17.68,-2.01 14.94,0.11 14.94,3.49 C14.94,3.49 15,15 15,15 " android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.456,0 0.464,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator android:propertyName="pathData" android:duration="133" android:startOffset="83" android:valueFrom="M27.13 10.19 C27.13,10.19 27.13,3.67 27.13,3.67 C27.13,0.3 24.38,-1.75 21.13,-1.87 C17.68,-2.01 14.94,0.11 14.94,3.49 C14.94,3.49 15,15 15,15 " android:valueTo="M2.5 10.38 C2.5,10.38 2.5,3.99 2.5,3.99 C2.5,0.61 5.3,-2.12 8.75,-2.12 C12.2,-2.12 15,0.61 15,3.99 C15,3.99 15,15 15,15 " android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.606,0 0.035,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator android:propertyName="pathData" android:duration="117" android:startOffset="217" android:valueFrom="M2.5 10.38 C2.5,10.38 2.5,3.99 2.5,3.99 C2.5,0.61 5.3,-2.12 8.75,-2.12 C12.2,-2.12 15,0.61 15,3.99 C15,3.99 15,15 15,15 " android:valueTo="M2.52 14.65 C2.52,14.65 2.5,8.61 2.5,8.61 C2.5,5.24 5.3,2.5 8.75,2.5 C12.2,2.5 15,5.24 15,8.61 C15,8.61 15.02,14.65 15.02,14.65 " android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.511,0 0.409,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_2_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="translateY" android:duration="333" android:startOffset="0" android:valueFrom="22.25" android:valueTo="22.25" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.535,0 0.426,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator android:propertyName="translateY" android:duration="67" android:startOffset="333" android:valueFrom="22.25" android:valueTo="24.25" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.535,0 0.426,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator android:propertyName="translateY" android:duration="100" android:startOffset="400" android:valueFrom="24.25" android:valueTo="22.25" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.641,0 0.499,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_1_G_N_4_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="translateY" android:duration="333" android:startOffset="0" android:valueFrom="22.25" android:valueTo="22.25" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.535,0 0.426,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator android:propertyName="translateY" android:duration="67" android:startOffset="333" android:valueFrom="22.25" android:valueTo="24.25" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.535,0 0.426,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator android:propertyName="translateY" android:duration="100" android:startOffset="400" android:valueFrom="24.25" android:valueTo="22.25" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.641,0 0.499,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_N_4_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="translateY" android:duration="333" android:startOffset="0" android:valueFrom="22.25" android:valueTo="22.25" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.535,0 0.426,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator android:propertyName="translateY" android:duration="67" android:startOffset="333" android:valueFrom="22.25" android:valueTo="24.25" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.535,0 0.426,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator android:propertyName="translateY" android:duration="100" android:startOffset="400" android:valueFrom="24.25" android:valueTo="22.25" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.641,0 0.499,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="translateX" android:duration="850" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+</animated-vector>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_pattern_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_pattern_view.xml
index 2b7bdc2..c772c96 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_pattern_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_pattern_view.xml
@@ -27,7 +27,7 @@
     android:orientation="vertical"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    androidprv:layout_maxWidth="@dimen/keyguard_security_width"
+    androidprv:layout_maxWidth="@dimen/biometric_auth_pattern_view_max_size"
     android:layout_gravity="center_horizontal|bottom"
     android:clipChildren="false"
     android:clipToPadding="false">
diff --git a/packages/SystemUI/res-keyguard/values-af/strings.xml b/packages/SystemUI/res-keyguard/values-af/strings.xml
index ea358f6..229a73b 100644
--- a/packages/SystemUI/res-keyguard/values-af/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-af/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laai tans"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laai tans vinnig"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laai tans stadig"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laaiproses word geoptimeer om battery te beskerm"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Druk Kieslys om te ontsluit."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Netwerk is gesluit"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Geen SIM-kaart nie"</string>
diff --git a/packages/SystemUI/res-keyguard/values-am/strings.xml b/packages/SystemUI/res-keyguard/values-am/strings.xml
index 8d1c9aa..c60f579 100644
--- a/packages/SystemUI/res-keyguard/values-am/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-am/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ኃይል በመሙላት ላይ"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • በፍጥነት ኃይልን በመሙላት ላይ"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • በዝግታ ኃይልን በመሙላት ላይ"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ባትሪን ለመጠበቅ ኃይል መሙላት ተብቷል"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ለመክፈት ምናሌ ተጫን።"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"አውታረ መረብ ተቆልፏል"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"ምንም ሲም ካርድ የለም"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml
index fe2e6e6..e78e010 100644
--- a/packages/SystemUI/res-keyguard/values-ar/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • جارٍ الشحن"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • جارٍ الشحن سريعًا"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • جارٍ الشحن ببطء"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • تم تحسين الشحن لحماية البطارية"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"اضغط على \"القائمة\" لإلغاء التأمين."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"الشبكة مؤمّنة"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"‏ليست هناك شريحة SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-as/strings.xml b/packages/SystemUI/res-keyguard/values-as/strings.xml
index a2f7fc4..18a79b8 100644
--- a/packages/SystemUI/res-keyguard/values-as/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-as/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • চ্চার্জ কৰি থকা হৈছে"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • দ্ৰুত গতিৰে চ্চাৰ্জ কৰি থকা হৈছে"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • লাহে লাহে চ্চাৰ্জ কৰি থকা হৈছে"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • বেটাৰী সুৰক্ষিত কৰিবলৈ চাৰ্জিং অপ্টিমাইজ কৰা হৈছে"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"আনলক কৰিবলৈ মেনু টিপক।"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"নেটৱর্ক লক কৰা অৱস্থাত আছে"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"কোনো ছিম কাৰ্ড নাই"</string>
diff --git a/packages/SystemUI/res-keyguard/values-az/strings.xml b/packages/SystemUI/res-keyguard/values-az/strings.xml
index 9b81c35..4c0b68c 100644
--- a/packages/SystemUI/res-keyguard/values-az/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-az/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Enerji yığır"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Sürətlə enerji yığır"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Yavaş enerji yığır"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Batareyanı qorumaq üçün şarj optimallaşdırılıb"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Kilidi açmaq üçün Menyu düyməsinə basın."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Şəbəkə kilidlidir"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM kart yoxdur."</string>
diff --git a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
index 01bd907..9f0e7b4 100644
--- a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
@@ -20,76 +20,75 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"Унесите PIN"</string>
-    <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"Унесите шаблон"</string>
-    <string name="keyguard_enter_your_password" msgid="7225626204122735501">"Унесите лозинку"</string>
-    <string name="keyguard_sim_error_message_short" msgid="633630844240494070">"Неважећа картица."</string>
-    <string name="keyguard_charged" msgid="5478247181205188995">"Напуњена је"</string>
-    <string name="keyguard_plugged_in_wireless" msgid="2537874724955057383">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Бежично пуњење"</string>
-    <string name="keyguard_plugged_in_dock" msgid="2122073051904360987">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Пуни се"</string>
-    <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Пуни се"</string>
-    <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Брзо се пуни"</string>
-    <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Споро се пуни"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Притисните Мени да бисте откључали."</string>
-    <string name="keyguard_network_locked_message" msgid="407096292844868608">"Мрежа је закључана"</string>
-    <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Нема SIM картице"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Уметните SIM картицу."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM картица недостаје или не може да се прочита. Уметните SIM картицу."</string>
-    <string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"SIM картица је неупотребљива."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="2490584154727897806">"SIM картица је трајно онемогућена.\nОбратите се добављачу услуге бежичне мреже да бисте добили другу SIM картицу."</string>
-    <string name="keyguard_sim_locked_message" msgid="4343544458476911044">"SIM картица је закључана."</string>
-    <string name="keyguard_sim_puk_locked_message" msgid="6253830777745450550">"SIM картица је закључана PUK кодом."</string>
-    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="2394023844117630429">"SIM картица се откључава…"</string>
-    <string name="keyguard_accessibility_pin_area" msgid="7403009340414014734">"Област за PIN"</string>
-    <string name="keyguard_accessibility_password" msgid="3524161948484801450">"Лозинка за уређај"</string>
-    <string name="keyguard_accessibility_sim_pin_area" msgid="6272116591533888062">"Област за PIN за SIM"</string>
-    <string name="keyguard_accessibility_sim_puk_area" msgid="5537294043180237374">"Област за PUK за SIM"</string>
-    <string name="keyboardview_keycode_delete" msgid="8489719929424895174">"Избриши"</string>
-    <string name="disable_carrier_button_text" msgid="7153361131709275746">"Онемогући eSIM"</string>
-    <string name="error_disable_esim_title" msgid="3802652622784813119">"Онемогућавање eSIM-а није успело"</string>
-    <string name="error_disable_esim_msg" msgid="2441188596467999327">"eSIM не може да се онемогући због грешке."</string>
+    <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"Unesite PIN"</string>
+    <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"Unesite šablon"</string>
+    <string name="keyguard_enter_your_password" msgid="7225626204122735501">"Unesite lozinku"</string>
+    <string name="keyguard_sim_error_message_short" msgid="633630844240494070">"Nevažeća kartica."</string>
+    <string name="keyguard_charged" msgid="5478247181205188995">"Napunjena je"</string>
+    <string name="keyguard_plugged_in_wireless" msgid="2537874724955057383">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Bežično punjenje"</string>
+    <string name="keyguard_plugged_in_dock" msgid="2122073051904360987">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Puni se"</string>
+    <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Puni se"</string>
+    <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Brzo se puni"</string>
+    <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Sporo se puni"</string>
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Punjenje je optimizovano da bi se zaštitila baterija"</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pritisnite Meni da biste otključali."</string>
+    <string name="keyguard_network_locked_message" msgid="407096292844868608">"Mreža je zaključana"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nema SIM kartice"</string>
+    <string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Umetnite SIM karticu."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM kartica nedostaje ili ne može da se pročita. Umetnite SIM karticu."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"SIM kartica je neupotrebljiva."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="2490584154727897806">"SIM kartica je trajno onemogućena.\nObratite se dobavljaču usluge bežične mreže da biste dobili drugu SIM karticu."</string>
+    <string name="keyguard_sim_locked_message" msgid="4343544458476911044">"SIM kartica je zaključana."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="6253830777745450550">"SIM kartica je zaključana PUK kodom."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="2394023844117630429">"SIM kartica se otključava…"</string>
+    <string name="keyguard_accessibility_pin_area" msgid="7403009340414014734">"Oblast za PIN"</string>
+    <string name="keyguard_accessibility_password" msgid="3524161948484801450">"Lozinka za uređaj"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="6272116591533888062">"Oblast za PIN za SIM"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="5537294043180237374">"Oblast za PUK za SIM"</string>
+    <string name="keyboardview_keycode_delete" msgid="8489719929424895174">"Izbriši"</string>
+    <string name="disable_carrier_button_text" msgid="7153361131709275746">"Onemogući eSIM"</string>
+    <string name="error_disable_esim_title" msgid="3802652622784813119">"Onemogućavanje eSIM-a nije uspelo"</string>
+    <string name="error_disable_esim_msg" msgid="2441188596467999327">"eSIM ne može da se onemogući zbog greške."</string>
     <string name="keyboardview_keycode_enter" msgid="6727192265631761174">"Enter"</string>
-    <string name="kg_wrong_pattern" msgid="5907301342430102842">"Погрешан шаблон"</string>
-    <string name="kg_wrong_password" msgid="4143127991071670512">"Погрешна лозинка"</string>
-    <string name="kg_wrong_pin" msgid="4160978845968732624">"Погрешан PIN"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{Пробајте поново за # секунду.}one{Пробајте поново за # секунду.}few{Пробајте поново за # секунде.}other{Пробајте поново за # секунди.}}"</string>
-    <string name="kg_sim_pin_instructions" msgid="1942424305184242951">"Унесите PIN за SIM."</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"Унесите PIN за SIM „<xliff:g id="CARRIER">%1$s</xliff:g>“."</string>
-    <string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Онемогућите eSIM да бисте уређај користили без мобилне услуге."</string>
-    <string name="kg_puk_enter_puk_hint" msgid="3005288372875367017">"SIM картица је сада онемогућена. Унесите PUK кôд да бисте наставили. Детаљне информације потражите од мобилног оператера."</string>
-    <string name="kg_puk_enter_puk_hint_multi" msgid="4876780689904862943">"SIM „<xliff:g id="CARRIER">%1$s</xliff:g>“ је сада онемогућен. Унесите PUK кôд да бисте наставили. Детаљне информације потражите од мобилног оператера."</string>
-    <string name="kg_puk_enter_pin_hint" msgid="6028432138916150399">"Унесите жељени PIN кôд"</string>
-    <string name="kg_enter_confirm_pin_hint" msgid="4261064020391799132">"Потврдите жељени PIN кôд"</string>
-    <string name="kg_sim_unlock_progress_dialog_message" msgid="4251352015304070326">"SIM картица се откључава…"</string>
-    <string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Унесите PIN који има 4–8 бројева."</string>
-    <string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK кôд треба да има 8 или више бројева."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Унели сте погрешан 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="190984061975729494">"Унели сте погрешну лозинку <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> сек."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Нацртали сте нетачан шаблон за откључавање <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> сек."</string>
-    <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Нетачан PIN кôд за SIM. Сада морате да контактирате мобилног оператера да бисте откључали уређај."</string>
-    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Нетачан PIN за SIM кôд. Имате још # покушај, а онда морате да се обратите мобилном оператеру да бисте откључали уређај.}one{Нетачан PIN за SIM кôд. Имате још # покушај. }few{Нетачан PIN за SIM кôд. Имате још # покушаја. }other{Нетачан PIN за SIM кôд. Имате још # покушаја. }}"</string>
-    <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM картица је неупотребљива. Контактирајте мобилног оператера."</string>
-    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Нетачан SIM PUK кôд. Имате још # покушај пре него што SIM картица постане трајно неупотребљива.}one{Нетачан PUK кôд за SIM. Имате још # покушај пре него што SIM картица постане трајно неупотребљива.}few{Нетачан PUK кôд за SIM. Имате још # покушаја пре него што SIM картица постане трајно неупотребљива.}other{Нетачан PUK кôд за SIM. Имате још # покушаја пре него што SIM картица постане трајно неупотребљива.}}"</string>
-    <string name="kg_password_pin_failed" msgid="5136259126330604009">"Радња са PIN кодом за SIM није успела!"</string>
-    <string name="kg_password_puk_failed" msgid="6778867411556937118">"Радња са PUK кодом за SIM није успела!"</string>
-    <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Промени метод уноса"</string>
-    <string name="airplane_mode" msgid="2528005343938497866">"Режим рада у авиону"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Треба да унесете шаблон када се уређај поново покрене"</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Треба да унесете PIN када се уређај поново покрене"</string>
-    <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Треба да унесете лозинку када се уређај поново покрене"</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"За додатну безбедност користите шаблон"</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"За додатну безбедност користите PIN"</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"За додатну безбедност користите лозинку"</string>
-    <string name="kg_prompt_reason_device_admin" msgid="6961159596224055685">"Администратор је закључао уређај"</string>
-    <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Уређај је ручно закључан"</string>
-    <string name="kg_face_not_recognized" msgid="7903950626744419160">"Није препознат"</string>
-    <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Откључавање лицем тражи приступ камери у Подешавањима"</string>
-    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Унесите PIN за SIM. Још # покушај и мораћете да се обратите мобилном оператеру да бисте откључали уређај.}one{Унесите PIN за SIM. Имате још # покушај.}few{Унесите PIN за SIM. Имате још # покушаја.}other{Унесите PIN за SIM. Имате још # покушаја.}}"</string>
-    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM је сада онемогућен. Унесите PUK кôд да бисте наставили. Имате још # покушај пре него што SIM постане трајно неупотребљив. Детаљне информације потражите од мобилног оператера.}one{SIM је сада онемогућен. Унесите PUK кôд да бисте наставили. Имате још # покушај пре него што SIM постане трајно неупотребљив. Детаљне информације потражите од мобилног оператера.}few{SIM је сада онемогућен. Унесите PUK кôд да бисте наставили. Имате још # покушаја пре него што SIM постане трајно неупотребљив. Детаљне информације потражите од мобилног оператера.}other{SIM је сада онемогућен. Унесите PUK кôд да бисте наставили. Имате још # покушаја пре него што SIM постане трајно неупотребљив. Детаљне информације потражите од мобилног оператера.}}"</string>
-    <string name="clock_title_default" msgid="6342735240617459864">"Подразумевани"</string>
-    <string name="clock_title_bubble" msgid="2204559396790593213">"Мехурићи"</string>
-    <string name="clock_title_analog" msgid="8409262532900918273">"Аналогни"</string>
-    <string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Откључајте уређај да бисте наставили"</string>
+    <string name="kg_wrong_pattern" msgid="5907301342430102842">"Pogrešan šablon"</string>
+    <string name="kg_wrong_password" msgid="4143127991071670512">"Pogrešna lozinka"</string>
+    <string name="kg_wrong_pin" msgid="4160978845968732624">"Pogrešan PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{Probajte ponovo za # sekundu.}one{Probajte ponovo za # sekundu.}few{Probajte ponovo za # sekunde.}other{Probajte ponovo za # sekundi.}}"</string>
+    <string name="kg_sim_pin_instructions" msgid="1942424305184242951">"Unesite PIN za SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"Unesite PIN za SIM „<xliff:g id="CARRIER">%1$s</xliff:g>“."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Onemogućite eSIM da biste uređaj koristili bez mobilne usluge."</string>
+    <string name="kg_puk_enter_puk_hint" msgid="3005288372875367017">"SIM kartica je sada onemogućena. Unesite PUK kôd da biste nastavili. Detaljne informacije potražite od mobilnog operatera."</string>
+    <string name="kg_puk_enter_puk_hint_multi" msgid="4876780689904862943">"SIM „<xliff:g id="CARRIER">%1$s</xliff:g>“ je sada onemogućen. Unesite PUK kôd da biste nastavili. Detaljne informacije potražite od mobilnog operatera."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="6028432138916150399">"Unesite željeni PIN kôd"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="4261064020391799132">"Potvrdite željeni PIN kôd"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="4251352015304070326">"SIM kartica se otključava…"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Unesite PIN koji ima 4–8 brojeva."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK kôd treba da ima 8 ili više brojeva."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Uneli ste pogrešan PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nProbajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Uneli ste pogrešnu lozinku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nProbajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Nacrtali ste netačan šablon za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nProbajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
+    <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Netačan PIN kôd za SIM. Sada morate da kontaktirate mobilnog operatera da biste otključali uređaj."</string>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Netačan PIN za SIM kôd. Imate još # pokušaj, a onda morate da se obratite mobilnom operateru da biste otključali uređaj.}one{Netačan PIN za SIM kôd. Imate još # pokušaj. }few{Netačan PIN za SIM kôd. Imate još # pokušaja. }other{Netačan PIN za SIM kôd. Imate još # pokušaja. }}"</string>
+    <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM kartica je neupotrebljiva. Kontaktirajte mobilnog operatera."</string>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Netačan SIM PUK kôd. Imate još # pokušaj pre nego što SIM kartica postane trajno neupotrebljiva.}one{Netačan PUK kôd za SIM. Imate još # pokušaj pre nego što SIM kartica postane trajno neupotrebljiva.}few{Netačan PUK kôd za SIM. Imate još # pokušaja pre nego što SIM kartica postane trajno neupotrebljiva.}other{Netačan PUK kôd za SIM. Imate još # pokušaja pre nego što SIM kartica postane trajno neupotrebljiva.}}"</string>
+    <string name="kg_password_pin_failed" msgid="5136259126330604009">"Radnja sa PIN kodom za SIM nije uspela!"</string>
+    <string name="kg_password_puk_failed" msgid="6778867411556937118">"Radnja sa PUK kodom za SIM nije uspela!"</string>
+    <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Promeni metod unosa"</string>
+    <string name="airplane_mode" msgid="2528005343938497866">"Režim rada u avionu"</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Treba da unesete šablon kada se uređaj ponovo pokrene"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Treba da unesete PIN kada se uređaj ponovo pokrene"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Treba da unesete lozinku kada se uređaj ponovo pokrene"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"Za dodatnu bezbednost koristite šablon"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"Za dodatnu bezbednost koristite PIN"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"Za dodatnu bezbednost koristite lozinku"</string>
+    <string name="kg_prompt_reason_device_admin" msgid="6961159596224055685">"Administrator je zaključao uređaj"</string>
+    <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Uređaj je ručno zaključan"</string>
+    <string name="kg_face_not_recognized" msgid="7903950626744419160">"Nije prepoznat"</string>
+    <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Otključavanje licem traži pristup kameri u Podešavanjima"</string>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Unesite PIN za SIM. Još # pokušaj i moraćete da se obratite mobilnom operateru da biste otključali uređaj.}one{Unesite PIN za SIM. Imate još # pokušaj.}few{Unesite PIN za SIM. Imate još # pokušaja.}other{Unesite PIN za SIM. Imate još # pokušaja.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još # pokušaj pre nego što SIM postane trajno neupotrebljiv. Detaljne informacije potražite od mobilnog operatera.}one{SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još # pokušaj pre nego što SIM postane trajno neupotrebljiv. Detaljne informacije potražite od mobilnog operatera.}few{SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još # pokušaja pre nego što SIM postane trajno neupotrebljiv. Detaljne informacije potražite od mobilnog operatera.}other{SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još # pokušaja pre nego što SIM postane trajno neupotrebljiv. Detaljne informacije potražite od mobilnog operatera.}}"</string>
+    <string name="clock_title_default" msgid="6342735240617459864">"Podrazumevani"</string>
+    <string name="clock_title_bubble" msgid="2204559396790593213">"Mehurići"</string>
+    <string name="clock_title_analog" msgid="8409262532900918273">"Analogni"</string>
+    <string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Otključajte uređaj da biste nastavili"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-be/strings.xml b/packages/SystemUI/res-keyguard/values-be/strings.xml
index e5da604..10e09a6 100644
--- a/packages/SystemUI/res-keyguard/values-be/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-be/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ідзе зарадка"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ідзе хуткая зарадка"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ідзе павольная зарадка"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • У мэтах зберажэння акумулятара зарадка аптымізавана"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Націсніце кнопку \"Меню\", каб разблакіраваць."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Сетка заблакіравана"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Няма SIM-карты"</string>
diff --git a/packages/SystemUI/res-keyguard/values-bg/strings.xml b/packages/SystemUI/res-keyguard/values-bg/strings.xml
index fcd6d57..725b2ec 100644
--- a/packages/SystemUI/res-keyguard/values-bg/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bg/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарежда се"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарежда се бързо"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарежда се бавно"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зареждането е оптимизирано с цел запазване на батерията"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Натиснете „Меню“, за да отключите."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Мрежата е заключена"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Няма SIM карта"</string>
diff --git a/packages/SystemUI/res-keyguard/values-bn/strings.xml b/packages/SystemUI/res-keyguard/values-bn/strings.xml
index 1588f21..c0b38c1 100644
--- a/packages/SystemUI/res-keyguard/values-bn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bn/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • চার্জ হচ্ছে"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • দ্রুত চার্জ হচ্ছে"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ধীরে চার্জ হচ্ছে"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ব্যাটারি ভাল রাখতে চার্জিং অপ্টিমাইজ করা হয়েছে"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"আনলক করতে মেনুতে টিপুন।"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"নেটওয়ার্ক লক করা আছে"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"কোনো সিম কার্ড নেই"</string>
diff --git a/packages/SystemUI/res-keyguard/values-bs/strings.xml b/packages/SystemUI/res-keyguard/values-bs/strings.xml
index 6b88e8b..5e1e4ed 100644
--- a/packages/SystemUI/res-keyguard/values-bs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bs/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Punjenje"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Brzo punjenje"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Sporo punjenje"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Punjenje je optimizirano radi zaštite baterije"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pritisnite meni da otključate."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Mreža je zaključana"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nema SIM kartice"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ca/strings.xml b/packages/SystemUI/res-keyguard/values-ca/strings.xml
index 0ccf1c1..fba2c8b1 100644
--- a/packages/SystemUI/res-keyguard/values-ca/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ca/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • S\'està carregant"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • S\'està carregant ràpidament"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • S\'està carregant lentament"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Càrrega optimitzada per protegir la bateria"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Prem Menú per desbloquejar."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"La xarxa està bloquejada"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"No hi ha cap SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-cs/strings.xml b/packages/SystemUI/res-keyguard/values-cs/strings.xml
index d130a79..f22e717 100644
--- a/packages/SystemUI/res-keyguard/values-cs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-cs/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Nabíjení"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Rychlé nabíjení"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Pomalé nabíjení"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Optimalizované nabíjení za účelem ochrany baterie"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Klávesy odemknete stisknutím tlačítka nabídky."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Síť je blokována"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Chybí SIM karta"</string>
diff --git a/packages/SystemUI/res-keyguard/values-da/strings.xml b/packages/SystemUI/res-keyguard/values-da/strings.xml
index 1d65ad4..fa3f78d 100644
--- a/packages/SystemUI/res-keyguard/values-da/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-da/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Oplader"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Oplader hurtigt"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Oplader langsomt"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Opladning er optimeret for at beskytte batteriet"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Tryk på menuen for at låse op."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Netværket er låst"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Intet SIM-kort"</string>
diff --git a/packages/SystemUI/res-keyguard/values-de/strings.xml b/packages/SystemUI/res-keyguard/values-de/strings.xml
index 21e330c..e303d24 100644
--- a/packages/SystemUI/res-keyguard/values-de/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-de/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Wird geladen"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Wird schnell geladen"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Wird langsam geladen"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Optimiertes Laden zur Akkuschonung"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Zum Entsperren die Menütaste drücken."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Netzwerk gesperrt"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Keine SIM-Karte"</string>
diff --git a/packages/SystemUI/res-keyguard/values-el/strings.xml b/packages/SystemUI/res-keyguard/values-el/strings.xml
index 3e6a9ad..1a155ee 100644
--- a/packages/SystemUI/res-keyguard/values-el/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-el/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Φόρτιση"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Γρήγορη φόρτιση"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Αργή φόρτιση"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Η φόρτιση βελτιστοποιήθηκε για την προστασία της μπαταρίας"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Πατήστε \"Μενού\" για ξεκλείδωμα."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Κλειδωμένο δίκτυο"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Δεν υπάρχει SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
index 5852fef..cce9dd7 100644
--- a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging rapidly"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging slowly"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging optimised to protect battery"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Press Menu to unlock."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Network locked"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"No SIM card"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
index 5852fef..cce9dd7 100644
--- a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging rapidly"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging slowly"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging optimised to protect battery"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Press Menu to unlock."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Network locked"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"No SIM card"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
index 5852fef..cce9dd7 100644
--- a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging rapidly"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging slowly"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging optimised to protect battery"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Press Menu to unlock."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Network locked"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"No SIM card"</string>
diff --git a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
index c609687..b998f18 100644
--- a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando rápidamente"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando lentamente"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carga optimizada para proteger la batería"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Presiona Menú para desbloquear."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Bloqueada para la red"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Sin tarjeta SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-es/strings.xml b/packages/SystemUI/res-keyguard/values-es/strings.xml
index bbff08c..7dfa2cf 100644
--- a/packages/SystemUI/res-keyguard/values-es/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando rápidamente"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando lentamente"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carga optimizada para proteger la batería"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pulsa el menú para desbloquear la pantalla."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Bloqueada para la red"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Falta la tarjeta SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-et/strings.xml b/packages/SystemUI/res-keyguard/values-et/strings.xml
index 4570bd5..355cd20 100644
--- a/packages/SystemUI/res-keyguard/values-et/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-et/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laadimine"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Kiirlaadimine"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Aeglane laadimine"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laadimine on aku kaitsmiseks optimeeritud"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Vajutage avamiseks menüüklahvi."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Võrk on lukus"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM-kaarti pole"</string>
diff --git a/packages/SystemUI/res-keyguard/values-eu/strings.xml b/packages/SystemUI/res-keyguard/values-eu/strings.xml
index eca4a36..3c794c6 100644
--- a/packages/SystemUI/res-keyguard/values-eu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-eu/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Kargatzen"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Bizkor kargatzen"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mantso kargatzen"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Kargatzea optimizatu da bateria ez kaltetzeko"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Desblokeatzeko, sakatu Menua."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Sarea blokeatuta dago"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Ez dago SIM txartelik"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fa/strings.xml b/packages/SystemUI/res-keyguard/values-fa/strings.xml
index 83e222d..9963c39 100644
--- a/packages/SystemUI/res-keyguard/values-fa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fa/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • درحال شارژ شدن"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • درحال شارژ سریع"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • آهسته‌آهسته شارژ می‌شود"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • برای محافظت از باتری، شارژ بهینه می‌شود"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"برای باز کردن قفل روی «منو» فشار دهید."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"شبکه قفل شد"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"سیم‌کارت موجود نیست"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fi/strings.xml b/packages/SystemUI/res-keyguard/values-fi/strings.xml
index d434dd3..23d985d 100644
--- a/packages/SystemUI/res-keyguard/values-fi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fi/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ladataan"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ladataan nopeasti"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ladataan hitaasti"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Lataus optimoitu akun suojaamiseksi"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Poista lukitus painamalla Valikkoa."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Verkko lukittu"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Ei SIM-korttia"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
index 252fea4..23d579c 100644
--- a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"En recharge : <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"En recharge rapide : <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"En recharge lente : <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Recharge optimisée pour protéger la pile"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Appuyez sur la touche Menu pour déverrouiller l\'appareil."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Réseau verrouillé"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Aucune carte SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fr/strings.xml b/packages/SystemUI/res-keyguard/values-fr/strings.xml
index e112943..da33e6b 100644
--- a/packages/SystemUI/res-keyguard/values-fr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Recharge…"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Recharge rapide…"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Recharge lente"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Recharge optimisée pour protéger la batterie"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Appuyez sur \"Menu\" pour déverrouiller le clavier."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Réseau verrouillé"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Pas de carte SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-gl/strings.xml b/packages/SystemUI/res-keyguard/values-gl/strings.xml
index fad23f8..cbeaf4e 100644
--- a/packages/SystemUI/res-keyguard/values-gl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gl/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando rapidamente"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando lentamente"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carga optimizada para protexer a batería"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Preme Menú para desbloquear."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Bloqueada pola rede"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Sen tarxeta SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-gu/strings.xml b/packages/SystemUI/res-keyguard/values-gu/strings.xml
index f85a6c3..1a12508 100644
--- a/packages/SystemUI/res-keyguard/values-gu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gu/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ચાર્જિંગ"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ઝડપથી ચાર્જિંગ"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ધીમેથી ચાર્જિંગ"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • બૅટરીની સુરક્ષા કરવા માટે, ચાર્જિંગ ઑપ્ટિમાઇઝ કરવામાં આવ્યું છે"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"અનલૉક કરવા માટે મેનૂ દબાવો."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"નેટવર્ક લૉક થયું"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"કોઈ સિમ કાર્ડ નથી"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hi/strings.xml b/packages/SystemUI/res-keyguard/values-hi/strings.xml
index 879bab5..fe72fe0 100644
--- a/packages/SystemUI/res-keyguard/values-hi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hi/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • चार्ज हो रहा है"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • तेज़ चार्ज हो रहा है"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • धीरे चार्ज हो रहा है"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • बैटरी को नुकसान से बचाने के लिए, उसकी चार्जिंग को ऑप्टिमाइज़ किया गया"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"लॉक खोलने के लिए मेन्यू दबाएं."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"नेटवर्क लॉक किया हुआ है"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"कोई सिम कार्ड नहीं है"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hr/strings.xml b/packages/SystemUI/res-keyguard/values-hr/strings.xml
index 99fd8cb..9293283 100644
--- a/packages/SystemUI/res-keyguard/values-hr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hr/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • punjenje"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • brzo punjenje"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • sporo punjenje"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Punjenje se optimizira radi zaštite baterije"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pritisnite Izbornik da biste otključali."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Mreža je zaključana"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nema SIM kartice"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hu/strings.xml b/packages/SystemUI/res-keyguard/values-hu/strings.xml
index 0704545..d86ab84 100644
--- a/packages/SystemUI/res-keyguard/values-hu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hu/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Töltés"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Gyors töltés"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Lassú töltés"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Optimalizált töltés az akkumulátor védelme érdekében"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"A feloldáshoz nyomja meg a Menü gombot."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Hálózat zárolva"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nincs SIM-kártya"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hy/strings.xml b/packages/SystemUI/res-keyguard/values-hy/strings.xml
index ddbb54e..b2d65e7 100644
--- a/packages/SystemUI/res-keyguard/values-hy/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hy/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Լիցքավորում"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Արագ լիցքավորում"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Դանդաղ լիցքավորում"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Մարտկոցը պաշտպանելու համար լիցքավորումն օպտիմալացվել է"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Ապակողպելու համար սեղմեք Ընտրացանկը:"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Ցանցը կողպված է"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM քարտ չկա"</string>
diff --git a/packages/SystemUI/res-keyguard/values-in/strings.xml b/packages/SystemUI/res-keyguard/values-in/strings.xml
index bf1b86c..e04ef4c 100644
--- a/packages/SystemUI/res-keyguard/values-in/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-in/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mengisi daya"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mengisi daya dengan cepat"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mengisi daya dengan lambat"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Pengisian daya dioptimalkan untuk melindungi baterai"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Tekan Menu untuk membuka kunci."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Jaringan terkunci"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Tidak ada kartu SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-is/strings.xml b/packages/SystemUI/res-keyguard/values-is/strings.xml
index a6f6f7d..6aa0cc6 100644
--- a/packages/SystemUI/res-keyguard/values-is/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-is/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Í hleðslu"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Hröð hleðsla"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Hæg hleðsla"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Hleðsla fínstillt til að vernda rafhlöðuna"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Ýttu á valmyndarhnappinn til að taka úr lás."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Net læst"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Ekkert SIM-kort"</string>
diff --git a/packages/SystemUI/res-keyguard/values-it/strings.xml b/packages/SystemUI/res-keyguard/values-it/strings.xml
index 3b93495..9d5db3a 100644
--- a/packages/SystemUI/res-keyguard/values-it/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-it/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • In carica"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ricarica veloce"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ricarica lenta"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ricarica ottimizzata per proteggere la batteria"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Premi Menu per sbloccare."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Rete bloccata"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nessuna SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-iw/strings.xml b/packages/SystemUI/res-keyguard/values-iw/strings.xml
index fbb42a6..619052a 100644
--- a/packages/SystemUI/res-keyguard/values-iw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-iw/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • בטעינה"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • בטעינה מהירה"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • בטעינה איטית"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • הטעינה עברה אופטימיזציה כדי להגן על הסוללה"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"יש ללחוץ על \'תפריט\' כדי לבטל את הנעילה."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"הרשת נעולה"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"‏אין כרטיס SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ja/strings.xml b/packages/SystemUI/res-keyguard/values-ja/strings.xml
index 4d3a4e0..390bfcb 100644
--- a/packages/SystemUI/res-keyguard/values-ja/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ja/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 充電中"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 急速充電中"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 低速充電中"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 充電最適化済み(バッテリーを保護)"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"メニューからロックを解除できます。"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"ネットワークがロックされました"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM カードなし"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ka/strings.xml b/packages/SystemUI/res-keyguard/values-ka/strings.xml
index 02d1935..2d47114 100644
--- a/packages/SystemUI/res-keyguard/values-ka/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ka/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • იტენება"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • სწრაფად იტენება"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ნელა იტენება"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • დატენვა ოპტიმიზირებულია ბატარეის დასაცავად"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"განსაბლოკად დააჭირეთ მენიუს."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"ქსელი ჩაკეტილია"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM ბარ. არაა"</string>
diff --git a/packages/SystemUI/res-keyguard/values-kk/strings.xml b/packages/SystemUI/res-keyguard/values-kk/strings.xml
index 612430c..845af85 100644
--- a/packages/SystemUI/res-keyguard/values-kk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kk/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарядталуда"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Жылдам зарядталуда"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Баяу зарядталуда"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Батареяны қорғау үшін, зарядтау оңтайландырылды"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Ашу үшін \"Мәзір\" пернесін басыңыз."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Желі құлыптаулы"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM картасы салынбаған"</string>
diff --git a/packages/SystemUI/res-keyguard/values-km/strings.xml b/packages/SystemUI/res-keyguard/values-km/strings.xml
index f4c7bcb..76ac97f 100644
--- a/packages/SystemUI/res-keyguard/values-km/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-km/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • កំពុង​សាកថ្ម"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • កំពុង​សាកថ្មយ៉ាង​ឆាប់រហ័ស"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • កំពុង​សាកថ្មយឺត"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • បានបង្កើនប្រសិទ្ធភាពនៃការសាក ដើម្បីការពារថ្ម"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ចុចម៉ឺនុយ ​ដើម្បី​ដោះ​សោ។"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"បណ្ដាញ​ជាប់​សោ"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"គ្មាន​ស៊ីម​កាត​ទេ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-kn/strings.xml b/packages/SystemUI/res-keyguard/values-kn/strings.xml
index ee63b4b..bdf89c2 100644
--- a/packages/SystemUI/res-keyguard/values-kn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kn/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ಚಾರ್ಜ್‌ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ವೇಗವಾಗಿ ಚಾರ್ಜ್‌ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ನಿಧಾನವಾಗಿ ಚಾರ್ಜ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ಬ್ಯಾಟರಿಯನ್ನು ರಕ್ಷಿಸಲು ಚಾರ್ಜಿಂಗ್ ಅನ್ನು ಆಪ್ಟಿಮೈಸ್ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ಅನ್‌ಲಾಕ್ ಮಾಡಲು ಮೆನು ಒತ್ತಿರಿ."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"ನೆಟ್‌ವರ್ಕ್ ಲಾಕ್ ಆಗಿದೆ"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"ಸಿಮ್‌ ಕಾರ್ಡ್ ಇಲ್ಲ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ko/strings.xml b/packages/SystemUI/res-keyguard/values-ko/strings.xml
index e284edc..e0c8976 100644
--- a/packages/SystemUI/res-keyguard/values-ko/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ko/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 충전 중"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 고속 충전 중"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 저속 충전 중"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 배터리 보호를 위해 충전 최적화됨"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"잠금 해제하려면 메뉴를 누르세요."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"네트워크 잠김"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM 카드 없음"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ky/strings.xml b/packages/SystemUI/res-keyguard/values-ky/strings.xml
index 61e1aac..a881259 100644
--- a/packages/SystemUI/res-keyguard/values-ky/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ky/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Кубатталууда"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Тез кубатталууда"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Жай кубатталууда"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Батареяны коргоо үчүн кубаттоо процесси оптималдаштырылды"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Кулпуну ачуу үчүн Менюну басыңыз."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Тармак кулпуланган"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM карта жок"</string>
diff --git a/packages/SystemUI/res-keyguard/values-lo/strings.xml b/packages/SystemUI/res-keyguard/values-lo/strings.xml
index d40fa7f..7782b19 100644
--- a/packages/SystemUI/res-keyguard/values-lo/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lo/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ກຳລັງສາກ"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ກຳລັງສາກແບບດ່ວນ"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ກຳລັງສາກແບບຊ້າ"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ການສາກຖືກປັບໃຫ້ເໝາະສົມເພື່ອປົກປ້ອງແບັດເຕີຣີ"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ກົດ \"ເມນູ\" ເພື່ອປົດລັອກ."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"ເຄືອຂ່າຍຖືກລັອກ"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"ບໍ່ມີຊິມກາດ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-lt/strings.xml b/packages/SystemUI/res-keyguard/values-lt/strings.xml
index 9ae5462..480922b 100644
--- a/packages/SystemUI/res-keyguard/values-lt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lt/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Įkraunama"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Greitai įkraunama"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Lėtai įkraunama"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Įkrovimas optimizuotas siekiant apsaugoti akumuliatorių"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Paspauskite meniu, jei norite atrakinti."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Tinklas užrakintas"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nėra SIM kortelės"</string>
diff --git a/packages/SystemUI/res-keyguard/values-lv/strings.xml b/packages/SystemUI/res-keyguard/values-lv/strings.xml
index 1e59a1e..0c16266 100644
--- a/packages/SystemUI/res-keyguard/values-lv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lv/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Notiek uzlāde"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Notiek ātrā uzlāde"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Notiek lēnā uzlāde"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Uzlāde optimizēta, lai saudzētu akumulatoru"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Lai atbloķētu, nospiediet izvēlnes ikonu."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Tīkls ir bloķēts."</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nav SIM kartes."</string>
diff --git a/packages/SystemUI/res-keyguard/values-mk/strings.xml b/packages/SystemUI/res-keyguard/values-mk/strings.xml
index 4f74412..28df6c0 100644
--- a/packages/SystemUI/res-keyguard/values-mk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mk/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Се полни"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Брзо полнење"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Бавно полнење"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Полнењето е оптимизирано за да се заштити батеријата"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Притиснете „Мени“ за отклучување."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Мрежата е заклучена"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Нема SIM-картичка"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ml/strings.xml b/packages/SystemUI/res-keyguard/values-ml/strings.xml
index f8098fb..88ecb87 100644
--- a/packages/SystemUI/res-keyguard/values-ml/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ml/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ചാർജ് ചെയ്യുന്നു"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • വേഗത്തിൽ ചാർജ് ചെയ്യുന്നു"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • പതുക്കെ ചാർജ് ചെയ്യുന്നു"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ബാറ്ററി പരിരക്ഷിക്കാൻ ചാർജിംഗ് ഒപ്റ്റിമൈസ് ചെയ്തു"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"അൺലോക്കുചെയ്യാൻ മെനു അമർത്തുക."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"നെറ്റ്‌വർക്ക് ലോക്കുചെയ്‌തു"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"സിം കാർഡില്ല"</string>
diff --git a/packages/SystemUI/res-keyguard/values-mn/strings.xml b/packages/SystemUI/res-keyguard/values-mn/strings.xml
index e4f8847..adcad3e 100644
--- a/packages/SystemUI/res-keyguard/values-mn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mn/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Цэнэглэж байна"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Хурдан цэнэглэж байна"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Удаан цэнэглэж байна"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Батарейг хамгаалахын тулд цэнэглэх явцыг оновчилсон"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Түгжээг тайлах бол цэсийг дарна уу."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Сүлжээ түгжигдсэн"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM карт алга"</string>
diff --git a/packages/SystemUI/res-keyguard/values-mr/strings.xml b/packages/SystemUI/res-keyguard/values-mr/strings.xml
index c7d4877..c3716cf 100644
--- a/packages/SystemUI/res-keyguard/values-mr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mr/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • चार्ज होत आहे"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • वेगाने चार्ज होत आहे"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • सावकाश चार्ज होत आहे"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • बॅटरीचे संरक्षण करण्यासाठी चार्जिंग ऑप्टिमाइझ केले आहे"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"अनलॉक करण्यासाठी मेनू दाबा."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"नेटवर्क लॉक केले"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"सिम कार्ड नाही"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ms/strings.xml b/packages/SystemUI/res-keyguard/values-ms/strings.xml
index 7012145..8bc0738 100644
--- a/packages/SystemUI/res-keyguard/values-ms/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ms/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mengecas"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mengecas dengan cepat"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mengecas dengan perlahan"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Pengecasan dioptimumkan untuk melindungi bateri"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Tekan Menu untuk membuka kunci."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Rangkaian dikunci"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Tiada kad SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-my/strings.xml b/packages/SystemUI/res-keyguard/values-my/strings.xml
index 7a742cb..26b60c7 100644
--- a/packages/SystemUI/res-keyguard/values-my/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-my/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • အားသွင်းနေသည်"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • အမြန်အားသွင်းနေသည်"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • နှေးကွေးစွာ အားသွင်းနေသည်"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ဘက်ထရီကာကွယ်ရန် အားသွင်းခြင်းကို အကောင်းဆုံးပြင်ဆင်ထားသည်"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"မီနူးကို နှိပ်၍ လော့ခ်ဖွင့်ပါ။"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"ကွန်ရက်ကို လော့ခ်ချထားသည်"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"ဆင်းမ်ကတ် မရှိပါ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-nb/strings.xml b/packages/SystemUI/res-keyguard/values-nb/strings.xml
index 4e0ba44..56b1f13 100644
--- a/packages/SystemUI/res-keyguard/values-nb/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nb/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Lader"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Lader raskt"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Lader sakte"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ladingen er optimalisert for å beskytte batteriet"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Trykk på menyknappen for å låse opp."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Nettverket er låst"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM-kort mangler"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml
index 72d2c5b..ff6abad 100644
--- a/packages/SystemUI/res-keyguard/values-ne/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • चार्ज गरिँदै"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • द्रुत गतिमा चार्ज गरिँदै छ"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • मन्द गतिमा चार्ज गरिँदै"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ब्याट्री जोगाउन चार्ज गर्ने प्रक्रिया अप्टिमाइज गरिएको छ"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"अनलक गर्न मेनु थिच्नुहोस्।"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"नेटवर्क लक भएको छ"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM कार्ड छैन"</string>
diff --git a/packages/SystemUI/res-keyguard/values-nl/strings.xml b/packages/SystemUI/res-keyguard/values-nl/strings.xml
index 141d735..f9a52f7 100644
--- a/packages/SystemUI/res-keyguard/values-nl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nl/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Opladen"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Snel opladen"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Langzaam opladen"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Opladen geoptimaliseerd om de batterij te beschermen"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Druk op Menu om te ontgrendelen."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Netwerk vergrendeld"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Geen simkaart"</string>
diff --git a/packages/SystemUI/res-keyguard/values-or/strings.xml b/packages/SystemUI/res-keyguard/values-or/strings.xml
index dc17e36..b6e710c 100644
--- a/packages/SystemUI/res-keyguard/values-or/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-or/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ଚାର୍ଜ ହେଉଛି"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ଦ୍ରୁତ ଭାବେ ଚାର୍ଜ ହେଉଛି"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ଧୀରେ ଚାର୍ଜ ହେଉଛି"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ବେଟେରୀକୁ ସୁରକ୍ଷିତ ରଖିବା ପାଇଁ ଚାର୍ଜିଂକୁ ଅପ୍ଟିମାଇଜ କରାଯାଇଛି"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ଅନଲକ୍‌ କରିବା ପାଇଁ ମେନୁକୁ ଦବାନ୍ତୁ।"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"ନେଟୱର୍କକୁ ଲକ୍‌ କରାଯାଇଛି"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"କୌଣସି SIM କାର୍ଡ ନାହିଁ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pa/strings.xml b/packages/SystemUI/res-keyguard/values-pa/strings.xml
index 3e05970..fe2b505 100644
--- a/packages/SystemUI/res-keyguard/values-pa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pa/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ਤੇਜ਼ੀ ਨਾਲ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ਹੌਲੀ-ਹੌਲੀ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ਬੈਟਰੀ ਦੀ ਸੁਰੱਖਿਆ ਲਈ ਚਾਰਜਿੰਗ ਨੂੰ ਸੁਯੋਗ ਬਣਾਇਆ ਗਿਆ"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ਅਣਲਾਕ ਕਰਨ ਲਈ \"ਮੀਨੂ\" ਦਬਾਓ।"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"ਨੈੱਟਵਰਕ  ਲਾਕ  ਕੀਤਾ ਗਿਆ"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"ਕੋਈ ਸਿਮ ਕਾਰਡ ਨਹੀਂ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pl/strings.xml b/packages/SystemUI/res-keyguard/values-pl/strings.xml
index 4d3fe58..8271246 100644
--- a/packages/SystemUI/res-keyguard/values-pl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pl/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ładowanie"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Szybkie ładowanie"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Wolne ładowanie"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ładowanie zoptymalizowane w celu ochrony baterii"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Naciśnij Menu, aby odblokować."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Sieć zablokowana"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Brak karty SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
index f61ee04..08e03bc 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregando"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregando rapidamente"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregando lentamente"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregamento otimizado para proteger a bateria"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pressione Menu para desbloquear."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Rede bloqueada"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Sem chip"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
index e8e21fa..7eecdc9 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • A carregar…"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • A carregar rapidamente…"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • A carregar lentamente…"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregamento otimizado para proteger a bateria"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Prima Menu para desbloquear."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Rede bloqueada"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nenhum cartão SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt/strings.xml b/packages/SystemUI/res-keyguard/values-pt/strings.xml
index f61ee04..08e03bc 100644
--- a/packages/SystemUI/res-keyguard/values-pt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregando"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregando rapidamente"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregando lentamente"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregamento otimizado para proteger a bateria"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pressione Menu para desbloquear."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Rede bloqueada"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Sem chip"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ro/strings.xml b/packages/SystemUI/res-keyguard/values-ro/strings.xml
index 073f5ed..6535046 100644
--- a/packages/SystemUI/res-keyguard/values-ro/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ro/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Se încarcă"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Se încarcă rapid"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Se încarcă lent"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Încărcarea este optimizată pentru a proteja bateria"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Apasă pe Meniu pentru a debloca."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Rețea blocată"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Niciun card SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ru/strings.xml b/packages/SystemUI/res-keyguard/values-ru/strings.xml
index 4cd4174..e616f76 100644
--- a/packages/SystemUI/res-keyguard/values-ru/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ru/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"Идет зарядка (<xliff:g id="PERCENTAGE">%s</xliff:g>)"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"Идет быстрая зарядка (<xliff:g id="PERCENTAGE">%s</xliff:g>)"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"Идет медленная зарядка (<xliff:g id="PERCENTAGE">%s</xliff:g>)"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарядка оптимизирована для защиты батареи"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Для разблокировки нажмите \"Меню\"."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Сеть заблокирована"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Нет SIM-карты."</string>
diff --git a/packages/SystemUI/res-keyguard/values-si/strings.xml b/packages/SystemUI/res-keyguard/values-si/strings.xml
index 6a9676f..8ab9fe9 100644
--- a/packages/SystemUI/res-keyguard/values-si/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-si/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ආරෝපණය වෙමින්"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • වේගයෙන් ආරෝපණය වෙමින්"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • සෙමින් ආරෝපණය වෙමින්"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • බැටරිය ආරක්ෂා කිරීම සඳහා ආරෝපණය ප්‍රශස්ත කර ඇත"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"අගුලු හැරීමට මෙනුව ඔබන්න."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"ජාලය අගුළු දමා ඇත"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM පත නැත"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sk/strings.xml b/packages/SystemUI/res-keyguard/values-sk/strings.xml
index 6076198..a076bf1 100644
--- a/packages/SystemUI/res-keyguard/values-sk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sk/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Nabíja sa"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Nabíja sa rýchlo"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Nabíja sa pomaly"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Nabíjanie je optimalizované, aby sa chránila batéria"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Odomknete stlačením tlačidla ponuky."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Sieť je zablokovaná"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Žiadna SIM karta"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sl/strings.xml b/packages/SystemUI/res-keyguard/values-sl/strings.xml
index 9269bc7..5e168a0 100644
--- a/packages/SystemUI/res-keyguard/values-sl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sl/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • polnjenje"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • hitro polnjenje"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • počasno polnjenje"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Polnjenje je optimizirano zaradi zaščite baterije"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Če želite odkleniti, pritisnite meni."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Omrežje je zaklenjeno"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Ni kartice SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sq/strings.xml b/packages/SystemUI/res-keyguard/values-sq/strings.xml
index 9943955..261c619 100644
--- a/packages/SystemUI/res-keyguard/values-sq/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sq/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Po karikohet"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Po karikohet me shpejtësi"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Po karikohet ngadalë"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Karikimi u optimizua për të mbrojtur baterinë"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Shtyp \"Meny\" për të shkyçur."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Rrjeti është i kyçur"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nuk ka kartë SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sr/strings.xml b/packages/SystemUI/res-keyguard/values-sr/strings.xml
index 01bd907..7faaf01 100644
--- a/packages/SystemUI/res-keyguard/values-sr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sr/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Пуни се"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Брзо се пуни"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Споро се пуни"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Пуњење је оптимизовано да би се заштитила батерија"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Притисните Мени да бисте откључали."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Мрежа је закључана"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Нема SIM картице"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sv/strings.xml b/packages/SystemUI/res-keyguard/values-sv/strings.xml
index ebba2e1..1b6e351 100644
--- a/packages/SystemUI/res-keyguard/values-sv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sv/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laddas"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laddas snabbt"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laddas långsamt"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laddningen har optimerats för att skydda batteriet"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Lås upp genom att trycka på Meny."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Nätverk låst"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Inget SIM-kort"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sw/strings.xml b/packages/SystemUI/res-keyguard/values-sw/strings.xml
index 55f4934..a4a365b 100644
--- a/packages/SystemUI/res-keyguard/values-sw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sw/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Inachaji"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Inachaji kwa kasi"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Inachaji pole pole"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Hali ya kuchaji imeboreshwa ili kulinda betri"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Bonyeza Menyu ili kufungua."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Mtandao umefungwa"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Hakuna SIM kadi"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sw540dp-port/dimens.xml b/packages/SystemUI/res-keyguard/values-sw540dp-port/dimens.xml
deleted file mode 100644
index a3c37e4..0000000
--- a/packages/SystemUI/res-keyguard/values-sw540dp-port/dimens.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/assets/res/any/dimens.xml
-**
-** Copyright 2013, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<resources>
-    <!-- Height of the sliding KeyguardSecurityContainer
-        (includes 2x keyguard_security_view_top_margin) -->
-    <dimen name="keyguard_security_height">550dp</dimen>
-</resources>
diff --git a/packages/SystemUI/res-keyguard/values-sw720dp/dimens.xml b/packages/SystemUI/res-keyguard/values-sw720dp/dimens.xml
index 1dc61c5..b7a1bb4 100644
--- a/packages/SystemUI/res-keyguard/values-sw720dp/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values-sw720dp/dimens.xml
@@ -17,10 +17,5 @@
 */
 -->
 <resources>
-
-    <!-- Height of the sliding KeyguardSecurityContainer
-         (includes 2x keyguard_security_view_top_margin) -->
-    <dimen name="keyguard_security_height">470dp</dimen>
-
     <dimen name="widget_big_font_size">100dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-ta/strings.xml b/packages/SystemUI/res-keyguard/values-ta/strings.xml
index 7a06971..4391958 100644
--- a/packages/SystemUI/res-keyguard/values-ta/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ta/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • சார்ஜாகிறது"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • வேகமாகச் சார்ஜாகிறது"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • மெதுவாகச் சார்ஜாகிறது"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • பேட்டரியைப் பாதுகாக்க சார்ஜிங் மேம்படுத்தப்பட்டுள்ளது"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"அன்லாக் செய்ய மெனுவை அழுத்தவும்."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"நெட்வொர்க் பூட்டப்பட்டது"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"சிம் கார்டு இல்லை"</string>
diff --git a/packages/SystemUI/res-keyguard/values-te/strings.xml b/packages/SystemUI/res-keyguard/values-te/strings.xml
index 20ca4b0..fde52be 100644
--- a/packages/SystemUI/res-keyguard/values-te/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-te/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ఛార్జ్ అవుతోంది"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • వేగంగా ఛార్జ్ అవుతోంది"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • నెమ్మదిగా ఛార్జ్ అవుతోంది"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • బ్యాటరీని రక్షించడానికి ఛార్జింగ్ ఆప్టిమైజ్ చేయబడింది"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"అన్‌లాక్ చేయడానికి మెనూను నొక్కండి."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"నెట్‌వర్క్ లాక్ చేయబడింది"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM కార్డ్ లేదు"</string>
diff --git a/packages/SystemUI/res-keyguard/values-th/strings.xml b/packages/SystemUI/res-keyguard/values-th/strings.xml
index 905dea6..43e8740 100644
--- a/packages/SystemUI/res-keyguard/values-th/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-th/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • กำลังชาร์จ"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • กำลังชาร์จอย่างเร็ว"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • กำลังชาร์จอย่างช้าๆ"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ปรับการชาร์จให้เหมาะสมเพื่อถนอมแบตเตอรี่"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"กด \"เมนู\" เพื่อปลดล็อก"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"เครือข่ายถูกล็อก"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"ไม่มีซิมการ์ด"</string>
diff --git a/packages/SystemUI/res-keyguard/values-tl/strings.xml b/packages/SystemUI/res-keyguard/values-tl/strings.xml
index 3cd1be8..d2ddf39 100644
--- a/packages/SystemUI/res-keyguard/values-tl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tl/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Nagcha-charge"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mabilis na nagcha-charge"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mabagal na nagcha-charge"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Naka-optimize ang pag-charge para protektahan ang baterya"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pindutin ang Menu upang i-unlock."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Naka-lock ang network"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Walang SIM card"</string>
diff --git a/packages/SystemUI/res-keyguard/values-tr/strings.xml b/packages/SystemUI/res-keyguard/values-tr/strings.xml
index 81a49cb..a86726e 100644
--- a/packages/SystemUI/res-keyguard/values-tr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tr/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Şarj oluyor"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Hızlı şarj oluyor"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Yavaş şarj oluyor"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Şarj işlemi pili korumak üzere optimize edildi"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Kilidi açmak için Menü\'ye basın."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Ağ kilitli"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM kart yok"</string>
diff --git a/packages/SystemUI/res-keyguard/values-uk/strings.xml b/packages/SystemUI/res-keyguard/values-uk/strings.xml
index 0c2e8e1..63e9bcd 100644
--- a/packages/SystemUI/res-keyguard/values-uk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uk/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Заряджання"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Швидке заряджання"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Повільне заряджання"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Заряджання оптимізовано, щоб захистити акумулятор"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Натисніть меню, щоб розблокувати."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Мережу заблоковано"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Немає SIM-карти"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ur/strings.xml b/packages/SystemUI/res-keyguard/values-ur/strings.xml
index 24fa955..bbc3c4f 100644
--- a/packages/SystemUI/res-keyguard/values-ur/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ur/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • چارج ہو رہا ہے"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • تیزی سے چارج ہو رہا ہے"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • آہستہ چارج ہو رہا ہے"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • بیٹری کی حفاظت کے لیے چارجنگ کو بہتر بنایا گیا"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"غیر مقفل کرنے کیلئے مینو دبائیں۔"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"نیٹ ورک مقفل ہو گیا"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"‏کوئی SIM کارڈ نہیں ہے"</string>
diff --git a/packages/SystemUI/res-keyguard/values-uz/strings.xml b/packages/SystemUI/res-keyguard/values-uz/strings.xml
index 7eab4ad..99b3601 100644
--- a/packages/SystemUI/res-keyguard/values-uz/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uz/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Quvvat olmoqda"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Tezkor quvvat olmoqda"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Sekin quvvat olmoqda"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Batareyani himoyalash uchun quvvatlash optimallashtirildi"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Qulfdan chiqarish uchun Menyu tugmasini bosing."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Tarmoq qulflangan"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM karta solinmagan"</string>
diff --git a/packages/SystemUI/res-keyguard/values-vi/strings.xml b/packages/SystemUI/res-keyguard/values-vi/strings.xml
index f52c880d..cd874e1 100644
--- a/packages/SystemUI/res-keyguard/values-vi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-vi/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Đang sạc"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Đang sạc nhanh"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Đang sạc chậm"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Quá trình sạc được tối ưu hoá để bảo vệ pin"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Nhấn vào Menu để mở khóa."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Mạng đã bị khóa"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Không có thẻ SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
index c961975..4633290 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 正在充电"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 正在快速充电"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 正在慢速充电"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 为保护电池,充电过程已优化"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"按“菜单”即可解锁。"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"网络已锁定"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"没有 SIM 卡"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
index eab0974..16cb820 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 正在充電"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 快速充電中"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 慢速充電中"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 為保護電池,系統已優化充電"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"按下 [選單] 即可解鎖。"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"網絡已鎖定"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"沒有 SIM 卡"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
index 31fffa5..27c85fe 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 充電中"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 快速充電中"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 慢速充電中"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 為保護電池,充電效能已最佳化"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"按選單鍵解鎖。"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"網路已鎖定"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"沒有 SIM 卡"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zu/strings.xml b/packages/SystemUI/res-keyguard/values-zu/strings.xml
index 145a8d1..8481691 100644
--- a/packages/SystemUI/res-keyguard/values-zu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zu/strings.xml
@@ -30,8 +30,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Iyashaja"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ishaja kaningi"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ishaja kancane"</string>
-    <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
-    <skip />
+    <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ukushaja kuthuthukisiwe ukuze kuvikelwe ibhethri"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Chofoza Menyu ukuvula."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Inethiwekhi ivaliwe"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Alikho ikhadi le-SIM."</string>
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index c5ffdc0..6cc5b9d 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -29,9 +29,6 @@
          (includes 2x keyguard_security_view_top_margin) -->
     <dimen name="keyguard_security_height">420dp</dimen>
 
-    <!-- Max Height of the sliding KeyguardSecurityContainer
-         (includes 2x keyguard_security_view_top_margin) -->
-
     <!-- pin/password field max height -->
     <dimen name="keyguard_password_height">80dp</dimen>
 
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 f1e6eec..287b3f6 100644
--- a/packages/SystemUI/res-product/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res-product/values-b+sr+Latn/strings.xml
@@ -19,30 +19,30 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="dock_alignment_slow_charging" product="default" msgid="6997633396534416792">"Поново поставите телефон ради бржег пуњења"</string>
-    <string name="dock_alignment_not_charging" product="default" msgid="3980752926226749808">"Поново поставите телефон ради бежичног пуњења"</string>
-    <string name="inattentive_sleep_warning_message" product="tv" msgid="6844464574089665063">"Android TV ће се ускоро искључити. Притисните дугме да би остао укључен."</string>
-    <string name="inattentive_sleep_warning_message" product="default" msgid="5693904520452332224">"Уређај ће се ускоро искључити. Притисните да би остао укључен."</string>
-    <string name="keyguard_missing_sim_message" product="tablet" msgid="5018086454277963787">"У таблету нема SIM картице."</string>
-    <string name="keyguard_missing_sim_message" product="default" msgid="7053347843877341391">"У телефону нема SIM картице."</string>
-    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="6278551068943958651">"PIN кодови се не подударају"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="302165994845009232">"Погрешно сте покушали да откључате таблет <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, овај таблет ће се ресетовати, чиме се бришу сви подаци корисника."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="2594813176164266847">"Погрешно сте покушали да откључате телефон <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, овај телефон ће се ресетовати, чиме се бришу сви подаци корисника."</string>
-    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="8710104080409538587">"Погрешно сте покушали да откључате таблет <xliff:g id="NUMBER">%d</xliff:g> пута. Овај таблет ће се ресетовати, чиме се бришу сви подаци."</string>
-    <string name="kg_failed_attempts_now_wiping" product="default" msgid="6381835450014881813">"Погрешно сте покушали да откључате телефон <xliff:g id="NUMBER">%d</xliff:g> пута. Овај телефон ће се ресетовати, чиме се бришу сви подаци."</string>
-    <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="7325071812832605911">"Погрешно сте покушали да откључате таблет <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, уклонићемо овог корисника, чиме се бришу сви подаци корисника."</string>
-    <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="8110939900089863103">"Погрешно сте покушали да откључате телефон <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, уклонићемо овог корисника, чиме се бришу сви подаци корисника."</string>
-    <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="8509811676952707883">"Погрешно сте покушали да откључате таблет <xliff:g id="NUMBER">%d</xliff:g> пута. Уклонићемо овог корисника, чиме се бришу сви подаци корисника."</string>
-    <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="3051962486994265014">"Погрешно сте покушали да откључате телефон <xliff:g id="NUMBER">%d</xliff:g> пута. Уклонићемо овог корисника, чиме се бришу сви подаци корисника."</string>
-    <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="1049523640263353830">"Погрешно сте покушали да откључате таблет <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, уклонићемо пословни профил, чиме се бришу сви подаци са профила."</string>
-    <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="3280816298678433681">"Погрешно сте покушали да откључате телефон <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, уклонићемо пословни профил, чиме се бришу сви подаци са профила."</string>
-    <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="4417100487251371559">"Погрешно сте покушали да откључате таблет <xliff:g id="NUMBER">%d</xliff:g> пута. Уклонићемо пословни профил, чиме се бришу сви подаци са профила."</string>
-    <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="global_action_lock_message" product="default" msgid="7092460751050168771">"Откључајте телефон за још опција"</string>
-    <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Откључајте таблет за још опција"</string>
-    <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Откључајте уређај за још опција"</string>
-    <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"Пушта се на овом телефону"</string>
-    <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"Пушта се на овом таблету"</string>
+    <string name="dock_alignment_slow_charging" product="default" msgid="6997633396534416792">"Ponovo postavite telefon radi bržeg punjenja"</string>
+    <string name="dock_alignment_not_charging" product="default" msgid="3980752926226749808">"Ponovo postavite telefon radi bežičnog punjenja"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="6844464574089665063">"Android TV će se uskoro isključiti. Pritisnite dugme da bi ostao uključen."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="5693904520452332224">"Uređaj će se uskoro isključiti. Pritisnite da bi ostao uključen."</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="5018086454277963787">"U tabletu nema SIM kartice."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="7053347843877341391">"U telefonu nema SIM kartice."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="6278551068943958651">"PIN kodovi se ne podudaraju"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="302165994845009232">"Pogrešno ste pokušali da otključate tablet <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, ovaj tablet će se resetovati, čime se brišu svi podaci korisnika."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="2594813176164266847">"Pogrešno ste pokušali da otključate telefon <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, ovaj telefon će se resetovati, čime se brišu svi podaci korisnika."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="8710104080409538587">"Pogrešno ste pokušali da otključate tablet <xliff:g id="NUMBER">%d</xliff:g> puta. Ovaj tablet će se resetovati, čime se brišu svi podaci."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="6381835450014881813">"Pogrešno ste pokušali da otključate telefon <xliff:g id="NUMBER">%d</xliff:g> puta. Ovaj telefon će se resetovati, čime se brišu svi podaci."</string>
+    <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="7325071812832605911">"Pogrešno ste pokušali da otključate tablet <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, uklonićemo ovog korisnika, čime se brišu svi podaci korisnika."</string>
+    <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="8110939900089863103">"Pogrešno ste pokušali da otključate telefon <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, uklonićemo ovog korisnika, čime se brišu svi podaci korisnika."</string>
+    <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="8509811676952707883">"Pogrešno ste pokušali da otključate tablet <xliff:g id="NUMBER">%d</xliff:g> puta. Uklonićemo ovog korisnika, čime se brišu svi podaci korisnika."</string>
+    <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="3051962486994265014">"Pogrešno ste pokušali da otključate telefon <xliff:g id="NUMBER">%d</xliff:g> puta. Uklonićemo ovog korisnika, čime se brišu svi podaci korisnika."</string>
+    <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="1049523640263353830">"Pogrešno ste pokušali da otključate tablet <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, uklonićemo poslovni profil, čime se brišu svi podaci sa profila."</string>
+    <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="3280816298678433681">"Pogrešno ste pokušali da otključate telefon <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, uklonićemo poslovni profil, čime se brišu svi podaci sa profila."</string>
+    <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="4417100487251371559">"Pogrešno ste pokušali da otključate tablet <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_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="global_action_lock_message" product="default" msgid="7092460751050168771">"Otključajte telefon za još opcija"</string>
+    <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Otključajte tablet za još opcija"</string>
+    <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Otključajte uređaj za još opcija"</string>
+    <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"Pušta se na ovom telefonu"</string>
+    <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"Pušta se na ovom tabletu"</string>
 </resources>
diff --git a/packages/SystemUI/res-product/values-de/strings.xml b/packages/SystemUI/res-product/values-de/strings.xml
index b8d1a7c..c82c739 100644
--- a/packages/SystemUI/res-product/values-de/strings.xml
+++ b/packages/SystemUI/res-product/values-de/strings.xml
@@ -43,6 +43,6 @@
     <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Entsperre dein Smartphone für weitere Optionen"</string>
     <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Entsperre dein Tablet für weitere Optionen"</string>
     <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Entsperre dein Gerät für weitere Optionen"</string>
-    <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"Wird auf diesem Smartphone abgespielt"</string>
-    <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"Wird auf diesem Tablet abgespielt"</string>
+    <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"Wiedergabe läuft auf diesem Smartphone"</string>
+    <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"Wiedergabe läuft auf diesem Tablet"</string>
 </resources>
diff --git a/packages/SystemUI/res-product/values-fr/strings.xml b/packages/SystemUI/res-product/values-fr/strings.xml
index a07c8d8..75a0862 100644
--- a/packages/SystemUI/res-product/values-fr/strings.xml
+++ b/packages/SystemUI/res-product/values-fr/strings.xml
@@ -43,6 +43,6 @@
     <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Déverrouillez votre téléphone pour obtenir plus d\'options"</string>
     <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Déverrouillez votre tablette pour obtenir plus d\'options"</string>
     <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Déverrouillez votre appareil pour obtenir plus d\'options"</string>
-    <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"Lecture sur ce téléphone…"</string>
+    <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"Lecture sur ce téléphone"</string>
     <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"Lecture sur cette tablette…"</string>
 </resources>
diff --git a/packages/SystemUI/res-product/values-ka/strings.xml b/packages/SystemUI/res-product/values-ka/strings.xml
index 1b496cc..3474a7f 100644
--- a/packages/SystemUI/res-product/values-ka/strings.xml
+++ b/packages/SystemUI/res-product/values-ka/strings.xml
@@ -43,6 +43,6 @@
     <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"მეტი ვარიანტის სანახავად განბლოკეთ თქვენი ტელეფონი"</string>
     <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"მეტი ვარიანტის სანახავად განბლოკეთ თქვენი ტაბლეტი"</string>
     <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"მეტი ვარიანტის სანახავად განბლოკეთ თქვენი მოწყობილობა"</string>
-    <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"უკრავს ტელეფონზე"</string>
+    <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"უკრავს ამ ტელეფონზე"</string>
     <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"უკრავს ამ ტაბლეტზე"</string>
 </resources>
diff --git a/packages/SystemUI/res-product/values-pt-rBR/strings.xml b/packages/SystemUI/res-product/values-pt-rBR/strings.xml
index b287fd9..fed58e6 100644
--- a/packages/SystemUI/res-product/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res-product/values-pt-rBR/strings.xml
@@ -43,6 +43,6 @@
     <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Desbloqueie seu smartphone para ver mais opções"</string>
     <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Desbloqueie seu tablet para ver mais opções"</string>
     <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Desbloqueie seu dispositivo para ver mais opções"</string>
-    <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"Mídia aberta neste smartphone"</string>
-    <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"Mídia aberta neste tablet"</string>
+    <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"Mídia tocando neste smartphone"</string>
+    <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"Mídia tocando neste tablet"</string>
 </resources>
diff --git a/packages/SystemUI/res-product/values-pt/strings.xml b/packages/SystemUI/res-product/values-pt/strings.xml
index b287fd9..fed58e6 100644
--- a/packages/SystemUI/res-product/values-pt/strings.xml
+++ b/packages/SystemUI/res-product/values-pt/strings.xml
@@ -43,6 +43,6 @@
     <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Desbloqueie seu smartphone para ver mais opções"</string>
     <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Desbloqueie seu tablet para ver mais opções"</string>
     <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Desbloqueie seu dispositivo para ver mais opções"</string>
-    <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"Mídia aberta neste smartphone"</string>
-    <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"Mídia aberta neste tablet"</string>
+    <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"Mídia tocando neste smartphone"</string>
+    <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"Mídia tocando neste tablet"</string>
 </resources>
diff --git a/packages/SystemUI/res-product/values-uz/strings.xml b/packages/SystemUI/res-product/values-uz/strings.xml
index bf8d94a..58309ff 100644
--- a/packages/SystemUI/res-product/values-uz/strings.xml
+++ b/packages/SystemUI/res-product/values-uz/strings.xml
@@ -43,6 +43,6 @@
     <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Boshqa parametrlar uchun telefoningiz qulfini oching"</string>
     <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Boshqa parametrlar uchun planshetingiz qulfini oching"</string>
     <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Boshqa parametrlar uchun qurilmangiz qulfini oching"</string>
-    <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"Bu telefonda ijro etilmoqda"</string>
+    <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"Bu telefonda ijro qilinmoqda"</string>
     <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"Bu planshetda ijro etilmoqda"</string>
 </resources>
diff --git a/packages/SystemUI/res/drawable/ic_brightness_full.xml b/packages/SystemUI/res/drawable/ic_brightness_full.xml
index f443332..1dc7cef 100644
--- a/packages/SystemUI/res/drawable/ic_brightness_full.xml
+++ b/packages/SystemUI/res/drawable/ic_brightness_full.xml
@@ -1,29 +1,45 @@
-<!--
-Copyright (C) 2020 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-
-    <path
-        android:pathData="M18,14.48V18h-3.52L12,20.48L9.52,18H6v-3.52L3.52,12L6,9.52V6h3.52L12,3.52L14.48,6H18v3.52L20.48,12L18,14.48z"
-    />
-
-    <path
-        android:pathData=" M20,8.69 V4h-4.69L12,0.69L8.69,4H4v4.69L0.69,12L4,15.31V20h4.69L12,23.31L15.31,20H20v-4.69L23.31,12L20,8.69z M18,14.48V18h-3.52L12,20.48L9.52,18H6v-3.52L3.52,12L6,9.52V6h3.52L12,3.52L14.48,6H18v3.52L20.48,12L18,14.48z M12,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5s5,-2.24 5,-5S14.76,7 12,7z"
-        android:fillColor="#FFFFFF" />
-</vector>
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportHeight="24"
+    android:viewportWidth="24">
+    <group android:name="_R_G">
+        <group
+            android:name="_R_G_L_1_G_N_1_T_0"
+            android:scaleX="0.1"
+            android:scaleY="0.1"
+            android:translateX="12"
+            android:translateY="12">
+            <group android:name="_R_G_L_1_G">
+                <path
+                    android:name="_R_G_L_1_G_D_0_P_0"
+                    android:fillAlpha="1"
+                    android:fillColor="#ffffff"
+                    android:fillType="nonZero"
+                    android:pathData=" M66.67 -27.59 C66.67,-27.59 66.67,-66.67 66.67,-66.67 C66.67,-66.67 27.59,-66.67 27.59,-66.67 C27.59,-66.67 0,-94.25 0,-94.25 C0,-94.25 -27.58,-66.67 -27.58,-66.67 C-27.58,-66.67 -66.66,-66.67 -66.66,-66.67 C-66.66,-66.67 -66.66,-27.59 -66.66,-27.59 C-66.66,-27.59 -94.25,0 -94.25,0 C-94.25,0 -66.66,27.58 -66.66,27.58 C-66.66,27.58 -66.66,66.66 -66.66,66.66 C-66.66,66.66 -27.58,66.66 -27.58,66.66 C-27.58,66.66 0,94.25 0,94.25 C0,94.25 27.59,66.66 27.59,66.66 C27.59,66.66 66.67,66.66 66.67,66.66 C66.67,66.66 66.67,27.58 66.67,27.58 C66.67,27.58 94.25,0 94.25,0 C94.25,0 66.67,-27.59 66.67,-27.59c  M50 20.66 C50,20.66 50,50 50,50 C50,50 20.67,50 20.67,50 C20.67,50 0,70.66 0,70.66 C0,70.66 -20.66,50 -20.66,50 C-20.66,50 -50,50 -50,50 C-50,50 -50,20.66 -50,20.66 C-50,20.66 -70.66,0 -70.66,0 C-70.66,0 -50,-20.67 -50,-20.67 C-50,-20.67 -50,-50 -50,-50 C-50,-50 -20.66,-50 -20.66,-50 C-20.66,-50 0,-70.67 0,-70.67 C0,-70.67 20.67,-50 20.67,-50 C20.67,-50 50,-50 50,-50 C50,-50 50,-20.67 50,-20.67 C50,-20.67 70.67,0 70.67,0 C70.67,0 50,20.66 50,20.66c " />
+            </group>
+        </group>
+        <group
+            android:name="_R_G_L_0_G"
+            android:scaleX="0.1"
+            android:scaleY="0.1"
+            android:translateX="12"
+            android:translateY="12">
+            <path
+                android:name="_R_G_L_0_G_D_0_P_0"
+                android:fillAlpha="1"
+                android:fillColor="#ffffff"
+                android:fillType="nonZero"
+                android:pathData=" M0 -32.5 C17.95,-32.5 32.5,-17.95 32.5,0 C32.5,17.95 17.95,32.5 0,32.5 C-17.95,32.5 -32.5,17.95 -32.5,0 C-32.5,-17.95 -17.95,-32.5 0,-32.5c " />
+            <path
+                android:name="_R_G_L_0_G_D_1_P_0"
+                android:pathData=" M0 -32.5 C17.95,-32.5 32.5,-17.95 32.5,0 C32.5,17.95 17.95,32.5 0,32.5 C-17.95,32.5 -32.5,17.95 -32.5,0 C-32.5,-17.95 -17.95,-32.5 0,-32.5c "
+                android:strokeAlpha="1"
+                android:strokeColor="#ffffff"
+                android:strokeLineCap="round"
+                android:strokeLineJoin="round"
+                android:strokeWidth="17" />
+        </group>
+    </group>
+    <group android:name="time_group" />
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_brightness_low.xml b/packages/SystemUI/res/drawable/ic_brightness_low.xml
index b463556..ded7567 100644
--- a/packages/SystemUI/res/drawable/ic_brightness_low.xml
+++ b/packages/SystemUI/res/drawable/ic_brightness_low.xml
@@ -1,10 +1,52 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:width="24dp"
     android:height="24dp"
-    android:viewportWidth="24"
     android:viewportHeight="24"
-    android:tint="?attr/colorControlNormal">
-  <path
-      android:fillColor="@android:color/white"
-      android:pathData="M20,8.69L20,4h-4.69L12,0.69 8.69,4L4,4v4.69L0.69,12 4,15.31L4,20h4.69L12,23.31 15.31,20L20,20v-4.69L23.31,12 20,8.69zM18,14.48L18,18h-3.52L12,20.48 9.52,18L6,18v-3.52L3.52,12 6,9.52L6,6h3.52L12,3.52 14.48,6L18,6v3.52L20.48,12 18,14.48zM12,9c1.65,0 3,1.35 3,3s-1.35,3 -3,3 -3,-1.35 -3,-3 1.35,-3 3,-3m0,-2c-2.76,0 -5,2.24 -5,5s2.24,5 5,5 5,-2.24 5,-5 -2.24,-5 -5,-5z"/>
-</vector>
+    android:viewportWidth="24">
+    <group android:name="_R_G">
+        <group
+            android:name="_R_G_L_1_G_N_1_T_0"
+            android:scaleX="0.1"
+            android:scaleY="0.1"
+            android:translateX="12"
+            android:translateY="12">
+            <group android:name="_R_G_L_1_G">
+                <path
+                    android:name="_R_G_L_1_G_D_0_P_0"
+                    android:fillAlpha="1"
+                    android:fillColor="#ffffff"
+                    android:fillType="nonZero"
+                    android:pathData=" M66.67 -27.59 C66.67,-27.59 66.67,-66.67 66.67,-66.67 C66.67,-66.67 27.59,-66.67 27.59,-66.67 C27.59,-66.67 0,-94.25 0,-94.25 C0,-94.25 -27.58,-66.67 -27.58,-66.67 C-27.58,-66.67 -66.66,-66.67 -66.66,-66.67 C-66.66,-66.67 -66.66,-27.59 -66.66,-27.59 C-66.66,-27.59 -94.25,0 -94.25,0 C-94.25,0 -66.66,27.58 -66.66,27.58 C-66.66,27.58 -66.66,66.66 -66.66,66.66 C-66.66,66.66 -27.58,66.66 -27.58,66.66 C-27.58,66.66 0,94.25 0,94.25 C0,94.25 27.59,66.66 27.59,66.66 C27.59,66.66 66.67,66.66 66.67,66.66 C66.67,66.66 66.67,27.58 66.67,27.58 C66.67,27.58 94.25,0 94.25,0 C94.25,0 66.67,-27.59 66.67,-27.59c  M50 20.66 C50,20.66 50,50 50,50 C50,50 20.67,50 20.67,50 C20.67,50 0,70.66 0,70.66 C0,70.66 -20.66,50 -20.66,50 C-20.66,50 -50,50 -50,50 C-50,50 -50,20.66 -50,20.66 C-50,20.66 -70.66,0 -70.66,0 C-70.66,0 -50,-20.67 -50,-20.67 C-50,-20.67 -50,-50 -50,-50 C-50,-50 -20.66,-50 -20.66,-50 C-20.66,-50 0,-70.67 0,-70.67 C0,-70.67 20.67,-50 20.67,-50 C20.67,-50 50,-50 50,-50 C50,-50 50,-20.67 50,-20.67 C50,-20.67 70.67,0 70.67,0 C70.67,0 50,20.66 50,20.66c " />
+            </group>
+        </group>
+        <group
+            android:name="_R_G_L_0_G"
+            android:scaleX="0.1"
+            android:scaleY="0.1"
+            android:translateX="12"
+            android:translateY="12">
+            <group android:name="_R_G_L_0_C_0_G">
+                <clip-path
+                    android:name="_R_G_L_0_C_0"
+                    android:pathData=" M-63 -50.5 C-63,-50.5 -63,48 -63,48 C-63,48 42.5,48 42.5,48 C42.5,48 42.5,-50.5 42.5,-50.5 C42.5,-50.5 -63,-50.5 -63,-50.5c " />
+                <group android:name="_R_G_L_0_C_0_G_G">
+                    <path
+                        android:name="_R_G_L_0_G_G_0_D_0_P_0"
+                        android:pathData=" M0 -32.5 C17.95,-32.5 32.5,-17.95 32.5,0 C32.5,17.95 17.95,32.5 0,32.5 C-17.95,32.5 -32.5,17.95 -32.5,0 C-32.5,-17.95 -17.95,-32.5 0,-32.5c "
+                        android:strokeAlpha="1"
+                        android:strokeColor="#ffffff"
+                        android:strokeLineCap="round"
+                        android:strokeLineJoin="round"
+                        android:strokeWidth="17" />
+                    <path
+                        android:name="_R_G_L_0_G_G_0_D_1_P_0"
+                        android:fillAlpha="0"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M0 -32.5 C17.95,-32.5 32.5,-17.95 32.5,0 C32.5,17.95 17.95,32.5 0,32.5 C-17.95,32.5 -32.5,17.95 -32.5,0 C-32.5,-17.95 -17.95,-32.5 0,-32.5c " />
+                </group>
+            </group>
+        </group>
+    </group>
+    <group android:name="time_group" />
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_brightness_medium.xml b/packages/SystemUI/res/drawable/ic_brightness_medium.xml
index 80acc4d..606c6da 100644
--- a/packages/SystemUI/res/drawable/ic_brightness_medium.xml
+++ b/packages/SystemUI/res/drawable/ic_brightness_medium.xml
@@ -1,10 +1,52 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:width="24dp"
     android:height="24dp"
-    android:viewportWidth="24"
     android:viewportHeight="24"
-    android:tint="?attr/colorControlNormal">
-  <path
-      android:fillColor="@android:color/white"
-      android:pathData="M20,8.69L20,4h-4.69L12,0.69 8.69,4L4,4v4.69L0.69,12 4,15.31L4,20h4.69L12,23.31 15.31,20L20,20v-4.69L23.31,12 20,8.69zM18,14.48L18,18h-3.52L12,20.48 9.52,18L6,18v-3.52L3.52,12 6,9.52L6,6h3.52L12,3.52 14.48,6L18,6v3.52L20.48,12 18,14.48zM12,17c2.76,0 5,-2.24 5,-5s-2.24,-5 -5,-5v10z"/>
-</vector>
+    android:viewportWidth="24">
+    <group android:name="_R_G">
+        <group
+            android:name="_R_G_L_1_G_N_1_T_0"
+            android:scaleX="0.1"
+            android:scaleY="0.1"
+            android:translateX="12"
+            android:translateY="12">
+            <group android:name="_R_G_L_1_G">
+                <path
+                    android:name="_R_G_L_1_G_D_0_P_0"
+                    android:fillAlpha="1"
+                    android:fillColor="#ffffff"
+                    android:fillType="nonZero"
+                    android:pathData="M66.67 -27.59 C66.67,-27.59 66.67,-66.67 66.67,-66.67 C66.67,-66.67 27.59,-66.67 27.59,-66.67 C27.59,-66.67 0,-94.25 0,-94.25 C0,-94.25 -27.58,-66.67 -27.58,-66.67 C-27.58,-66.67 -66.66,-66.67 -66.66,-66.67 C-66.66,-66.67 -66.66,-27.59 -66.66,-27.59 C-66.66,-27.59 -94.25,0 -94.25,0 C-94.25,0 -66.66,27.58 -66.66,27.58 C-66.66,27.58 -66.66,66.66 -66.66,66.66 C-66.66,66.66 -27.58,66.66 -27.58,66.66 C-27.58,66.66 0,94.25 0,94.25 C0,94.25 27.59,66.66 27.59,66.66 C27.59,66.66 66.67,66.66 66.67,66.66 C66.67,66.66 66.67,27.58 66.67,27.58 C66.67,27.58 94.25,0 94.25,0 C94.25,0 66.67,-27.59 66.67,-27.59c  M50 20.66 C50,20.66 50,50 50,50 C50,50 20.67,50 20.67,50 C20.67,50 0,70.66 0,70.66 C0,70.66 -20.66,50 -20.66,50 C-20.66,50 -50,50 -50,50 C-50,50 -50,20.66 -50,20.66 C-50,20.66 -70.66,0 -70.66,0 C-70.66,0 -50,-20.67 -50,-20.67 C-50,-20.67 -50,-50 -50,-50 C-50,-50 -20.66,-50 -20.66,-50 C-20.66,-50 0,-70.67 0,-70.67 C0,-70.67 20.67,-50 20.67,-50 C20.67,-50 50,-50 50,-50 C50,-50 50,-20.67 50,-20.67 C50,-20.67 70.67,0 70.67,0 C70.67,0 50,20.66 50,20.66c " />
+            </group>
+        </group>
+        <group
+            android:name="_R_G_L_0_G"
+            android:scaleX="0.1"
+            android:scaleY="0.1"
+            android:translateX="12"
+            android:translateY="12">
+            <group android:name="_R_G_L_0_C_0_G">
+                <clip-path
+                    android:name="_R_G_L_0_C_0"
+                    android:pathData="M-105.5 -50.5 C-105.5,-50.5 -105.5,48 -105.5,48 C-105.5,48 0,48 0,48 C0,48 0,-50.5 0,-50.5 C0,-50.5 -105.5,-50.5 -105.5,-50.5c " />
+                <group android:name="_R_G_L_0_C_0_G_G">
+                    <path
+                        android:name="_R_G_L_0_G_G_0_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData="M0 -32.5 C17.95,-32.5 32.5,-17.95 32.5,0 C32.5,17.95 17.95,32.5 0,32.5 C-17.95,32.5 -32.5,17.95 -32.5,0 C-32.5,-17.95 -17.95,-32.5 0,-32.5c " />
+                    <path
+                        android:name="_R_G_L_0_G_G_0_D_1_P_0"
+                        android:pathData="M0 -32.5 C17.95,-32.5 32.5,-17.95 32.5,0 C32.5,17.95 17.95,32.5 0,32.5 C-17.95,32.5 -32.5,17.95 -32.5,0 C-32.5,-17.95 -17.95,-32.5 0,-32.5c "
+                        android:strokeAlpha="1"
+                        android:strokeColor="#ffffff"
+                        android:strokeLineCap="round"
+                        android:strokeLineJoin="round"
+                        android:strokeWidth="17" />
+                </group>
+            </group>
+        </group>
+    </group>
+    <group android:name="time_group" />
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_camera.xml b/packages/SystemUI/res/drawable/ic_camera.xml
new file mode 100644
index 0000000..ef1406c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_camera.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="48"
+    android:viewportHeight="48"
+    android:tint="?attr/colorControlNormal">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M7,42Q5.8,42 4.9,41.1Q4,40.2 4,39V13.35Q4,12.15 4.9,11.25Q5.8,10.35 7,10.35H14.35L18,6H30L33.65,10.35H41Q42.2,10.35 43.1,11.25Q44,12.15 44,13.35V39Q44,40.2 43.1,41.1Q42.2,42 41,42ZM7,39H41Q41,39 41,39Q41,39 41,39V13.35Q41,13.35 41,13.35Q41,13.35 41,13.35H7Q7,13.35 7,13.35Q7,13.35 7,13.35V39Q7,39 7,39Q7,39 7,39ZM7,39Q7,39 7,39Q7,39 7,39V13.35Q7,13.35 7,13.35Q7,13.35 7,13.35Q7,13.35 7,13.35Q7,13.35 7,13.35V39Q7,39 7,39Q7,39 7,39ZM24,34.7Q27.5,34.7 30,32.225Q32.5,29.75 32.5,26.2Q32.5,22.7 30,20.2Q27.5,17.7 24,17.7Q20.45,17.7 17.975,20.2Q15.5,22.7 15.5,26.2Q15.5,29.75 17.975,32.225Q20.45,34.7 24,34.7ZM24,26.2Q24,26.2 24,26.2Q24,26.2 24,26.2Q24,26.2 24,26.2Q24,26.2 24,26.2Q24,26.2 24,26.2Q24,26.2 24,26.2Q24,26.2 24,26.2Q24,26.2 24,26.2Z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_media_explicit_indicator.xml b/packages/SystemUI/res/drawable/ic_media_explicit_indicator.xml
new file mode 100644
index 0000000..08c5aaf
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_media_explicit_indicator.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="13dp"
+    android:height="13dp"
+    android:viewportWidth="48"
+    android:viewportHeight="48"
+    android:tint="?attr/colorControlNormal">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M18.3,34H29.65V31H21.3V25.7H29.65V22.7H21.3V17.35H29.65V14.35H18.3ZM9,42Q7.8,42 6.9,41.1Q6,40.2 6,39V9Q6,7.8 6.9,6.9Q7.8,6 9,6H39Q40.2,6 41.1,6.9Q42,7.8 42,9V39Q42,40.2 41.1,41.1Q40.2,42 39,42ZM9,39H39Q39,39 39,39Q39,39 39,39V9Q39,9 39,9Q39,9 39,9H9Q9,9 9,9Q9,9 9,9V39Q9,39 9,39Q9,39 9,39ZM9,9Q9,9 9,9Q9,9 9,9V39Q9,39 9,39Q9,39 9,39Q9,39 9,39Q9,39 9,39V9Q9,9 9,9Q9,9 9,9Z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_note_task_button.xml b/packages/SystemUI/res/drawable/ic_note_task_shortcut_keyguard.xml
similarity index 92%
copy from packages/SystemUI/res/drawable/ic_note_task_button.xml
copy to packages/SystemUI/res/drawable/ic_note_task_shortcut_keyguard.xml
index bb5e224..ee8d4883 100644
--- a/packages/SystemUI/res/drawable/ic_note_task_button.xml
+++ b/packages/SystemUI/res/drawable/ic_note_task_shortcut_keyguard.xml
@@ -19,10 +19,13 @@
     android:viewportHeight="24"
     android:viewportWidth="24">
     <path
-        android:fillColor="#636C6F"
+        android:fillAlpha="1"
+        android:fillColor="@android:color/white"
+        android:fillType="nonZero"
         android:pathData="M17.6258,4.96L19.0358,6.37L7.4058,18.01L5.9958,16.6L17.6258,4.96ZM16.1358,3.62L4.1258,15.63L3.0158,19.83C2.9058,20.45 3.3858,21 3.9958,21C4.0558,21 4.1058,21 4.1658,20.99L8.3658,19.88L20.3758,7.86C20.7758,7.46 20.9958,6.93 20.9958,6.37C20.9958,5.81 20.7758,5.28 20.3758,4.88L19.1058,3.61C18.7158,3.22 18.1858,3 17.6258,3C17.0658,3 16.5358,3.22 16.1358,3.62Z" />
     <path
-        android:fillColor="#636C6F"
-        android:fillType="evenOdd"
+        android:fillAlpha="1"
+        android:fillColor="@android:color/white"
+        android:fillType="nonZero"
         android:pathData="M20.1936,15.3369C20.3748,16.3837 19.9151,17.5414 18.8846,18.7597C19.1546,18.872 19.4576,18.9452 19.7724,18.9867C20.0839,19.0278 20.3683,19.0325 20.5749,19.0266C20.6772,19.0236 20.7578,19.0181 20.8101,19.0138C20.8362,19.0116 20.855,19.0097 20.8657,19.0085L20.8754,19.0074L20.875,19.0075C21.4217,18.9385 21.9214,19.325 21.9918,19.8718C22.0624,20.4195 21.6756,20.9208 21.1279,20.9914L21,19.9996C21.1279,20.9914 21.1265,20.9916 21.1265,20.9916L21.1249,20.9918L21.1211,20.9923L21.1107,20.9935L21.0795,20.997C21.0542,20.9998 21.0199,21.0032 20.9775,21.0067C20.8929,21.0138 20.7753,21.0216 20.6323,21.0257C20.3481,21.0339 19.9533,21.0279 19.5109,20.9695C18.873,20.8854 18.0393,20.6793 17.3106,20.1662C16.9605,20.3559 16.5876,20.4952 16.2299,20.6003C15.5742,20.7927 14.8754,20.8968 14.2534,20.9534C13.6801,21.0055 13.4553,21.0037 13.1015,21.0008C13.0689,21.0005 13.0352,21.0002 13,21H12.8594C12.8214,21.0002 12.785,21.0006 12.7504,21.0009C12.6524,21.0019 12.5683,21.0027 12.5,21H12.0562C12.0277,21.0003 12.0054,21.0006 11.9926,21.001L11.9751,21H9L11,19H11.9795C11.9929,18.9997 12.0064,18.9997 12.0199,19H12.4117C12.4534,18.9996 12.4864,18.9995 12.5,19H12.9675C12.977,18.9999 12.9878,18.9999 13,19C13.0446,19.0003 13.0859,19.0007 13.1249,19.0011C13.4259,19.0038 13.591,19.0054 14.0723,18.9616C14.6201,18.9118 15.1795,18.8242 15.6665,18.6813C15.753,18.6559 15.8346,18.6295 15.9114,18.6022C15.0315,17.2981 14.7125,16.1044 15.015,15.0829C15.4095,13.7511 16.6784,13.2418 17.7026,13.2864C18.7262,13.3309 19.954,13.9529 20.1936,15.3369ZM16.9327,15.6508C16.873,15.8523 16.8651,16.3878 17.4697,17.334C18.2007,16.4284 18.2585,15.8839 18.2229,15.6781C18.1939,15.5108 18.0297,15.3025 17.6157,15.2845C17.2025,15.2665 16.9885,15.4626 16.9327,15.6508Z" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_note_task_button.xml b/packages/SystemUI/res/drawable/ic_note_task_shortcut_widget.xml
similarity index 95%
rename from packages/SystemUI/res/drawable/ic_note_task_button.xml
rename to packages/SystemUI/res/drawable/ic_note_task_shortcut_widget.xml
index bb5e224..7590182 100644
--- a/packages/SystemUI/res/drawable/ic_note_task_button.xml
+++ b/packages/SystemUI/res/drawable/ic_note_task_shortcut_widget.xml
@@ -19,10 +19,13 @@
     android:viewportHeight="24"
     android:viewportWidth="24">
     <path
+        android:fillAlpha="1"
         android:fillColor="#636C6F"
+        android:fillType="nonZero"
         android:pathData="M17.6258,4.96L19.0358,6.37L7.4058,18.01L5.9958,16.6L17.6258,4.96ZM16.1358,3.62L4.1258,15.63L3.0158,19.83C2.9058,20.45 3.3858,21 3.9958,21C4.0558,21 4.1058,21 4.1658,20.99L8.3658,19.88L20.3758,7.86C20.7758,7.46 20.9958,6.93 20.9958,6.37C20.9958,5.81 20.7758,5.28 20.3758,4.88L19.1058,3.61C18.7158,3.22 18.1858,3 17.6258,3C17.0658,3 16.5358,3.22 16.1358,3.62Z" />
     <path
+        android:fillAlpha="1"
         android:fillColor="#636C6F"
-        android:fillType="evenOdd"
+        android:fillType="nonZero"
         android:pathData="M20.1936,15.3369C20.3748,16.3837 19.9151,17.5414 18.8846,18.7597C19.1546,18.872 19.4576,18.9452 19.7724,18.9867C20.0839,19.0278 20.3683,19.0325 20.5749,19.0266C20.6772,19.0236 20.7578,19.0181 20.8101,19.0138C20.8362,19.0116 20.855,19.0097 20.8657,19.0085L20.8754,19.0074L20.875,19.0075C21.4217,18.9385 21.9214,19.325 21.9918,19.8718C22.0624,20.4195 21.6756,20.9208 21.1279,20.9914L21,19.9996C21.1279,20.9914 21.1265,20.9916 21.1265,20.9916L21.1249,20.9918L21.1211,20.9923L21.1107,20.9935L21.0795,20.997C21.0542,20.9998 21.0199,21.0032 20.9775,21.0067C20.8929,21.0138 20.7753,21.0216 20.6323,21.0257C20.3481,21.0339 19.9533,21.0279 19.5109,20.9695C18.873,20.8854 18.0393,20.6793 17.3106,20.1662C16.9605,20.3559 16.5876,20.4952 16.2299,20.6003C15.5742,20.7927 14.8754,20.8968 14.2534,20.9534C13.6801,21.0055 13.4553,21.0037 13.1015,21.0008C13.0689,21.0005 13.0352,21.0002 13,21H12.8594C12.8214,21.0002 12.785,21.0006 12.7504,21.0009C12.6524,21.0019 12.5683,21.0027 12.5,21H12.0562C12.0277,21.0003 12.0054,21.0006 11.9926,21.001L11.9751,21H9L11,19H11.9795C11.9929,18.9997 12.0064,18.9997 12.0199,19H12.4117C12.4534,18.9996 12.4864,18.9995 12.5,19H12.9675C12.977,18.9999 12.9878,18.9999 13,19C13.0446,19.0003 13.0859,19.0007 13.1249,19.0011C13.4259,19.0038 13.591,19.0054 14.0723,18.9616C14.6201,18.9118 15.1795,18.8242 15.6665,18.6813C15.753,18.6559 15.8346,18.6295 15.9114,18.6022C15.0315,17.2981 14.7125,16.1044 15.015,15.0829C15.4095,13.7511 16.6784,13.2418 17.7026,13.2864C18.7262,13.3309 19.954,13.9529 20.1936,15.3369ZM16.9327,15.6508C16.873,15.8523 16.8651,16.3878 17.4697,17.334C18.2007,16.4284 18.2585,15.8839 18.2229,15.6781C18.1939,15.5108 18.0297,15.3025 17.6157,15.2845C17.2025,15.2665 16.9885,15.4626 16.9327,15.6508Z" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_videocam.xml b/packages/SystemUI/res/drawable/ic_videocam.xml
new file mode 100644
index 0000000..de2bc7b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_videocam.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="48"
+    android:viewportHeight="48"
+    android:tint="?attr/colorControlNormal">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M7,40Q5.8,40 4.9,39.1Q4,38.2 4,37V11Q4,9.8 4.9,8.9Q5.8,8 7,8H33Q34.2,8 35.1,8.9Q36,9.8 36,11V21.75L44,13.75V34.25L36,26.25V37Q36,38.2 35.1,39.1Q34.2,40 33,40ZM7,37H33Q33,37 33,37Q33,37 33,37V11Q33,11 33,11Q33,11 33,11H7Q7,11 7,11Q7,11 7,11V37Q7,37 7,37Q7,37 7,37ZM7,37Q7,37 7,37Q7,37 7,37V11Q7,11 7,11Q7,11 7,11Q7,11 7,11Q7,11 7,11V37Q7,37 7,37Q7,37 7,37Z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml b/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml
index 18fcebb..87b5a4c 100644
--- a/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml
+++ b/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml
@@ -16,53 +16,13 @@
 * limitations under the License.
 */
 -->
-<selector
+<shape
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
-
-  <item android:state_selected="true">
-    <layer-list>
-      <item
-          android:left="3dp"
-          android:top="3dp"
-          android:right="3dp"
-          android:bottom="3dp">
-        <shape android:shape="oval">
-          <solid android:color="?androidprv:attr/colorSurface"/>
-          <size
-              android:width="@dimen/keyguard_affordance_width"
-              android:height="@dimen/keyguard_affordance_height"/>
-        </shape>
-      </item>
-
-      <item>
-        <shape android:shape="oval">
-          <stroke
-              android:color="@color/control_primary_text"
-              android:width="2dp"/>
-          <size
-              android:width="@dimen/keyguard_affordance_width"
-              android:height="@dimen/keyguard_affordance_height"/>
-        </shape>
-      </item>
-    </layer-list>
-  </item>
-
-  <item>
-    <layer-list>
-      <item
-          android:left="3dp"
-          android:top="3dp"
-          android:right="3dp"
-          android:bottom="3dp">
-        <shape android:shape="oval">
-          <solid android:color="?androidprv:attr/colorSurface"/>
-          <size
-              android:width="@dimen/keyguard_affordance_width"
-              android:height="@dimen/keyguard_affordance_height"/>
-        </shape>
-      </item>
-    </layer-list>
-  </item>
-
-</selector>
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+    android:shape="rectangle">
+  <solid android:color="?androidprv:attr/colorSurface"/>
+  <size
+      android:width="@dimen/keyguard_affordance_fixed_width"
+      android:height="@dimen/keyguard_affordance_fixed_height"/>
+  <corners android:radius="@dimen/keyguard_affordance_fixed_radius" />
+</shape>
diff --git a/packages/SystemUI/res/drawable/keyguard_bottom_affordance_selected_border.xml b/packages/SystemUI/res/drawable/keyguard_bottom_affordance_selected_border.xml
new file mode 100644
index 0000000..acd2462
--- /dev/null
+++ b/packages/SystemUI/res/drawable/keyguard_bottom_affordance_selected_border.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright 2023, The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+  <item android:state_selected="true">
+    <shape android:shape="oval">
+      <stroke
+          android:color="@color/control_primary_text"
+          android:width="2dp"/>
+      <size
+          android:width="@dimen/keyguard_affordance_fixed_width"
+          android:height="@dimen/keyguard_affordance_fixed_height"/>
+    </shape>
+  </item>
+</selector>
diff --git a/packages/SystemUI/res/drawable/overlay_badge_background.xml b/packages/SystemUI/res/drawable/overlay_badge_background.xml
index 857632e..53122c1 100644
--- a/packages/SystemUI/res/drawable/overlay_badge_background.xml
+++ b/packages/SystemUI/res/drawable/overlay_badge_background.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2020 The Android Open Source Project
+  ~ Copyright (C) 2022 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -14,8 +14,11 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-        xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
-        android:shape="oval">
-    <solid android:color="?androidprv:attr/colorSurface"/>
-</shape>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="48dp"
+        android:height="48dp"
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0">
+    <path
+        android:pathData="M0,0M48,48"/>
+</vector>
diff --git a/packages/SystemUI/res/layout-land/auth_credential_pattern_view.xml b/packages/SystemUI/res/layout-land/auth_credential_pattern_view.xml
index a3dd334..3505a3e 100644
--- a/packages/SystemUI/res/layout-land/auth_credential_pattern_view.xml
+++ b/packages/SystemUI/res/layout-land/auth_credential_pattern_view.xml
@@ -71,8 +71,8 @@
         <com.android.internal.widget.LockPatternView
             android:id="@+id/lockPattern"
             android:layout_gravity="center"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"/>
+            android:layout_width="@dimen/biometric_auth_pattern_view_size"
+            android:layout_height="@dimen/biometric_auth_pattern_view_size"/>
 
         <TextView
             android:id="@+id/error"
diff --git a/packages/SystemUI/res/layout/auth_credential_pattern_view.xml b/packages/SystemUI/res/layout/auth_credential_pattern_view.xml
index 4af9970..147ea82 100644
--- a/packages/SystemUI/res/layout/auth_credential_pattern_view.xml
+++ b/packages/SystemUI/res/layout/auth_credential_pattern_view.xml
@@ -67,8 +67,8 @@
         <com.android.internal.widget.LockPatternView
             android:id="@+id/lockPattern"
             android:layout_gravity="center"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"/>
+            android:layout_width="@dimen/biometric_auth_pattern_view_size"
+            android:layout_height="@dimen/biometric_auth_pattern_view_size"/>
 
         <TextView
             android:id="@+id/error"
diff --git a/packages/SystemUI/res/layout/chipbar.xml b/packages/SystemUI/res/layout/chipbar.xml
index bc97e51..8cf4f4d 100644
--- a/packages/SystemUI/res/layout/chipbar.xml
+++ b/packages/SystemUI/res/layout/chipbar.xml
@@ -23,6 +23,7 @@
     android:layout_width="wrap_content"
     android:layout_height="wrap_content">
 
+    <!-- Extra marginBottom to give room for the drop shadow. -->
     <LinearLayout
         android:id="@+id/chipbar_inner"
         android:orientation="horizontal"
@@ -33,6 +34,8 @@
         android:layout_marginTop="20dp"
         android:layout_marginStart="@dimen/notification_side_paddings"
         android:layout_marginEnd="@dimen/notification_side_paddings"
+        android:translationZ="4dp"
+        android:layout_marginBottom="8dp"
         android:clipToPadding="false"
         android:gravity="center_vertical"
         android:alpha="0.0"
diff --git a/packages/SystemUI/res/layout/clipboard_overlay.xml b/packages/SystemUI/res/layout/clipboard_overlay.xml
index 9134f96..eec3b11 100644
--- a/packages/SystemUI/res/layout/clipboard_overlay.xml
+++ b/packages/SystemUI/res/layout/clipboard_overlay.xml
@@ -32,26 +32,26 @@
         android:elevation="4dp"
         android:background="@drawable/action_chip_container_background"
         android:layout_marginStart="@dimen/overlay_action_container_margin_horizontal"
-        app:layout_constraintBottom_toBottomOf="@+id/actions_container"
+        android:layout_marginBottom="@dimen/overlay_action_container_margin_bottom"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="@+id/actions_container"
-        app:layout_constraintEnd_toEndOf="@+id/actions_container"/>
+        app:layout_constraintEnd_toEndOf="@+id/actions_container"
+        app:layout_constraintBottom_toBottomOf="parent"/>
     <HorizontalScrollView
         android:id="@+id/actions_container"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_marginEnd="@dimen/overlay_action_container_margin_horizontal"
-        android:paddingEnd="@dimen/overlay_action_container_padding_right"
+        android:paddingEnd="@dimen/overlay_action_container_padding_end"
         android:paddingVertical="@dimen/overlay_action_container_padding_vertical"
         android:elevation="4dp"
         android:scrollbars="none"
-        android:layout_marginBottom="4dp"
         app:layout_constraintHorizontal_bias="0"
         app:layout_constraintWidth_percent="1.0"
         app:layout_constraintWidth_max="wrap"
-        app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintStart_toEndOf="@+id/preview_border"
-        app:layout_constraintEnd_toEndOf="parent">
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintBottom_toBottomOf="@id/actions_container_background">
         <LinearLayout
             android:id="@+id/actions"
             android:layout_width="wrap_content"
@@ -69,44 +69,30 @@
         android:id="@+id/preview_border"
         android:layout_width="0dp"
         android:layout_height="0dp"
-        android:layout_marginStart="@dimen/overlay_offset_x"
-        android:layout_marginBottom="12dp"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent"
+        android:layout_marginStart="@dimen/overlay_preview_container_margin"
+        android:layout_marginTop="@dimen/overlay_border_width_neg"
+        android:layout_marginEnd="@dimen/overlay_border_width_neg"
+        android:layout_marginBottom="@dimen/overlay_preview_container_margin"
         android:elevation="7dp"
-        app:layout_constraintEnd_toEndOf="@id/clipboard_preview_end"
-        app:layout_constraintTop_toTopOf="@id/clipboard_preview_top"
-        android:background="@drawable/overlay_border"/>
-    <androidx.constraintlayout.widget.Barrier
-        android:id="@+id/clipboard_preview_end"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        app:barrierMargin="@dimen/overlay_border_width"
-        app:barrierDirection="end"
-        app:constraint_referenced_ids="clipboard_preview"/>
-    <androidx.constraintlayout.widget.Barrier
-        android:id="@+id/clipboard_preview_top"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        app:barrierDirection="top"
-        app:barrierMargin="@dimen/overlay_border_width_neg"
-        app:constraint_referenced_ids="clipboard_preview"/>
+        android:background="@drawable/overlay_border"
+        app:layout_constraintStart_toStartOf="@id/actions_container_background"
+        app:layout_constraintTop_toTopOf="@id/clipboard_preview"
+        app:layout_constraintEnd_toEndOf="@id/clipboard_preview"
+        app:layout_constraintBottom_toBottomOf="@id/actions_container_background"/>
     <FrameLayout
         android:id="@+id/clipboard_preview"
+        android:layout_width="@dimen/clipboard_preview_size"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/overlay_border_width"
+        android:layout_marginBottom="@dimen/overlay_border_width"
+        android:layout_gravity="center"
         android:elevation="7dp"
         android:background="@drawable/overlay_preview_background"
         android:clipChildren="true"
         android:clipToOutline="true"
         android:clipToPadding="true"
-        android:layout_width="@dimen/clipboard_preview_size"
-        android:layout_margin="@dimen/overlay_border_width"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        app:layout_constraintHorizontal_bias="0"
-        app:layout_constraintBottom_toBottomOf="@id/preview_border"
         app:layout_constraintStart_toStartOf="@id/preview_border"
-        app:layout_constraintEnd_toEndOf="@id/preview_border"
-        app:layout_constraintTop_toTopOf="@id/preview_border">
+        app:layout_constraintBottom_toBottomOf="@id/preview_border">
         <TextView android:id="@+id/text_preview"
                   android:textFontWeight="500"
                   android:padding="8dp"
diff --git a/packages/SystemUI/res/layout/combined_qs_header.xml b/packages/SystemUI/res/layout/combined_qs_header.xml
index a565988..d689828 100644
--- a/packages/SystemUI/res/layout/combined_qs_header.xml
+++ b/packages/SystemUI/res/layout/combined_qs_header.xml
@@ -148,9 +148,4 @@
         <include layout="@layout/ongoing_privacy_chip"/>
     </FrameLayout>
 
-    <Space
-        android:layout_width="0dp"
-        android:layout_height="0dp"
-        android:id="@+id/space"
-    />
 </com.android.systemui.util.NoRemeasureMotionLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml b/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
index 9add32c..885e5e2 100644
--- a/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
@@ -57,6 +57,7 @@
             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"
@@ -67,6 +68,7 @@
             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"
@@ -77,6 +79,7 @@
             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/emergency_cryptkeeper_text.xml b/packages/SystemUI/res/layout/emergency_cryptkeeper_text.xml
deleted file mode 100644
index 0a1730a..0000000
--- a/packages/SystemUI/res/layout/emergency_cryptkeeper_text.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2016 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<com.android.systemui.statusbar.policy.EmergencyCryptkeeperText
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:id="@+id/emergency_cryptkeeper_text"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:textAppearance="@style/TextAppearance.StatusBar.Clock"
-        android:paddingStart="6dp"
-        android:singleLine="true"
-        android:ellipsize="marquee"
-        android:gravity="center_vertical|start"
-        />
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index 6120863..3f95515 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -67,6 +67,7 @@
         android:scaleType="center"
         android:tint="?android:attr/textColorPrimary"
         android:background="@drawable/keyguard_bottom_affordance_bg"
+        android:foreground="@drawable/keyguard_bottom_affordance_selected_border"
         android:layout_marginStart="@dimen/keyguard_affordance_horizontal_offset"
         android:layout_marginBottom="@dimen/keyguard_affordance_vertical_offset"
         android:visibility="gone" />
@@ -79,6 +80,7 @@
         android:scaleType="center"
         android:tint="?android:attr/textColorPrimary"
         android:background="@drawable/keyguard_bottom_affordance_bg"
+        android:foreground="@drawable/keyguard_bottom_affordance_selected_border"
         android:layout_marginEnd="@dimen/keyguard_affordance_horizontal_offset"
         android:layout_marginBottom="@dimen/keyguard_affordance_vertical_offset"
         android:visibility="gone" />
diff --git a/packages/SystemUI/res/layout/media_output_dialog.xml b/packages/SystemUI/res/layout/media_output_dialog.xml
index b76de5a..e182a6a 100644
--- a/packages/SystemUI/res/layout/media_output_dialog.xml
+++ b/packages/SystemUI/res/layout/media_output_dialog.xml
@@ -24,6 +24,7 @@
     android:orientation="vertical">
 
     <LinearLayout
+        android:id="@+id/media_metadata_section"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:gravity="start|center_vertical"
diff --git a/packages/SystemUI/res/layout/media_session_view.xml b/packages/SystemUI/res/layout/media_session_view.xml
index 95aefab..abc8337 100644
--- a/packages/SystemUI/res/layout/media_session_view.xml
+++ b/packages/SystemUI/res/layout/media_session_view.xml
@@ -147,6 +147,14 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content" />
 
+    <!-- Explicit Indicator -->
+    <com.android.internal.widget.CachingIconView
+        android:id="@+id/media_explicit_indicator"
+        android:layout_width="@dimen/qs_media_explicit_indicator_icon_size"
+        android:layout_height="@dimen/qs_media_explicit_indicator_icon_size"
+        android:src="@drawable/ic_media_explicit_indicator"
+        />
+
     <!-- Artist name -->
     <TextView
         android:id="@+id/header_artist"
diff --git a/packages/SystemUI/res/layout/media_ttt_chip_receiver.xml b/packages/SystemUI/res/layout/media_ttt_chip_receiver.xml
index 21d12c2..4483db8 100644
--- a/packages/SystemUI/res/layout/media_ttt_chip_receiver.xml
+++ b/packages/SystemUI/res/layout/media_ttt_chip_receiver.xml
@@ -27,6 +27,14 @@
         android:layout_height="wrap_content"
         />
 
+    <com.android.systemui.media.taptotransfer.receiver.ReceiverChipRippleView
+        android:id="@+id/icon_glow_ripple"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        />
+
+    <!-- Add a bottom margin to avoid the glow of the icon ripple from being cropped by screen
+     bounds while animating with the icon -->
     <com.android.internal.widget.CachingIconView
         android:id="@+id/app_icon"
         android:background="@drawable/media_ttt_chip_background_receiver"
@@ -34,6 +42,7 @@
         android:layout_height="@dimen/media_ttt_icon_size_receiver"
         android:layout_gravity="center|bottom"
         android:alpha="0.0"
+        android:layout_marginBottom="@dimen/media_ttt_receiver_icon_bottom_margin"
         />
 
 </FrameLayout>
diff --git a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
index 5aa6080..d1a2cf4 100644
--- a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
+++ b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
@@ -25,6 +25,7 @@
     android:focusable="true"
     android:clipChildren="false"
     android:clipToPadding="false"
+    android:paddingStart="8dp"
     >
 
         <LinearLayout
diff --git a/packages/SystemUI/res/layout/screenshot_static.xml b/packages/SystemUI/res/layout/screenshot_static.xml
index e4e0bd4..496eb6e 100644
--- a/packages/SystemUI/res/layout/screenshot_static.xml
+++ b/packages/SystemUI/res/layout/screenshot_static.xml
@@ -27,26 +27,26 @@
         android:elevation="4dp"
         android:background="@drawable/action_chip_container_background"
         android:layout_marginStart="@dimen/overlay_action_container_margin_horizontal"
-        app:layout_constraintBottom_toBottomOf="@+id/actions_container"
+        android:layout_marginBottom="@dimen/overlay_action_container_margin_bottom"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="@+id/actions_container"
-        app:layout_constraintEnd_toEndOf="@+id/actions_container"/>
+        app:layout_constraintEnd_toEndOf="@+id/actions_container"
+        app:layout_constraintBottom_toTopOf="@id/screenshot_message_container"/>
     <HorizontalScrollView
         android:id="@+id/actions_container"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_marginEnd="@dimen/overlay_action_container_margin_horizontal"
-        android:layout_marginBottom="4dp"
-        android:paddingEnd="@dimen/overlay_action_container_padding_right"
+        android:paddingEnd="@dimen/overlay_action_container_padding_end"
         android:paddingVertical="@dimen/overlay_action_container_padding_vertical"
         android:elevation="4dp"
         android:scrollbars="none"
         app:layout_constraintHorizontal_bias="0"
         app:layout_constraintWidth_percent="1.0"
         app:layout_constraintWidth_max="wrap"
-        app:layout_constraintBottom_toTopOf="@id/screenshot_message_container"
         app:layout_constraintStart_toEndOf="@+id/screenshot_preview_border"
-        app:layout_constraintEnd_toEndOf="parent">
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintBottom_toBottomOf="@id/actions_container_background">
         <LinearLayout
             android:id="@+id/screenshot_actions"
             android:layout_width="wrap_content"
@@ -64,35 +64,24 @@
         android:id="@+id/screenshot_preview_border"
         android:layout_width="0dp"
         android:layout_height="0dp"
-        android:layout_marginStart="@dimen/overlay_offset_x"
-        android:layout_marginBottom="12dp"
+        android:layout_marginStart="@dimen/overlay_preview_container_margin"
+        android:layout_marginTop="@dimen/overlay_border_width_neg"
+        android:layout_marginEnd="@dimen/overlay_border_width_neg"
+        android:layout_marginBottom="@dimen/overlay_preview_container_margin"
         android:elevation="7dp"
         android:alpha="0"
         android:background="@drawable/overlay_border"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintBottom_toTopOf="@id/screenshot_message_container"
-        app:layout_constraintEnd_toEndOf="@id/screenshot_preview_end"
-        app:layout_constraintTop_toTopOf="@id/screenshot_preview_top"/>
-    <androidx.constraintlayout.widget.Barrier
-        android:id="@+id/screenshot_preview_end"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        app:barrierMargin="@dimen/overlay_border_width"
-        app:barrierDirection="end"
-        app:constraint_referenced_ids="screenshot_preview"/>
-    <androidx.constraintlayout.widget.Barrier
-        android:id="@+id/screenshot_preview_top"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        app:barrierDirection="top"
-        app:barrierMargin="@dimen/overlay_border_width_neg"
-        app:constraint_referenced_ids="screenshot_preview"/>
+        app:layout_constraintStart_toStartOf="@id/actions_container_background"
+        app:layout_constraintTop_toTopOf="@id/screenshot_preview"
+        app:layout_constraintEnd_toEndOf="@id/screenshot_preview"
+        app:layout_constraintBottom_toBottomOf="@id/actions_container_background"/>
     <ImageView
         android:id="@+id/screenshot_preview"
         android:visibility="invisible"
         android:layout_width="@dimen/overlay_x_scale"
-        android:layout_margin="@dimen/overlay_border_width"
         android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/overlay_border_width"
+        android:layout_marginBottom="@dimen/overlay_border_width"
         android:layout_gravity="center"
         android:elevation="7dp"
         android:contentDescription="@string/screenshot_edit_description"
@@ -100,20 +89,14 @@
         android:background="@drawable/overlay_preview_background"
         android:adjustViewBounds="true"
         android:clickable="true"
-        app:layout_constraintHorizontal_bias="0"
-        app:layout_constraintBottom_toBottomOf="@id/screenshot_preview_border"
         app:layout_constraintStart_toStartOf="@id/screenshot_preview_border"
-        app:layout_constraintEnd_toEndOf="@id/screenshot_preview_border"
-        app:layout_constraintTop_toTopOf="@id/screenshot_preview_border"/>
+        app:layout_constraintBottom_toBottomOf="@id/screenshot_preview_border"/>
     <ImageView
         android:id="@+id/screenshot_badge"
-        android:layout_width="24dp"
-        android:layout_height="24dp"
-        android:padding="4dp"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
         android:visibility="gone"
-        android:background="@drawable/overlay_badge_background"
         android:elevation="8dp"
-        android:src="@drawable/overlay_cancel"
         app:layout_constraintBottom_toBottomOf="@id/screenshot_preview_border"
         app:layout_constraintEnd_toEndOf="@id/screenshot_preview_border"/>
     <FrameLayout
@@ -150,7 +133,7 @@
         android:layout_height="wrap_content"
         android:layout_marginHorizontal="@dimen/overlay_action_container_margin_horizontal"
         android:layout_marginVertical="4dp"
-        android:paddingHorizontal="@dimen/overlay_action_container_padding_right"
+        android:paddingHorizontal="@dimen/overlay_action_container_padding_end"
         android:paddingVertical="@dimen/overlay_action_container_padding_vertical"
         android:elevation="4dp"
         android:background="@drawable/action_chip_container_background"
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index 3b71dc3..64aa629 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -149,11 +149,4 @@
         </FrameLayout>
     </LinearLayout>
 
-    <ViewStub
-        android:id="@+id/emergency_cryptkeeper_text"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout="@layout/emergency_cryptkeeper_text"
-    />
-
 </com.android.systemui.statusbar.phone.PhoneStatusBarView>
diff --git a/packages/SystemUI/res/layout/status_bar_notification_footer.xml b/packages/SystemUI/res/layout/status_bar_notification_footer.xml
index bbb8df1c..db94c92 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_footer.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_footer.xml
@@ -26,6 +26,17 @@
         android:id="@+id/content"
         android:layout_width="match_parent"
         android:layout_height="wrap_content">
+        <TextView
+            android:id="@+id/unlock_prompt_footer"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="12dp"
+            android:layout_gravity="center_horizontal"
+            android:gravity="center"
+            android:drawablePadding="8dp"
+            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"
diff --git a/packages/SystemUI/res/layout/user_switcher_fullscreen.xml b/packages/SystemUI/res/layout/user_switcher_fullscreen.xml
index fa9d739..7eaed43 100644
--- a/packages/SystemUI/res/layout/user_switcher_fullscreen.xml
+++ b/packages/SystemUI/res/layout/user_switcher_fullscreen.xml
@@ -46,7 +46,7 @@
           app:layout_constraintEnd_toEndOf="parent"
           app:flow_horizontalBias="0.5"
           app:flow_verticalAlign="center"
-          app:flow_wrapMode="chain"
+          app:flow_wrapMode="chain2"
           app:flow_horizontalGap="@dimen/user_switcher_fullscreen_horizontal_gap"
           app:flow_verticalGap="44dp"
           app:flow_horizontalStyle="packed"/>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 25a47f4..fbe6280 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -85,11 +85,14 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Deel skermskoot"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Vang meer vas"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Maak skermkiekie toe"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Maak werkprofielboodskap toe"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Skermkiekievoorskou"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Bogrens <xliff:g id="PERCENT">%1$d</xliff:g> persent"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Ondergrens <xliff:g id="PERCENT">%1$d</xliff:g> persent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Linkergrens <xliff:g id="PERCENT">%1$d</xliff:g> persent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Regtergrens <xliff:g id="PERCENT">%1$d</xliff:g> persent"</string>
+    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Werkskermskote word in die <xliff:g id="APP">%1$s</xliff:g>-app gestoor"</string>
+    <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Lêers"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Skermopnemer"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Verwerk tans skermopname"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Deurlopende kennisgewing vir \'n skermopnamesessie"</string>
@@ -372,11 +375,11 @@
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"Begin opneem of uitsaai met <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
     <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"Laat <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> toe om te deel of op te neem?"</string>
     <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"Hele skerm"</string>
-    <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"’n Enkele program"</string>
+    <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"’n Enkele app"</string>
     <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"Wanneer jy deel, opneem of uitsaai, het <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> toegang tot enigiets wat op jou skerm sigbaar is of op jou toestel gespeel word. Wees dus versigtig met wagwoorde, betalingbesonderhede, boodskappe of ander sensitiewe inligting."</string>
     <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Wanneer jy ’n program deel, opneem of uitsaai, het <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> toegang tot enigiets wat in daardie program sigbaar is of daarin gespeel word. Wees dus versigtig met wagwoorde, betalingbesonderhede, boodskappe of ander sensitiewe inligting."</string>
     <string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Gaan voort"</string>
-    <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Deel of neem ’n program op"</string>
+    <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Deel of neem ’n app op"</string>
     <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Laat hierdie app toe om te deel of op te neem?"</string>
     <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Wanneer jy deel, opneem of uitsaai, het hierdie app toegang tot enigiets wat op jou skerm sigbaar is of op jou toestel gespeel word. Wees dus versigtig met wagwoorde, betalingbesonderhede, boodskappe of ander sensitiewe inligting."</string>
     <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Wanneer jy ’n app deel, opneem of uitsaai, het hierdie app toegang tot enigiets wat in daardie program sigbaar is of daarin gespeel word. Wees dus versigtig met wagwoorde, betalingbesonderhede, boodskappe of ander sensitiewe inligting."</string>
@@ -731,8 +734,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi is af"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth is af"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Moenie Steur Nie is af"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Moenie Steur Nie is aan"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"\'n Outomatiese reël (<xliff:g id="ID_1">%s</xliff:g>) het Moenie Steur Nie aangeskakel."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"\'n Program (<xliff:g id="ID_1">%s</xliff:g>) het Moenie Steur Nie aangeskakel."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"\'n Outomatiese reël of program het Moenie Steur Nie aangeskakel."</string>
@@ -850,9 +852,12 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Speel <xliff:g id="SONG_NAME">%1$s</xliff:g> vanaf <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Ontdoen"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Beweeg nader om op <xliff:g id="DEVICENAME">%1$s</xliff:g> te speel"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Beweeg nader aan <xliff:g id="DEVICENAME">%1$s</xliff:g> om hier te speel"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Speel tans op <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Iets is fout. Probeer weer."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Laai tans"</string>
+    <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Onaktief, gaan program na"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nie gekry nie"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrole is nie beskikbaar nie"</string>
@@ -875,6 +880,8 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Beskikbare toestelle vir oudio-uitsette."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</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">"Luidsprekers en skerms"</string>
+    <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Voorgestelde toestelle"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Hoe uitsaai werk"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Saai uit"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Mense in jou omtrek met versoenbare Bluetooth-toestelle kan na die media luister wat jy uitsaai"</string>
@@ -998,14 +1005,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Maak <xliff:g id="APPNAME">%1$s</xliff:g> oop"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Om die <xliff:g id="APPNAME">%1$s</xliff:g>-app as ’n kortpad by te voeg, moet jy seker maak dat"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Die app opgestel is"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Minstens een kaart by Wallet gevoeg is"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Installeer ’n kamera-app"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Die app opgestel is"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Minstens een toestel beskikbaar is"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Raak en hou kortpad"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Kanselleer"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Draai nou om"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Vou foon oop vir ’n beter selfie"</string>
@@ -1014,6 +1019,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Hierdie skerm sal afskakel"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Voubare toestel word ontvou"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Voubare toestel word omgekeer"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index e4b5307..0a26c1d 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"ቅጽበታዊ ገጽ እይታን ያጋሩ"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"ተጨማሪ ይቅረጹ"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ቅጽበታዊ ገጽ ዕይታን አሰናብት"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"የስራ መገለጫ መልዕክትን ያሰናብታል"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"የቅጽበታዊ ገጽ ዕይታ ቅድመ-ዕይታ"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"የላይ ወሰን <xliff:g id="PERCENT">%1$d</xliff:g> በመቶ"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"የታች ወሰን <xliff:g id="PERCENT">%1$d</xliff:g> በመቶ"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"የግራ ወሰን <xliff:g id="PERCENT">%1$d</xliff:g> በመቶ"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"የቀኝ ወሰን <xliff:g id="PERCENT">%1$d</xliff:g> በመቶ"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"የማያ መቅጃ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"የማያ ገጽ ቀረጻን በማሰናዳት ላይ"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ለአንድ የማያ ገጽ ቀረጻ ክፍለ-ጊዜ በመካሄድ ያለ ማሳወቂያ"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi ጠፍቷል"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"ብሉቱዝ ጠፍቷል"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"አትረብሽ ጠፍቷል"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"አትረብሽ በርቷል"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"አትረብሽ በአንድ ራስ-ሰር ደንብ (<xliff:g id="ID_1">%s</xliff:g>) በርቷል።"</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"አትረብሽ በአንድ መተግበሪያ (<xliff:g id="ID_1">%s</xliff:g>) በርቷል።"</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"አትረብሽ በአንድ ራስ-ሰር ደንብ ወይም መተግበሪያ በርቷል።"</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ከ<xliff:g id="APP_LABEL">%2$s</xliff:g> ያጫውቱ"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"ቀልብስ"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"በ<xliff:g id="DEVICENAME">%1$s</xliff:g> ላይ ለማጫወት ጠጋ ያድርጉ"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"እዚህ ለመጫወት ወደ <xliff:g id="DEVICENAME">%1$s</xliff:g> ቀረብ ይበሉ"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"በ<xliff:g id="DEVICENAME">%1$s</xliff:g> ላይ በማጫወት ላይ"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"የሆነ ችግር ተፈጥሯል። እንደገና ይሞክሩ።"</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"በመጫን ላይ"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"ንቁ ያልኾነ፣ መተግበሪያን ይፈትሹ"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"አልተገኘም"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"መቆጣጠሪያ አይገኝም"</string>
@@ -875,6 +883,9 @@
     <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">"ድምጽ ማውጫዎች እና ማሳያዎች"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ማሰራጨት እንዴት እንደሚሠራ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ስርጭት"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ተኳሃኝ የብሉቱዝ መሣሪያዎች ያላቸው በአቅራቢያዎ ያሉ ሰዎች እርስዎ እያሰራጩት ያሉትን ሚዲያ ማዳመጥ ይችላሉ"</string>
@@ -998,24 +1009,22 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ይክፈቱ"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"የ<xliff:g id="APPNAME">%1$s</xliff:g> መተግበሪያን እንደ አቋራጭ ለማከል የሚከተሉትን ማድረግዎን እርግጠኛ ይሁኑ"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• መተግበሪያው ተዋቅሯል"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• ቢያንስ አንድ ካርድ ወደ Wallet ታክሏል"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• የካሜራ መተግበሪያ ይጫኑ"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• መተግበሪያው ተዋቅሯል"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ቢያንስ አንድ መሣሪያ ይገኛል"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"የይንኩ እና ይያዙ አቋራጭ"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ይቅር"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"አሁን ገልበጥ"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ለተሻለ የራስ ፎቶ ስልክን ይዘርጉ"</string>
     <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"ለተሻለ የራስ ፎቶ ወደፊት ማሳያ ይገልበጥ?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ከፍተኛ ጥራት ላለው ሰፊ ፎቶ የኋለኛውን ካሜራ ይጠቀሙ።"</string>
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ይህ ማያ ገጽ ይጠፋል"</b></string>
-    <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
+    <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"መታጠፍ የሚችል መሣሪያ እየተዘረጋ ነው"</string>
+    <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"መታጠፍ የሚችል መሣሪያ እየተገለበጠ ነው"</string>
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
     <skip />
-    <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
-    <skip />
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 361cf3a..d641887 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"مشاركة لقطة الشاشة"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"التقاط المزيد من المحتوى"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"إغلاق لقطة الشاشة"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"تجاهل رسالة الملف الشخصي للعمل"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"معاينة لقطة الشاشة"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"الحد العلوي <xliff:g id="PERCENT">%1$d</xliff:g> في المئة"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"الحد السفلى <xliff:g id="PERCENT">%1$d</xliff:g> في المئة"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"الحد الأيسر <xliff:g id="PERCENT">%1$d</xliff:g> في المئة"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"الحد الأيمن <xliff:g id="PERCENT">%1$d</xliff:g> في المئة"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"مسجّل الشاشة"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"جارٍ معالجة تسجيل الشاشة"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"إشعار مستمر لجلسة تسجيل شاشة"</string>
@@ -370,7 +375,7 @@
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"ستتمكن الخدمة التي تقدّم هذه الوظيفة من الوصول إلى كل المعلومات المرئية لك على الشاشة أو التي يتم تشغيلها على جهازك أثناء التسجيل أو البث. ويشمل ذلك معلومات مثل كلمات المرور وتفاصيل الدفع والصور والرسائل والمقاطع الصوتية التي تشغِّلها."</string>
     <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"هل تريد بدء التسجيل أو البث؟"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"هل تريد بدء التسجيل أو الإرسال باستخدام <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>؟"</string>
-    <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"هل تريد السماح لتطبيق <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>بالمشاركة أو التسجيل؟"</string>
+    <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"هل تريد السماح لتطبيق <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> بالمشاركة أو التسجيل؟"</string>
     <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"الشاشة بالكامل"</string>
     <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"تطبيق واحد"</string>
     <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"أثناء المشاركة أو التسجيل أو البث، يمكن لتطبيق <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> الوصول إلى كل العناصر المرئية على شاشتك أو التي يتم تشغيلها على جهازك، لذا يُرجى توخي الحذر بشأن كلمات المرور أو تفاصيل الدفع أو الرسائل أو المعلومات الحساسة الأخرى."</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"‏ميزة Wi-Fi غير مفعّلة"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"تم إيقاف البلوتوث."</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"تم إيقاف وضع \"عدم الإزعاج\""</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"ميزة \"عدم الإزعاج\" مفعَّلة."</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"تم تفعيل وضع \"عدم الإزعاج\" بواسطة قاعدة تلقائية (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"تم تفعيل وضع \"عدم الإزعاج\" بواسطة تطبيق (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"تم تفعيل وضع \"عدم الإزعاج\" بواسطة قاعدة تلقائية أو تطبيق."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"تشغيل <xliff:g id="SONG_NAME">%1$s</xliff:g> من تطبيق <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"تراجع"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"عليك الاقتراب لتشغيل الوسائط على <xliff:g id="DEVICENAME">%1$s</xliff:g>."</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"يُرجى الاقتراب من <xliff:g id="DEVICENAME">%1$s</xliff:g> لتشغيل الوسائط هنا."</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"جارٍ تشغيل الوسائط على <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"حدث خطأ. يُرجى إعادة المحاولة."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"جارٍ التحميل"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"غير نشط، تحقّق من التطبيق."</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"لم يتم العثور عليه."</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"عنصر التحكّم غير متوفّر"</string>
@@ -875,6 +883,9 @@
     <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">"مكبّرات الصوت والشاشات"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"كيفية عمل البث"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"البث"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"يمكن للأشخاص القريبين منك الذين لديهم أجهزة متوافقة تتضمّن بلوتوث الاستماع إلى الوسائط التي تبثها."</string>
@@ -998,24 +1009,22 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"فتح \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"لإضافة تطبيق \"<xliff:g id="APPNAME">%1$s</xliff:g>\" كاختصار، تأكّد من"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• إعداد التطبيق"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"‏• إضافة بطاقة واحدة على الأقل إلى \"محفظة Google\""</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• تثبيت تطبيق كاميرا"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• إعداد التطبيق"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• توفُّر جهاز واحد على الأقل"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"انقر مع الاستمرار على الاختصار."</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"إلغاء"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"قلب الجهاز الآن"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"عليك فتح الهاتف لالتقاط صورة ذاتية بشكل أفضل."</string>
     <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"أتريد استخدام الكاميرا الأمامية لصورة ذاتية أفضل؟"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"استخدِم الكاميرا الخلفية لالتقاط صورة أعرض وبدرجة دقة أعلى."</string>
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"* سيتم إطفاء هذه الشاشة."</b></string>
-    <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
+    <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"جهاز قابل للطي يجري فتحه"</string>
+    <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"جهاز قابل للطي يجري قلبه"</string>
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
     <skip />
-    <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
-    <skip />
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 6c102a5..e376a6c 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"স্ক্ৰীনশ্বট শ্বেয়াৰ কৰক"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"অধিক কেপচাৰ কৰক"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"স্ক্ৰীনশ্বট অগ্ৰাহ্য কৰক"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"কৰ্মস্থানৰ প্ৰ’ফাইলৰ বাৰ্তা অগ্ৰাহ্য কৰক"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"স্ক্ৰীনশ্বটৰ পূৰ্বদৰ্শন"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"শীৰ্ষৰ সীমা <xliff:g id="PERCENT">%1$d</xliff:g> শতাংশ"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"তলৰ সীমা <xliff:g id="PERCENT">%1$d</xliff:g> শতাংশ"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"বাওঁফালৰ সীমা <xliff:g id="PERCENT">%1$d</xliff:g> শতাংশ"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"সোঁফালৰ সীমা <xliff:g id="PERCENT">%1$d</xliff:g> শতাংশ"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"স্ক্ৰীন ৰেকৰ্ডাৰ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"স্ক্রীন ৰেকৰ্ডিঙৰ প্ৰক্ৰিয়াকৰণ হৈ আছে"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"স্ক্রীন ৰেকৰ্ডিং ছেশ্বন চলি থকা সময়ত পোৱা জাননী"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"ৱাই-ফাই অফ অৱস্থাত আছে"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"ব্লুটুথ অফ অৱস্থাত আছে"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"অসুবিধা নিদিব অফ অৱস্থাত আছে"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"অসুবিধা নিদিব অন অৱস্থাত আছে"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"অসুবিধা নিদিব-ক এটা স্বয়ংক্ৰিয় নিয়ম (<xliff:g id="ID_1">%s</xliff:g>)এ অন কৰিলে।"</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"অসুবিধা নিদিব-ক কোনো এপ্ (<xliff:g id="ID_1">%s</xliff:g>)এ অন কৰিলে।"</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"অসুবিধা নিদিব-ক এটা স্বয়ংক্ৰিয় নিয়ম বা এপে অন কৰিলে।"</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g>ত <xliff:g id="SONG_NAME">%1$s</xliff:g> গীতটো প্লে’ কৰক"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"আনডু কৰক"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>ত প্লে’ কৰিবলৈ ওচৰলৈ যাওক"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ইয়াত খেলিবলৈ <xliff:g id="DEVICENAME">%1$s</xliff:g>ৰ আৰু ওচৰলৈ যাওক"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>ত প্লে কৰি থকা হৈছে"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"কিবা ভুল হ’ল। পুনৰ চেষ্টা কৰক।"</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"ল’ড হৈ আছে"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"সক্ৰিয় নহয়, এপ্‌টো পৰীক্ষা কৰক"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"বিচাৰি পোৱা নগ’ল"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"নিয়ন্ত্ৰণটো উপলব্ধ নহয়"</string>
@@ -875,6 +883,9 @@
     <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">"স্পীকাৰ আৰু ডিছপ্লে’"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"সম্প্ৰচাৰ কৰাটোৱে কেনেকৈ কাম কৰে"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"সম্প্ৰচাৰ"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"সমিল ব্লুটুথ ডিভাইচৰ সৈতে আপোনাৰ নিকটৱৰ্তী স্থানত থকা লোকসকলে আপুনি সম্প্ৰচাৰ কৰা মিডিয়াটো শুনিব পাৰে"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> খোলক"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"<xliff:g id="APPNAME">%1$s</xliff:g> এপ্‌টোক এটা শ্বৰ্টকাট হিচাপে যোগ দিবলৈ, এইকেইটা কথা নিশ্চিত কৰক"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• এপ্‌টো ছেট আপ কৰা হৈছে"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Walletত অতি কমেও এখন কাৰ্ড যোগ দিয়া হৈছে"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• এটা কেমেৰা এপ্ ইনষ্টল কৰক"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• এপ্‌টো ছেট আপ কৰা হৈছে"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• অতি কমেও এটা ডিভাইচ উপলব্ধ"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"শ্বৰ্টকাটটোত স্পৰ্শ কৰি ধৰি ৰাখক"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"বাতিল কৰক"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"এতিয়াই লুটিয়াই দিয়ক"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"উন্নত ছেল্ফিৰ বাবে ফ’নটো আনফ’ল্ড কৰক"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ই স্ক্ৰীনখন অফ হ’ব"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"জপাব পৰা ডিভাইচৰ জাপ খুলি থকা হৈছে"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"জপাব পৰা ডিভাইচৰ ওলোটাই থকা হৈছে"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index d2529a2..a2f20ce 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Skrinşotu paylaşın"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Genişləndirin"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Ekran şəklini ötürün"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"İş profili mesajını qapadın"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Ekran şəklinə önbaxış"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Yuxarı sərhəd <xliff:g id="PERCENT">%1$d</xliff:g> faiz"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Aşağı sərhəd <xliff:g id="PERCENT">%1$d</xliff:g> faiz"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Sol sərhəd <xliff:g id="PERCENT">%1$d</xliff:g> faiz"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Sağ sərhəd <xliff:g id="PERCENT">%1$d</xliff:g> faiz"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekran Yazıcısı"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran çəkilişi emal edilir"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekranın video çəkimi ərzində silinməyən bildiriş"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi deaktivdir"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth deaktivdir"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"\"Narahat Etməyin\" deaktivdir"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"\"Narahat Etməyin\" rejimi aktivdir"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"\"Narahat etməyin\" rejimi (<xliff:g id="ID_1">%s</xliff:g>) avtomatik qaydası tərəfindən aktiv edildi."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"\"Narahat etməyin\" rejimi (<xliff:g id="ID_1">%s</xliff:g>) tətbiqi tərəfindən aktiv edildi."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"\"Narahat etməyin\" rejimi avtomatik qayda və ya tətbiq tərəfindən aktiv edildi."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> mahnısını <xliff:g id="APP_LABEL">%2$s</xliff:g> tətbiqindən oxudun"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Geri qaytarın"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> cihazında oxutmaq üçün yaxınlaşın"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Burada oxutmaq üçün <xliff:g id="DEVICENAME">%1$s</xliff:g> cihazına yaxınlaşın"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> cihazında oxudulur"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Xəta oldu. Yenə cəhd edin."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Yüklənir"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Aktiv deyil, tətbiqi yoxlayın"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Tapılmadı"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Nəzarət əlçatan deyil"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Audio çıxış üçün əlçatan cihazlar."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Səs"</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">"Dinamiklər &amp; Displeylər"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Yayım necə işləyir"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Yayım"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Uyğun Bluetooth cihazları olan yaxınlığınızdakı insanlar yayımladığınız medianı dinləyə bilər"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"s:dd"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"ss:dd"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> tətbiqini açın"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"<xliff:g id="APPNAME">%1$s</xliff:g> tətbiqini qısayol kimi əlavə etmək üçün bunları təmin edin:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Tətbiq ayarlanmalıdır"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Pulqabına ən azı bir kart əlavə edilməlidir"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Kamera tətbiqini quraşdırın"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Tətbiq ayarlanmalıdır"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ən azı bir cihaz əlçatandır"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Qısayola toxunub saxlayın"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Ləğv edin"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"İndi fırladın"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Daha yaxşı selfi üçün telefonu açın"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Bu ekran deaktiv ediləcək"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Qatlana bilən cihaz açılır"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Qatlana bilən cihaz fırladılır"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn-land/strings.xml b/packages/SystemUI/res/values-b+sr+Latn-land/strings.xml
index 992fe1c..b956edb 100644
--- a/packages/SystemUI/res/values-b+sr+Latn-land/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn-land/strings.xml
@@ -19,5 +19,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="toast_rotation_locked" msgid="4914046305911646988">"Екран је сада закључан у вертикалном положају."</string>
+    <string name="toast_rotation_locked" msgid="4914046305911646988">"Ekran je sada zaključan u vertikalnom položaju."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn-ldrtl/strings.xml b/packages/SystemUI/res/values-b+sr+Latn-ldrtl/strings.xml
index f4106f1..8e5ecf9 100644
--- a/packages/SystemUI/res/values-b+sr+Latn-ldrtl/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn-ldrtl/strings.xml
@@ -19,5 +19,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="recents_quick_scrub_onboarding" msgid="2452671841151577157">"Превуците улево да бисте брзо променили апликације"</string>
+    <string name="recents_quick_scrub_onboarding" msgid="2452671841151577157">"Prevucite ulevo da biste brzo promenili aplikacije"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index f3c3de3..1920987 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -19,1001 +19,1012 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="4811759950673118541">"UI система"</string>
-    <string name="battery_low_title" msgid="5319680173344341779">"Желите ли да укључите Уштеду батерије?"</string>
-    <string name="battery_low_description" msgid="3282977755476423966">"Преостали ниво напуњености батерије је <xliff:g id="PERCENTAGE">%s</xliff:g>. Уштеда батерије укључује Тамну тему, ограничава активности у позадини и одлаже обавештења."</string>
-    <string name="battery_low_intro" msgid="5148725009653088790">"Уштеда батерије укључује Тамну тему, ограничава активности у позадини и одлаже обавештења."</string>
-    <string name="battery_low_percent_format" msgid="4276661262843170964">"Још <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
-    <string name="invalid_charger_title" msgid="938685362320735167">"Пуњење преко USB-а није успело"</string>
-    <string name="invalid_charger_text" msgid="2339310107232691577">"Користите пуњач који сте добили уз уређај"</string>
-    <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"Желите да укључите Уштеду батерије?"</string>
-    <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"О Уштеди батерије"</string>
-    <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Укључи"</string>
-    <string name="battery_saver_start_action" msgid="8353766979886287140">"Укључи"</string>
-    <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Не, хвала"</string>
-    <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Аутоматско ротирање екрана"</string>
-    <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Дозвољавате да <xliff:g id="APPLICATION">%1$s</xliff:g> приступа уређају <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
-    <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Желите ли да дозволите да <xliff:g id="APPLICATION">%1$s</xliff:g> приступа уређају <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nОва апликација нема дозволу за снимање, али би могла да снима звук помоћу овог USB уређаја."</string>
-    <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Дозвољавате да <xliff:g id="APPLICATION">%1$s</xliff:g> приступа уређају <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
-    <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Желите ли да отворите апликацију <xliff:g id="APPLICATION">%1$s</xliff:g> да бисте користили уређај <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
-    <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Ова апликација нема дозволу за снимање, али би могла да снима звук помоћу овог USB уређаја. Ако користите апликацију <xliff:g id="APPLICATION">%1$s</xliff:g> са овим уређајем, можда нећете чути позиве, обавештења и аларме."</string>
-    <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Ако користите апликацију <xliff:g id="APPLICATION">%1$s</xliff:g> са овим уређајем, можда нећете чути позиве, обавештења и аларме."</string>
-    <string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Дозвољавате да <xliff:g id="APPLICATION">%1$s</xliff:g> приступа уређају <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
-    <string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Желите да отворите <xliff:g id="APPLICATION">%1$s</xliff:g> да бисте користили <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
-    <string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Желите ли да отворите апликацију <xliff:g id="APPLICATION">%1$s</xliff:g> ради руковања уређајем <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nОва апликација нема дозволу за снимање, али би могла да снима звук помоћу овог USB уређаја."</string>
-    <string name="usb_accessory_confirm_prompt" msgid="5728408382798643421">"Желите ли да отворите апликацију <xliff:g id="APPLICATION">%1$s</xliff:g> да бисте користили уређај <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
-    <string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"Инсталиране апликације не функционишу са овим USB помоћним уређајем. Сазнајте више о њему на адреси <xliff:g id="URL">%1$s</xliff:g>"</string>
-    <string name="title_usb_accessory" msgid="1236358027511638648">"USB помоћни уређај"</string>
-    <string name="label_view" msgid="6815442985276363364">"Прикажи"</string>
-    <string name="always_use_device" msgid="210535878779644679">"Увек отварај апликацију <xliff:g id="APPLICATION">%1$s</xliff:g> када је уређај <xliff:g id="USB_DEVICE">%2$s</xliff:g> повезан"</string>
-    <string name="always_use_accessory" msgid="1977225429341838444">"Увек отварај апликацију <xliff:g id="APPLICATION">%1$s</xliff:g> када је уређај <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> повезан"</string>
-    <string name="usb_debugging_title" msgid="8274884945238642726">"Желите ли да дозволите отклањање USB грешака?"</string>
-    <string name="usb_debugging_message" msgid="5794616114463921773">"Дигитални отисак RSA кључа овог рачунара је:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
-    <string name="usb_debugging_always" msgid="4003121804294739548">"Увек дозволи са овог рачунара"</string>
-    <string name="usb_debugging_allow" msgid="1722643858015321328">"Дозволи"</string>
-    <string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Отклањање грешака на USB-у није дозвољено"</string>
-    <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Корисник који је тренутно пријављен на овај уређај не може да укључи отклањање грешака на USB-у. Да бисте користили ову функцију, пребаците на примарног корисника."</string>
-    <string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Да ли желите да промените језик система на <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
-    <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Други уређај је затражио промену језика система"</string>
-    <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Промени језик"</string>
-    <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Задржи актуелни језик"</string>
-    <string name="wifi_debugging_title" msgid="7300007687492186076">"Желите да дозволите бежично отклањање грешака на овој мрежи?"</string>
-    <string name="wifi_debugging_message" msgid="5461204211731802995">"Назив мреже (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi адреса (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string>
-    <string name="wifi_debugging_always" msgid="2968383799517975155">"Увек дозволи на овој мрежи"</string>
-    <string name="wifi_debugging_allow" msgid="4573224609684957886">"Дозволи"</string>
-    <string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Бежично отклањање грешака није дозвољено"</string>
-    <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Корисник који је тренутно пријављен на овај уређај не може да укључи бежично отклањање грешака. Да бисте користили ову функцију, пређите на примарног корисника."</string>
-    <string name="usb_contaminant_title" msgid="894052515034594113">"USB порт је онемогућен"</string>
-    <string name="usb_contaminant_message" msgid="7730476585174719805">"Да би се уређај заштитио од течности или нечистоће, USB порт је онемогућен и неће откривати додатну опрему.\n\nОбавестићемо вас када поново будете могли да користите USB порт."</string>
-    <string name="usb_port_enabled" msgid="531823867664717018">"USB порт је омогућен ради откривања пуњача и додатне опреме"</string>
-    <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="9097102067802412936">"Smart Lock је онемогућен"</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>
-    <string name="screenshot_saved_title" msgid="8893267638659083153">"Снимак екрана је сачуван"</string>
-    <string name="screenshot_failed_title" msgid="3259148215671936891">"Чување снимка екрана није успело"</string>
-    <string name="screenshot_failed_to_save_user_locked_text" msgid="6156607948256936920">"Уређај мора да буде откључан да би снимак екрана могао да се сачува"</string>
-    <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Пробајте да поново направите снимак екрана"</string>
-    <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Чување снимка екрана није успело"</string>
-    <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Апликација или организација не дозвољавају прављење снимака екрана"</string>
-    <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"ИТ администратор блокира прављење снимака екрана"</string>
-    <string name="screenshot_edit_label" msgid="8754981973544133050">"Измени"</string>
-    <string name="screenshot_edit_description" msgid="3333092254706788906">"Измените снимак екрана"</string>
-    <string name="screenshot_share_description" msgid="2861628935812656612">"Делите снимак екрана"</string>
-    <string name="screenshot_scroll_label" msgid="2930198809899329367">"Снимите још"</string>
-    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Одбаците снимак екрана"</string>
-    <string name="screenshot_preview_description" msgid="7606510140714080474">"Преглед снимка екрана"</string>
-    <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Горња ивица <xliff:g id="PERCENT">%1$d</xliff:g> посто"</string>
-    <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Доња ивица <xliff:g id="PERCENT">%1$d</xliff:g> посто"</string>
-    <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Лева ивица <xliff:g id="PERCENT">%1$d</xliff:g> посто"</string>
-    <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Десна ивица <xliff:g id="PERCENT">%1$d</xliff:g> посто"</string>
-    <string name="screenrecord_name" msgid="2596401223859996572">"Снимач екрана"</string>
-    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обрађујемо видео снимка екрана"</string>
-    <string name="screenrecord_channel_description" msgid="4147077128486138351">"Обавештење о сесији снимања екрана је активно"</string>
-    <string name="screenrecord_start_label" msgid="1750350278888217473">"Желите да започнете снимање?"</string>
-    <string name="screenrecord_description" msgid="1123231719680353736">"Током снимања Android систем може да сними осетљиве информације које су видљиве на екрану или које се пуштају на уређају. То обухвата лозинке, информације о плаћању, слике, поруке и звук."</string>
-    <string name="screenrecord_option_entire_screen" msgid="1732437834603426934">"Снимај цео екран"</string>
-    <string name="screenrecord_option_single_app" msgid="5954863081500035825">"Снимај једну апликацију"</string>
-    <string name="screenrecord_warning_entire_screen" msgid="8141407178104195610">"Android има приступ комплетном садржају који је видљив на екрану или се пушта на уређају док снимате. Будите пажљиви са лозинкама, информацијама о плаћању, порукама или другим осетљивим информацијама."</string>
-    <string name="screenrecord_warning_single_app" msgid="7760723997065948283">"Када снимате апликацију, Android има приступ комплетном садржају који је видљив или се пушта у тој апликацији. Будите пажљиви са лозинкама, информацијама о плаћању, порукама или другим осетљивим информацијама."</string>
-    <string name="screenrecord_start_recording" msgid="348286842544768740">"Започни снимање"</string>
-    <string name="screenrecord_audio_label" msgid="6183558856175159629">"Снимај звук"</string>
-    <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Звук уређаја"</string>
-    <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Звук са уређаја, на пример, музика, позиви и мелодије звона"</string>
-    <string name="screenrecord_mic_label" msgid="2111264835791332350">"Микрофон"</string>
-    <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Звук уређаја и микрофон"</string>
-    <string name="screenrecord_start" msgid="330991441575775004">"Покрени"</string>
-    <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Снима се екран"</string>
-    <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Снимају се екран и звук"</string>
-    <string name="screenrecord_taps_label" msgid="1595690528298857649">"Приказуј додире на екрану"</string>
-    <string name="screenrecord_stop_label" msgid="72699670052087989">"Заустави"</string>
-    <string name="screenrecord_share_label" msgid="5025590804030086930">"Дели"</string>
-    <string name="screenrecord_save_title" msgid="1886652605520893850">"Снимак екрана је сачуван"</string>
-    <string name="screenrecord_save_text" msgid="3008973099800840163">"Додирните да бисте прегледали"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Дошло је до проблема при брисању снимка екрана"</string>
-    <string name="screenrecord_start_error" msgid="2200660692479682368">"Грешка при покретању снимања екрана"</string>
-    <string name="accessibility_back" msgid="6530104400086152611">"Назад"</string>
-    <string name="accessibility_home" msgid="5430449841237966217">"Почетна"</string>
-    <string name="accessibility_menu" msgid="2701163794470513040">"Мени"</string>
-    <string name="accessibility_accessibility_button" msgid="4089042473497107709">"Приступачност"</string>
-    <string name="accessibility_rotate_button" msgid="1238584767612362586">"Ротирајте екран"</string>
-    <string name="accessibility_recent" msgid="901641734769533575">"Преглед"</string>
-    <string name="accessibility_camera_button" msgid="2938898391716647247">"Камера"</string>
-    <string name="accessibility_phone_button" msgid="4256353121703100427">"Телефон"</string>
-    <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Гласовна помоћ"</string>
-    <string name="accessibility_wallet_button" msgid="1458258783460555507">"Новчаник"</string>
-    <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Скенер QR кода"</string>
-    <string name="accessibility_unlock_button" msgid="3613812140816244310">"Откључано"</string>
-    <string name="accessibility_lock_icon" msgid="661492842417875775">"Уређај је закључан"</string>
-    <string name="accessibility_scanning_face" msgid="3093828357921541387">"Скенирање лица"</string>
-    <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Пошаљи"</string>
-    <string name="cancel" msgid="1089011503403416730">"Откажи"</string>
-    <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Потврди"</string>
-    <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Пробај поново"</string>
-    <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Додирните да бисте отказали потврду идентитета"</string>
-    <string name="biometric_dialog_face_icon_description_idle" msgid="4351777022315116816">"Пробајте поново"</string>
-    <string name="biometric_dialog_face_icon_description_authenticating" msgid="3401633342366146535">"Тражи се ваше лице"</string>
-    <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Лице је потврђено"</string>
-    <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Потврђено"</string>
-    <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Додирните Потврди да бисте завршили"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Откључано је лицем. Притисните икону откључавања за наставак"</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>
-    <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Користите PIN"</string>
-    <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Користите шаблон"</string>
-    <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Користите лозинку"</string>
-    <string name="biometric_dialog_wrong_pin" msgid="1878539073972762803">"Погрешан PIN"</string>
-    <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Погрешан шаблон"</string>
-    <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Погрешна лозинка"</string>
-    <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Превише нетачних покушаја.\n Пробајте поново за <xliff:g id="NUMBER">%d</xliff:g> сек."</string>
-    <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Пробајте поново. <xliff:g id="ATTEMPTS_0">%1$d</xliff:g>. покушај од <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string>
-    <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Подаци ће се избрисати"</string>
-    <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Ако унесете нетачан шаблон при следећем покушају, избрисаћемо податке са овог уређаја."</string>
-    <string name="biometric_dialog_last_pin_attempt_before_wipe_device" msgid="9151756675698215723">"Ако унесете нетачан PIN при следећем покушају, избрисаћемо податке са овог уређаја."</string>
-    <string name="biometric_dialog_last_password_attempt_before_wipe_device" msgid="2363778585575998317">"Ако унесете нетачну лозинку при следећем покушају, избрисаћемо податке са овог уређаја."</string>
-    <string name="biometric_dialog_last_pattern_attempt_before_wipe_user" msgid="8400180746043407270">"Ако унесете нетачан шаблон при следећем покушају, избрисаћемо овог корисника."</string>
-    <string name="biometric_dialog_last_pin_attempt_before_wipe_user" msgid="4159878829962411168">"Ако унесете нетачан PIN при следећем покушају, избрисаћемо овог корисника."</string>
-    <string name="biometric_dialog_last_password_attempt_before_wipe_user" msgid="4695682515465063885">"Ако унесете нетачну лозинку при следећем покушају, избрисаћемо овог корисника."</string>
-    <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ако унесете нетачан шаблон при следећем покушају, избрисаћемо пословни профил и његове податке."</string>
-    <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ако унесете нетачан PIN при следећем покушају, избрисаћемо пословни профил и његове податке."</string>
-    <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ако унесете нетачну лозинку при следећем покушају, избрисаћемо пословни профил и његове податке."</string>
-    <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Додирните сензор за отисак прста"</string>
-    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Икона отиска прста"</string>
-    <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Лице није препознато. Користите отисак прста."</string>
+    <string name="app_label" msgid="4811759950673118541">"UI sistema"</string>
+    <string name="battery_low_title" msgid="5319680173344341779">"Želite li da uključite Uštedu baterije?"</string>
+    <string name="battery_low_description" msgid="3282977755476423966">"Preostali nivo napunjenosti baterije je <xliff:g id="PERCENTAGE">%s</xliff:g>. Ušteda baterije uključuje Tamnu temu, ograničava aktivnosti u pozadini i odlaže obaveštenja."</string>
+    <string name="battery_low_intro" msgid="5148725009653088790">"Ušteda baterije uključuje Tamnu temu, ograničava aktivnosti u pozadini i odlaže obaveštenja."</string>
+    <string name="battery_low_percent_format" msgid="4276661262843170964">"Još <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
+    <string name="invalid_charger_title" msgid="938685362320735167">"Punjenje preko USB-a nije uspelo"</string>
+    <string name="invalid_charger_text" msgid="2339310107232691577">"Koristite punjač koji ste dobili uz uređaj"</string>
+    <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"Želite da uključite Uštedu baterije?"</string>
+    <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"O Uštedi baterije"</string>
+    <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Uključi"</string>
+    <string name="battery_saver_start_action" msgid="8353766979886287140">"Uključi"</string>
+    <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Ne, hvala"</string>
+    <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Automatsko rotiranje ekrana"</string>
+    <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Dozvoljavate da <xliff:g id="APPLICATION">%1$s</xliff:g> pristupa uređaju <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+    <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Želite li da dozvolite da <xliff:g id="APPLICATION">%1$s</xliff:g> pristupa uređaju <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nOva aplikacija nema dozvolu za snimanje, ali bi mogla da snima zvuk pomoću ovog USB uređaja."</string>
+    <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Dozvoljavate da <xliff:g id="APPLICATION">%1$s</xliff:g> pristupa uređaju <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+    <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Želite li da otvorite aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> da biste koristili uređaj <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+    <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Ova aplikacija nema dozvolu za snimanje, ali bi mogla da snima zvuk pomoću ovog USB uređaja. Ako koristite aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> sa ovim uređajem, možda nećete čuti pozive, obaveštenja i alarme."</string>
+    <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Ako koristite aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> sa ovim uređajem, možda nećete čuti pozive, obaveštenja i alarme."</string>
+    <string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Dozvoljavate da <xliff:g id="APPLICATION">%1$s</xliff:g> pristupa uređaju <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
+    <string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Želite da otvorite <xliff:g id="APPLICATION">%1$s</xliff:g> da biste koristili <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+    <string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Želite li da otvorite aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> radi rukovanja uređajem <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nOva aplikacija nema dozvolu za snimanje, ali bi mogla da snima zvuk pomoću ovog USB uređaja."</string>
+    <string name="usb_accessory_confirm_prompt" msgid="5728408382798643421">"Želite li da otvorite aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> da biste koristili uređaj <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
+    <string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"Instalirane aplikacije ne funkcionišu sa ovim USB pomoćnim uređajem. Saznajte više o njemu na adresi <xliff:g id="URL">%1$s</xliff:g>"</string>
+    <string name="title_usb_accessory" msgid="1236358027511638648">"USB pomoćni uređaj"</string>
+    <string name="label_view" msgid="6815442985276363364">"Prikaži"</string>
+    <string name="always_use_device" msgid="210535878779644679">"Uvek otvaraj aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> kada je uređaj <xliff:g id="USB_DEVICE">%2$s</xliff:g> povezan"</string>
+    <string name="always_use_accessory" msgid="1977225429341838444">"Uvek otvaraj aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> kada je uređaj <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> povezan"</string>
+    <string name="usb_debugging_title" msgid="8274884945238642726">"Želite li da dozvolite otklanjanje USB grešaka?"</string>
+    <string name="usb_debugging_message" msgid="5794616114463921773">"Digitalni otisak RSA ključa ovog računara je:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_always" msgid="4003121804294739548">"Uvek dozvoli sa ovog računara"</string>
+    <string name="usb_debugging_allow" msgid="1722643858015321328">"Dozvoli"</string>
+    <string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Otklanjanje grešaka na USB-u nije dozvoljeno"</string>
+    <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Korisnik koji je trenutno prijavljen na ovaj uređaj ne može da uključi otklanjanje grešaka na USB-u. Da biste koristili ovu funkciju, prebacite na primarnog korisnika."</string>
+    <string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Da li želite da promenite jezik sistema na <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
+    <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Drugi uređaj je zatražio promenu jezika sistema"</string>
+    <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Promeni jezik"</string>
+    <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Zadrži aktuelni jezik"</string>
+    <string name="wifi_debugging_title" msgid="7300007687492186076">"Želite da dozvolite bežično otklanjanje grešaka na ovoj mreži?"</string>
+    <string name="wifi_debugging_message" msgid="5461204211731802995">"Naziv mreže (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi adresa (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string>
+    <string name="wifi_debugging_always" msgid="2968383799517975155">"Uvek dozvoli na ovoj mreži"</string>
+    <string name="wifi_debugging_allow" msgid="4573224609684957886">"Dozvoli"</string>
+    <string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Bežično otklanjanje grešaka nije dozvoljeno"</string>
+    <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Korisnik koji je trenutno prijavljen na ovaj uređaj ne može da uključi bežično otklanjanje grešaka. Da biste koristili ovu funkciju, pređite na primarnog korisnika."</string>
+    <string name="usb_contaminant_title" msgid="894052515034594113">"USB port je onemogućen"</string>
+    <string name="usb_contaminant_message" msgid="7730476585174719805">"Da bi se uređaj zaštitio od tečnosti ili nečistoće, USB port je onemogućen i neće otkrivati dodatnu opremu.\n\nObavestićemo vas kada ponovo budete mogli da koristite USB port."</string>
+    <string name="usb_port_enabled" msgid="531823867664717018">"USB port je omogućen radi otkrivanja punjača i dodatne opreme"</string>
+    <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Omogući USB"</string>
+    <string name="learn_more" msgid="4690632085667273811">"Saznajte više"</string>
+    <string name="global_action_screenshot" msgid="2760267567509131654">"Snimak ekrana"</string>
+    <string name="global_action_smart_lock_disabled" msgid="9097102067802412936">"Smart Lock je onemogućen"</string>
+    <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"je poslao/la sliku"</string>
+    <string name="screenshot_saving_title" msgid="2298349784913287333">"Čuvanje snimka ekrana..."</string>
+    <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Snimak ekrana se čuva na poslovnom profilu…"</string>
+    <string name="screenshot_saved_title" msgid="8893267638659083153">"Snimak ekrana je sačuvan"</string>
+    <string name="screenshot_failed_title" msgid="3259148215671936891">"Čuvanje snimka ekrana nije uspelo"</string>
+    <string name="screenshot_failed_to_save_user_locked_text" msgid="6156607948256936920">"Uređaj mora da bude otključan da bi snimak ekrana mogao da se sačuva"</string>
+    <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Probajte da ponovo napravite snimak ekrana"</string>
+    <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Čuvanje snimka ekrana nije uspelo"</string>
+    <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Aplikacija ili organizacija ne dozvoljavaju pravljenje snimaka ekrana"</string>
+    <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"IT administrator blokira pravljenje snimaka ekrana"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Izmeni"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Izmenite snimak ekrana"</string>
+    <string name="screenshot_share_description" msgid="2861628935812656612">"Delite snimak ekrana"</string>
+    <string name="screenshot_scroll_label" msgid="2930198809899329367">"Snimite još"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Odbacite snimak ekrana"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Odbaci poruku poslovnog profila"</string>
+    <string name="screenshot_preview_description" msgid="7606510140714080474">"Pregled snimka ekrana"</string>
+    <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Gornja ivica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
+    <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Donja ivica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
+    <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Leva ivica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
+    <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Desna ivica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
+    <string name="screenrecord_name" msgid="2596401223859996572">"Snimač ekrana"</string>
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrađujemo video snimka ekrana"</string>
+    <string name="screenrecord_channel_description" msgid="4147077128486138351">"Obaveštenje o sesiji snimanja ekrana je aktivno"</string>
+    <string name="screenrecord_start_label" msgid="1750350278888217473">"Želite da započnete snimanje?"</string>
+    <string name="screenrecord_description" msgid="1123231719680353736">"Tokom snimanja Android sistem može da snimi osetljive informacije koje su vidljive na ekranu ili koje se puštaju na uređaju. To obuhvata lozinke, informacije o plaćanju, slike, poruke i zvuk."</string>
+    <string name="screenrecord_option_entire_screen" msgid="1732437834603426934">"Snimaj ceo ekran"</string>
+    <string name="screenrecord_option_single_app" msgid="5954863081500035825">"Snimaj jednu aplikaciju"</string>
+    <string name="screenrecord_warning_entire_screen" msgid="8141407178104195610">"Android ima pristup kompletnom sadržaju koji je vidljiv na ekranu ili se pušta na uređaju dok snimate. Budite pažljivi sa lozinkama, informacijama o plaćanju, porukama ili drugim osetljivim informacijama."</string>
+    <string name="screenrecord_warning_single_app" msgid="7760723997065948283">"Kada snimate aplikaciju, Android ima pristup kompletnom sadržaju koji je vidljiv ili se pušta u toj aplikaciji. Budite pažljivi sa lozinkama, informacijama o plaćanju, porukama ili drugim osetljivim informacijama."</string>
+    <string name="screenrecord_start_recording" msgid="348286842544768740">"Započni snimanje"</string>
+    <string name="screenrecord_audio_label" msgid="6183558856175159629">"Snimaj zvuk"</string>
+    <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Zvuk uređaja"</string>
+    <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Zvuk sa uređaja, na primer, muzika, pozivi i melodije zvona"</string>
+    <string name="screenrecord_mic_label" msgid="2111264835791332350">"Mikrofon"</string>
+    <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Zvuk uređaja i mikrofon"</string>
+    <string name="screenrecord_start" msgid="330991441575775004">"Pokreni"</string>
+    <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Snima se ekran"</string>
+    <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Snimaju se ekran i zvuk"</string>
+    <string name="screenrecord_taps_label" msgid="1595690528298857649">"Prikazuj dodire na ekranu"</string>
+    <string name="screenrecord_stop_label" msgid="72699670052087989">"Zaustavi"</string>
+    <string name="screenrecord_share_label" msgid="5025590804030086930">"Deli"</string>
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"Snimak ekrana je sačuvan"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"Dodirnite da biste pregledali"</string>
+    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Došlo je do problema pri brisanju snimka ekrana"</string>
+    <string name="screenrecord_start_error" msgid="2200660692479682368">"Greška pri pokretanju snimanja ekrana"</string>
+    <string name="accessibility_back" msgid="6530104400086152611">"Nazad"</string>
+    <string name="accessibility_home" msgid="5430449841237966217">"Početna"</string>
+    <string name="accessibility_menu" msgid="2701163794470513040">"Meni"</string>
+    <string name="accessibility_accessibility_button" msgid="4089042473497107709">"Pristupačnost"</string>
+    <string name="accessibility_rotate_button" msgid="1238584767612362586">"Rotirajte ekran"</string>
+    <string name="accessibility_recent" msgid="901641734769533575">"Pregled"</string>
+    <string name="accessibility_camera_button" msgid="2938898391716647247">"Kamera"</string>
+    <string name="accessibility_phone_button" msgid="4256353121703100427">"Telefon"</string>
+    <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Glasovna pomoć"</string>
+    <string name="accessibility_wallet_button" msgid="1458258783460555507">"Novčanik"</string>
+    <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Skener QR koda"</string>
+    <string name="accessibility_unlock_button" msgid="3613812140816244310">"Otključano"</string>
+    <string name="accessibility_lock_icon" msgid="661492842417875775">"Uređaj je zaključan"</string>
+    <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skeniranje lica"</string>
+    <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Pošalji"</string>
+    <string name="cancel" msgid="1089011503403416730">"Otkaži"</string>
+    <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potvrdi"</string>
+    <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Probaj ponovo"</string>
+    <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Dodirnite da biste otkazali potvrdu identiteta"</string>
+    <string name="biometric_dialog_face_icon_description_idle" msgid="4351777022315116816">"Probajte ponovo"</string>
+    <string name="biometric_dialog_face_icon_description_authenticating" msgid="3401633342366146535">"Traži se vaše lice"</string>
+    <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Lice je potvrđeno"</string>
+    <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrđeno"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Dodirnite Potvrdi da biste završili"</string>
+    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Otključano je licem. Pritisnite ikonu otključavanja za nastavak"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Otključano je licem. Pritisnite da biste nastavili."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Lice je prepoznato. Pritisnite da biste nastavili."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Lice prepoznato. Pritisnite ikonu otključavanja za nastavak."</string>
+    <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Identitet je potvrđen"</string>
+    <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Koristite PIN"</string>
+    <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Koristite šablon"</string>
+    <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Koristite lozinku"</string>
+    <string name="biometric_dialog_wrong_pin" msgid="1878539073972762803">"Pogrešan PIN"</string>
+    <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Pogrešan šablon"</string>
+    <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Pogrešna lozinka"</string>
+    <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Previše netačnih pokušaja.\n Probajte ponovo za <xliff:g id="NUMBER">%d</xliff:g> sek."</string>
+    <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Probajte ponovo. <xliff:g id="ATTEMPTS_0">%1$d</xliff:g>. pokušaj od <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string>
+    <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Podaci će se izbrisati"</string>
+    <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Ako unesete netačan šablon pri sledećem pokušaju, izbrisaćemo podatke sa ovog uređaja."</string>
+    <string name="biometric_dialog_last_pin_attempt_before_wipe_device" msgid="9151756675698215723">"Ako unesete netačan PIN pri sledećem pokušaju, izbrisaćemo podatke sa ovog uređaja."</string>
+    <string name="biometric_dialog_last_password_attempt_before_wipe_device" msgid="2363778585575998317">"Ako unesete netačnu lozinku pri sledećem pokušaju, izbrisaćemo podatke sa ovog uređaja."</string>
+    <string name="biometric_dialog_last_pattern_attempt_before_wipe_user" msgid="8400180746043407270">"Ako unesete netačan šablon pri sledećem pokušaju, izbrisaćemo ovog korisnika."</string>
+    <string name="biometric_dialog_last_pin_attempt_before_wipe_user" msgid="4159878829962411168">"Ako unesete netačan PIN pri sledećem pokušaju, izbrisaćemo ovog korisnika."</string>
+    <string name="biometric_dialog_last_password_attempt_before_wipe_user" msgid="4695682515465063885">"Ako unesete netačnu lozinku pri sledećem pokušaju, izbrisaćemo ovog korisnika."</string>
+    <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ako unesete netačan šablon pri sledećem pokušaju, izbrisaćemo poslovni profil i njegove podatke."</string>
+    <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ako unesete netačan PIN pri sledećem pokušaju, izbrisaćemo poslovni profil i njegove podatke."</string>
+    <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ako unesete netačnu lozinku pri sledećem pokušaju, izbrisaćemo poslovni profil i njegove podatke."</string>
+    <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Dodirnite senzor za otisak prsta"</string>
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ikona otiska prsta"</string>
+    <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Lice nije prepoznato. Koristite otisak prsta."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
     <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="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>
-    <string name="accessibility_cast_name" msgid="7344437925388773685">"Повезани смо са уређајем <xliff:g id="CAST">%s</xliff:g>."</string>
-    <string name="accessibility_not_connected" msgid="4061305616351042142">"Није повезано."</string>
-    <string name="data_connection_roaming" msgid="375650836665414797">"Роминг"</string>
-    <string name="cell_data_off" msgid="4886198950247099526">"Искључено"</string>
-    <string name="accessibility_airplane_mode" msgid="1899529214045998505">"Режим рада у авиону."</string>
-    <string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN је укључен."</string>
-    <string name="accessibility_battery_level" msgid="5143715405241138822">"Батерија је на <xliff:g id="NUMBER">%d</xliff:g> посто."</string>
-    <string name="accessibility_battery_level_with_estimate" msgid="6548654589315074529">"Батерија је на <xliff:g id="PERCENTAGE">%1$d</xliff:g> посто, <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Батерија се пуни, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> посто."</string>
-    <string name="accessibility_battery_level_charging_paused" msgid="3560711496775146763">"Батерија је на <xliff:g id="PERCENTAGE">%d</xliff:g> посто, пуњење је паузирано да би се заштитила батерија."</string>
-    <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="2223541217743647858">"Батерија је на <xliff:g id="PERCENTAGE">%1$d</xliff:g> посто, <xliff:g id="TIME">%2$s</xliff:g>, пуњење је паузирано да би се заштитила батерија."</string>
-    <string name="accessibility_overflow_action" msgid="8555835828182509104">"Погледајте сва обавештења"</string>
-    <string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter је омогућен."</string>
-    <string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Вибрација звона."</string>
-    <string name="accessibility_ringer_silent" msgid="8994620163934249882">"Нечујно звоно."</string>
+    <string name="keyguard_face_failed" msgid="9044619102286917151">"Lice nije prepoznato"</string>
+    <string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Koristite otisak prsta"</string>
+    <string name="keyguard_face_unlock_unavailable" msgid="1581949044193418736">"Otključavanje licem nije dostupno"</string>
+    <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth je priključen."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Procenat napunjenosti baterije nije poznat."</string>
+    <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Povezani ste sa <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
+    <string name="accessibility_cast_name" msgid="7344437925388773685">"Povezani smo sa uređajem <xliff:g id="CAST">%s</xliff:g>."</string>
+    <string name="accessibility_not_connected" msgid="4061305616351042142">"Nije povezano."</string>
+    <string name="data_connection_roaming" msgid="375650836665414797">"Roming"</string>
+    <string name="cell_data_off" msgid="4886198950247099526">"Isključeno"</string>
+    <string name="accessibility_airplane_mode" msgid="1899529214045998505">"Režim rada u avionu."</string>
+    <string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN je uključen."</string>
+    <string name="accessibility_battery_level" msgid="5143715405241138822">"Baterija je na <xliff:g id="NUMBER">%d</xliff:g> posto."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="6548654589315074529">"Baterija je na <xliff:g id="PERCENTAGE">%1$d</xliff:g> posto, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Baterija se puni, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> posto."</string>
+    <string name="accessibility_battery_level_charging_paused" msgid="3560711496775146763">"Baterija je na <xliff:g id="PERCENTAGE">%d</xliff:g> posto, punjenje je pauzirano da bi se zaštitila baterija."</string>
+    <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="2223541217743647858">"Baterija je na <xliff:g id="PERCENTAGE">%1$d</xliff:g> posto, <xliff:g id="TIME">%2$s</xliff:g>, punjenje je pauzirano da bi se zaštitila baterija."</string>
+    <string name="accessibility_overflow_action" msgid="8555835828182509104">"Pogledajte sva obaveštenja"</string>
+    <string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter je omogućen."</string>
+    <string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Vibracija zvona."</string>
+    <string name="accessibility_ringer_silent" msgid="8994620163934249882">"Nečujno zvono."</string>
     <!-- no translation found for accessibility_casting (8708751252897282313) -->
     <skip />
-    <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Прозор са обавештењима."</string>
-    <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Брза подешавања."</string>
-    <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Закључан екран."</string>
-    <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Закључан екран за посао"</string>
-    <string name="accessibility_desc_close" msgid="8293708213442107755">"Затвори"</string>
-    <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"потпуна тишина"</string>
-    <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"само аларми"</string>
-    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Не узнемиравај."</string>
+    <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Prozor sa obaveštenjima."</string>
+    <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Brza podešavanja."</string>
+    <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Zaključan ekran."</string>
+    <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Zaključan ekran za posao"</string>
+    <string name="accessibility_desc_close" msgid="8293708213442107755">"Zatvori"</string>
+    <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"potpuna tišina"</string>
+    <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"samo alarmi"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Ne uznemiravaj."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
-    <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth је укључен."</string>
-    <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Аларм је подешен за <xliff:g id="TIME">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_more_time" msgid="7646479831704665284">"Више времена."</string>
-    <string name="accessibility_quick_settings_less_time" msgid="9110364286464977870">"Мање времена."</string>
-    <string name="accessibility_casting_turned_off" msgid="1387906158563374962">"Пребацивање екрана је заустављено."</string>
-    <string name="accessibility_brightness" msgid="5391187016177823721">"Осветљеност екрана"</string>
-    <string name="data_usage_disabled_dialog_mobile_title" msgid="2286843518689837719">"Мобилни подаци су паузирани"</string>
-    <string name="data_usage_disabled_dialog_title" msgid="9131615296036724838">"Подаци су паузирани"</string>
-    <string name="data_usage_disabled_dialog" msgid="7933201635215099780">"Достигли се ограничење за податке које сте подесили. Више не користите мобилне податке.\n\nАко наставите, можда ће важити тарифе за потрошњу података."</string>
-    <string name="data_usage_disabled_dialog_enable" msgid="2796648546086408937">"Настави"</string>
-    <string name="accessibility_location_active" msgid="2845747916764660369">"Има активних захтева за локацију"</string>
-    <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Сензори су искључени"</string>
-    <string name="accessibility_clear_all" msgid="970525598287244592">"Обриши сва обавештења."</string>
-    <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"и још <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Унутра је још # обавештење.}one{Унутра је још # обавештење.}few{Унутра су још # обавештења.}other{Унутра је још # обавештења.}}"</string>
-    <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Екран је закључан у хоризонталном положају."</string>
-    <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Екран је закључан у вертикалном положају."</string>
-    <string name="dessert_case" msgid="9104973640704357717">"Витрина са посластицама"</string>
-    <string name="start_dreams" msgid="9131802557946276718">"Чувар екрана"</string>
-    <string name="ethernet_label" msgid="2203544727007463351">"Етернет"</string>
-    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Не узнемиравај"</string>
+    <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth je uključen."</string>
+    <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarm je podešen za <xliff:g id="TIME">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_more_time" msgid="7646479831704665284">"Više vremena."</string>
+    <string name="accessibility_quick_settings_less_time" msgid="9110364286464977870">"Manje vremena."</string>
+    <string name="accessibility_casting_turned_off" msgid="1387906158563374962">"Prebacivanje ekrana je zaustavljeno."</string>
+    <string name="accessibility_brightness" msgid="5391187016177823721">"Osvetljenost ekrana"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="2286843518689837719">"Mobilni podaci su pauzirani"</string>
+    <string name="data_usage_disabled_dialog_title" msgid="9131615296036724838">"Podaci su pauzirani"</string>
+    <string name="data_usage_disabled_dialog" msgid="7933201635215099780">"Dostigli se ograničenje za podatke koje ste podesili. Više ne koristite mobilne podatke.\n\nAko nastavite, možda će važiti tarife za potrošnju podataka."</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="2796648546086408937">"Nastavi"</string>
+    <string name="accessibility_location_active" msgid="2845747916764660369">"Ima aktivnih zahteva za lokaciju"</string>
+    <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Senzori su isključeni"</string>
+    <string name="accessibility_clear_all" msgid="970525598287244592">"Obriši sva obaveštenja."</string>
+    <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"i još <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Unutra je još # obaveštenje.}one{Unutra je još # obaveštenje.}few{Unutra su još # obaveštenja.}other{Unutra je još # obaveštenja.}}"</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Ekran je zaključan u horizontalnom položaju."</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Ekran je zaključan u vertikalnom položaju."</string>
+    <string name="dessert_case" msgid="9104973640704357717">"Vitrina sa poslasticama"</string>
+    <string name="start_dreams" msgid="9131802557946276718">"Čuvar ekrana"</string>
+    <string name="ethernet_label" msgid="2203544727007463351">"Eternet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne uznemiravaj"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
-    <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Није доступан ниједан упарени уређај"</string>
-    <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
-    <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудио"</string>
-    <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Слушалице"</string>
-    <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Унос"</string>
-    <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"Слушни апарати"</string>
-    <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Укључује се..."</string>
-    <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Аутоматска ротација"</string>
-    <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Аутоматско ротирање екрана"</string>
-    <string name="quick_settings_location_label" msgid="2621868789013389163">"Локација"</string>
-    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Чувар екрана"</string>
-    <string name="quick_settings_camera_label" msgid="5612076679385269339">"Приступ камери"</string>
-    <string name="quick_settings_mic_label" msgid="8392773746295266375">"Приступ микрофону"</string>
-    <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Доступно"</string>
-    <string name="quick_settings_camera_mic_blocked" msgid="4710884905006788281">"Блокирано"</string>
-    <string name="quick_settings_media_device_label" msgid="8034019242363789941">"Медијски уређај"</string>
-    <string name="quick_settings_user_title" msgid="8673045967216204537">"Корисник"</string>
+    <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nije dostupan nijedan upareni uređaj"</string>
+    <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
+    <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
+    <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Slušalice"</string>
+    <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Unos"</string>
+    <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"Slušni aparati"</string>
+    <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Uključuje se..."</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatska rotacija"</string>
+    <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatsko rotiranje ekrana"</string>
+    <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokacija"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Čuvar ekrana"</string>
+    <string name="quick_settings_camera_label" msgid="5612076679385269339">"Pristup kameri"</string>
+    <string name="quick_settings_mic_label" msgid="8392773746295266375">"Pristup mikrofonu"</string>
+    <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Dostupno"</string>
+    <string name="quick_settings_camera_mic_blocked" msgid="4710884905006788281">"Blokirano"</string>
+    <string name="quick_settings_media_device_label" msgid="8034019242363789941">"Medijski uređaj"</string>
+    <string name="quick_settings_user_title" msgid="8673045967216204537">"Korisnik"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"WiFi"</string>
-    <string name="quick_settings_internet_label" msgid="6603068555872455463">"Интернет"</string>
-    <string name="quick_settings_networks_available" msgid="1875138606855420438">"Мреже су доступне"</string>
-    <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Мреже нису доступне"</string>
-    <string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"Није доступна ниједна WiFi мрежа"</string>
-    <string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"Укључује се..."</string>
-    <string name="quick_settings_cast_title" msgid="2279220930629235211">"Пребацивање екрана"</string>
-    <string name="quick_settings_casting" msgid="1435880708719268055">"Пребацивање"</string>
-    <string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"Неименовани уређај"</string>
-    <string name="quick_settings_cast_detail_empty_text" msgid="2846282280014617785">"Није доступан ниједан уређај"</string>
-    <string name="quick_settings_cast_no_wifi" msgid="6980194769795014875">"WiFi није повезан"</string>
-    <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Осветљеност"</string>
-    <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Инверзија боја"</string>
-    <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Корекција боја"</string>
-    <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Управљаjте корисницима"</string>
-    <string name="quick_settings_done" msgid="2163641301648855793">"Готово"</string>
-    <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Затвори"</string>
-    <string name="quick_settings_connected" msgid="3873605509184830379">"Повезан"</string>
-    <string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"Повезано, ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
-    <string name="quick_settings_connecting" msgid="2381969772953268809">"Повезује се..."</string>
-    <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Хотспот"</string>
-    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Укључује се..."</string>
-    <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Уштеда података је укључена"</string>
-    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# уређај}one{# уређај}few{# уређаја}other{# уређаја}}"</string>
-    <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Лампа"</string>
-    <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Користи се камера"</string>
-    <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Мобилни подаци"</string>
-    <string name="quick_settings_cellular_detail_data_usage" msgid="6105969068871138427">"Потрошња података"</string>
-    <string name="quick_settings_cellular_detail_remaining_data" msgid="1136599216568805644">"Преостала количина података"</string>
-    <string name="quick_settings_cellular_detail_over_limit" msgid="4561921367680636235">"Преко ограничења"</string>
-    <string name="quick_settings_cellular_detail_data_used" msgid="6798849610647988987">"Искористили сте <xliff:g id="DATA_USED">%s</xliff:g>"</string>
-    <string name="quick_settings_cellular_detail_data_limit" msgid="1791389609409211628">"Ограничење од <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <string name="quick_settings_cellular_detail_data_warning" msgid="7957253810481086455">"Упозорење за <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <string name="quick_settings_work_mode_label" msgid="6440531507319809121">"Пословне апликације"</string>
-    <string name="quick_settings_night_display_label" msgid="8180030659141778180">"Ноћно светло"</string>
-    <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Укључује се по заласку сунца"</string>
-    <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"До изласка сунца"</string>
-    <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Укључује се у <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"До <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"Тамна тема"</string>
-    <string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"Уштеда батерије"</string>
-    <string name="quick_settings_dark_mode_secondary_label_on_at_sunset" msgid="6017379738102015710">"Укључује се по заласку сунца"</string>
-    <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"До изласка сунца"</string>
-    <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Укључује се у <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"До <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_dark_mode_secondary_label_on_at_bedtime" msgid="2274300599408864897">"Укључује се у време за спавање"</string>
-    <string name="quick_settings_dark_mode_secondary_label_until_bedtime_ends" msgid="1790772410777123685">"Док се време за спавање не заврши"</string>
+    <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
+    <string name="quick_settings_networks_available" msgid="1875138606855420438">"Mreže su dostupne"</string>
+    <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Mreže nisu dostupne"</string>
+    <string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"Nije dostupna nijedna WiFi mreža"</string>
+    <string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"Uključuje se..."</string>
+    <string name="quick_settings_cast_title" msgid="2279220930629235211">"Prebacivanje ekrana"</string>
+    <string name="quick_settings_casting" msgid="1435880708719268055">"Prebacivanje"</string>
+    <string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"Neimenovani uređaj"</string>
+    <string name="quick_settings_cast_detail_empty_text" msgid="2846282280014617785">"Nije dostupan nijedan uređaj"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="6980194769795014875">"WiFi nije povezan"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Osvetljenost"</string>
+    <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inverzija boja"</string>
+    <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Korekcija boja"</string>
+    <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Upravljajte korisnicima"</string>
+    <string name="quick_settings_done" msgid="2163641301648855793">"Gotovo"</string>
+    <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Zatvori"</string>
+    <string name="quick_settings_connected" msgid="3873605509184830379">"Povezan"</string>
+    <string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"Povezano, nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="quick_settings_connecting" msgid="2381969772953268809">"Povezuje se..."</string>
+    <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Hotspot"</string>
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Uključuje se..."</string>
+    <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Ušteda podataka je uključena"</string>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# uređaj}one{# uređaj}few{# uređaja}other{# uređaja}}"</string>
+    <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Lampa"</string>
+    <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Koristi se kamera"</string>
+    <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobilni podaci"</string>
+    <string name="quick_settings_cellular_detail_data_usage" msgid="6105969068871138427">"Potrošnja podataka"</string>
+    <string name="quick_settings_cellular_detail_remaining_data" msgid="1136599216568805644">"Preostala količina podataka"</string>
+    <string name="quick_settings_cellular_detail_over_limit" msgid="4561921367680636235">"Preko ograničenja"</string>
+    <string name="quick_settings_cellular_detail_data_used" msgid="6798849610647988987">"Iskoristili ste <xliff:g id="DATA_USED">%s</xliff:g>"</string>
+    <string name="quick_settings_cellular_detail_data_limit" msgid="1791389609409211628">"Ograničenje od <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <string name="quick_settings_cellular_detail_data_warning" msgid="7957253810481086455">"Upozorenje za <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <string name="quick_settings_work_mode_label" msgid="6440531507319809121">"Poslovne aplikacije"</string>
+    <string name="quick_settings_night_display_label" msgid="8180030659141778180">"Noćno svetlo"</string>
+    <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Uključuje se po zalasku sunca"</string>
+    <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"Do izlaska sunca"</string>
+    <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Uključuje se u <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"Do <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"Tamna tema"</string>
+    <string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"Ušteda baterije"</string>
+    <string name="quick_settings_dark_mode_secondary_label_on_at_sunset" msgid="6017379738102015710">"Uključuje se po zalasku sunca"</string>
+    <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Do izlaska sunca"</string>
+    <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Uključuje se u <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Do <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="quick_settings_dark_mode_secondary_label_on_at_bedtime" msgid="2274300599408864897">"Uključuje se u vreme za spavanje"</string>
+    <string name="quick_settings_dark_mode_secondary_label_until_bedtime_ends" msgid="1790772410777123685">"Dok se vreme za spavanje ne završi"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
-    <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC је онемогућен"</string>
-    <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC је омогућен"</string>
-    <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Снимање екрана"</string>
-    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Почните"</string>
-    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Зауставите"</string>
-    <string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Режим једном руком"</string>
-    <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Желите да одблокирате микрофон уређаја?"</string>
-    <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Желите да одблокирате камеру уређаја?"</string>
-    <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Желите да одблокирате камеру и микрофон уређаја?"</string>
-    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Овим ће се одблокирати приступ за све апликације и услуге које имају дозволу за коришћење микрофона."</string>
-    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Овим ће се одблокирати приступ за све апликације и услуге које имају дозволу за коришћење камере."</string>
-    <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Овим ће се одблокирати приступ за све апликације и услуге које имају дозволу за коришћење камере или микрофона."</string>
-    <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"Микрофон је блокиран"</string>
-    <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"Камера је блокирана"</string>
-    <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_title" msgid="195236134743281973">"Микрофон и камера су блокирани"</string>
-    <string name="sensor_privacy_start_use_mic_blocked_dialog_content" msgid="2138318880682877747">"Да бисте одблокирали, померите прекидач за приватност на уређају на позицију укључено за микрофон како бисте омогућили приступ микрофону. Погледајте приручник за уређај да бисте пронашли прекидач за приватност на уређају."</string>
-    <string name="sensor_privacy_start_use_camera_blocked_dialog_content" msgid="7216015168047965948">"Да бисте одблокирали, померите прекидач за приватност на уређају на позицију укључено за камеру како бисте омогућили приступ камери. Погледајте приручник за уређај да бисте пронашли прекидач за приватност на уређају."</string>
-    <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_content" msgid="3960837827570483762">"Да бисте их одблокирали, померите прекидач за приватност на уређају на позицију одблокирано како бисте омогућили приступ. Погледајте приручник за уређај да бисте пронашли прекидач за приватност на уређају."</string>
-    <string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"Микрофон је доступан"</string>
-    <string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"Камера је доступна"</string>
-    <string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"Микрофон и камера су доступни"</string>
-    <string name="media_seamless_other_device" msgid="4654849800789196737">"Други уређај"</string>
-    <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Укључи/искључи преглед"</string>
-    <string name="zen_priority_introduction" msgid="3159291973383796646">"Неће вас узнемиравати звукови и вибрације осим за аларме, подсетнике, догађаје и позиваоце које наведете. И даље ћете чути све што одаберете да пустите, укључујући музику, видео снимке и игре."</string>
-    <string name="zen_alarms_introduction" msgid="3987266042682300470">"Неће вас узнемиравати звукови и вибрације осим за аларме. И даље ћете чути све што одаберете да пустите, укључујући музику, видео снимке и игре."</string>
-    <string name="zen_priority_customize_button" msgid="4119213187257195047">"Прилагоди"</string>
-    <string name="zen_silence_introduction_voice" msgid="853573681302712348">"Ово блокира СВЕ звукове и вибрације укључујући аларме, музику, видео снимке и игре. И даље ћете моћи да упућујете позиве."</string>
-    <string name="zen_silence_introduction" msgid="6117517737057344014">"Ово блокира СВЕ звукове и вибрације укључујући аларме, музику, видео снимке и игре."</string>
-    <string name="notification_tap_again" msgid="4477318164947497249">"Додирните поново да бисте отворили"</string>
-    <string name="tap_again" msgid="1315420114387908655">"Додирните поново"</string>
-    <string name="keyguard_unlock" msgid="8031975796351361601">"Превуците нагоре да бисте отворили"</string>
-    <string name="keyguard_unlock_press" msgid="9140109453735019209">"Притисните икону откључавања да бисте отворили."</string>
-    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Откључано је лицем. Превуците нагоре да бисте отворили."</string>
-    <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Откључано је лицем. Притисните икону откључавања да бисте отворили."</string>
-    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Откључано је лицем. Притисните да бисте отворили."</string>
-    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Лице је препознато. Притисните да бисте отворили."</string>
-    <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_alt1" msgid="5853906076353839628">"Лице је препознато"</string>
+    <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC je onemogućen"</string>
+    <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC je omogućen"</string>
+    <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Snimanje ekrana"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Počnite"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Zaustavite"</string>
+    <string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Režim jednom rukom"</string>
+    <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Želite da odblokirate mikrofon uređaja?"</string>
+    <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Želite da odblokirate kameru uređaja?"</string>
+    <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Želite da odblokirate kameru i mikrofon uređaja?"</string>
+    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Ovim će se odblokirati pristup za sve aplikacije i usluge koje imaju dozvolu za korišćenje mikrofona."</string>
+    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Ovim će se odblokirati pristup za sve aplikacije i usluge koje imaju dozvolu za korišćenje kamere."</string>
+    <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Ovim će se odblokirati pristup za sve aplikacije i usluge koje imaju dozvolu za korišćenje kamere ili mikrofona."</string>
+    <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"Mikrofon je blokiran"</string>
+    <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"Kamera je blokirana"</string>
+    <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_title" msgid="195236134743281973">"Mikrofon i kamera su blokirani"</string>
+    <string name="sensor_privacy_start_use_mic_blocked_dialog_content" msgid="2138318880682877747">"Da biste odblokirali, pomerite prekidač za privatnost na uređaju na poziciju uključeno za mikrofon kako biste omogućili pristup mikrofonu. Pogledajte priručnik za uređaj da biste pronašli prekidač za privatnost na uređaju."</string>
+    <string name="sensor_privacy_start_use_camera_blocked_dialog_content" msgid="7216015168047965948">"Da biste odblokirali, pomerite prekidač za privatnost na uređaju na poziciju uključeno za kameru kako biste omogućili pristup kameri. Pogledajte priručnik za uređaj da biste pronašli prekidač za privatnost na uređaju."</string>
+    <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_content" msgid="3960837827570483762">"Da biste ih odblokirali, pomerite prekidač za privatnost na uređaju na poziciju odblokirano kako biste omogućili pristup. Pogledajte priručnik za uređaj da biste pronašli prekidač za privatnost na uređaju."</string>
+    <string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"Mikrofon je dostupan"</string>
+    <string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"Kamera je dostupna"</string>
+    <string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"Mikrofon i kamera su dostupni"</string>
+    <string name="media_seamless_other_device" msgid="4654849800789196737">"Drugi uređaj"</string>
+    <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Uključi/isključi pregled"</string>
+    <string name="zen_priority_introduction" msgid="3159291973383796646">"Neće vas uznemiravati zvukovi i vibracije osim za alarme, podsetnike, događaje i pozivaoce koje navedete. I dalje ćete čuti sve što odaberete da pustite, uključujući muziku, video snimke i igre."</string>
+    <string name="zen_alarms_introduction" msgid="3987266042682300470">"Neće vas uznemiravati zvukovi i vibracije osim za alarme. I dalje ćete čuti sve što odaberete da pustite, uključujući muziku, video snimke i igre."</string>
+    <string name="zen_priority_customize_button" msgid="4119213187257195047">"Prilagodi"</string>
+    <string name="zen_silence_introduction_voice" msgid="853573681302712348">"Ovo blokira SVE zvukove i vibracije uključujući alarme, muziku, video snimke i igre. I dalje ćete moći da upućujete pozive."</string>
+    <string name="zen_silence_introduction" msgid="6117517737057344014">"Ovo blokira SVE zvukove i vibracije uključujući alarme, muziku, video snimke i igre."</string>
+    <string name="notification_tap_again" msgid="4477318164947497249">"Dodirnite ponovo da biste otvorili"</string>
+    <string name="tap_again" msgid="1315420114387908655">"Dodirnite ponovo"</string>
+    <string name="keyguard_unlock" msgid="8031975796351361601">"Prevucite nagore da biste otvorili"</string>
+    <string name="keyguard_unlock_press" msgid="9140109453735019209">"Pritisnite ikonu otključavanja da biste otvorili."</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Otključano je licem. Prevucite nagore da biste otvorili."</string>
+    <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Otključano je licem. Pritisnite ikonu otključavanja da biste otvorili."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Otključano je licem. Pritisnite da biste otvorili."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Lice je prepoznato. Pritisnite da biste otvorili."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Lice prepoznato. Pritisnite ikonu otključavanja da biste otvorili."</string>
+    <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Otključano je licem"</string>
+    <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Lice je prepoznato"</string>
   <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Померите налево"</item>
-    <item msgid="5558598599408514296">"Померите надоле"</item>
-    <item msgid="4844142668312841831">"Померите надесно"</item>
-    <item msgid="5640521437931460125">"Померите нагоре"</item>
+    <item msgid="1901953991150295169">"Pomerite nalevo"</item>
+    <item msgid="5558598599408514296">"Pomerite nadole"</item>
+    <item msgid="4844142668312841831">"Pomerite nadesno"</item>
+    <item msgid="5640521437931460125">"Pomerite nagore"</item>
   </string-array>
-    <string name="keyguard_retry" msgid="886802522584053523">"Превуците нагоре да бисте пробали поново"</string>
-    <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Откључајте да бисте користили NFC"</string>
-    <string name="do_disclosure_generic" msgid="4896482821974707167">"Овај уређај припада организацији"</string>
-    <string name="do_disclosure_with_name" msgid="2091641464065004091">"Овај уређај припада организацији <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
-    <string name="do_financed_disclosure_with_name" msgid="6723004643314467864">"Овај уређај пружа <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
-    <string name="phone_hint" msgid="6682125338461375925">"Превуците од иконе за телефон"</string>
-    <string name="voice_hint" msgid="7476017460191291417">"Превуците од иконе за гласовну помоћ"</string>
-    <string name="camera_hint" msgid="4519495795000658637">"Превуците од иконе за камеру"</string>
-    <string name="interruption_level_none_with_warning" msgid="8394434073508145437">"Потпуна тишина. И читачи екрана ће бити искључени."</string>
-    <string name="interruption_level_none" msgid="219484038314193379">"Потпуна тишина"</string>
-    <string name="interruption_level_priority" msgid="661294280016622209">"Само приоритетни прекиди"</string>
-    <string name="interruption_level_alarms" msgid="2457850481335846959">"Само аларми"</string>
-    <string name="interruption_level_none_twoline" msgid="8579382742855486372">"Потпуна\nтишина"</string>
-    <string name="interruption_level_priority_twoline" msgid="8523482736582498083">"Само\nприорит. прекиди"</string>
-    <string name="interruption_level_alarms_twoline" msgid="2045067991335708767">"Само\nаларми"</string>
-    <string name="keyguard_indication_charging_time_wireless" msgid="577856646141738675">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Бежично се пуни • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до краја пуњења"</string>
-    <string name="keyguard_indication_charging_time" msgid="6492711711891071502">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Пуни се • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до краја пуњења"</string>
-    <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Брзо се пуни • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до краја пуњења"</string>
-    <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Споро се пуни • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до краја пуњења"</string>
-    <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Пуни се • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до краја пуњења"</string>
-    <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Замени корисника"</string>
-    <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"падајући мени"</string>
-    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Све апликације и подаци у овој сесији ће бити избрисани."</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Добро дошли назад, госте!"</string>
-    <string name="guest_wipe_session_message" msgid="3393823610257065457">"Желите ли да наставите сесију?"</string>
-    <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Почни из почетка"</string>
-    <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Да, настави"</string>
-    <string name="guest_notification_app_name" msgid="2110425506754205509">"Режим госта"</string>
-    <string name="guest_notification_session_active" msgid="5567273684713471450">"Користите режим госта"</string>
-    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Додавањем новог корисника изаћи ћете из режима госта и избрисаћете све апликације и податке из актуелне сесије госта."</string>
-    <string name="user_limit_reached_title" msgid="2429229448830346057">"Достигнут максимални број корисника"</string>
-    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Можете да направите само једног корисника.}one{Можете да додате највише # корисника.}few{Можете да додате највише # корисника.}other{Можете да додате највише # корисника.}}"</string>
-    <string name="user_remove_user_title" msgid="9124124694835811874">"Желите ли да уклоните корисника?"</string>
-    <string name="user_remove_user_message" msgid="6702834122128031833">"Све апликације и подаци овог корисника ће бити избрисани."</string>
-    <string name="user_remove_user_remove" msgid="8387386066949061256">"Уклони"</string>
-    <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ће имати приступ свим информацијама које се приказују на екрану или репродукују са уређаја током снимања или пребацивања. То обухвата информације попут лозинки, информација о плаћању, слика, порука и звука који пуштате."</string>
-    <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Услуга која пружа ову функцију ће имати приступ свим информацијама које се приказују на екрану или репродукују са уређаја током снимања или пребацивања. То обухвата информације попут лозинки, информација о плаћању, слика, порука и звука који пуштате."</string>
-    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Желите да почнете снимање или пребацивање?"</string>
-    <string name="media_projection_dialog_title" msgid="3316063622495360646">"Желите да почнете снимање или пребацивање помоћу апликације <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
-    <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"Желите да дозволите дељење и снимање за <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
-    <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"Цео екран"</string>
-    <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"Једна апликација"</string>
-    <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"Када делите, снимате или пребацујете, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> има приступ комплетном садржају који је видљив на екрану или се пушта на уређају. Будите пажљиви са лозинкама, информацијама о плаћању, порукама или другим осетљивим информацијама."</string>
-    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Када делите, снимате или пребацујете апликацију, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> има приступ комплетном садржају који је видљив или се пушта у тој апликацији. Будите пажљиви са лозинкама, информацијама о плаћању, порукама или другим осетљивим информацијама."</string>
-    <string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Настави"</string>
-    <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Делите или снимите апликацију"</string>
-    <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Желите да дозволите овој апликацији да дели или снима?"</string>
-    <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Када делите, снимате или пребацујете, ова апликација има приступ комплетном садржају који је видљив на екрану или се пушта на уређају. Будите пажљиви са лозинкама, информацијама о плаћању, порукама или другим осетљивим информацијама."</string>
-    <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Када делите, снимате или пребацујете апликацију, ова апликација има приступ комплетном садржају који је видљив или се пушта у тој апликацији. Будите пажљиви са лозинкама, информацијама о плаћању, порукама или другим осетљивим информацијама."</string>
-    <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Блокира ИТ администратор"</string>
-    <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Снимање екрана је онемогућено смерницама за уређај"</string>
-    <string name="clear_all_notifications_text" msgid="348312370303046130">"Обриши све"</string>
-    <string name="manage_notifications_text" msgid="6885645344647733116">"Управљајте"</string>
-    <string name="manage_notifications_history_text" msgid="57055985396576230">"Историја"</string>
-    <string name="notification_section_header_incoming" msgid="850925217908095197">"Ново"</string>
-    <string name="notification_section_header_gentle" msgid="6804099527336337197">"Нечујно"</string>
-    <string name="notification_section_header_alerting" msgid="5581175033680477651">"Обавештења"</string>
-    <string name="notification_section_header_conversations" msgid="821834744538345661">"Конверзације"</string>
-    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Обришите сва нечујна обавештења"</string>
-    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Обавештења су паузирана режимом Не узнемиравај"</string>
-    <string name="media_projection_action_text" msgid="3634906766918186440">"Започни"</string>
-    <string name="empty_shade_text" msgid="8935967157319717412">"Нема обавештења"</string>
-    <string name="no_unseen_notif_text" msgid="395512586119868682">"Нема нових обавештења"</string>
-    <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Откључајте да видите старија обавештења"</string>
-    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Овим уређајем управља родитељ"</string>
-    <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Организација је власник уређаја и може да надгледа мрежни саобраћај"</string>
-    <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> је власник овог уређаја и може да надгледа мрежни саобраћај"</string>
-    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Овај уређај пружа <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
-    <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Овај уређај припада вашој организацији и повезан је на интернет преко: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
-    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Власник овог уређаја је <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, а повезан је на интернет преко: <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
-    <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Овај уређај припада организацији"</string>
-    <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Овај уређај припада организацији <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
-    <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Овај уређај припада вашој организацији и повезан је на интернет преко VPN-ова"</string>
-    <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Власник овог уређаја је <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, а повезан је на интернет преко VPN-ова"</string>
-    <string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Организација може да прати мрежни саобраћај на пословном профилу"</string>
-    <string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> може да надгледа мрежни саобраћај на пословном профилу"</string>
-    <string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Активност на мрежи пословног профила је видљива ИТ администратору"</string>
-    <string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Мрежа се можда надгледа"</string>
-    <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Овај уређај је повезан на интернет преко VPN-ова"</string>
-    <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Ваше пословне апликације су повезане на интернет преко: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
-    <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Ваше личне апликације су повезане на интернет преко: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
-    <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Овај уређај је повезан на интернет преко: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
-    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Овај уређај пружа <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
-    <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Управљање уређајима"</string>
+    <string name="keyguard_retry" msgid="886802522584053523">"Prevucite nagore da biste probali ponovo"</string>
+    <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Otključajte da biste koristili NFC"</string>
+    <string name="do_disclosure_generic" msgid="4896482821974707167">"Ovaj uređaj pripada organizaciji"</string>
+    <string name="do_disclosure_with_name" msgid="2091641464065004091">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+    <string name="do_financed_disclosure_with_name" msgid="6723004643314467864">"Ovaj uređaj pruža <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+    <string name="phone_hint" msgid="6682125338461375925">"Prevucite od ikone za telefon"</string>
+    <string name="voice_hint" msgid="7476017460191291417">"Prevucite od ikone za glasovnu pomoć"</string>
+    <string name="camera_hint" msgid="4519495795000658637">"Prevucite od ikone za kameru"</string>
+    <string name="interruption_level_none_with_warning" msgid="8394434073508145437">"Potpuna tišina. I čitači ekrana će biti isključeni."</string>
+    <string name="interruption_level_none" msgid="219484038314193379">"Potpuna tišina"</string>
+    <string name="interruption_level_priority" msgid="661294280016622209">"Samo prioritetni prekidi"</string>
+    <string name="interruption_level_alarms" msgid="2457850481335846959">"Samo alarmi"</string>
+    <string name="interruption_level_none_twoline" msgid="8579382742855486372">"Potpuna\ntišina"</string>
+    <string name="interruption_level_priority_twoline" msgid="8523482736582498083">"Samo\npriorit. prekidi"</string>
+    <string name="interruption_level_alarms_twoline" msgid="2045067991335708767">"Samo\nalarmi"</string>
+    <string name="keyguard_indication_charging_time_wireless" msgid="577856646141738675">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Bežično se puni • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> do kraja punjenja"</string>
+    <string name="keyguard_indication_charging_time" msgid="6492711711891071502">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Puni se • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> do kraja punjenja"</string>
+    <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Brzo se puni • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> do kraja punjenja"</string>
+    <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Sporo se puni • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> do kraja punjenja"</string>
+    <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Puni se • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> do kraja punjenja"</string>
+    <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Zameni korisnika"</string>
+    <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući meni"</string>
+    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci u ovoj sesiji će biti izbrisani."</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"Dobro došli nazad, goste!"</string>
+    <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li da nastavite sesiju?"</string>
+    <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni iz početka"</string>
+    <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Da, nastavi"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Režim gosta"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Koristite režim gosta"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Dodavanjem novog korisnika izaći ćete iz režima gosta i izbrisaćete sve aplikacije i podatke iz aktuelne sesije gosta."</string>
+    <string name="user_limit_reached_title" msgid="2429229448830346057">"Dostignut maksimalni broj korisnika"</string>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Možete da napravite samo jednog korisnika.}one{Možete da dodate najviše # korisnika.}few{Možete da dodate najviše # korisnika.}other{Možete da dodate najviše # korisnika.}}"</string>
+    <string name="user_remove_user_title" msgid="9124124694835811874">"Želite li da uklonite korisnika?"</string>
+    <string name="user_remove_user_message" msgid="6702834122128031833">"Sve aplikacije i podaci ovog korisnika će biti izbrisani."</string>
+    <string name="user_remove_user_remove" msgid="8387386066949061256">"Ukloni"</string>
+    <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> će imati pristup svim informacijama koje se prikazuju na ekranu ili reprodukuju sa uređaja tokom snimanja ili prebacivanja. To obuhvata informacije poput lozinki, informacija o plaćanju, slika, poruka i zvuka koji puštate."</string>
+    <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Usluga koja pruža ovu funkciju će imati pristup svim informacijama koje se prikazuju na ekranu ili reprodukuju sa uređaja tokom snimanja ili prebacivanja. To obuhvata informacije poput lozinki, informacija o plaćanju, slika, poruka i zvuka koji puštate."</string>
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Želite da počnete snimanje ili prebacivanje?"</string>
+    <string name="media_projection_dialog_title" msgid="3316063622495360646">"Želite da počnete snimanje ili prebacivanje pomoću aplikacije <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
+    <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"Želite da dozvolite deljenje i snimanje za <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
+    <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"Ceo ekran"</string>
+    <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"Jedna aplikacija"</string>
+    <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"Kada delite, snimate ili prebacujete, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup kompletnom sadržaju koji je vidljiv na ekranu ili se pušta na uređaju. Budite pažljivi sa lozinkama, informacijama o plaćanju, porukama ili drugim osetljivim informacijama."</string>
+    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Kada delite, snimate ili prebacujete aplikaciju, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup kompletnom sadržaju koji je vidljiv ili se pušta u toj aplikaciji. Budite pažljivi sa lozinkama, informacijama o plaćanju, porukama ili drugim osetljivim informacijama."</string>
+    <string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Nastavi"</string>
+    <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Delite ili snimite aplikaciju"</string>
+    <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Želite da dozvolite ovoj aplikaciji da deli ili snima?"</string>
+    <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Kada delite, snimate ili prebacujete, ova aplikacija ima pristup kompletnom sadržaju koji je vidljiv na ekranu ili se pušta na uređaju. Budite pažljivi sa lozinkama, informacijama o plaćanju, porukama ili drugim osetljivim informacijama."</string>
+    <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Kada delite, snimate ili prebacujete aplikaciju, ova aplikacija ima pristup kompletnom sadržaju koji je vidljiv ili se pušta u toj aplikaciji. Budite pažljivi sa lozinkama, informacijama o plaćanju, porukama ili drugim osetljivim informacijama."</string>
+    <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Blokira IT administrator"</string>
+    <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Snimanje ekrana je onemogućeno smernicama za uređaj"</string>
+    <string name="clear_all_notifications_text" msgid="348312370303046130">"Obriši sve"</string>
+    <string name="manage_notifications_text" msgid="6885645344647733116">"Upravljajte"</string>
+    <string name="manage_notifications_history_text" msgid="57055985396576230">"Istorija"</string>
+    <string name="notification_section_header_incoming" msgid="850925217908095197">"Novo"</string>
+    <string name="notification_section_header_gentle" msgid="6804099527336337197">"Nečujno"</string>
+    <string name="notification_section_header_alerting" msgid="5581175033680477651">"Obaveštenja"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Konverzacije"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Obrišite sva nečujna obaveštenja"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Obaveštenja su pauzirana režimom Ne uznemiravaj"</string>
+    <string name="media_projection_action_text" msgid="3634906766918186440">"Započni"</string>
+    <string name="empty_shade_text" msgid="8935967157319717412">"Nema obaveštenja"</string>
+    <string name="no_unseen_notif_text" msgid="395512586119868682">"Nema novih obaveštenja"</string>
+    <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Otključajte da vidite starija obaveštenja"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Ovim uređajem upravlja roditelj"</string>
+    <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organizacija je vlasnik uređaja i može da nadgleda mrežni saobraćaj"</string>
+    <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> je vlasnik ovog uređaja i može da nadgleda mrežni saobraćaj"</string>
+    <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Ovaj uređaj pruža <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Ovaj uređaj pripada vašoj organizaciji i povezan je na internet preko: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Vlasnik ovog uređaja je <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, a povezan je na internet preko: <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Ovaj uređaj pripada organizaciji"</string>
+    <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Ovaj uređaj pripada vašoj organizaciji i povezan je na internet preko VPN-ova"</string>
+    <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Vlasnik ovog uređaja je <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, a povezan je na internet preko VPN-ova"</string>
+    <string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Organizacija može da prati mrežni saobraćaj na poslovnom profilu"</string>
+    <string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> može da nadgleda mrežni saobraćaj na poslovnom profilu"</string>
+    <string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Aktivnost na mreži poslovnog profila je vidljiva IT administratoru"</string>
+    <string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Mreža se možda nadgleda"</string>
+    <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Ovaj uređaj je povezan na internet preko VPN-ova"</string>
+    <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Vaše poslovne aplikacije su povezane na internet preko: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Vaše lične aplikacije su povezane na internet preko: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Ovaj uređaj je povezan na internet preko: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Ovaj uređaj pruža <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+    <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Upravljanje uređajima"</string>
     <string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
-    <string name="monitoring_subtitle_network_logging" msgid="2444199331891219596">"Евидентирање мреже"</string>
-    <string name="monitoring_subtitle_ca_certificate" msgid="8588092029755175800">"CA сертификати"</string>
-    <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Прикажи смернице"</string>
-    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Прикажи контроле"</string>
-    <string name="monitoring_description_named_management" msgid="505833016545056036">"Овај уређај припада организацији <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nИТ администратор може да надгледа подешавања, корпоративни приступ, апликације, податке повезане са уређајем и информације о локацији уређаја, као и да управља њима.\n\nВише информација потражите од ИТ администратора."</string>
-    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> можда може да приступа подацима повезаним са овим уређајем, да управља апликацијама и да мења подешавања овог уређаја.\n\nАко имате питања, обратите се организацији <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
-    <string name="monitoring_description_management" msgid="4308879039175729014">"Овај уређај припада организацији.\n\nИТ администратор може да надгледа подешавања, корпоративни приступ, апликације, податке повезане са уређајем и информације о локацији уређаја, као и да управља њима.\n\nВише информација потражите од ИТ администратора."</string>
-    <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Организација је на овом уређају инсталирала ауторитет за издавање сертификата. Безбедни мрежни саобраћај може да се прати или мења."</string>
-    <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Организација је на пословном профилу инсталирала ауторитет за издавање сертификата. Безбедни мрежни саобраћај може да се прати или мења."</string>
-    <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"На овом уређају је инсталиран ауторитет за издавање сертификата. Безбедни мрежни саобраћај може да се прати или мења."</string>
-    <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Администратор је укључио евидентирање мреже, које прати саобраћај на уређају."</string>
-    <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Администратор је укључио евидентирање мреже, које прати саобраћај на пословном профилу, али не и на личном профилу."</string>
-    <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Овај уређај је повезан на интернет преко: <xliff:g id="VPN_APP">%1$s</xliff:g>. Ваша активност на мрежи, укључујући имејлове и податке прегледања, видљива је ИТ администратору."</string>
-    <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Овај уређај је повезан на интернет преко: <xliff:g id="VPN_APP_0">%1$s</xliff:g> и <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Ваша активност на мрежи, укључујући имејлове и податке прегледања, видљива је ИТ администратору."</string>
-    <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Ваше пословне апликације су повезане на интернет преко: <xliff:g id="VPN_APP">%1$s</xliff:g>. Ваша активност на мрежи у пословним апликацијама, укључујући имејлове и податке прегледања, видљива је ИТ администратору и добављачу VPN-а."</string>
-    <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Ваше личне апликације су повезане на интернет преко: <xliff:g id="VPN_APP">%1$s</xliff:g>. Ваша активност на мрежи, укључујући имејлове и податке прегледања, видљива је добављачу VPN-а."</string>
+    <string name="monitoring_subtitle_network_logging" msgid="2444199331891219596">"Evidentiranje mreže"</string>
+    <string name="monitoring_subtitle_ca_certificate" msgid="8588092029755175800">"CA sertifikati"</string>
+    <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Prikaži smernice"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Prikaži kontrole"</string>
+    <string name="monitoring_description_named_management" msgid="505833016545056036">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nIT administrator može da nadgleda podešavanja, korporativni pristup, aplikacije, podatke povezane sa uređajem i informacije o lokaciji uređaja, kao i da upravlja njima.\n\nViše informacija potražite od IT administratora."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> možda može da pristupa podacima povezanim sa ovim uređajem, da upravlja aplikacijama i da menja podešavanja ovog uređaja.\n\nAko imate pitanja, obratite se organizaciji <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
+    <string name="monitoring_description_management" msgid="4308879039175729014">"Ovaj uređaj pripada organizaciji.\n\nIT administrator može da nadgleda podešavanja, korporativni pristup, aplikacije, podatke povezane sa uređajem i informacije o lokaciji uređaja, kao i da upravlja njima.\n\nViše informacija potražite od IT administratora."</string>
+    <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organizacija je na ovom uređaju instalirala autoritet za izdavanje sertifikata. Bezbedni mrežni saobraćaj može da se prati ili menja."</string>
+    <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Organizacija je na poslovnom profilu instalirala autoritet za izdavanje sertifikata. Bezbedni mrežni saobraćaj može da se prati ili menja."</string>
+    <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Na ovom uređaju je instaliran autoritet za izdavanje sertifikata. Bezbedni mrežni saobraćaj može da se prati ili menja."</string>
+    <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Administrator je uključio evidentiranje mreže, koje prati saobraćaj na uređaju."</string>
+    <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Administrator je uključio evidentiranje mreže, koje prati saobraćaj na poslovnom profilu, ali ne i na ličnom profilu."</string>
+    <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Ovaj uređaj je povezan na internet preko: <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaša aktivnost na mreži, uključujući imejlove i podatke pregledanja, vidljiva je IT administratoru."</string>
+    <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Ovaj uređaj je povezan na internet preko: <xliff:g id="VPN_APP_0">%1$s</xliff:g> i <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Vaša aktivnost na mreži, uključujući imejlove i podatke pregledanja, vidljiva je IT administratoru."</string>
+    <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Vaše poslovne aplikacije su povezane na internet preko: <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaša aktivnost na mreži u poslovnim aplikacijama, uključujući imejlove i podatke pregledanja, vidljiva je IT administratoru i dobavljaču VPN-a."</string>
+    <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Vaše lične aplikacije su povezane na internet preko: <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaša aktivnost na mreži, uključujući imejlove i podatke pregledanja, vidljiva je dobavljaču VPN-a."</string>
     <string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
-    <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Отвори подешавања VPN-а"</string>
-    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Овим уређајем управља родитељ. Родитељ може да види информације, као што су апликације које користиш, твоју локацију и време испред екрана, и да управља њима."</string>
+    <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Otvori podešavanja VPN-a"</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Ovim uređajem upravlja roditelj. Roditelj može da vidi informacije, kao što su aplikacije koje koristiš, tvoju lokaciju i vreme ispred ekrana, i da upravlja njima."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
-    <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Поуздани агент спречава закључавање"</string>
+    <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Pouzdani agent sprečava zaključavanje"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="accessibility_volume_settings" msgid="1458961116951564784">"Подешавања звука"</string>
-    <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Аутоматски титл за медије"</string>
-    <string name="accessibility_volume_close_odi_captions_tip" msgid="8924753283621160480">"Опис титла"</string>
-    <string name="volume_odi_captions_content_description" msgid="4172765742046013630">"Преклапање титлова"</string>
-    <string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"омогућите"</string>
-    <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"онемогућите"</string>
-    <string name="sound_settings" msgid="8874581353127418308">"Звук и вибрирање"</string>
-    <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Подешавања"</string>
-    <string name="screen_pinning_title" msgid="9058007390337841305">"Апликација је закачена"</string>
-    <string name="screen_pinning_description" msgid="8699395373875667743">"На овај начин се ово стално приказује док га не откачите. Додирните и задржите Назад и Преглед да бисте га откачили."</string>
-    <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"На овај начин се ово стално приказује док га не откачите. Додирните и задржите Назад и Почетна да бисте га откачили."</string>
-    <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Стално ће се приказивати док је не откачите. Превуците нагоре и задржите да бисте је откачили."</string>
-    <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"На овај начин се ово стално приказује док га не откачите. Додирните и задржите Преглед да бисте га откачили."</string>
-    <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"На овај начин се ово стално приказује док га не откачите. Додирните и задржите Почетна да бисте га откачили."</string>
-    <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Могу да буду доступни лични подаци (као што су контакти и садржај имејлова)."</string>
-    <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Закачена апликација може да отвара друге апликације."</string>
-    <string name="screen_pinning_toast" msgid="8177286912533744328">"Да бисте откачили ову апликацију, додирните и задржите дугмад Назад и Преглед"</string>
-    <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Да бисте откачили ову апликацију, додирните и задржите дугмад Назад и Почетна"</string>
-    <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"Да бисте откачили ову апликацију, превуците нагоре и задржите"</string>
-    <string name="screen_pinning_positive" msgid="3285785989665266984">"Важи"</string>
-    <string name="screen_pinning_negative" msgid="6882816864569211666">"Не, хвала"</string>
-    <string name="screen_pinning_start" msgid="7483998671383371313">"Апликација је закачена"</string>
-    <string name="screen_pinning_exit" msgid="4553787518387346893">"Апликација је откачена"</string>
-    <string name="stream_voice_call" msgid="7468348170702375660">"Позив"</string>
-    <string name="stream_system" msgid="7663148785370565134">"Систем"</string>
-    <string name="stream_ring" msgid="7550670036738697526">"Звоно"</string>
-    <string name="stream_music" msgid="2188224742361847580">"Медији"</string>
-    <string name="stream_alarm" msgid="16058075093011694">"Аларм"</string>
-    <string name="stream_notification" msgid="7930294049046243939">"Обавештење"</string>
+    <string name="accessibility_volume_settings" msgid="1458961116951564784">"Podešavanja zvuka"</string>
+    <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Automatski titl za medije"</string>
+    <string name="accessibility_volume_close_odi_captions_tip" msgid="8924753283621160480">"Opis titla"</string>
+    <string name="volume_odi_captions_content_description" msgid="4172765742046013630">"Preklapanje titlova"</string>
+    <string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"omogućite"</string>
+    <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"onemogućite"</string>
+    <string name="sound_settings" msgid="8874581353127418308">"Zvuk i vibriranje"</string>
+    <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Podešavanja"</string>
+    <string name="screen_pinning_title" msgid="9058007390337841305">"Aplikacija je zakačena"</string>
+    <string name="screen_pinning_description" msgid="8699395373875667743">"Na ovaj način se ovo stalno prikazuje dok ga ne otkačite. Dodirnite i zadržite Nazad i Pregled da biste ga otkačili."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Na ovaj način se ovo stalno prikazuje dok ga ne otkačite. Dodirnite i zadržite Nazad i Početna da biste ga otkačili."</string>
+    <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Stalno će se prikazivati dok je ne otkačite. Prevucite nagore i zadržite da biste je otkačili."</string>
+    <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"Na ovaj način se ovo stalno prikazuje dok ga ne otkačite. Dodirnite i zadržite Pregled da biste ga otkačili."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Na ovaj način se ovo stalno prikazuje dok ga ne otkačite. Dodirnite i zadržite Početna da biste ga otkačili."</string>
+    <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Mogu da budu dostupni lični podaci (kao što su kontakti i sadržaj imejlova)."</string>
+    <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Zakačena aplikacija može da otvara druge aplikacije."</string>
+    <string name="screen_pinning_toast" msgid="8177286912533744328">"Da biste otkačili ovu aplikaciju, dodirnite i zadržite dugmad Nazad i Pregled"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Da biste otkačili ovu aplikaciju, dodirnite i zadržite dugmad Nazad i Početna"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"Da biste otkačili ovu aplikaciju, prevucite nagore i zadržite"</string>
+    <string name="screen_pinning_positive" msgid="3285785989665266984">"Važi"</string>
+    <string name="screen_pinning_negative" msgid="6882816864569211666">"Ne, hvala"</string>
+    <string name="screen_pinning_start" msgid="7483998671383371313">"Aplikacija je zakačena"</string>
+    <string name="screen_pinning_exit" msgid="4553787518387346893">"Aplikacija je otkačena"</string>
+    <string name="stream_voice_call" msgid="7468348170702375660">"Poziv"</string>
+    <string name="stream_system" msgid="7663148785370565134">"Sistem"</string>
+    <string name="stream_ring" msgid="7550670036738697526">"Zvono"</string>
+    <string name="stream_music" msgid="2188224742361847580">"Mediji"</string>
+    <string name="stream_alarm" msgid="16058075093011694">"Alarm"</string>
+    <string name="stream_notification" msgid="7930294049046243939">"Obaveštenje"</string>
     <string name="stream_bluetooth_sco" msgid="6234562365528664331">"Bluetooth"</string>
-    <string name="stream_dtmf" msgid="7322536356554673067">"Вишеструка фреквенција дуалног тона"</string>
-    <string name="stream_accessibility" msgid="3873610336741987152">"Приступачност"</string>
-    <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Активирај звоно"</string>
-    <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Вибрирај"</string>
-    <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Искључи звук"</string>
-    <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Додирните да бисте укључили звук."</string>
-    <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Додирните да бисте подесили на вибрацију. Звук услуга приступачности ће можда бити искључен."</string>
-    <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Додирните да бисте искључили звук. Звук услуга приступачности ће можда бити искључен."</string>
-    <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Додирните да бисте подесили на вибрацију."</string>
-    <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Додирните да бисте искључили звук."</string>
-    <string name="volume_ringer_change" msgid="3574969197796055532">"Додирните да бисте променили режим звона"</string>
-    <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"искључите звук"</string>
-    <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"укључите звук"</string>
-    <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"вибрација"</string>
-    <string name="volume_dialog_title" msgid="6502703403483577940">"Контроле за јачину звука за %s"</string>
-    <string name="volume_dialog_ringer_guidance_ring" msgid="9143194270463146858">"Мелодија звона за позиве и обавештења је укључена (<xliff:g id="VOLUME_LEVEL">%1$s</xliff:g>)"</string>
-    <string name="system_ui_tuner" msgid="1471348823289954729">"Тјунер за кориснички интерфејс система"</string>
-    <string name="status_bar" msgid="4357390266055077437">"Статусна трака"</string>
-    <string name="demo_mode" msgid="263484519766901593">"Режим демонстрације за кориснички интерфејс система"</string>
-    <string name="enable_demo_mode" msgid="3180345364745966431">"Омогући режим демонстрације"</string>
-    <string name="show_demo_mode" msgid="3677956462273059726">"Прикажи режим демонстрације"</string>
-    <string name="status_bar_ethernet" msgid="5690979758988647484">"Етернет"</string>
-    <string name="status_bar_alarm" msgid="87160847643623352">"Аларм"</string>
-    <string name="wallet_title" msgid="5369767670735827105">"Новчаник"</string>
-    <string name="wallet_empty_state_label" msgid="7776761245237530394">"Обавите конфигурисање да бисте могли брже и сигурније да купујете помоћу телефона"</string>
-    <string name="wallet_app_button_label" msgid="7123784239111190992">"Прикажи све"</string>
-    <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"Додирните и отворите"</string>
-    <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Ажурира се"</string>
-    <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Откључај ради коришћења"</string>
-    <string name="wallet_error_generic" msgid="257704570182963611">"Дошло је до проблема при преузимању картица. Пробајте поново касније"</string>
-    <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Подешавања закључаног екрана"</string>
-    <string name="qr_code_scanner_title" msgid="1938155688725760702">"Скенер QR кода"</string>
-    <string name="qr_code_scanner_updating_secondary_label" msgid="8344598017007876352">"Ажурира се"</string>
-    <string name="status_bar_work" msgid="5238641949837091056">"Пословни профил"</string>
-    <string name="status_bar_airplane" msgid="4848702508684541009">"Режим рада у авиону"</string>
-    <string name="zen_alarm_warning" msgid="7844303238486849503">"Нећете чути следећи аларм у <xliff:g id="WHEN">%1$s</xliff:g>"</string>
-    <string name="alarm_template" msgid="2234991538018805736">"у <xliff:g id="WHEN">%1$s</xliff:g>"</string>
-    <string name="alarm_template_far" msgid="3561752195856839456">"у <xliff:g id="WHEN">%1$s</xliff:g>"</string>
-    <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Хотспот"</string>
-    <string name="accessibility_managed_profile" msgid="4703836746209377356">"Пословни профил"</string>
-    <string name="tuner_warning_title" msgid="7721976098452135267">"Забава за неке, али не за све"</string>
-    <string name="tuner_warning" msgid="1861736288458481650">"Тјунер за кориснички интерфејс система вам пружа додатне начине за подешавање и прилагођавање Android корисничког интерфејса. Ове експерименталне функције могу да се промене, откажу или нестану у будућим издањима. Будите опрезни."</string>
-    <string name="tuner_persistent_warning" msgid="230466285569307806">"Ове експерименталне функције могу да се промене, откажу или нестану у будућим издањима. Будите опрезни."</string>
-    <string name="got_it" msgid="477119182261892069">"Важи"</string>
-    <string name="tuner_toast" msgid="3812684836514766951">"Честитамо! Тјунер за кориснички интерфејс система је додат у Подешавања"</string>
-    <string name="remove_from_settings" msgid="633775561782209994">"Уклони из Подешавања"</string>
-    <string name="remove_from_settings_prompt" msgid="551565437265615426">"Желите ли да уклоните Тјунер за кориснички интерфејс система из Подешавања и да престанете да користите све његове функције?"</string>
-    <string name="enable_bluetooth_title" msgid="866883307336662596">"Желите ли да укључите Bluetooth?"</string>
-    <string name="enable_bluetooth_message" msgid="6740938333772779717">"Да бисте повезали тастатуру са таблетом, прво морате да укључите Bluetooth."</string>
-    <string name="enable_bluetooth_confirmation_ok" msgid="2866408183324184876">"Укључи"</string>
-    <string name="tuner_full_importance_settings" msgid="1388025816553459059">"Напредне контроле за обавештења"</string>
-    <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Укључено – на основу лица"</string>
-    <string name="power_notification_controls_description" msgid="1334963837572708952">"Помоћу напредних контрола за обавештења можете да подесите ниво важности од 0. до 5. за обавештења апликације. \n\n"<b>"5. ниво"</b>" \n– Приказују се у врху листе обавештења \n- Дозволи прекид режима целог екрана \n– Увек завируј \n\n"<b>"4. ниво"</b>" \n– Спречи прекид режима целог екрана \n– Увек завируј \n\n"<b>"3. ниво"</b>" \n– Спречи прекид режима целог екрана \n– Никада не завируј \n\n"<b>"2. ниво"</b>" \n– Спречи прекид режима целог екрана \n– Никада не завируј \n– Никада не производи звук или вибрацију \n\n"<b>"1. ниво"</b>" \n– Спречи прекид режима целог екрана \n– Никада не завируј \n– Никада не производи звук или вибрацију \n– Сакриј на закључаном екрану и статусној траци \n– Приказују се у дну листе обавештења \n\n"<b>"0. ниво"</b>" \n– Блокирај сва обавештења из апликације"</string>
-    <string name="inline_done_button" msgid="6043094985588909584">"Готово"</string>
-    <string name="inline_ok_button" msgid="603075490581280343">"Примени"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Искључи обавештења"</string>
-    <string name="notification_silence_title" msgid="8608090968400832335">"Нечујно"</string>
-    <string name="notification_alert_title" msgid="3656229781017543655">"Подразумевано"</string>
-    <string name="notification_automatic_title" msgid="3745465364578762652">"Аутоматска"</string>
-    <string name="notification_channel_summary_low" msgid="4860617986908931158">"Без звука и вибрирања"</string>
-    <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Без звука и вибрирања и приказује се у наставку одељка за конверзације"</string>
-    <string name="notification_channel_summary_default" msgid="3282930979307248890">"Може да звони или вибрира у зависности од подешавања телефона"</string>
-    <string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Може да звони или вибрира у зависности од подешавања телефона. Конверзације из апликације <xliff:g id="APP_NAME">%1$s</xliff:g> се подразумевано приказују у облачићима."</string>
-    <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Нека систем утврди да ли ово обавештење треба да емитује звук или да вибрира"</string>
-    <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"&lt;b&gt;Статус:&lt;/b&gt; Унапређено у Подразумевано"</string>
-    <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"&lt;b&gt;Статус:&lt;/b&gt; Деградирано у Нечујно"</string>
-    <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"&lt;b&gt;Статус:&lt;/b&gt; Рангирано више"</string>
-    <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Статус:&lt;/b&gt; Рангирано ниже"</string>
-    <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Приказује се у врху обавештења о конверзацијама и као слика профила на закључаном екрану"</string>
-    <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Приказује се у врху обавештења о конверзацијама и као слика профила на закључаном екрану, појављује се као облачић"</string>
-    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Приказује се у врху обавештења о конверзацијама и као слика профила на закључаном екрану, прекида режим Не узнемиравај"</string>
-    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Приказује се у врху обавештења о конверзацијама и као слика профила на закључаном екрану, појављује се као облачић, прекида режим Не узнемиравај"</string>
-    <string name="notification_priority_title" msgid="2079708866333537093">"Приоритетно"</string>
-    <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не подржава функције конверзације"</string>
-    <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ова обавештења не могу да се мењају."</string>
-    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Обавештења о позивима не могу да се мењају."</string>
-    <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ова група обавештења не може да се конфигурише овде"</string>
-    <string name="notification_delegate_header" msgid="1264510071031479920">"Обавештење преко проксија"</string>
-    <string name="notification_channel_dialog_title" msgid="6856514143093200019">"Сва обавештења апликације <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="see_more_title" msgid="7409317011708185729">"Прикажи још"</string>
-    <string name="feedback_alerted" msgid="5192459808484271208">"Систем је ово обавештење аутоматски &lt;b&gt;унапредио у подразумевано&lt;/b&gt;."</string>
-    <string name="feedback_silenced" msgid="9116540317466126457">"Систем је ово обавештење аутоматски &lt;b&gt;деградирао у Нечујно&lt;/b&gt;."</string>
-    <string name="feedback_promoted" msgid="2125562787759780807">"Ово обавештење је аутоматски &lt;b&gt;рангирано више&lt;/b&gt; на траци са обавештењима."</string>
-    <string name="feedback_demoted" msgid="951884763467110604">"Ово обавештење је аутоматски &lt;b&gt;рангирано ниже&lt;/b&gt; на траци са обавештењима."</string>
-    <string name="feedback_prompt" msgid="3656728972307896379">"Пошаљите програмеру повратне информације. Да ли је то тачно?"</string>
-    <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Контроле обавештења за отварање апликације <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="notification_channel_controls_closed_accessibility" msgid="1561909368876911701">"Контроле обавештења за затварање апликације <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="notification_more_settings" msgid="4936228656989201793">"Још подешавања"</string>
-    <string name="notification_app_settings" msgid="8963648463858039377">"Прилагоди"</string>
-    <string name="notification_conversation_bubble" msgid="2242180995373949022">"Прикажи облачић"</string>
-    <string name="notification_conversation_unbubble" msgid="6908427185031099868">"Уклони облачиће"</string>
+    <string name="stream_dtmf" msgid="7322536356554673067">"Višestruka frekvencija dualnog tona"</string>
+    <string name="stream_accessibility" msgid="3873610336741987152">"Pristupačnost"</string>
+    <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Aktiviraj zvono"</string>
+    <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibriraj"</string>
+    <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Isključi zvuk"</string>
+    <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Dodirnite da biste uključili zvuk."</string>
+    <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Dodirnite da biste podesili na vibraciju. Zvuk usluga pristupačnosti će možda biti isključen."</string>
+    <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Dodirnite da biste isključili zvuk. Zvuk usluga pristupačnosti će možda biti isključen."</string>
+    <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Dodirnite da biste podesili na vibraciju."</string>
+    <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Dodirnite da biste isključili zvuk."</string>
+    <string name="volume_ringer_change" msgid="3574969197796055532">"Dodirnite da biste promenili režim zvona"</string>
+    <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"isključite zvuk"</string>
+    <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"uključite zvuk"</string>
+    <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibracija"</string>
+    <string name="volume_dialog_title" msgid="6502703403483577940">"Kontrole za jačinu zvuka za %s"</string>
+    <string name="volume_dialog_ringer_guidance_ring" msgid="9143194270463146858">"Melodija zvona za pozive i obaveštenja je uključena (<xliff:g id="VOLUME_LEVEL">%1$s</xliff:g>)"</string>
+    <string name="system_ui_tuner" msgid="1471348823289954729">"Tjuner za korisnički interfejs sistema"</string>
+    <string name="status_bar" msgid="4357390266055077437">"Statusna traka"</string>
+    <string name="demo_mode" msgid="263484519766901593">"Režim demonstracije za korisnički interfejs sistema"</string>
+    <string name="enable_demo_mode" msgid="3180345364745966431">"Omogući režim demonstracije"</string>
+    <string name="show_demo_mode" msgid="3677956462273059726">"Prikaži režim demonstracije"</string>
+    <string name="status_bar_ethernet" msgid="5690979758988647484">"Eternet"</string>
+    <string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
+    <string name="wallet_title" msgid="5369767670735827105">"Novčanik"</string>
+    <string name="wallet_empty_state_label" msgid="7776761245237530394">"Obavite konfigurisanje da biste mogli brže i sigurnije da kupujete pomoću telefona"</string>
+    <string name="wallet_app_button_label" msgid="7123784239111190992">"Prikaži sve"</string>
+    <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"Dodirnite i otvorite"</string>
+    <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Ažurira se"</string>
+    <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Otključaj radi korišćenja"</string>
+    <string name="wallet_error_generic" msgid="257704570182963611">"Došlo je do problema pri preuzimanju kartica. Probajte ponovo kasnije"</string>
+    <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Podešavanja zaključanog ekrana"</string>
+    <string name="qr_code_scanner_title" msgid="1938155688725760702">"Skener QR koda"</string>
+    <string name="qr_code_scanner_updating_secondary_label" msgid="8344598017007876352">"Ažurira se"</string>
+    <string name="status_bar_work" msgid="5238641949837091056">"Poslovni profil"</string>
+    <string name="status_bar_airplane" msgid="4848702508684541009">"Režim rada u avionu"</string>
+    <string name="zen_alarm_warning" msgid="7844303238486849503">"Nećete čuti sledeći alarm u <xliff:g id="WHEN">%1$s</xliff:g>"</string>
+    <string name="alarm_template" msgid="2234991538018805736">"u <xliff:g id="WHEN">%1$s</xliff:g>"</string>
+    <string name="alarm_template_far" msgid="3561752195856839456">"u <xliff:g id="WHEN">%1$s</xliff:g>"</string>
+    <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string>
+    <string name="accessibility_managed_profile" msgid="4703836746209377356">"Poslovni profil"</string>
+    <string name="tuner_warning_title" msgid="7721976098452135267">"Zabava za neke, ali ne za sve"</string>
+    <string name="tuner_warning" msgid="1861736288458481650">"Tjuner za korisnički interfejs sistema vam pruža dodatne načine za podešavanje i prilagođavanje Android korisničkog interfejsa. Ove eksperimentalne funkcije mogu da se promene, otkažu ili nestanu u budućim izdanjima. Budite oprezni."</string>
+    <string name="tuner_persistent_warning" msgid="230466285569307806">"Ove eksperimentalne funkcije mogu da se promene, otkažu ili nestanu u budućim izdanjima. Budite oprezni."</string>
+    <string name="got_it" msgid="477119182261892069">"Važi"</string>
+    <string name="tuner_toast" msgid="3812684836514766951">"Čestitamo! Tjuner za korisnički interfejs sistema je dodat u Podešavanja"</string>
+    <string name="remove_from_settings" msgid="633775561782209994">"Ukloni iz Podešavanja"</string>
+    <string name="remove_from_settings_prompt" msgid="551565437265615426">"Želite li da uklonite Tjuner za korisnički interfejs sistema iz Podešavanja i da prestanete da koristite sve njegove funkcije?"</string>
+    <string name="enable_bluetooth_title" msgid="866883307336662596">"Želite li da uključite Bluetooth?"</string>
+    <string name="enable_bluetooth_message" msgid="6740938333772779717">"Da biste povezali tastaturu sa tabletom, prvo morate da uključite Bluetooth."</string>
+    <string name="enable_bluetooth_confirmation_ok" msgid="2866408183324184876">"Uključi"</string>
+    <string name="tuner_full_importance_settings" msgid="1388025816553459059">"Napredne kontrole za obaveštenja"</string>
+    <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Uključeno – na osnovu lica"</string>
+    <string name="power_notification_controls_description" msgid="1334963837572708952">"Pomoću naprednih kontrola za obaveštenja možete da podesite nivo važnosti od 0. do 5. za obaveštenja aplikacije. \n\n"<b>"5. nivo"</b>" \n– Prikazuju se u vrhu liste obaveštenja \n- Dozvoli prekid režima celog ekrana \n– Uvek zaviruj \n\n"<b>"4. nivo"</b>" \n– Spreči prekid režima celog ekrana \n– Uvek zaviruj \n\n"<b>"3. nivo"</b>" \n– Spreči prekid režima celog ekrana \n– Nikada ne zaviruj \n\n"<b>"2. nivo"</b>" \n– Spreči prekid režima celog ekrana \n– Nikada ne zaviruj \n– Nikada ne proizvodi zvuk ili vibraciju \n\n"<b>"1. nivo"</b>" \n– Spreči prekid režima celog ekrana \n– Nikada ne zaviruj \n– Nikada ne proizvodi zvuk ili vibraciju \n– Sakrij na zaključanom ekranu i statusnoj traci \n– Prikazuju se u dnu liste obaveštenja \n\n"<b>"0. nivo"</b>" \n– Blokiraj sva obaveštenja iz aplikacije"</string>
+    <string name="inline_done_button" msgid="6043094985588909584">"Gotovo"</string>
+    <string name="inline_ok_button" msgid="603075490581280343">"Primeni"</string>
+    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Isključi obaveštenja"</string>
+    <string name="notification_silence_title" msgid="8608090968400832335">"Nečujno"</string>
+    <string name="notification_alert_title" msgid="3656229781017543655">"Podrazumevano"</string>
+    <string name="notification_automatic_title" msgid="3745465364578762652">"Automatska"</string>
+    <string name="notification_channel_summary_low" msgid="4860617986908931158">"Bez zvuka i vibriranja"</string>
+    <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Bez zvuka i vibriranja i prikazuje se u nastavku odeljka za konverzacije"</string>
+    <string name="notification_channel_summary_default" msgid="3282930979307248890">"Može da zvoni ili vibrira u zavisnosti od podešavanja telefona"</string>
+    <string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Može da zvoni ili vibrira u zavisnosti od podešavanja telefona. Konverzacije iz aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> se podrazumevano prikazuju u oblačićima."</string>
+    <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Neka sistem utvrdi da li ovo obaveštenje treba da emituje zvuk ili da vibrira"</string>
+    <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"&lt;b&gt;Status:&lt;/b&gt; Unapređeno u Podrazumevano"</string>
+    <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"&lt;b&gt;Status:&lt;/b&gt; Degradirano u Nečujno"</string>
+    <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"&lt;b&gt;Status:&lt;/b&gt; Rangirano više"</string>
+    <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; Rangirano niže"</string>
+    <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Prikazuje se u vrhu obaveštenja o konverzacijama i kao slika profila na zaključanom ekranu"</string>
+    <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Prikazuje se u vrhu obaveštenja o konverzacijama i kao slika profila na zaključanom ekranu, pojavljuje se kao oblačić"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Prikazuje se u vrhu obaveštenja o konverzacijama i kao slika profila na zaključanom ekranu, prekida režim Ne uznemiravaj"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Prikazuje se u vrhu obaveštenja o konverzacijama i kao slika profila na zaključanom ekranu, pojavljuje se kao oblačić, prekida režim Ne uznemiravaj"</string>
+    <string name="notification_priority_title" msgid="2079708866333537093">"Prioritetno"</string>
+    <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ne podržava funkcije konverzacije"</string>
+    <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ova obaveštenja ne mogu da se menjaju."</string>
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Obaveštenja o pozivima ne mogu da se menjaju."</string>
+    <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ova grupa obaveštenja ne može da se konfiguriše ovde"</string>
+    <string name="notification_delegate_header" msgid="1264510071031479920">"Obaveštenje preko proksija"</string>
+    <string name="notification_channel_dialog_title" msgid="6856514143093200019">"Sva obaveštenja aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="see_more_title" msgid="7409317011708185729">"Prikaži još"</string>
+    <string name="feedback_alerted" msgid="5192459808484271208">"Sistem je ovo obaveštenje automatski &lt;b&gt;unapredio u podrazumevano&lt;/b&gt;."</string>
+    <string name="feedback_silenced" msgid="9116540317466126457">"Sistem je ovo obaveštenje automatski &lt;b&gt;degradirao u Nečujno&lt;/b&gt;."</string>
+    <string name="feedback_promoted" msgid="2125562787759780807">"Ovo obaveštenje je automatski &lt;b&gt;rangirano više&lt;/b&gt; na traci sa obaveštenjima."</string>
+    <string name="feedback_demoted" msgid="951884763467110604">"Ovo obaveštenje je automatski &lt;b&gt;rangirano niže&lt;/b&gt; na traci sa obaveštenjima."</string>
+    <string name="feedback_prompt" msgid="3656728972307896379">"Pošaljite programeru povratne informacije. Da li je to tačno?"</string>
+    <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Kontrole obaveštenja za otvaranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="notification_channel_controls_closed_accessibility" msgid="1561909368876911701">"Kontrole obaveštenja za zatvaranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="notification_more_settings" msgid="4936228656989201793">"Još podešavanja"</string>
+    <string name="notification_app_settings" msgid="8963648463858039377">"Prilagodi"</string>
+    <string name="notification_conversation_bubble" msgid="2242180995373949022">"Prikaži oblačić"</string>
+    <string name="notification_conversation_unbubble" msgid="6908427185031099868">"Ukloni oblačiće"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
-    <string name="notification_menu_gear_description" msgid="6429668976593634862">"контроле обавештења"</string>
-    <string name="notification_menu_snooze_description" msgid="4740133348901973244">"опције за одлагање обавештења"</string>
-    <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Подсети ме"</string>
-    <string name="snooze_undo" msgid="2738844148845992103">"Опозови"</string>
-    <string name="snoozed_for_time" msgid="7586689374860469469">"Одложено је за <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# сат}=2{# сата}one{# сат}few{# сата}other{# сати}}"</string>
-    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# минут}one{# минут}few{# минута}other{# минута}}"</string>
-    <string name="battery_detail_switch_title" msgid="6940976502957380405">"Уштеда батерије"</string>
-    <string name="keyboard_key_button_template" msgid="8005673627272051429">"Дугме <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="keyboard_key_home" msgid="3734400625170020657">"Тастер Почетна"</string>
-    <string name="keyboard_key_back" msgid="4185420465469481999">"Тастер Назад"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Тастер са стрелицом нагоре"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Тастер са стрелицом надоле"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Тастер са стрелицом налево"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Тастер са стрелицом надесно"</string>
-    <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Тастер са централном стрелицом"</string>
+    <string name="notification_menu_gear_description" msgid="6429668976593634862">"kontrole obaveštenja"</string>
+    <string name="notification_menu_snooze_description" msgid="4740133348901973244">"opcije za odlaganje obaveštenja"</string>
+    <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Podseti me"</string>
+    <string name="snooze_undo" msgid="2738844148845992103">"Opozovi"</string>
+    <string name="snoozed_for_time" msgid="7586689374860469469">"Odloženo je za <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# sat}=2{# sata}one{# sat}few{# sata}other{# sati}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minut}one{# minut}few{# minuta}other{# minuta}}"</string>
+    <string name="battery_detail_switch_title" msgid="6940976502957380405">"Ušteda baterije"</string>
+    <string name="keyboard_key_button_template" msgid="8005673627272051429">"Dugme <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="3734400625170020657">"Taster Početna"</string>
+    <string name="keyboard_key_back" msgid="4185420465469481999">"Taster Nazad"</string>
+    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Taster sa strelicom nagore"</string>
+    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Taster sa strelicom nadole"</string>
+    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Taster sa strelicom nalevo"</string>
+    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Taster sa strelicom nadesno"</string>
+    <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Taster sa centralnom strelicom"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
-    <string name="keyboard_key_space" msgid="6980847564173394012">"Размак"</string>
+    <string name="keyboard_key_space" msgid="6980847564173394012">"Razmak"</string>
     <string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
-    <string name="keyboard_key_backspace" msgid="4095278312039628074">"Тастер за брисање уназад"</string>
-    <string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Тастер за репродукцију/паузирање"</string>
-    <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Тастер за заустављање"</string>
-    <string name="keyboard_key_media_next" msgid="8502476691227914952">"Тастер Следећа"</string>
-    <string name="keyboard_key_media_previous" msgid="5637875709190955351">"Тастер Претходна"</string>
-    <string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Тастер за премотавање уназад"</string>
-    <string name="keyboard_key_media_fast_forward" msgid="3572444327046911822">"Тастер за премотавање унапред"</string>
-    <string name="keyboard_key_page_up" msgid="173914303254199845">"Тастер за страницу нагоре"</string>
-    <string name="keyboard_key_page_down" msgid="9035902490071829731">"Тастер за страницу надоле"</string>
-    <string name="keyboard_key_forward_del" msgid="5325501825762733459">"Тастер за брисање"</string>
-    <string name="keyboard_key_move_home" msgid="3496502501803911971">"Тастер Почетна"</string>
-    <string name="keyboard_key_move_end" msgid="99190401463834854">"Тастер за крај"</string>
-    <string name="keyboard_key_insert" msgid="4621692715704410493">"Тастер за уметање"</string>
+    <string name="keyboard_key_backspace" msgid="4095278312039628074">"Taster za brisanje unazad"</string>
+    <string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Taster za reprodukciju/pauziranje"</string>
+    <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Taster za zaustavljanje"</string>
+    <string name="keyboard_key_media_next" msgid="8502476691227914952">"Taster Sledeća"</string>
+    <string name="keyboard_key_media_previous" msgid="5637875709190955351">"Taster Prethodna"</string>
+    <string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Taster za premotavanje unazad"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3572444327046911822">"Taster za premotavanje unapred"</string>
+    <string name="keyboard_key_page_up" msgid="173914303254199845">"Taster za stranicu nagore"</string>
+    <string name="keyboard_key_page_down" msgid="9035902490071829731">"Taster za stranicu nadole"</string>
+    <string name="keyboard_key_forward_del" msgid="5325501825762733459">"Taster za brisanje"</string>
+    <string name="keyboard_key_move_home" msgid="3496502501803911971">"Taster Početna"</string>
+    <string name="keyboard_key_move_end" msgid="99190401463834854">"Taster za kraj"</string>
+    <string name="keyboard_key_insert" msgid="4621692715704410493">"Taster za umetanje"</string>
     <string name="keyboard_key_num_lock" msgid="7209960042043090548">"Num Lock"</string>
-    <string name="keyboard_key_numpad_template" msgid="7316338238459991821">"Тастер <xliff:g id="NAME">%1$s</xliff:g> на нумеричкој тастатури"</string>
-    <string name="notif_inline_reply_remove_attachment_description" msgid="7954075334095405429">"Уклони прилог"</string>
-    <string name="keyboard_shortcut_group_system" msgid="1583416273777875970">"Систем"</string>
-    <string name="keyboard_shortcut_group_system_home" msgid="7465138628692109907">"Почетни"</string>
-    <string name="keyboard_shortcut_group_system_recents" msgid="8628108256824616927">"Недавни садржај"</string>
-    <string name="keyboard_shortcut_group_system_back" msgid="1055709713218453863">"Назад"</string>
-    <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Обавештења"</string>
-    <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Тастерске пречице"</string>
-    <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Промени распоред тастатуре"</string>
-    <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Апликације"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Апликација за помоћ"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Прегледач"</string>
-    <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Контакти"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Имејл"</string>
+    <string name="keyboard_key_numpad_template" msgid="7316338238459991821">"Taster <xliff:g id="NAME">%1$s</xliff:g> na numeričkoj tastaturi"</string>
+    <string name="notif_inline_reply_remove_attachment_description" msgid="7954075334095405429">"Ukloni prilog"</string>
+    <string name="keyboard_shortcut_group_system" msgid="1583416273777875970">"Sistem"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="7465138628692109907">"Početni"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="8628108256824616927">"Nedavni sadržaj"</string>
+    <string name="keyboard_shortcut_group_system_back" msgid="1055709713218453863">"Nazad"</string>
+    <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Obaveštenja"</string>
+    <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Tasterske prečice"</string>
+    <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Promeni raspored tastature"</string>
+    <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Aplikacije"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Aplikacija za pomoć"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Pregledač"</string>
+    <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Kontakti"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Imejl"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
-    <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Музика"</string>
-    <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календар"</string>
-    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Не узнемиравај"</string>
-    <string name="volume_dnd_silent" msgid="4154597281458298093">"Пречица за дугмад за јачину звука"</string>
-    <string name="battery" msgid="769686279459897127">"Батерија"</string>
-    <string name="headset" msgid="4485892374984466437">"Наглавне слушалице"</string>
-    <string name="accessibility_long_click_tile" msgid="210472753156768705">"Отворите подешавања"</string>
-    <string name="accessibility_status_bar_headphones" msgid="1304082414912647414">"Слушалице су повезане"</string>
-    <string name="accessibility_status_bar_headset" msgid="2699275863720926104">"Наглавне слушалице су повезане"</string>
-    <string name="data_saver" msgid="3484013368530820763">"Уштеда података"</string>
-    <string name="accessibility_data_saver_on" msgid="5394743820189757731">"Уштеда података је укључена"</string>
-    <string name="switch_bar_on" msgid="1770868129120096114">"Укључено"</string>
-    <string name="switch_bar_off" msgid="5669805115416379556">"Искључено"</string>
-    <string name="tile_unavailable" msgid="3095879009136616920">"Недоступно"</string>
-    <string name="accessibility_tile_disabled_by_policy_action_description" msgid="6958422730461646926">"сазнајте више"</string>
-    <string name="nav_bar" msgid="4642708685386136807">"Трака за навигацију"</string>
-    <string name="nav_bar_layout" msgid="4716392484772899544">"Распоред"</string>
-    <string name="left_nav_bar_button_type" msgid="2634852842345192790">"Додатни тип левог дугмета"</string>
-    <string name="right_nav_bar_button_type" msgid="4472566498647364715">"Додатни тип десног дугмета"</string>
+    <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muzika"</string>
+    <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendar"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ne uznemiravaj"</string>
+    <string name="volume_dnd_silent" msgid="4154597281458298093">"Prečica za dugmad za jačinu zvuka"</string>
+    <string name="battery" msgid="769686279459897127">"Baterija"</string>
+    <string name="headset" msgid="4485892374984466437">"Naglavne slušalice"</string>
+    <string name="accessibility_long_click_tile" msgid="210472753156768705">"Otvorite podešavanja"</string>
+    <string name="accessibility_status_bar_headphones" msgid="1304082414912647414">"Slušalice su povezane"</string>
+    <string name="accessibility_status_bar_headset" msgid="2699275863720926104">"Naglavne slušalice su povezane"</string>
+    <string name="data_saver" msgid="3484013368530820763">"Ušteda podataka"</string>
+    <string name="accessibility_data_saver_on" msgid="5394743820189757731">"Ušteda podataka je uključena"</string>
+    <string name="switch_bar_on" msgid="1770868129120096114">"Uključeno"</string>
+    <string name="switch_bar_off" msgid="5669805115416379556">"Isključeno"</string>
+    <string name="tile_unavailable" msgid="3095879009136616920">"Nedostupno"</string>
+    <string name="accessibility_tile_disabled_by_policy_action_description" msgid="6958422730461646926">"saznajte više"</string>
+    <string name="nav_bar" msgid="4642708685386136807">"Traka za navigaciju"</string>
+    <string name="nav_bar_layout" msgid="4716392484772899544">"Raspored"</string>
+    <string name="left_nav_bar_button_type" msgid="2634852842345192790">"Dodatni tip levog dugmeta"</string>
+    <string name="right_nav_bar_button_type" msgid="4472566498647364715">"Dodatni tip desnog dugmeta"</string>
   <string-array name="nav_bar_buttons">
-    <item msgid="2681220472659720036">"Меморија"</item>
-    <item msgid="4795049793625565683">"Кôд тастера"</item>
-    <item msgid="80697951177515644">"Потврда ротирања, пребацивач за тастатуру"</item>
-    <item msgid="7626977989589303588">"Ништа"</item>
+    <item msgid="2681220472659720036">"Memorija"</item>
+    <item msgid="4795049793625565683">"Kôd tastera"</item>
+    <item msgid="80697951177515644">"Potvrda rotiranja, prebacivač za tastaturu"</item>
+    <item msgid="7626977989589303588">"Ništa"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
-    <item msgid="9156773083127904112">"Нормални"</item>
-    <item msgid="2019571224156857610">"Компактни"</item>
-    <item msgid="7453955063378349599">"Уз леву страну"</item>
-    <item msgid="5874146774389433072">"Уз десну страну"</item>
+    <item msgid="9156773083127904112">"Normalni"</item>
+    <item msgid="2019571224156857610">"Kompaktni"</item>
+    <item msgid="7453955063378349599">"Uz levu stranu"</item>
+    <item msgid="5874146774389433072">"Uz desnu stranu"</item>
   </string-array>
-    <string name="save" msgid="3392754183673848006">"Сачувај"</string>
-    <string name="reset" msgid="8715144064608810383">"Ресетуј"</string>
-    <string name="clipboard" msgid="8517342737534284617">"Привремена меморија"</string>
-    <string name="accessibility_key" msgid="3471162841552818281">"Прилагођено дугме за навигацију"</string>
-    <string name="left_keycode" msgid="8211040899126637342">"Лево дугме за кôд тастера"</string>
-    <string name="right_keycode" msgid="2480715509844798438">"Десно дугме за кôд тастера"</string>
-    <string name="left_icon" msgid="5036278531966897006">"Лева икона"</string>
-    <string name="right_icon" msgid="1103955040645237425">"Десна икона"</string>
-    <string name="drag_to_add_tiles" msgid="8933270127508303672">"Задржите и превуците да бисте додали плочице"</string>
-    <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Задржите и превуците да бисте променили распоред плочица"</string>
-    <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Превуците овде да бисте уклонили"</string>
-    <string name="drag_to_remove_disabled" msgid="933046987838658850">"Минималан број плочица је <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
-    <string name="qs_edit" msgid="5583565172803472437">"Измени"</string>
-    <string name="tuner_time" msgid="2450785840990529997">"Време"</string>
+    <string name="save" msgid="3392754183673848006">"Sačuvaj"</string>
+    <string name="reset" msgid="8715144064608810383">"Resetuj"</string>
+    <string name="clipboard" msgid="8517342737534284617">"Privremena memorija"</string>
+    <string name="accessibility_key" msgid="3471162841552818281">"Prilagođeno dugme za navigaciju"</string>
+    <string name="left_keycode" msgid="8211040899126637342">"Levo dugme za kôd tastera"</string>
+    <string name="right_keycode" msgid="2480715509844798438">"Desno dugme za kôd tastera"</string>
+    <string name="left_icon" msgid="5036278531966897006">"Leva ikona"</string>
+    <string name="right_icon" msgid="1103955040645237425">"Desna ikona"</string>
+    <string name="drag_to_add_tiles" msgid="8933270127508303672">"Zadržite i prevucite da biste dodali pločice"</string>
+    <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Zadržite i prevucite da biste promenili raspored pločica"</string>
+    <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Prevucite ovde da biste uklonili"</string>
+    <string name="drag_to_remove_disabled" msgid="933046987838658850">"Minimalan broj pločica je <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
+    <string name="qs_edit" msgid="5583565172803472437">"Izmeni"</string>
+    <string name="tuner_time" msgid="2450785840990529997">"Vreme"</string>
   <string-array name="clock_options">
-    <item msgid="3986445361435142273">"Прикажи сате, минуте и секунде"</item>
-    <item msgid="1271006222031257266">"Прикажи сате и минуте (подразумевано)"</item>
-    <item msgid="6135970080453877218">"Не приказуј ову икону"</item>
+    <item msgid="3986445361435142273">"Prikaži sate, minute i sekunde"</item>
+    <item msgid="1271006222031257266">"Prikaži sate i minute (podrazumevano)"</item>
+    <item msgid="6135970080453877218">"Ne prikazuj ovu ikonu"</item>
   </string-array>
   <string-array name="battery_options">
-    <item msgid="7714004721411852551">"Увек приказуј проценат"</item>
-    <item msgid="3805744470661798712">"Прикажи проценат током пуњења (подразумевано)"</item>
-    <item msgid="8619482474544321778">"Не приказуј ову икону"</item>
+    <item msgid="7714004721411852551">"Uvek prikazuj procenat"</item>
+    <item msgid="3805744470661798712">"Prikaži procenat tokom punjenja (podrazumevano)"</item>
+    <item msgid="8619482474544321778">"Ne prikazuj ovu ikonu"</item>
   </string-array>
-    <string name="tuner_low_priority" msgid="8412666814123009820">"Прикажи иконе обавештења ниског приоритета"</string>
-    <string name="other" msgid="429768510980739978">"Друго"</string>
-    <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"уклонили плочицу"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"додали плочицу на крај"</string>
-    <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Преместите плочицу"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Додајте плочицу"</string>
-    <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Преместите на <xliff:g id="POSITION">%1$d</xliff:g>. позицију"</string>
-    <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Додајте на <xliff:g id="POSITION">%1$d</xliff:g>. позицију"</string>
-    <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g>. позиција"</string>
-    <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Плочица је додата"</string>
-    <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Плочица је уклоњена"</string>
-    <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Уређивач за Брза подешавања."</string>
-    <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Обавештења за <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
-    <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Отвори Подешавања."</string>
-    <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Отвори Брза подешавања."</string>
-    <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Затвори Брза подешавања."</string>
-    <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Пријављени сте као <xliff:g id="ID_1">%s</xliff:g>"</string>
-    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"одабрали корисника"</string>
-    <string name="data_connection_no_internet" msgid="691058178914184544">"Нема интернета"</string>
-    <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Отвори подешавања за <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Измени редослед подешавања."</string>
-    <string name="accessibility_quick_settings_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>
-    <string name="high_temp_alarm_help_care_steps" msgid="5017002218341329566">"Погледајте упозорења"</string>
-    <string name="lockscreen_shortcut_left" msgid="1238765178956067599">"Лева пречица"</string>
-    <string name="lockscreen_shortcut_right" msgid="4138414674531853719">"Десна пречица"</string>
-    <string name="lockscreen_unlock_left" msgid="1417801334370269374">"И лева пречица откључава"</string>
-    <string name="lockscreen_unlock_right" msgid="4658008735541075346">"И десна пречица откључава"</string>
-    <string name="lockscreen_none" msgid="4710862479308909198">"Ништа"</string>
-    <string name="tuner_launch_app" msgid="3906265365971743305">"Покрени <xliff:g id="APP">%1$s</xliff:g>"</string>
-    <string name="tuner_other_apps" msgid="7767462881742291204">"Друге апликације"</string>
-    <string name="tuner_circle" msgid="5270591778160525693">"Круг"</string>
-    <string name="tuner_plus" msgid="4130366441154416484">"Плус"</string>
-    <string name="tuner_minus" msgid="5258518368944598545">"Минус"</string>
-    <string name="tuner_left" msgid="5758862558405684490">"Стрелица улево"</string>
-    <string name="tuner_right" msgid="8247571132790812149">"Стрелица удесно"</string>
-    <string name="tuner_menu" msgid="363690665924769420">"Мени"</string>
-    <string name="tuner_app" msgid="6949280415826686972">"Апликација <xliff:g id="APP">%1$s</xliff:g>"</string>
-    <string name="notification_channel_alerts" msgid="3385787053375150046">"Обавештења"</string>
-    <string name="notification_channel_battery" msgid="9219995638046695106">"Батерија"</string>
-    <string name="notification_channel_screenshot" msgid="7665814998932211997">"Снимци екрана"</string>
-    <string name="notification_channel_instant" msgid="7556135423486752680">"Инстант апликације"</string>
-    <string name="notification_channel_setup" msgid="7660580986090760350">"Подешавање"</string>
-    <string name="notification_channel_storage" msgid="2720725707628094977">"Меморијски простор"</string>
-    <string name="notification_channel_hints" msgid="7703783206000346876">"Савети"</string>
-    <string name="instant_apps" msgid="8337185853050247304">"Инстант апликације"</string>
-    <string name="instant_apps_title" msgid="8942706782103036910">"Апликација <xliff:g id="APP">%1$s</xliff:g> је покренута"</string>
-    <string name="instant_apps_message" msgid="6112428971833011754">"Апликација се отворила без инсталирања."</string>
-    <string name="instant_apps_message_with_help" msgid="1816952263531203932">"Апликација се отворила без инсталирања. Додирните да бисте сазнали више."</string>
-    <string name="app_info" msgid="5153758994129963243">"Информације о апликацији"</string>
-    <string name="go_to_web" msgid="636673528981366511">"Иди на прегледач"</string>
-    <string name="mobile_data" msgid="4564407557775397216">"Мобилни подаци"</string>
+    <string name="tuner_low_priority" msgid="8412666814123009820">"Prikaži ikone obaveštenja niskog prioriteta"</string>
+    <string name="other" msgid="429768510980739978">"Drugo"</string>
+    <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"uklonili pločicu"</string>
+    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"dodali pločicu na kraj"</string>
+    <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Premestite pločicu"</string>
+    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Dodajte pločicu"</string>
+    <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Premestite na <xliff:g id="POSITION">%1$d</xliff:g>. poziciju"</string>
+    <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodajte na <xliff:g id="POSITION">%1$d</xliff:g>. poziciju"</string>
+    <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g>. pozicija"</string>
+    <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Pločica je dodata"</string>
+    <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Pločica je uklonjena"</string>
+    <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Uređivač za Brza podešavanja."</string>
+    <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Obaveštenja za <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Otvori Podešavanja."</string>
+    <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Otvori Brza podešavanja."</string>
+    <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Zatvori Brza podešavanja."</string>
+    <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Prijavljeni ste kao <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"odabrali korisnika"</string>
+    <string name="data_connection_no_internet" msgid="691058178914184544">"Nema interneta"</string>
+    <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Otvori podešavanja za <xliff:g id="ID_1">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Izmeni redosled podešavanja."</string>
+    <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>
+    <string name="high_temp_alarm_help_care_steps" msgid="5017002218341329566">"Pogledajte upozorenja"</string>
+    <string name="lockscreen_shortcut_left" msgid="1238765178956067599">"Leva prečica"</string>
+    <string name="lockscreen_shortcut_right" msgid="4138414674531853719">"Desna prečica"</string>
+    <string name="lockscreen_unlock_left" msgid="1417801334370269374">"I leva prečica otključava"</string>
+    <string name="lockscreen_unlock_right" msgid="4658008735541075346">"I desna prečica otključava"</string>
+    <string name="lockscreen_none" msgid="4710862479308909198">"Ništa"</string>
+    <string name="tuner_launch_app" msgid="3906265365971743305">"Pokreni <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="tuner_other_apps" msgid="7767462881742291204">"Druge aplikacije"</string>
+    <string name="tuner_circle" msgid="5270591778160525693">"Krug"</string>
+    <string name="tuner_plus" msgid="4130366441154416484">"Plus"</string>
+    <string name="tuner_minus" msgid="5258518368944598545">"Minus"</string>
+    <string name="tuner_left" msgid="5758862558405684490">"Strelica ulevo"</string>
+    <string name="tuner_right" msgid="8247571132790812149">"Strelica udesno"</string>
+    <string name="tuner_menu" msgid="363690665924769420">"Meni"</string>
+    <string name="tuner_app" msgid="6949280415826686972">"Aplikacija <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="notification_channel_alerts" msgid="3385787053375150046">"Obaveštenja"</string>
+    <string name="notification_channel_battery" msgid="9219995638046695106">"Baterija"</string>
+    <string name="notification_channel_screenshot" msgid="7665814998932211997">"Snimci ekrana"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant aplikacije"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Podešavanje"</string>
+    <string name="notification_channel_storage" msgid="2720725707628094977">"Memorijski prostor"</string>
+    <string name="notification_channel_hints" msgid="7703783206000346876">"Saveti"</string>
+    <string name="instant_apps" msgid="8337185853050247304">"Instant aplikacije"</string>
+    <string name="instant_apps_title" msgid="8942706782103036910">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> je pokrenuta"</string>
+    <string name="instant_apps_message" msgid="6112428971833011754">"Aplikacija se otvorila bez instaliranja."</string>
+    <string name="instant_apps_message_with_help" msgid="1816952263531203932">"Aplikacija se otvorila bez instaliranja. Dodirnite da biste saznali više."</string>
+    <string name="app_info" msgid="5153758994129963243">"Informacije o aplikaciji"</string>
+    <string name="go_to_web" msgid="636673528981366511">"Idi na pregledač"</string>
+    <string name="mobile_data" msgid="4564407557775397216">"Mobilni podaci"</string>
     <string name="mobile_data_text_format" msgid="6806501540022589786">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
-    <string name="wifi_is_off" msgid="5389597396308001471">"WiFi је искључен"</string>
-    <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth је искључен"</string>
-    <string name="dnd_is_off" msgid="3185706903793094463">"Режим Не узнемиравај је искључен"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
-    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Аутоматско правило (<xliff:g id="ID_1">%s</xliff:g>) је укључило режим Не узнемиравај."</string>
-    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Апликација (<xliff:g id="ID_1">%s</xliff:g>) је укључила режим Не узнемиравај."</string>
-    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Аутоматско правило или апликација су укључили режим Не узнемиравај."</string>
-    <string name="running_foreground_services_title" msgid="5137313173431186685">"Апликације покренуте у позадини"</string>
-    <string name="running_foreground_services_msg" msgid="3009459259222695385">"Додирните за детаље о батерији и потрошњи података"</string>
-    <string name="mobile_data_disable_title" msgid="5366476131671617790">"Желите да искључите мобилне податке?"</string>
-    <string name="mobile_data_disable_message" msgid="8604966027899770415">"Нећете имати приступ подацима или интернету преко мобилног оператера <xliff:g id="CARRIER">%s</xliff:g>. Интернет ће бити доступан само преко WiFi везе."</string>
-    <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"мобилни оператер"</string>
-    <string name="auto_data_switch_disable_title" msgid="5146527155665190652">"Желите да се вратите на мобилног оператера <xliff:g id="CARRIER">%s</xliff:g>?"</string>
-    <string name="auto_data_switch_disable_message" msgid="5885533647399535852">"Мобилни подаци се неће аутоматски променити на основу доступности"</string>
-    <string name="auto_data_switch_dialog_negative_button" msgid="2370876875999891444">"Не, хвала"</string>
-    <string name="auto_data_switch_dialog_positive_button" msgid="8531782041263087564">"Да, пређи"</string>
-    <string name="touch_filtered_warning" msgid="8119511393338714836">"Подешавања не могу да верификују ваш одговор јер апликација скрива захтев за дозволу."</string>
-    <string name="slice_permission_title" msgid="3262615140094151017">"Желите ли да дозволите апликацији <xliff:g id="APP_0">%1$s</xliff:g> да приказује исечке из апликације <xliff:g id="APP_2">%2$s</xliff:g>?"</string>
-    <string name="slice_permission_text_1" msgid="6675965177075443714">"– Може да чита податке из апликације <xliff:g id="APP">%1$s</xliff:g>"</string>
-    <string name="slice_permission_text_2" msgid="6758906940360746983">"– Може да обавља радње у апликацији <xliff:g id="APP">%1$s</xliff:g>"</string>
-    <string name="slice_permission_checkbox" msgid="4242888137592298523">"Дозволите апликацији <xliff:g id="APP">%1$s</xliff:g> да приказује исечке из било које апликације"</string>
-    <string name="slice_permission_allow" msgid="6340449521277951123">"Дозволи"</string>
-    <string name="slice_permission_deny" msgid="6870256451658176895">"Одбиј"</string>
-    <string name="auto_saver_title" msgid="6873691178754086596">"Додирните да бисте направили распоред за уштеду батерије"</string>
-    <string name="auto_saver_text" msgid="3214960308353838764">"Укључите ако ће батерија вероватно да се испразни"</string>
-    <string name="no_auto_saver_action" msgid="7467924389609773835">"Не, хвала"</string>
-    <string name="heap_dump_tile_name" msgid="2464189856478823046">"Издвоји SysUI мем."</string>
-    <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"У употреби"</string>
-    <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Апликације користе <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+    <string name="wifi_is_off" msgid="5389597396308001471">"WiFi je isključen"</string>
+    <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth je isključen"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Režim Ne uznemiravaj je isključen"</string>
+    <string name="dnd_is_on" msgid="7009368176361546279">"Režim Ne uznemiravaj je uključen"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Automatsko pravilo (<xliff:g id="ID_1">%s</xliff:g>) je uključilo režim Ne uznemiravaj."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Aplikacija (<xliff:g id="ID_1">%s</xliff:g>) je uključila režim Ne uznemiravaj."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Automatsko pravilo ili aplikacija su uključili režim Ne uznemiravaj."</string>
+    <string name="running_foreground_services_title" msgid="5137313173431186685">"Aplikacije pokrenute u pozadini"</string>
+    <string name="running_foreground_services_msg" msgid="3009459259222695385">"Dodirnite za detalje o bateriji i potrošnji podataka"</string>
+    <string name="mobile_data_disable_title" msgid="5366476131671617790">"Želite da isključite mobilne podatke?"</string>
+    <string name="mobile_data_disable_message" msgid="8604966027899770415">"Nećete imati pristup podacima ili internetu preko mobilnog operatera <xliff:g id="CARRIER">%s</xliff:g>. Internet će biti dostupan samo preko WiFi veze."</string>
+    <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"mobilni operater"</string>
+    <string name="auto_data_switch_disable_title" msgid="5146527155665190652">"Želite da se vratite na mobilnog operatera <xliff:g id="CARRIER">%s</xliff:g>?"</string>
+    <string name="auto_data_switch_disable_message" msgid="5885533647399535852">"Mobilni podaci se neće automatski promeniti na osnovu dostupnosti"</string>
+    <string name="auto_data_switch_dialog_negative_button" msgid="2370876875999891444">"Ne, hvala"</string>
+    <string name="auto_data_switch_dialog_positive_button" msgid="8531782041263087564">"Da, pređi"</string>
+    <string name="touch_filtered_warning" msgid="8119511393338714836">"Podešavanja ne mogu da verifikuju vaš odgovor jer aplikacija skriva zahtev za dozvolu."</string>
+    <string name="slice_permission_title" msgid="3262615140094151017">"Želite li da dozvolite aplikaciji <xliff:g id="APP_0">%1$s</xliff:g> da prikazuje isečke iz aplikacije <xliff:g id="APP_2">%2$s</xliff:g>?"</string>
+    <string name="slice_permission_text_1" msgid="6675965177075443714">"– Može da čita podatke iz aplikacije <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="slice_permission_text_2" msgid="6758906940360746983">"– Može da obavlja radnje u aplikaciji <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="slice_permission_checkbox" msgid="4242888137592298523">"Dozvolite aplikaciji <xliff:g id="APP">%1$s</xliff:g> da prikazuje isečke iz bilo koje aplikacije"</string>
+    <string name="slice_permission_allow" msgid="6340449521277951123">"Dozvoli"</string>
+    <string name="slice_permission_deny" msgid="6870256451658176895">"Odbij"</string>
+    <string name="auto_saver_title" msgid="6873691178754086596">"Dodirnite da biste napravili raspored za uštedu baterije"</string>
+    <string name="auto_saver_text" msgid="3214960308353838764">"Uključite ako će baterija verovatno da se isprazni"</string>
+    <string name="no_auto_saver_action" msgid="7467924389609773835">"Ne, hvala"</string>
+    <string name="heap_dump_tile_name" msgid="2464189856478823046">"Izdvoji SysUI mem."</string>
+    <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"U upotrebi"</string>
+    <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacije koriste <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
     <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
-    <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" и "</string>
-    <string name="ongoing_privacy_dialog_using_op" msgid="426635338010011796">"Користи: <xliff:g id="APPLICATION_NAME">%1$s</xliff:g>"</string>
-    <string name="ongoing_privacy_dialog_recent_op" msgid="2736290123662790026">"Недавно користио/ла <xliff:g id="APPLICATION_NAME">%1$s</xliff:g>"</string>
-    <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(посао)"</string>
-    <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефонски позив"</string>
-    <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(преко: <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" i "</string>
+    <string name="ongoing_privacy_dialog_using_op" msgid="426635338010011796">"Koristi: <xliff:g id="APPLICATION_NAME">%1$s</xliff:g>"</string>
+    <string name="ongoing_privacy_dialog_recent_op" msgid="2736290123662790026">"Nedavno koristio/la <xliff:g id="APPLICATION_NAME">%1$s</xliff:g>"</string>
+    <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(posao)"</string>
+    <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonski poziv"</string>
+    <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(preko: <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
     <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
     <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
-    <string name="privacy_type_camera" msgid="7974051382167078332">"камеру"</string>
-    <string name="privacy_type_location" msgid="7991481648444066703">"локацију"</string>
-    <string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
-    <string name="privacy_type_media_projection" msgid="8136723828804251547">"снимање екрана"</string>
-    <string name="music_controls_no_title" msgid="4166497066552290938">"Без наслова"</string>
-    <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Стање приправности"</string>
-    <string name="magnification_window_title" msgid="4863914360847258333">"Прозор за увећање"</string>
-    <string name="magnification_controls_title" msgid="8421106606708891519">"Контроле прозора за увећање"</string>
-    <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Увећајте"</string>
-    <string name="accessibility_control_zoom_out" msgid="69578832020304084">"Умањите"</string>
-    <string name="accessibility_control_move_up" msgid="6622825494014720136">"Померите нагоре"</string>
-    <string name="accessibility_control_move_down" msgid="5390922476900974512">"Померите надоле"</string>
-    <string name="accessibility_control_move_left" msgid="8156206978511401995">"Померите налево"</string>
-    <string name="accessibility_control_move_right" msgid="8926821093629582888">"Померите надесно"</string>
-    <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Прелазак на други режим увећања"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Увећајте цео екран"</string>
-    <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Увећајте део екрана"</string>
-    <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Пређи"</string>
-    <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Додирните за функције приступачности. Прилагодите или замените ово дугме у Подешавањима.\n\n"<annotation id="link">"Подешавања"</annotation></string>
-    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Померите дугме до ивице да бисте га привремено сакрили"</string>
-    <string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"Премести горе лево"</string>
-    <string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"Премести горе десно"</string>
-    <string name="accessibility_floating_button_action_move_bottom_left" msgid="8063394111137429725">"Премести доле лево"</string>
-    <string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Премести доле десно"</string>
-    <string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Премести до ивице и сакриј"</string>
-    <string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Премести изван ивице и прикажи"</string>
-    <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"укључите/искључите"</string>
-    <string name="quick_controls_title" msgid="6839108006171302273">"Контроле уређаја"</string>
-    <string name="controls_providers_title" msgid="6879775889857085056">"Одаберите апликацију за додавање контрола"</string>
-    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# контрола је додата.}one{# контрола је додата.}few{# контроле су додате.}other{# контрола је додато.}}"</string>
-    <string name="controls_removed" msgid="3731789252222856959">"Уклоњено"</string>
-    <string name="accessibility_control_favorite" msgid="8694362691985545985">"Означено је као омиљено"</string>
-    <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Означено је као омиљено, <xliff:g id="NUMBER">%d</xliff:g>. позиција"</string>
-    <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Уклоњено је из омиљених"</string>
-    <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"означили као омиљено"</string>
-    <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"уклонили из омиљених"</string>
-    <string name="accessibility_control_move" msgid="8980344493796647792">"Преместите на <xliff:g id="NUMBER">%d</xliff:g>. позицију"</string>
-    <string name="controls_favorite_default_title" msgid="967742178688938137">"Контроле"</string>
-    <string name="controls_favorite_subtitle" msgid="6481675111056961083">"Одаберите контроле да бисте им приступили из Брзих подешавања"</string>
-    <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Задржите и превуците да бисте променили распоред контрола"</string>
-    <string name="controls_favorite_removed" msgid="5276978408529217272">"Све контроле су уклоњене"</string>
-    <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Промене нису сачуване"</string>
-    <string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"Погледајте друге апликације"</string>
-    <string name="controls_favorite_load_error" msgid="5126216176144877419">"Учитавање контрола није успело. Погледајте апликацију <xliff:g id="APP">%s</xliff:g> да бисте се уверили да се подешавања апликације нису променила."</string>
-    <string name="controls_favorite_load_none" msgid="7687593026725357775">"Компатибилне контроле нису доступне"</string>
-    <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Друго"</string>
-    <string name="controls_dialog_title" msgid="2343565267424406202">"Додајте у контроле уређаја"</string>
-    <string name="controls_dialog_ok" msgid="2770230012857881822">"Додај"</string>
-    <string name="controls_dialog_message" msgid="342066938390663844">"Предлаже <xliff:g id="APP">%s</xliff:g>"</string>
-    <string name="controls_tile_locked" msgid="731547768182831938">"Уређај је закључан"</string>
-    <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Желите ли да приказујете и контролишете уређаје са закључаног екрана?"</string>
-    <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Можете да додате контроле за спољне уређаје на закључани екран.\n\nАпликација на уређају може да вам омогући да контролишете неке уређаје без откључавања телефона или таблета.\n\nТо можете да промените кад год желите у Подешавањима."</string>
-    <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Желите ли да контролишете уређаје са закључаног екрана?"</string>
-    <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"Неке уређаје можете да контролишете без откључавања телефона или таблета.\n\nАпликација на уређају одређује који уређаји могу да се контролишу на овај начин."</string>
-    <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Не, хвала"</string>
-    <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Да"</string>
-    <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN садржи слова или симболе"</string>
-    <string name="controls_pin_verify" msgid="3452778292918877662">"Верификујте: <xliff:g id="DEVICE">%s</xliff:g>"</string>
-    <string name="controls_pin_wrong" msgid="6162694056042164211">"Погрешан PIN"</string>
-    <string name="controls_pin_instructions" msgid="6363309783822475238">"Унесите PIN"</string>
-    <string name="controls_pin_instructions_retry" msgid="1566667581012131046">"Пробајте други PIN"</string>
-    <string name="controls_confirmation_message" msgid="7744104992609594859">"Потврдите промену за: <xliff:g id="DEVICE">%s</xliff:g>"</string>
-    <string name="controls_structure_tooltip" msgid="4355922222944447867">"Превуците да бисте видели још"</string>
-    <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Учитавају се препоруке"</string>
-    <string name="controls_media_title" msgid="1746947284862928133">"Медији"</string>
-    <string name="controls_media_close_session" msgid="4780485355795635052">"Желите ли да сакријете ову контролу за медије за: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <string name="controls_media_active_session" msgid="3146882316024153337">"Актуелна сесија медија не може да буде сакривена."</string>
-    <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Сакриј"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Настави"</string>
-    <string name="controls_media_settings_button" msgid="5815790345117172504">"Подешавања"</string>
-    <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> извођача <xliff:g id="ARTIST_NAME">%2$s</xliff:g> се пушта из апликације <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
-    <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> од <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
-    <string name="controls_media_button_play" msgid="2705068099607410633">"Пусти"</string>
-    <string name="controls_media_button_pause" msgid="8614887780950376258">"Паузирај"</string>
-    <string name="controls_media_button_prev" msgid="8126822360056482970">"Претходна песма"</string>
-    <string name="controls_media_button_next" msgid="6662636627525947610">"Следећа песма"</string>
-    <string name="controls_media_button_connecting" msgid="3138354625847598095">"Повезује се"</string>
-    <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Пусти"</string>
-    <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Отворите <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
-    <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Пустите <xliff:g id="SONG_NAME">%1$s</xliff:g> извођача <xliff:g id="ARTIST_NAME">%2$s</xliff:g> из апликације <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
-    <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Пустите <xliff:g id="SONG_NAME">%1$s</xliff:g> из апликације <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
-    <string name="media_transfer_undo" msgid="1895606387620728736">"Опозови"</string>
-    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Приближите да бисте пуштали музику на: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Приближите се уређају <xliff:g id="DEVICENAME">%1$s</xliff:g> да бисте на њему пуштали"</string>
-    <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Пушта се на уређају <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_transfer_failed" msgid="7955354964610603723">"Дошло је до грешке. Пробајте поново."</string>
-    <string name="controls_error_timeout" msgid="794197289772728958">"Неактивно. Видите апликацију"</string>
-    <string name="controls_error_removed" msgid="6675638069846014366">"Није пронађено"</string>
-    <string name="controls_error_removed_title" msgid="1207794911208047818">"Контрола није доступна"</string>
-    <string name="controls_error_removed_message" msgid="2885911717034750542">"Приступање уређају <xliff:g id="DEVICE">%1$s</xliff:g> није успело. Погледајте апликацију <xliff:g id="APPLICATION">%2$s</xliff:g> да бисте се уверили да је контрола још увек доступна и да се подешавања апликације нису променила."</string>
-    <string name="controls_open_app" msgid="483650971094300141">"Отвори апликацију"</string>
-    <string name="controls_error_generic" msgid="352500456918362905">"Учитавање статуса није успело"</string>
-    <string name="controls_error_failed" msgid="960228639198558525">"Грешка. Пробајте поново"</string>
-    <string name="controls_menu_add" msgid="4447246119229920050">"Додај контроле"</string>
-    <string name="controls_menu_edit" msgid="890623986951347062">"Измени контроле"</string>
-    <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Додајте излазе"</string>
-    <string name="media_output_dialog_group" msgid="5571251347877452212">"Група"</string>
-    <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Изабран је 1 уређај"</string>
-    <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Изабраних уређаја: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
-    <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(веза је прекинута)"</string>
-    <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Пребацивање није успело. Пробајте поново."</string>
-    <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Повежите уређај"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Да бисте пребацивали ову сесију, отворите апликацију."</string>
-    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Непозната апликација"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Заустави пребацивање"</string>
-    <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_first_broadcast_title" msgid="6292237789860753022">"Како функционише емитовање"</string>
-    <string name="media_output_broadcast" msgid="3555580945878071543">"Емитовање"</string>
-    <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Људи у близини са компатибилним Bluetooth уређајима могу да слушају медијски садржај који емитујете"</string>
-    <string name="media_output_broadcasting_message" msgid="4150299923404886073">"Да би слушали емитовање, људи у близини са компатибилним Bluetooth уређајима могу да скенирају QR кôд или да користе назив и лозинку емитовања"</string>
-    <string name="media_output_broadcast_name" msgid="8786127091542624618">"Назив емитовања"</string>
-    <string name="media_output_broadcast_code" msgid="870795639644728542">"Лозинка"</string>
-    <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Сачувај"</string>
-    <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Покреће се…"</string>
-    <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Емитовање није успело"</string>
-    <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Чување није успело. Пробајте поново."</string>
-    <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Чување није успело."</string>
-    <string name="build_number_clip_data_label" msgid="3623176728412560914">"Број верзије"</string>
-    <string name="build_number_copy_toast" msgid="877720921605503046">"Број верзије је копиран у привремену меморију."</string>
-    <string name="basic_status" msgid="2315371112182658176">"Отворите конверзацију"</string>
-    <string name="select_conversation_title" msgid="6716364118095089519">"Виџети за конверзацију"</string>
-    <string name="select_conversation_text" msgid="3376048251434956013">"Додирните конверзацију да бисте је додали на почетни екран"</string>
-    <string name="no_conversations_text" msgid="5354115541282395015">"Недавне конверзације ће се приказати овде"</string>
-    <string name="priority_conversations" msgid="3967482288896653039">"Приоритетне конверзације"</string>
-    <string name="recent_conversations" msgid="8531874684782574622">"Недавне конверзације"</string>
-    <string name="days_timestamp" msgid="5821854736213214331">"Пре <xliff:g id="DURATION">%1$s</xliff:g> дана"</string>
-    <string name="one_week_timestamp" msgid="4925600765473875590">"Пре недељу дана"</string>
-    <string name="two_weeks_timestamp" msgid="9111801081871962155">"Пре 2 недеље"</string>
-    <string name="over_one_week_timestamp" msgid="3770560704420807142">"Пре више од недељу дана"</string>
-    <string name="over_two_weeks_timestamp" msgid="6300507859007874050">"Пре више од 2 недеље"</string>
-    <string name="birthday_status" msgid="2596961629465396761">"Рођендан"</string>
-    <string name="birthday_status_content_description" msgid="682836371128282925">"<xliff:g id="NAME">%1$s</xliff:g> данас слави рођендан"</string>
-    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Рођендан је ускоро"</string>
-    <string name="upcoming_birthday_status_content_description" msgid="2165036816803797148">"<xliff:g id="NAME">%1$s</xliff:g> ускоро слави рођендан"</string>
-    <string name="anniversary_status" msgid="1790034157507590838">"Годишњица"</string>
-    <string name="anniversary_status_content_description" msgid="8212171790843327442">"<xliff:g id="NAME">%1$s</xliff:g> данас слави годишњицу"</string>
-    <string name="location_status" msgid="1294990572202541812">"Дели се локација"</string>
-    <string name="location_status_content_description" msgid="2982386178160071305">"<xliff:g id="NAME">%1$s</xliff:g> дели локацију"</string>
-    <string name="new_story_status" msgid="9012195158584846525">"Нова прича"</string>
-    <string name="new_story_status_content_description" msgid="4963137422622516708">"<xliff:g id="NAME">%1$s</xliff:g> дели нову причу"</string>
-    <string name="video_status" msgid="4548544654316843225">"Гледа се"</string>
-    <string name="audio_status" msgid="4237055636967709208">"Слуша се"</string>
-    <string name="game_status" msgid="1340694320630973259">"Игра се"</string>
-    <string name="empty_user_name" msgid="3389155775773578300">"Пријатељи"</string>
-    <string name="empty_status" msgid="5938893404951307749">"Ћаскамо вечерас?"</string>
-    <string name="status_before_loading" msgid="1500477307859631381">"Садржај ће се ускоро појавити"</string>
-    <string name="missed_call" msgid="4228016077700161689">"Пропуштен позив"</string>
-    <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
-    <string name="people_tile_description" msgid="8154966188085545556">"Погледајте недавне поруке, пропуштене позиве и ажурирања статуса"</string>
-    <string name="people_tile_title" msgid="6589377493334871272">"Конверзација"</string>
-    <string name="paused_by_dnd" msgid="7856941866433556428">"Паузирано режимом Не узнемиравај"</string>
-    <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> је послао/ла поруку: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
-    <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> шаље слику"</string>
-    <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> има ажурирање статуса: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
-    <string name="person_available" msgid="2318599327472755472">"Доступно"</string>
-    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Проблем са очитавањем мерача батерије"</string>
-    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Додирните за више информација"</string>
-    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Није подешен"</string>
-    <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Сензор за отисак прста"</string>
-    <string name="accessibility_authenticate_hint" msgid="798914151813205721">"потврдите идентитет"</string>
-    <string name="accessibility_enter_hint" msgid="2617864063504824834">"унесите уређај"</string>
-    <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Отворите помоћу отиска прста"</string>
-    <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Потребна је потврда идентитета. Додирните сензор за отисак прста да бисте потврдили идентитет."</string>
-    <string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"Актуелни телефонски позив"</string>
-    <string name="mobile_data_settings_title" msgid="3955246641380064901">"Мобилни подаци"</string>
-    <string name="preference_summary_default_combination" msgid="8453246369903749670">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="NETWORKMODE">%2$s</xliff:g>"</string>
-    <string name="mobile_data_connection_active" msgid="944490013299018227">"Повезано"</string>
-    <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Привремено повезано"</string>
-    <string name="mobile_data_poor_connection" msgid="819617772268371434">"Веза је лоша"</string>
-    <string name="mobile_data_off_summary" msgid="3663995422004150567">"Није успело аутом. повезивање преко моб. података"</string>
-    <string name="mobile_data_no_connection" msgid="1713872434869947377">"Веза није успостављена"</string>
-    <string name="non_carrier_network_unavailable" msgid="770049357024492372">"Није доступна ниједна друга мрежа"</string>
-    <string name="all_network_unavailable" msgid="4112774339909373349">"Нема доступних мрежа"</string>
-    <string name="turn_on_wifi" msgid="1308379840799281023">"WiFi"</string>
-    <string name="tap_a_network_to_connect" msgid="1565073330852369558">"Додирните мрежу да бисте се повезали"</string>
-    <string name="unlock_to_view_networks" msgid="5072880496312015676">"Откључајте да бисте видели мреже"</string>
-    <string name="wifi_empty_list_wifi_on" msgid="3864376632067585377">"Траже се мреже…"</string>
-    <string name="wifi_failed_connect_message" msgid="4161863112079000071">"Повезивање са мрежом није успело"</string>
-    <string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"WiFi тренутно не може да се аутоматски повеже"</string>
-    <string name="see_all_networks" msgid="3773666844913168122">"Погледајте све"</string>
-    <string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Да бисте променили мрежу, прекините етернет везу"</string>
-    <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Ради бољег доживљаја уређаја, апликације и услуге и даље могу да траже WiFi мреже у било ком тренутку, чак и када је WiFi искључен. То можете да промените у подешавањима WiFi скенирања. "<annotation id="link">"Промените"</annotation></string>
-    <string name="turn_off_airplane_mode" msgid="8425587763226548579">"Искључите режим рада у авиону"</string>
-    <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> жели да дода следећу плочицу у Брза подешавања"</string>
-    <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Додај плочицу"</string>
-    <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Не додај плочицу"</string>
-    <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Изаберите корисника"</string>
-    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# апликација је активна}one{# апликација је активна}few{# апликације су активне}other{# апликација је активно}}"</string>
-    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Нове информације"</string>
-    <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активне апликације"</string>
-    <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Ове апликације су активне и раде чак и када их не користите. То им побољшава функционалност, али може да утиче и на трајање батерије."</string>
-    <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Заустави"</string>
-    <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Заустављено"</string>
-    <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Готово"</string>
-    <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Копирано је"</string>
-    <string name="clipboard_edit_source" msgid="9156488177277788029">"Од: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="clipboard_dismiss_description" msgid="3335990369850165486">"Одбаци копирани текст"</string>
-    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Измените копирани текст"</string>
-    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Измените копирану слику"</string>
-    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Пошаљи на уређај у близини"</string>
-    <string name="clipboard_text_hidden" msgid="7926899867471812305">"Додирните да бисте прегледали"</string>
-    <string name="clipboard_text_copied" msgid="5100836834278976679">"Текст је копиран"</string>
-    <string name="clipboard_image_copied" msgid="3793365360174328722">"Слика је копирана"</string>
-    <string name="clipboard_content_copied" msgid="144452398567828145">"Садржај је копиран"</string>
-    <string name="clipboard_editor" msgid="2971197550401892843">"Уређивач привремене меморије"</string>
-    <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Привремена меморија"</string>
-    <string name="clipboard_image_preview" msgid="2156475174343538128">"Преглед слике"</string>
-    <string name="clipboard_edit" msgid="4500155216174011640">"измените"</string>
-    <string name="add" msgid="81036585205287996">"Додај"</string>
-    <string name="manage_users" msgid="1823875311934643849">"Управљаjте корисницима"</string>
-    <string name="drag_split_not_supported" msgid="4326847447699729722">"Ово обавештење не подржава превлачење на подељени екран."</string>
-    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi није доступан"</string>
-    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Приоритетни режим"</string>
-    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Аларм је подешен"</string>
-    <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Камера је искључена"</string>
-    <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Микрофон је искључен"</string>
-    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера и микрофон су искључени"</string>
-    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# обавештење}one{# обавештење}few{# обавештења}other{# обавештења}}"</string>
-    <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
-    <string name="note_task_button_label" msgid="8718616095800343136">"Прављење бележака"</string>
-    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Емитовање"</string>
-    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Желите да зауставите емитовање апликације <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ако емитујете апликацију <xliff:g id="SWITCHAPP">%1$s</xliff:g> или промените излаз, актуелно емитовање ће се зауставити"</string>
-    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Емитујте апликацију <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
-    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Промените излаз"</string>
-    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Непознато"</string>
-    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"с:мин"</string>
-    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"ч:мин"</string>
-    <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Отворите: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Да бисте додали апликацију <xliff:g id="APPNAME">%1$s</xliff:g> као пречицу, уверите се:"</string>
-    <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• да је апликација подешена"</string>
-    <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• да је у Новчаник додата барем једна картица"</string>
-    <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• да сте инсталирали апликацију за камеру"</string>
-    <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• да је апликација подешена"</string>
-    <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• да је доступан барем један уређај"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+    <string name="privacy_type_camera" msgid="7974051382167078332">"kameru"</string>
+    <string name="privacy_type_location" msgid="7991481648444066703">"lokaciju"</string>
+    <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
+    <string name="privacy_type_media_projection" msgid="8136723828804251547">"snimanje ekrana"</string>
+    <string name="music_controls_no_title" msgid="4166497066552290938">"Bez naslova"</string>
+    <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje pripravnosti"</string>
+    <string name="magnification_window_title" msgid="4863914360847258333">"Prozor za uvećanje"</string>
+    <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrole prozora za uvećanje"</string>
+    <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Uvećajte"</string>
+    <string name="accessibility_control_zoom_out" msgid="69578832020304084">"Umanjite"</string>
+    <string name="accessibility_control_move_up" msgid="6622825494014720136">"Pomerite nagore"</string>
+    <string name="accessibility_control_move_down" msgid="5390922476900974512">"Pomerite nadole"</string>
+    <string name="accessibility_control_move_left" msgid="8156206978511401995">"Pomerite nalevo"</string>
+    <string name="accessibility_control_move_right" msgid="8926821093629582888">"Pomerite nadesno"</string>
+    <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Prelazak na drugi režim uvećanja"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Uvećajte ceo ekran"</string>
+    <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Uvećajte deo ekrana"</string>
+    <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Pređi"</string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Dodirnite za funkcije pristupačnosti. Prilagodite ili zamenite ovo dugme u Podešavanjima.\n\n"<annotation id="link">"Podešavanja"</annotation></string>
+    <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Pomerite dugme do ivice da biste ga privremeno sakrili"</string>
+    <string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"Premesti gore levo"</string>
+    <string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"Premesti gore desno"</string>
+    <string name="accessibility_floating_button_action_move_bottom_left" msgid="8063394111137429725">"Premesti dole levo"</string>
+    <string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Premesti dole desno"</string>
+    <string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Premesti do ivice i sakrij"</string>
+    <string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Premesti izvan ivice i prikaži"</string>
+    <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"uključite/isključite"</string>
+    <string name="quick_controls_title" msgid="6839108006171302273">"Kontrole uređaja"</string>
+    <string name="controls_providers_title" msgid="6879775889857085056">"Odaberite aplikaciju za dodavanje kontrola"</string>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrola je dodata.}one{# kontrola je dodata.}few{# kontrole su dodate.}other{# kontrola je dodato.}}"</string>
+    <string name="controls_removed" msgid="3731789252222856959">"Uklonjeno"</string>
+    <string name="accessibility_control_favorite" msgid="8694362691985545985">"Označeno je kao omiljeno"</string>
+    <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Označeno je kao omiljeno, <xliff:g id="NUMBER">%d</xliff:g>. pozicija"</string>
+    <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Uklonjeno je iz omiljenih"</string>
+    <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"označili kao omiljeno"</string>
+    <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"uklonili iz omiljenih"</string>
+    <string name="accessibility_control_move" msgid="8980344493796647792">"Premestite na <xliff:g id="NUMBER">%d</xliff:g>. poziciju"</string>
+    <string name="controls_favorite_default_title" msgid="967742178688938137">"Kontrole"</string>
+    <string name="controls_favorite_subtitle" msgid="6481675111056961083">"Odaberite kontrole da biste im pristupili iz Brzih podešavanja"</string>
+    <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Zadržite i prevucite da biste promenili raspored kontrola"</string>
+    <string name="controls_favorite_removed" msgid="5276978408529217272">"Sve kontrole su uklonjene"</string>
+    <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Promene nisu sačuvane"</string>
+    <string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"Pogledajte druge aplikacije"</string>
+    <string name="controls_favorite_load_error" msgid="5126216176144877419">"Učitavanje kontrola nije uspelo. Pogledajte aplikaciju <xliff:g id="APP">%s</xliff:g> da biste se uverili da se podešavanja aplikacije nisu promenila."</string>
+    <string name="controls_favorite_load_none" msgid="7687593026725357775">"Kompatibilne kontrole nisu dostupne"</string>
+    <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Drugo"</string>
+    <string name="controls_dialog_title" msgid="2343565267424406202">"Dodajte u kontrole uređaja"</string>
+    <string name="controls_dialog_ok" msgid="2770230012857881822">"Dodaj"</string>
+    <string name="controls_dialog_message" msgid="342066938390663844">"Predlaže <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="controls_tile_locked" msgid="731547768182831938">"Uređaj je zaključan"</string>
+    <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Želite li da prikazujete i kontrolišete uređaje sa zaključanog ekrana?"</string>
+    <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Možete da dodate kontrole za spoljne uređaje na zaključani ekran.\n\nAplikacija na uređaju može da vam omogući da kontrolišete neke uređaje bez otključavanja telefona ili tableta.\n\nTo možete da promenite kad god želite u Podešavanjima."</string>
+    <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Želite li da kontrolišete uređaje sa zaključanog ekrana?"</string>
+    <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"Neke uređaje možete da kontrolišete bez otključavanja telefona ili tableta.\n\nAplikacija na uređaju određuje koji uređaji mogu da se kontrolišu na ovaj način."</string>
+    <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Ne, hvala"</string>
+    <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Da"</string>
+    <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN sadrži slova ili simbole"</string>
+    <string name="controls_pin_verify" msgid="3452778292918877662">"Verifikujte: <xliff:g id="DEVICE">%s</xliff:g>"</string>
+    <string name="controls_pin_wrong" msgid="6162694056042164211">"Pogrešan PIN"</string>
+    <string name="controls_pin_instructions" msgid="6363309783822475238">"Unesite PIN"</string>
+    <string name="controls_pin_instructions_retry" msgid="1566667581012131046">"Probajte drugi PIN"</string>
+    <string name="controls_confirmation_message" msgid="7744104992609594859">"Potvrdite promenu za: <xliff:g id="DEVICE">%s</xliff:g>"</string>
+    <string name="controls_structure_tooltip" msgid="4355922222944447867">"Prevucite da biste videli još"</string>
+    <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Učitavaju se preporuke"</string>
+    <string name="controls_media_title" msgid="1746947284862928133">"Mediji"</string>
+    <string name="controls_media_close_session" msgid="4780485355795635052">"Želite li da sakrijete ovu kontrolu za medije za: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="controls_media_active_session" msgid="3146882316024153337">"Aktuelna sesija medija ne može da bude sakrivena."</string>
+    <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sakrij"</string>
+    <string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string>
+    <string name="controls_media_settings_button" msgid="5815790345117172504">"Podešavanja"</string>
+    <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> izvođača <xliff:g id="ARTIST_NAME">%2$s</xliff:g> se pušta iz aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
+    <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> od <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_button_play" msgid="2705068099607410633">"Pusti"</string>
+    <string name="controls_media_button_pause" msgid="8614887780950376258">"Pauziraj"</string>
+    <string name="controls_media_button_prev" msgid="8126822360056482970">"Prethodna pesma"</string>
+    <string name="controls_media_button_next" msgid="6662636627525947610">"Sledeća pesma"</string>
+    <string name="controls_media_button_connecting" msgid="3138354625847598095">"Povezuje se"</string>
+    <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Pusti"</string>
+    <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Otvorite <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Pustite <xliff:g id="SONG_NAME">%1$s</xliff:g> izvođača <xliff:g id="ARTIST_NAME">%2$s</xliff:g> iz aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Pustite <xliff:g id="SONG_NAME">%1$s</xliff:g> iz aplikacije <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="media_transfer_undo" msgid="1895606387620728736">"Opozovi"</string>
+    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Približite da biste puštali muziku na: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
     <skip />
-    <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Откажи"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Обрните"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Отворите телефон за бољи селфи"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Желите да обрнете на предњи екран за бољи селфи?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Користите задњу камеру да бисте снимили ширу слику са вишом резолуцијом."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Овај екран ће се искључити"</b></string>
-    <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Уређај на преклоп се отвара"</string>
-    <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Уређај на преклоп се обрће"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Pušta se na uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
+    <string name="media_transfer_failed" msgid="7955354964610603723">"Došlo je do greške. Probajte ponovo."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Učitava se"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
+    <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno. Vidite aplikaciju"</string>
+    <string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string>
+    <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrola nije dostupna"</string>
+    <string name="controls_error_removed_message" msgid="2885911717034750542">"Pristupanje uređaju <xliff:g id="DEVICE">%1$s</xliff:g> nije uspelo. Pogledajte aplikaciju <xliff:g id="APPLICATION">%2$s</xliff:g> da biste se uverili da je kontrola još uvek dostupna i da se podešavanja aplikacije nisu promenila."</string>
+    <string name="controls_open_app" msgid="483650971094300141">"Otvori aplikaciju"</string>
+    <string name="controls_error_generic" msgid="352500456918362905">"Učitavanje statusa nije uspelo"</string>
+    <string name="controls_error_failed" msgid="960228639198558525">"Greška. Probajte ponovo"</string>
+    <string name="controls_menu_add" msgid="4447246119229920050">"Dodaj kontrole"</string>
+    <string name="controls_menu_edit" msgid="890623986951347062">"Izmeni kontrole"</string>
+    <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Dodajte izlaze"</string>
+    <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupa"</string>
+    <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Izabran je 1 uređaj"</string>
+    <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Izabranih uređaja: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+    <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(veza je prekinuta)"</string>
+    <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Prebacivanje nije uspelo. Probajte ponovo."</string>
+    <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Povežite uređaj"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Da biste prebacivali ovu sesiju, otvorite aplikaciju."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nepoznata aplikacija"</string>
+    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zaustavi prebacivanje"</string>
+    <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dostupni uređaji za audio izlaz."</string>
+    <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Zvuk"</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">"Zvučnici i ekrani"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
+    <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kako funkcioniše emitovanje"</string>
+    <string name="media_output_broadcast" msgid="3555580945878071543">"Emitovanje"</string>
+    <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Ljudi u blizini sa kompatibilnim Bluetooth uređajima mogu da slušaju medijski sadržaj koji emitujete"</string>
+    <string name="media_output_broadcasting_message" msgid="4150299923404886073">"Da bi slušali emitovanje, ljudi u blizini sa kompatibilnim Bluetooth uređajima mogu da skeniraju QR kôd ili da koriste naziv i lozinku emitovanja"</string>
+    <string name="media_output_broadcast_name" msgid="8786127091542624618">"Naziv emitovanja"</string>
+    <string name="media_output_broadcast_code" msgid="870795639644728542">"Lozinka"</string>
+    <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Sačuvaj"</string>
+    <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Pokreće se…"</string>
+    <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Emitovanje nije uspelo"</string>
+    <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Čuvanje nije uspelo. Probajte ponovo."</string>
+    <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Čuvanje nije uspelo."</string>
+    <string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string>
+    <string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u privremenu memoriju."</string>
+    <string name="basic_status" msgid="2315371112182658176">"Otvorite konverzaciju"</string>
+    <string name="select_conversation_title" msgid="6716364118095089519">"Vidžeti za konverzaciju"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"Dodirnite konverzaciju da biste je dodali na početni ekran"</string>
+    <string name="no_conversations_text" msgid="5354115541282395015">"Nedavne konverzacije će se prikazati ovde"</string>
+    <string name="priority_conversations" msgid="3967482288896653039">"Prioritetne konverzacije"</string>
+    <string name="recent_conversations" msgid="8531874684782574622">"Nedavne konverzacije"</string>
+    <string name="days_timestamp" msgid="5821854736213214331">"Pre <xliff:g id="DURATION">%1$s</xliff:g> dana"</string>
+    <string name="one_week_timestamp" msgid="4925600765473875590">"Pre nedelju dana"</string>
+    <string name="two_weeks_timestamp" msgid="9111801081871962155">"Pre 2 nedelje"</string>
+    <string name="over_one_week_timestamp" msgid="3770560704420807142">"Pre više od nedelju dana"</string>
+    <string name="over_two_weeks_timestamp" msgid="6300507859007874050">"Pre više od 2 nedelje"</string>
+    <string name="birthday_status" msgid="2596961629465396761">"Rođendan"</string>
+    <string name="birthday_status_content_description" msgid="682836371128282925">"<xliff:g id="NAME">%1$s</xliff:g> danas slavi rođendan"</string>
+    <string name="upcoming_birthday_status" msgid="2005452239256870351">"Rođendan je uskoro"</string>
+    <string name="upcoming_birthday_status_content_description" msgid="2165036816803797148">"<xliff:g id="NAME">%1$s</xliff:g> uskoro slavi rođendan"</string>
+    <string name="anniversary_status" msgid="1790034157507590838">"Godišnjica"</string>
+    <string name="anniversary_status_content_description" msgid="8212171790843327442">"<xliff:g id="NAME">%1$s</xliff:g> danas slavi godišnjicu"</string>
+    <string name="location_status" msgid="1294990572202541812">"Deli se lokacija"</string>
+    <string name="location_status_content_description" msgid="2982386178160071305">"<xliff:g id="NAME">%1$s</xliff:g> deli lokaciju"</string>
+    <string name="new_story_status" msgid="9012195158584846525">"Nova priča"</string>
+    <string name="new_story_status_content_description" msgid="4963137422622516708">"<xliff:g id="NAME">%1$s</xliff:g> deli novu priču"</string>
+    <string name="video_status" msgid="4548544654316843225">"Gleda se"</string>
+    <string name="audio_status" msgid="4237055636967709208">"Sluša se"</string>
+    <string name="game_status" msgid="1340694320630973259">"Igra se"</string>
+    <string name="empty_user_name" msgid="3389155775773578300">"Prijatelji"</string>
+    <string name="empty_status" msgid="5938893404951307749">"Ćaskamo večeras?"</string>
+    <string name="status_before_loading" msgid="1500477307859631381">"Sadržaj će se uskoro pojaviti"</string>
+    <string name="missed_call" msgid="4228016077700161689">"Propušten poziv"</string>
+    <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
+    <string name="people_tile_description" msgid="8154966188085545556">"Pogledajte nedavne poruke, propuštene pozive i ažuriranja statusa"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"Konverzacija"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Pauzirano režimom Ne uznemiravaj"</string>
+    <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> je poslao/la poruku: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
+    <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> šalje sliku"</string>
+    <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ima ažuriranje statusa: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+    <string name="person_available" msgid="2318599327472755472">"Dostupno"</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem sa očitavanjem merača baterije"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dodirnite za više informacija"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nije podešen"</string>
+    <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Senzor za otisak prsta"</string>
+    <string name="accessibility_authenticate_hint" msgid="798914151813205721">"potvrdite identitet"</string>
+    <string name="accessibility_enter_hint" msgid="2617864063504824834">"unesite uređaj"</string>
+    <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Otvorite pomoću otiska prsta"</string>
+    <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Potrebna je potvrda identiteta. Dodirnite senzor za otisak prsta da biste potvrdili identitet."</string>
+    <string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"Aktuelni telefonski poziv"</string>
+    <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobilni podaci"</string>
+    <string name="preference_summary_default_combination" msgid="8453246369903749670">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="NETWORKMODE">%2$s</xliff:g>"</string>
+    <string name="mobile_data_connection_active" msgid="944490013299018227">"Povezano"</string>
+    <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Privremeno povezano"</string>
+    <string name="mobile_data_poor_connection" msgid="819617772268371434">"Veza je loša"</string>
+    <string name="mobile_data_off_summary" msgid="3663995422004150567">"Nije uspelo autom. povezivanje preko mob. podataka"</string>
+    <string name="mobile_data_no_connection" msgid="1713872434869947377">"Veza nije uspostavljena"</string>
+    <string name="non_carrier_network_unavailable" msgid="770049357024492372">"Nije dostupna nijedna druga mreža"</string>
+    <string name="all_network_unavailable" msgid="4112774339909373349">"Nema dostupnih mreža"</string>
+    <string name="turn_on_wifi" msgid="1308379840799281023">"WiFi"</string>
+    <string name="tap_a_network_to_connect" msgid="1565073330852369558">"Dodirnite mrežu da biste se povezali"</string>
+    <string name="unlock_to_view_networks" msgid="5072880496312015676">"Otključajte da biste videli mreže"</string>
+    <string name="wifi_empty_list_wifi_on" msgid="3864376632067585377">"Traže se mreže…"</string>
+    <string name="wifi_failed_connect_message" msgid="4161863112079000071">"Povezivanje sa mrežom nije uspelo"</string>
+    <string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"WiFi trenutno ne može da se automatski poveže"</string>
+    <string name="see_all_networks" msgid="3773666844913168122">"Pogledajte sve"</string>
+    <string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Da biste promenili mrežu, prekinite eternet vezu"</string>
+    <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Radi boljeg doživljaja uređaja, aplikacije i usluge i dalje mogu da traže WiFi mreže u bilo kom trenutku, čak i kada je WiFi isključen. To možete da promenite u podešavanjima WiFi skeniranja. "<annotation id="link">"Promenite"</annotation></string>
+    <string name="turn_off_airplane_mode" msgid="8425587763226548579">"Isključite režim rada u avionu"</string>
+    <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> želi da doda sledeću pločicu u Brza podešavanja"</string>
+    <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Dodaj pločicu"</string>
+    <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ne dodaj pločicu"</string>
+    <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Izaberite korisnika"</string>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# aplikacija je aktivna}one{# aplikacija je aktivna}few{# aplikacije su aktivne}other{# aplikacija je aktivno}}"</string>
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nove informacije"</string>
+    <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivne aplikacije"</string>
+    <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Ove aplikacije su aktivne i rade čak i kada ih ne koristite. To im poboljšava funkcionalnost, ali može da utiče i na trajanje baterije."</string>
+    <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Zaustavi"</string>
+    <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Zaustavljeno"</string>
+    <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Gotovo"</string>
+    <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopirano je"</string>
+    <string name="clipboard_edit_source" msgid="9156488177277788029">"Od: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
+    <string name="clipboard_dismiss_description" msgid="3335990369850165486">"Odbaci kopirani tekst"</string>
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Izmenite kopirani tekst"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Izmenite kopiranu sliku"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Pošalji na uređaj u blizini"</string>
+    <string name="clipboard_text_hidden" msgid="7926899867471812305">"Dodirnite da biste pregledali"</string>
+    <string name="clipboard_text_copied" msgid="5100836834278976679">"Tekst je kopiran"</string>
+    <string name="clipboard_image_copied" msgid="3793365360174328722">"Slika je kopirana"</string>
+    <string name="clipboard_content_copied" msgid="144452398567828145">"Sadržaj je kopiran"</string>
+    <string name="clipboard_editor" msgid="2971197550401892843">"Uređivač privremene memorije"</string>
+    <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Privremena memorija"</string>
+    <string name="clipboard_image_preview" msgid="2156475174343538128">"Pregled slike"</string>
+    <string name="clipboard_edit" msgid="4500155216174011640">"izmenite"</string>
+    <string name="add" msgid="81036585205287996">"Dodaj"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Upravljajte korisnicima"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Ovo obaveštenje ne podržava prevlačenje na podeljeni ekran."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi nije dostupan"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritetni režim"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je podešen"</string>
+    <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kamera je isključena"</string>
+    <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofon je isključen"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera i mikrofon su isključeni"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obaveštenje}one{# obaveštenje}few{# obaveštenja}other{# obaveštenja}}"</string>
+    <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
+    <string name="note_task_button_label" msgid="8718616095800343136">"Pravljenje beležaka"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Emitovanje"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Želite da zaustavite emitovanje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ako emitujete aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promenite izlaz, aktuelno emitovanje će se zaustaviti"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitujte aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Promenite izlaz"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nepoznato"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"s:min"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"č:min"</string>
+    <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Otvorite: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• da je aplikacija podešena"</string>
+    <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• da je u Novčanik dodata barem jedna kartica"</string>
+    <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• da ste instalirali aplikaciju za kameru"</string>
+    <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• da je aplikacija podešena"</string>
+    <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• da je dostupan barem jedan uređaj"</string>
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Dodirnite i zadržite prečicu"</string>
+    <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Otkaži"</string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Obrnite"</string>
+    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Otvorite telefon za bolji selfi"</string>
+    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Želite da obrnete na prednji ekran za bolji selfi?"</string>
+    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Koristite zadnju kameru da biste snimili širu sliku sa višom rezolucijom."</string>
+    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Ovaj ekran će se isključiti"</b></string>
+    <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Uređaj na preklop se otvara"</string>
+    <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Uređaj na preklop se obrće"</string>
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
index 8ca1057..27e22d8 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
@@ -19,15 +19,15 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="notification_vpn_connected" msgid="3891023882833274730">"VPN је повезан"</string>
-    <string name="notification_vpn_disconnected" msgid="7150747626448044843">"Веза са VPN-ом је прекинута"</string>
-    <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Преко: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
-    <string name="tv_notification_panel_title" msgid="5311050946506276154">"Обавештења"</string>
-    <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Нема обавештења"</string>
-    <string name="mic_recording_announcement" msgid="7587123608060316575">"Микрофон снима"</string>
-    <string name="camera_recording_announcement" msgid="7240177719403759112">"Камера снима"</string>
-    <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Камера и микрофон снимају"</string>
-    <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Снимање микрофоном је заустављено"</string>
-    <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Снимање камером је заустављено"</string>
-    <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Снимање камером и микрофоном је заустављено"</string>
+    <string name="notification_vpn_connected" msgid="3891023882833274730">"VPN je povezan"</string>
+    <string name="notification_vpn_disconnected" msgid="7150747626448044843">"Veza sa VPN-om je prekinuta"</string>
+    <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Preko: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="tv_notification_panel_title" msgid="5311050946506276154">"Obaveštenja"</string>
+    <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Nema obaveštenja"</string>
+    <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon snima"</string>
+    <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera snima"</string>
+    <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera i mikrofon snimaju"</string>
+    <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Snimanje mikrofonom je zaustavljeno"</string>
+    <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Snimanje kamerom je zaustavljeno"</string>
+    <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Snimanje kamerom i mikrofonom je zaustavljeno"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
index dace491..b69b064 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
@@ -32,148 +32,148 @@
     <!-- no translation found for tile_states_default:1 (7086813178962737808) -->
     <!-- no translation found for tile_states_default:2 (9192445505551219506) -->
   <string-array name="tile_states_internet">
-    <item msgid="5499482407653291407">"Недоступно"</item>
-    <item msgid="3048856902433862868">"Искључено"</item>
-    <item msgid="6877982264300789870">"Укључено"</item>
+    <item msgid="5499482407653291407">"Nedostupno"</item>
+    <item msgid="3048856902433862868">"Isključeno"</item>
+    <item msgid="6877982264300789870">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_wifi">
-    <item msgid="8054147400538405410">"Недоступно"</item>
-    <item msgid="4293012229142257455">"Искључено"</item>
-    <item msgid="6221288736127914861">"Укључено"</item>
+    <item msgid="8054147400538405410">"Nedostupno"</item>
+    <item msgid="4293012229142257455">"Isključeno"</item>
+    <item msgid="6221288736127914861">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_cell">
-    <item msgid="1235899788959500719">"Недоступно"</item>
-    <item msgid="2074416252859094119">"Искључено"</item>
-    <item msgid="287997784730044767">"Укључено"</item>
+    <item msgid="1235899788959500719">"Nedostupno"</item>
+    <item msgid="2074416252859094119">"Isključeno"</item>
+    <item msgid="287997784730044767">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_battery">
-    <item msgid="6311253873330062961">"Недоступно"</item>
-    <item msgid="7838121007534579872">"Искључено"</item>
-    <item msgid="1578872232501319194">"Укључено"</item>
+    <item msgid="6311253873330062961">"Nedostupno"</item>
+    <item msgid="7838121007534579872">"Isključeno"</item>
+    <item msgid="1578872232501319194">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_dnd">
-    <item msgid="467587075903158357">"Недоступно"</item>
-    <item msgid="5376619709702103243">"Искључено"</item>
-    <item msgid="4875147066469902392">"Укључено"</item>
+    <item msgid="467587075903158357">"Nedostupno"</item>
+    <item msgid="5376619709702103243">"Isključeno"</item>
+    <item msgid="4875147066469902392">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_flashlight">
-    <item msgid="3465257127433353857">"Недоступно"</item>
-    <item msgid="5044688398303285224">"Искључено"</item>
-    <item msgid="8527389108867454098">"Укључено"</item>
+    <item msgid="3465257127433353857">"Nedostupno"</item>
+    <item msgid="5044688398303285224">"Isključeno"</item>
+    <item msgid="8527389108867454098">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_rotation">
-    <item msgid="4578491772376121579">"Недоступно"</item>
-    <item msgid="5776427577477729185">"Искључено"</item>
-    <item msgid="7105052717007227415">"Укључено"</item>
+    <item msgid="4578491772376121579">"Nedostupno"</item>
+    <item msgid="5776427577477729185">"Isključeno"</item>
+    <item msgid="7105052717007227415">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_bt">
-    <item msgid="5330252067413512277">"Недоступно"</item>
-    <item msgid="5315121904534729843">"Искључено"</item>
-    <item msgid="503679232285959074">"Укључено"</item>
+    <item msgid="5330252067413512277">"Nedostupno"</item>
+    <item msgid="5315121904534729843">"Isključeno"</item>
+    <item msgid="503679232285959074">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_airplane">
-    <item msgid="1985366811411407764">"Недоступно"</item>
-    <item msgid="4801037224991420996">"Искључено"</item>
-    <item msgid="1982293347302546665">"Укључено"</item>
+    <item msgid="1985366811411407764">"Nedostupno"</item>
+    <item msgid="4801037224991420996">"Isključeno"</item>
+    <item msgid="1982293347302546665">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_location">
-    <item msgid="3316542218706374405">"Недоступно"</item>
-    <item msgid="4813655083852587017">"Искључено"</item>
-    <item msgid="6744077414775180687">"Укључено"</item>
+    <item msgid="3316542218706374405">"Nedostupno"</item>
+    <item msgid="4813655083852587017">"Isključeno"</item>
+    <item msgid="6744077414775180687">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_hotspot">
-    <item msgid="3145597331197351214">"Недоступно"</item>
-    <item msgid="5715725170633593906">"Искључено"</item>
-    <item msgid="2075645297847971154">"Укључено"</item>
+    <item msgid="3145597331197351214">"Nedostupno"</item>
+    <item msgid="5715725170633593906">"Isključeno"</item>
+    <item msgid="2075645297847971154">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_color_correction">
-    <item msgid="2840507878437297682">"Недоступно"</item>
-    <item msgid="1909756493418256167">"Искључено"</item>
-    <item msgid="4531508423703413340">"Укључено"</item>
+    <item msgid="2840507878437297682">"Nedostupno"</item>
+    <item msgid="1909756493418256167">"Isključeno"</item>
+    <item msgid="4531508423703413340">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_inversion">
-    <item msgid="3638187931191394628">"Недоступно"</item>
-    <item msgid="9103697205127645916">"Искључено"</item>
-    <item msgid="8067744885820618230">"Укључено"</item>
+    <item msgid="3638187931191394628">"Nedostupno"</item>
+    <item msgid="9103697205127645916">"Isključeno"</item>
+    <item msgid="8067744885820618230">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_saver">
-    <item msgid="39714521631367660">"Недоступно"</item>
-    <item msgid="6983679487661600728">"Искључено"</item>
-    <item msgid="7520663805910678476">"Укључено"</item>
+    <item msgid="39714521631367660">"Nedostupno"</item>
+    <item msgid="6983679487661600728">"Isključeno"</item>
+    <item msgid="7520663805910678476">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_dark">
-    <item msgid="2762596907080603047">"Недоступно"</item>
-    <item msgid="400477985171353">"Искључено"</item>
-    <item msgid="630890598801118771">"Укључено"</item>
+    <item msgid="2762596907080603047">"Nedostupno"</item>
+    <item msgid="400477985171353">"Isključeno"</item>
+    <item msgid="630890598801118771">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_work">
-    <item msgid="389523503690414094">"Недоступно"</item>
-    <item msgid="8045580926543311193">"Искључено"</item>
-    <item msgid="4913460972266982499">"Укључено"</item>
+    <item msgid="389523503690414094">"Nedostupno"</item>
+    <item msgid="8045580926543311193">"Isključeno"</item>
+    <item msgid="4913460972266982499">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_cast">
-    <item msgid="6032026038702435350">"Недоступно"</item>
-    <item msgid="1488620600954313499">"Искључено"</item>
-    <item msgid="588467578853244035">"Укључено"</item>
+    <item msgid="6032026038702435350">"Nedostupno"</item>
+    <item msgid="1488620600954313499">"Isključeno"</item>
+    <item msgid="588467578853244035">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_night">
-    <item msgid="7857498964264855466">"Недоступно"</item>
-    <item msgid="2744885441164350155">"Искључено"</item>
-    <item msgid="151121227514952197">"Укључено"</item>
+    <item msgid="7857498964264855466">"Nedostupno"</item>
+    <item msgid="2744885441164350155">"Isključeno"</item>
+    <item msgid="151121227514952197">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_screenrecord">
-    <item msgid="1085836626613341403">"Недоступно"</item>
-    <item msgid="8259411607272330225">"Искључено"</item>
-    <item msgid="578444932039713369">"Укључено"</item>
+    <item msgid="1085836626613341403">"Nedostupno"</item>
+    <item msgid="8259411607272330225">"Isključeno"</item>
+    <item msgid="578444932039713369">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_reverse">
-    <item msgid="3574611556622963971">"Недоступно"</item>
-    <item msgid="8707481475312432575">"Искључено"</item>
-    <item msgid="8031106212477483874">"Укључено"</item>
+    <item msgid="3574611556622963971">"Nedostupno"</item>
+    <item msgid="8707481475312432575">"Isključeno"</item>
+    <item msgid="8031106212477483874">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_reduce_brightness">
-    <item msgid="1839836132729571766">"Недоступно"</item>
-    <item msgid="4572245614982283078">"Искључено"</item>
-    <item msgid="6536448410252185664">"Укључено"</item>
+    <item msgid="1839836132729571766">"Nedostupno"</item>
+    <item msgid="4572245614982283078">"Isključeno"</item>
+    <item msgid="6536448410252185664">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_cameratoggle">
-    <item msgid="6680671247180519913">"Недоступно"</item>
-    <item msgid="4765607635752003190">"Искључено"</item>
-    <item msgid="1697460731949649844">"Укључено"</item>
+    <item msgid="6680671247180519913">"Nedostupno"</item>
+    <item msgid="4765607635752003190">"Isključeno"</item>
+    <item msgid="1697460731949649844">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_mictoggle">
-    <item msgid="6895831614067195493">"Недоступно"</item>
-    <item msgid="3296179158646568218">"Искључено"</item>
-    <item msgid="8998632451221157987">"Укључено"</item>
+    <item msgid="6895831614067195493">"Nedostupno"</item>
+    <item msgid="3296179158646568218">"Isključeno"</item>
+    <item msgid="8998632451221157987">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_controls">
-    <item msgid="8199009425335668294">"Недоступно"</item>
-    <item msgid="4544919905196727508">"Искључено"</item>
-    <item msgid="3422023746567004609">"Укључено"</item>
+    <item msgid="8199009425335668294">"Nedostupno"</item>
+    <item msgid="4544919905196727508">"Isključeno"</item>
+    <item msgid="3422023746567004609">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_wallet">
-    <item msgid="4177615438710836341">"Недоступно"</item>
-    <item msgid="7571394439974244289">"Искључено"</item>
-    <item msgid="6866424167599381915">"Укључено"</item>
+    <item msgid="4177615438710836341">"Nedostupno"</item>
+    <item msgid="7571394439974244289">"Isključeno"</item>
+    <item msgid="6866424167599381915">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_qr_code_scanner">
-    <item msgid="7435143266149257618">"Недоступно"</item>
-    <item msgid="3301403109049256043">"Искључено"</item>
-    <item msgid="8878684975184010135">"Укључено"</item>
+    <item msgid="7435143266149257618">"Nedostupno"</item>
+    <item msgid="3301403109049256043">"Isključeno"</item>
+    <item msgid="8878684975184010135">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_alarm">
-    <item msgid="4936533380177298776">"Недоступно"</item>
-    <item msgid="2710157085538036590">"Искључено"</item>
-    <item msgid="7809470840976856149">"Укључено"</item>
+    <item msgid="4936533380177298776">"Nedostupno"</item>
+    <item msgid="2710157085538036590">"Isključeno"</item>
+    <item msgid="7809470840976856149">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_onehanded">
-    <item msgid="8189342855739930015">"Недоступно"</item>
-    <item msgid="146088982397753810">"Искључено"</item>
-    <item msgid="460891964396502657">"Укључено"</item>
+    <item msgid="8189342855739930015">"Nedostupno"</item>
+    <item msgid="146088982397753810">"Isključeno"</item>
+    <item msgid="460891964396502657">"Uključeno"</item>
   </string-array>
   <string-array name="tile_states_dream">
-    <item msgid="6184819793571079513">"Недоступно"</item>
-    <item msgid="8014986104355098744">"Искључено"</item>
-    <item msgid="5966994759929723339">"Укључено"</item>
+    <item msgid="6184819793571079513">"Nedostupno"</item>
+    <item msgid="8014986104355098744">"Isključeno"</item>
+    <item msgid="5966994759929723339">"Uključeno"</item>
   </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 97a29bd..537622e 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Абагуліць здымак экрана"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Захапіць больш"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Адхіліць здымак экрана"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Закрыць паведамленне працоўнага профілю"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Перадпрагляд здымка экрана"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Верхняя граніца: <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Ніжняя граніца: <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Левая граніца: <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Правая граніца: <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Запіс экрана"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Апрацоўваецца запіс экрана"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Бягучае апавяшчэнне для сеанса запісу экрана"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi выключаны"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth выключаны"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Рэжым \"Не турбаваць\" выключаны"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Рэжым \"Не турбаваць\" уключаны"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Рэжым \"Не турбаваць\" быў уключаны аўтаматычным правілам (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Рэжым \"Не турбаваць\" быў уключаны праграмай (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Рэжым \"Не турбаваць\" быў уключаны аўтаматычным правілам ці праграмай."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Прайграйце кампазіцыю \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" з дапамогай праграмы \"<xliff:g id="APP_LABEL">%2$s</xliff:g>\""</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Адрабіць"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Каб прайграць мультымедыя на прыладзе \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\", наблізьцеся да яе"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Падыдзіце бліжэй да прылады \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\", каб прайграць на гэтай"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Прайграецца на прыладзе \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\""</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Нешта пайшло не так. Паўтарыце спробу."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Ідзе загрузка"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Неактыўна, праверце праграму"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Не знойдзена"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Кіраванне недаступнае"</string>
@@ -875,6 +883,9 @@
     <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">"Дынамікі і дысплэі"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Як адбываецца трансляцыя"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Трансляцыя"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Людзі паблізу, у якіх ёсць прылады з Bluetooth, змогуць праслухваць мультымедыйнае змесціва, якое вы трансліруеце"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Адкрыць праграму \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Каб дадаць ярлык для праграмы \"<xliff:g id="APPNAME">%1$s</xliff:g>\", патрабуюцца наступныя ўмовы:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Праграма наладжана."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• У Кашалёк дададзена хаця б адна картка."</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Усталявана праграма \"Камера\"."</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Праграма наладжана."</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Даступная хаця б адна прылада."</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Дакраніцеся і ўтрымлівайце ярлык"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Скасаваць"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Пераключыць"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Каб атрымаць лепшае сэлфі, раскрыйце тэлефон"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Гэты экран будзе выключаны"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Складная прылада ў раскладзеным выглядзе"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Перавернутая складная прылада"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 2dd94d2..eba0d03 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Споделяне на екранната снимка"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Заснемане на още"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Отхвърляне на екранната снимка"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Отхвърляне на съобщението за служебния потребителски профил"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Визуализация на екранната снимка"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Горна граница: <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Долна граница: <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Лява граница: <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Дясна граница: <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Запис на екрана"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Записът на екрана се обработва"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Текущо известие за сесия за записване на екрана"</string>
@@ -374,12 +379,12 @@
     <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"Цял екран"</string>
     <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"Едно приложение"</string>
     <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"Когато споделяте, записвате или предавате, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> има достъп до всичко, което се вижда на екрана ви или се възпроизвежда на устройството ви, затова бъдете внимателни с пароли, подробности за начини на плащане, съобщения или друга поверителна информация."</string>
-    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Когато споделяте, записвате или предавате, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> има достъп до всичко, което се показва или възпроизвежда в това приложение, затова бъдете внимателни с пароли, подробности за начини на плащане, съобщения или друга поверителна информация."</string>
+    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Когато споделяте, записвате или предавате приложение, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> има достъп до всичко, което се показва или възпроизвежда в това приложение, затова бъдете внимателни с пароли, подробности за начини на плащане, съобщения или друга поверителна информация."</string>
     <string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Напред"</string>
     <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Споделяне или записване на приложение"</string>
     <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Да се разреши ли на това приложение да споделя или записва?"</string>
     <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Когато споделяте, записвате или предавате, това приложение има достъп до всичко, което се вижда на екрана ви или се възпроизвежда на устройството ви, затова бъдете внимателни с пароли, подробности за начини на плащане, съобщения или друга поверителна информация."</string>
-    <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Когато споделяте, записвате или предавате, това приложение има достъп до всичко, което се показва или възпроизвежда в него, затова бъдете внимателни с пароли, подробности за начини на плащане, съобщения или друга поверителна информация."</string>
+    <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Когато споделяте, записвате или предавате приложение, това приложение има достъп до всичко, което се показва или възпроизвежда в приложението, затова бъдете внимателни с пароли, подробности за начини на плащане, съобщения или друга поверителна информация."</string>
     <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Блокирано от системния ви администратор"</string>
     <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Заснемането на екрана е деактивирано от правило за устройството"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Изчистване на всички"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Функцията за Wi‑Fi е изключена"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Функцията за Bluetooth е изключена"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Режимът „Не безпокойте“ е изключен"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Режимът „Не безпокойте“ е включен"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Режимът „Не безпокойте“ бе включен от автоматично правило (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Режимът „Не безпокойте“ бе включен от приложение (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Режимът „Не безпокойте“ бе включен от автоматично правило или от приложение."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Пускане на <xliff:g id="SONG_NAME">%1$s</xliff:g> от <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Отмяна"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Преместете се по-близо, за да се възпроизведе на <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Приближете се до <xliff:g id="DEVICENAME">%1$s</xliff:g> за възпроизвеждане на това устройство"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Възпроизвежда се на <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Нещо се обърка. Опитайте отново."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Зарежда се"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Неактивно, проверете прилож."</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Не е намерено"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Контролата не е налице"</string>
@@ -875,6 +883,9 @@
     <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">"Високоговорители и екрани"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Как работи предаването"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Предаване"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Хората в близост със съвместими устройства с Bluetooth могат да слушат мултимедията, която предавате"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Отваряне на <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"За да добавите пряк път към приложението <xliff:g id="APPNAME">%1$s</xliff:g>, трябва да се уверите в следното:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Приложението е настроено."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• В Wallet е добавена поне една карта."</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Инсталирано е приложение за камера."</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Приложението е настроено."</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Налице е поне едно устройство."</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Докоснете и задръжте прекия път"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Отказ"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Обръщане сега"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Отворете телефона за по-добро селфи"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Този екран ще се изключи"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Разгъване на сгъваемо устройство"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Обръщане на сгъваемо устройство"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 864d7e7..13353aa 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -85,11 +85,14 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"স্ক্রিনশট শেয়ার করুন"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"আরও বেশি ক্যাপচার করুন"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"স্ক্রিনশট বাতিল করুন"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"অফিস প্রোফাইল সংক্রান্ত মেসেজ বাতিল করুন"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"স্ক্রিনশটের প্রিভিউ"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"উপরের প্রান্ত থেকে <xliff:g id="PERCENT">%1$d</xliff:g> শতাংশ"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"নিচের প্রান্ত থেকে <xliff:g id="PERCENT">%1$d</xliff:g> শতাংশ"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"বাঁ প্রান্ত থেকে <xliff:g id="PERCENT">%1$d</xliff:g> শতাংশ"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"ডান প্রান্ত থেকে <xliff:g id="PERCENT">%1$d</xliff:g> percent"</string>
+    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"অফিসের স্ক্রিনশট <xliff:g id="APP">%1$s</xliff:g> অ্যাপে সেভ করা হয়"</string>
+    <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ফাইল"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"স্ক্রিন রেকর্ডার"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"স্ক্রিন রেকর্ডিং প্রসেস হচ্ছে"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"স্ক্রিন রেকর্ডিং সেশন চলার বিজ্ঞপ্তি"</string>
@@ -731,8 +734,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"ওয়াই ফাই বন্ধ আছে"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"ব্লুটুথ বন্ধ আছে"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"বিরক্ত করবে না বিকল্পটি বন্ধ আছে"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"\'বিরক্ত করবে না\' মোড চালু আছে"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"বিরক্ত করবে না বিকল্পটি একটি স্বয়ংক্রিয় নিয়ম <xliff:g id="ID_1">%s</xliff:g> এর দ্বারা চালু করা হয়েছে।"</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"বিরক্ত করবে না বিকল্পটি একটি অ্যাপ <xliff:g id="ID_1">%s</xliff:g> এর দ্বারা চালু করা হয়েছে।"</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"বিরক্ত করবে না বিকল্পটি একটি স্বয়ংক্রিয় নিয়ম বা অ্যাপের দ্বারা চালু করা হয়েছে।"</string>
@@ -850,9 +852,12 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> গানটি <xliff:g id="APP_LABEL">%2$s</xliff:g> অ্যাপে চালান"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"আগের অবস্থায় ফিরুন"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>-এ চালাতে আরও কাছে আনুন"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"এখান থেকে চালাতে <xliff:g id="DEVICENAME">%1$s</xliff:g>-এর কাছে নিয়ে যান"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>-এ ভিডিও চালানো হচ্ছে"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"কোনও সমস্যা হয়েছে। আবার চেষ্টা করুন।"</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"লোড করা হচ্ছে"</string>
+    <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ট্যাবলেট"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"বন্ধ আছে, অ্যাপ চেক করুন"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"খুঁজে পাওয়া যায়নি"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"কন্ট্রোল উপলভ্য নেই"</string>
@@ -875,6 +880,8 @@
     <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_suggested_device" msgid="4157186235837903826">"সাজেস্ট করা ডিভাইস"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ব্রডকাস্ট কীভাবে কাজ করে"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"সম্প্রচার করুন"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"আশপাশে লোকজন যাদের মানানসই ব্লুটুথ ডিভাইস আছে, তারা আপনার ব্রডকাস্ট করা মিডিয়া শুনতে পারবেন"</string>
@@ -998,14 +1005,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> খুলুন"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"শর্টকাট হিসেবে <xliff:g id="APPNAME">%1$s</xliff:g> অ্যাপ যোগ করতে, এই বিষয়গুলি নিশ্চিত করুন"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• অ্যাপ সেট-আপ করা হয়ে গেছে"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• অন্তত একটি কার্ড Wallet-এ যোগ করা হয়েছে"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• ক্যামেরা অ্যাপ ইনস্টল করুন"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• অ্যাপ সেট-আপ করা হয়ে গেছে"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• অন্তত একটি ডিভাইস উপলভ্য"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"শর্টকাট টাচ করে ধরে রাখুন"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"বাতিল করুন"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"এখনই উল্টান"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"আরও ভাল সেলফির জন্য ফোন আনফোল্ড করা"</string>
@@ -1014,6 +1019,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ এই স্ক্রিন বন্ধ হয়ে যাবে"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ফোল্ড করা যায় এমন ডিভাইস খোলা হচ্ছে"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ফোল্ড করা যায় এমন ডিভাইস উল্টানো হচ্ছে"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 87b6d3b..2475a47 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -85,11 +85,14 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Dijeljenje snimka ekrana"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Snimi više"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Odbacite snimak ekrana"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Odbacite poruku radnog profila"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Pregled snimka ekrana"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Gornja granica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Donja granica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Lijeva granica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Desna granica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
+    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Poslovni snimci ekrana se pohranjuju u aplikaciji <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fajlovi"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Snimač ekrana"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrađivanje snimka ekrana"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Obavještenje za sesiju snimanja ekrana je u toku"</string>
@@ -376,7 +379,7 @@
     <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"Kada dijelite, snimate ili emitirate, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup svemu što se vidi na ekranu ili što se reproducira na uređaju. Zato budite oprezni s lozinkama, detaljima o plaćanju, porukama i drugim osjetljivim informacijama."</string>
     <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Kada aplikaciju dijelite, snimate ili emitirate, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Zato budite oprezni s lozinkama, detaljima o plaćanju, porukama i drugim osjetljivim informacijama."</string>
     <string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Nastavi"</string>
-    <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Dijelite ili snimite aplikaciju"</string>
+    <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Dijelite ili snimajte aplikaciju"</string>
     <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Dozvoliti aplikaciji da dijeli ili snima?"</string>
     <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Kada dijelite, snimate ili emitirate, aplikacija ima pristup svemu što je vidljivo na ekranu ili što se reproducira na uređaju. Zato budite oprezni s lozinkama, detaljima o plaćanju, porukama i drugim osjetljivim informacijama."</string>
     <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Kada dijelite, snimate ili emitirate aplikaciju, ona ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Zato budite oprezni s lozinkama, detaljima o plaćanju, porukama i drugim osjetljivim informacijama."</string>
@@ -731,8 +734,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"WiFi je isključen"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth je isključen"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Način rada Ne ometaj je isključen"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Funkcija Ne ometaj je uključena"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Opciju Ne ometaju uključilo je automatsko pravilo (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Način rada Ne ometaj uključila je aplikacija <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Način rada Ne ometaj uključilo je automatsko pravilo ili aplikacija."</string>
@@ -849,10 +851,13 @@
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Reproducirajte pjesmu <xliff:g id="SONG_NAME">%1$s</xliff:g> izvođača <xliff:g id="ARTIST_NAME">%2$s</xliff:g> pomoću aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Reproducirajte pjesmu <xliff:g id="SONG_NAME">%1$s</xliff:g> pomoću aplikacije <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Poništi"</string>
-    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Približite se da reproducirate na uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Približite se uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g> da na njemu reproducirate"</string>
+    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Približite da reproducirate na uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Reproducira se na uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Nešto nije uredu. Pokušajte ponovo."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Učitavanje"</string>
+    <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, vidite aplikaciju"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrola nije dostupna"</string>
@@ -875,6 +880,8 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dostupni uređaji za audio izlaz."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Jačina zvuka"</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">"Zvučnici i ekrani"</string>
+    <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Predloženi uređaji"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kako funkcionira emitiranje"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Emitirajte"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Osobe u vašoj blizini s kompatibilnim Bluetooth uređajima mogu slušati medijske sadržaje koje emitirate"</string>
@@ -998,14 +1005,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Otvori aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Da dodate aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g> kao prečicu, pobrinite se za sljedeće"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Aplikacija je postavljena"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Najmanje jedna kartica je dodana u Novčanik"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Instalirajte aplikaciju kamere"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Aplikacija je postavljena"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Dostupan je najmanje jedan uređaj"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Dodirnite i zadržite prečicu"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Otkaži"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Obrni sada"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Raširite telefon za bolji selfi"</string>
@@ -1014,6 +1019,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Ekran će se isključiti"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Sklopivi uređaj se rasklapa"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Sklopivi uređaj se obrće"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index fcbd841..ef73218 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Comparteix la captura de pantalla"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Captura més"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Ignora la captura de pantalla"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Ignora el missatge del perfil de treball"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Previsualització de la captura de pantalla"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Marge superior <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Marge inferior <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Marge esquerre <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Marge dret <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Gravació de pantalla"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processant gravació de pantalla"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificació en curs d\'una sessió de gravació de la pantalla"</string>
@@ -97,7 +102,7 @@
     <string name="screenrecord_description" msgid="1123231719680353736">"Durant la gravació, el sistema Android pot capturar qualsevol informació sensible que es mostri a la pantalla o que es reprodueixi al dispositiu. Això inclou contrasenyes, informació de pagament, fotos, missatges i àudio."</string>
     <string name="screenrecord_option_entire_screen" msgid="1732437834603426934">"Grava la pantalla completa"</string>
     <string name="screenrecord_option_single_app" msgid="5954863081500035825">"Grava una sola aplicació"</string>
-    <string name="screenrecord_warning_entire_screen" msgid="8141407178104195610">"Mentre graves, Android té accés a qualsevol cosa que es vegi a la pantalla o que es reprodueixi al dispositiu. Per aquest motiu, ves amb compte amb les contrasenyes, les dades de pagament, els missatges o altra informació sensible."</string>
+    <string name="screenrecord_warning_entire_screen" msgid="8141407178104195610">"Mentre graves contingut, Android pot accedir a tot el que es veu a la pantalla o que es reprodueix al dispositiu. Per això cal que vagis amb compte amb les contrasenyes, les dades de pagament, els missatges o qualsevol altra informació sensible."</string>
     <string name="screenrecord_warning_single_app" msgid="7760723997065948283">"Mentre graves una aplicació, Android té accés a qualsevol cosa que es vegi a la pantalla o que es reprodueixi a l\'aplicació. Per aquest motiu, ves amb compte amb les contrasenyes, les dades de pagament, els missatges o altra informació sensible."</string>
     <string name="screenrecord_start_recording" msgid="348286842544768740">"Inicia la gravació"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Grava l\'àudio"</string>
@@ -370,11 +375,11 @@
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"El servei que ofereix aquesta funció tindrà accés a tota la informació visible a la teva pantalla o que es reprodueix al dispositiu mentre graves o emets contingut, com ara contrasenyes, detalls dels pagaments, fotos, missatges i àudio que reprodueixis."</string>
     <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Vols començar a gravar o emetre contingut?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"Vols començar a gravar o emetre contingut amb <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
-    <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"Vols permetre que <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> comparteixi o gravi?"</string>
+    <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"Vols permetre que <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> comparteixi o gravi contingut?"</string>
     <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"Tota la pantalla"</string>
     <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"Una sola aplicació"</string>
     <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"Quan estàs compartint, gravant o emetent, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> té accés a qualsevol cosa que es vegi a la pantalla o que es reprodueixi al dispositiu. Per aquest motiu, ves amb compte amb les contrasenyes, les dades de pagament, els missatges o altra informació sensible."</string>
-    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Quan estàs compartint, gravant o emetent, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> té accés a qualsevol cosa que es vegi a la pantalla o que es reprodueixi a l\'aplicació. Per aquest motiu, ves amb compte amb les contrasenyes, les dades de pagament, els missatges o altra informació sensible."</string>
+    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Mentre comparteixes, graves o emets contingut, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> pot accedir a tot el que es veu a la pantalla o que es reprodueix a l\'aplicació. Per això cal que vagis amb compte amb les contrasenyes, les dades de pagament, els missatges o qualsevol altra informació sensible."</string>
     <string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Continua"</string>
     <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Comparteix o grava una aplicació"</string>
     <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Vols permetre que aquesta aplicació comparteixi o gravi contingut?"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"La Wi-Fi està desactivada"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"El Bluetooth està desactivat"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"El mode No molestis està desactivat"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Mode No molestis activat"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Una regla automàtica (<xliff:g id="ID_1">%s</xliff:g>) ha activat el mode No molestis."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Una aplicació (<xliff:g id="ID_1">%s</xliff:g>) ha activat el mode No molestis."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Una regla automàtica o una aplicació han activat el mode No molestis."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Reprodueix <xliff:g id="SONG_NAME">%1$s</xliff:g> des de l\'aplicació <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Desfés"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Mou més a prop per reproduir a <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Acosta\'t a <xliff:g id="DEVICENAME">%1$s</xliff:g> per reproduir el contingut aquí"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"S\'està reproduint a <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"S\'ha produït un error. Torna-ho a provar."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"S\'està carregant"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactiu; comprova l\'aplicació"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"No s\'ha trobat"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"El control no està disponible"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dispositius disponibles per a la sortida d\'àudio."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volum"</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">"Altaveus i pantalles"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Com funciona l\'emissió"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Emet"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Les persones properes amb dispositius Bluetooth compatibles poden escoltar el contingut multimèdia que emets"</string>
@@ -998,22 +1009,22 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"hh:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Obre <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Per afegir l\'aplicació <xliff:g id="APPNAME">%1$s</xliff:g> com a drecera, assegura\'t que:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• L\'aplicació està configurada."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Almenys s\'ha afegit una targeta a Wallet."</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Tens una aplicació de càmera."</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• L\'aplicació està configurada."</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Almenys un dispositiu està disponible."</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Mantén premuda la drecera"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel·la"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Gira ara"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Desplega el telèfon per fer una millor selfie"</string>
     <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Girar a pantalla frontal per fer millors selfies?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Utilitza la càmera posterior per obtenir una foto més àmplia amb una resolució més alta."</string>
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Aquesta pantalla s\'apagarà"</b></string>
-    <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositiu plegable que es desplega"</string>
-    <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositiu plegable que gira"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositiu plegable desplegant-se"</string>
+    <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositiu plegable girant"</string>
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 3f6dd91..3c8c6da 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Sdílet snímek obrazovky"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Zvětšit záběr snímku"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Zavřít snímek obrazovky"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Zavřít zprávu o pracovním profilu"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Náhled snímku obrazovky"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Horní okraj <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Dolní okraj <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Levý okraj <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Pravý okraj <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Rekordér obrazovky"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Záznam obrazovky se zpracovává"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Trvalé oznámení o relaci nahrávání"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi je vypnuta"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth je vypnuto"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Režim Nerušit je vypnut"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Režim Nerušit je zapnutý"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Režim Nerušit byl zapnut automatickým pravidlem (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Režim Nerušit byl zapnut aplikací (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Režim Nerušit byl zapnut automatickým pravidlem nebo aplikací."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Přehrát skladbu <xliff:g id="SONG_NAME">%1$s</xliff:g> z aplikace <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Vrátit zpět"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Pokud chcete přehrávat na zařízení <xliff:g id="DEVICENAME">%1$s</xliff:g>, přibližte se k němu"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Pokud zde chcete přehrávat média, přibližte se k zařízení <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Přehrávání v zařízení <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Došlo k chybě. Zkuste to znovu."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Načítání"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivní, zkontrolujte aplikaci"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nenalezeno"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Ovládání není k dispozici"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dostupná zařízení pro zvukový výstup."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Hlasitost"</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">"Reproduktory a displeje"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Jak vysílání funguje"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Vysílání"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Lidé ve vašem okolí s kompatibilními zařízeními Bluetooth mohou poslouchat média, která vysíláte"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"H:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Otevřít <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Podmínky pro to, aby aplikaci <xliff:g id="APPNAME">%1$s</xliff:g> bylo možné přidat jako zkratku:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Aplikace je nastavena"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Do Peněženky byla přidána alespoň jedna karta"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Je nainstalována aplikace pro fotoaparát"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Aplikace je nastavena"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Je k dispozici alespoň jedno zařízení"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Podržte zkratku"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Zrušit"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Otočit"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Rozložte telefon, selfie bude lepší"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Tato obrazovka se vypne"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Rozkládání rozkládacího zařízení"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Otáčení rozkládacího zařízení"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 3596d0e..585d858 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Del screenshottet"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Medtag mere"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Luk screenshot"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Luk arbejdsprofilmeddelelsen"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Forhåndsvisning af screenshot"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Øverste kant: <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Nederste kant: <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Venstre kant: <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Højre kant: <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Skærmoptagelse"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Behandler skærmoptagelse"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Konstant notifikation om skærmoptagelse"</string>
@@ -647,7 +652,7 @@
     <string name="right_keycode" msgid="2480715509844798438">"Højre tastekode"</string>
     <string name="left_icon" msgid="5036278531966897006">"Venstre ikon"</string>
     <string name="right_icon" msgid="1103955040645237425">"Højre ikon"</string>
-    <string name="drag_to_add_tiles" msgid="8933270127508303672">"Tilføj felter ved at holde dem nede og trække"</string>
+    <string name="drag_to_add_tiles" msgid="8933270127508303672">"Tilføj felter ved at holde dem nede og trække dem"</string>
     <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Flyt rundt på felterne ved at holde dem nede og trække"</string>
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Træk herhen for at fjerne"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Du skal bruge mindst <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> felter"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi er slået fra"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth er slået fra"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Forstyr ikke er slået fra"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Forstyr ikke er aktiveret"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Tilstanden Forstyr ikke blev aktiveret af en automatisk regel (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Tilstanden Forstyr ikke blev aktiveret af en app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Tilstanden Forstyr ikke blev aktiveret af en automatisk regel eller en app."</string>
@@ -849,10 +853,14 @@
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Afspil <xliff:g id="SONG_NAME">%1$s</xliff:g> af <xliff:g id="ARTIST_NAME">%2$s</xliff:g> via <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Afspil <xliff:g id="SONG_NAME">%1$s</xliff:g> via <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Fortryd"</string>
-    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Flyt enheden tættere på for at afspille på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Ryk tættere på <xliff:g id="DEVICENAME">%1$s</xliff:g> for at afspille her"</string>
+    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Ryk tættere på for at afspille på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Afspilles på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Noget gik galt. Prøv igen."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Indlæser"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv. Tjek appen"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Ikke fundet"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Styringselement ikke tilgængeligt"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Enheder, der er tilgængelige for lydoutput."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Lydstyrke"</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">"Højttalere og skærme"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Sådan fungerer udsendelser"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Udsendelse"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Personer i nærheden, som har kompatible Bluetooth-enheder, kan lytte til det medie, du udsender"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"tt.mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk.mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Åbn <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Før du tilføjer <xliff:g id="APPNAME">%1$s</xliff:g>-appen som en genvej, skal du sørge for følgende:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Appen er konfigureret"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Mindst ét kort er føjet til Wallet"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Installer en kameraapp"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Appen er konfigureret"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Mindst én enhed er tilgængelig"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Hold fingeren på genvejen"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annuller"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Vend nu"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Fold telefonen ud for at tage en bedre selfie"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ *Denne skærm slukkes"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldbar enhed foldes ud"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldbar enhed vendes om"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index bcae5b4..078c02d 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Screenshot teilen"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Mehr aufnehmen"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Screenshot schließen"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Arbeitsprofilnachricht schließen"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Screenshotvorschau"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Oberer Rand <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Unterer Rand <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Linker Rand <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Rechter Rand <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Bildschirmaufzeichnung"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Bildschirmaufzeichnung…"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Fortlaufende Benachrichtigung für eine Bildschirmaufzeichnung"</string>
@@ -97,8 +102,8 @@
     <string name="screenrecord_description" msgid="1123231719680353736">"Beim Aufnehmen kann das Android-System vertrauliche Informationen erfassen, die auf deinem Bildschirm angezeigt oder von deinem Gerät wiedergegeben werden. Das können Passwörter, Zahlungsinformationen, Fotos, Nachrichten und Audioinhalte sein."</string>
     <string name="screenrecord_option_entire_screen" msgid="1732437834603426934">"Gesamten Bildschirm aufnehmen"</string>
     <string name="screenrecord_option_single_app" msgid="5954863081500035825">"Eine einzelne App aufnehmen"</string>
-    <string name="screenrecord_warning_entire_screen" msgid="8141407178104195610">"Während der Aufnahme hat Android Zugriff auf alle Inhalte, die auf dem Bildschirm sichtbar sind oder auf dem Gerät wiedergegeben werden. Sei daher mit Passwörtern, Zahlungsdetails, Nachrichten oder anderen vertraulichen Informationen vorsichtig."</string>
-    <string name="screenrecord_warning_single_app" msgid="7760723997065948283">"Während der Aufnahme einer App hat Android Zugriff auf alle Inhalte, die in dieser App sichtbar sind oder wiedergegeben werden. Sei daher mit Passwörtern, Zahlungsdetails, Nachrichten oder anderen vertraulichen Informationen vorsichtig."</string>
+    <string name="screenrecord_warning_entire_screen" msgid="8141407178104195610">"Während der Aufnahme hat Android Zugriff auf alle Inhalte, die auf dem Bildschirm sichtbar sind oder auf dem Gerät wiedergegeben werden. Sei daher vorsichtig mit Passwörtern, Zahlungsdetails, Nachrichten oder anderen vertraulichen Informationen."</string>
+    <string name="screenrecord_warning_single_app" msgid="7760723997065948283">"Während der Aufnahme einer App hat Android Zugriff auf alle Inhalte, die in dieser App sichtbar sind oder wiedergegeben werden. Sei daher vorsichtig mit Passwörtern, Zahlungsdetails, Nachrichten oder anderen vertraulichen Informationen."</string>
     <string name="screenrecord_start_recording" msgid="348286842544768740">"Aufnahme starten"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Audio aufnehmen"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Audio des Geräts"</string>
@@ -373,13 +378,13 @@
     <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"Zulassen, dass <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> Inhalte teilt oder aufnimmt?"</string>
     <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"Gesamter Bildschirm"</string>
     <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"Eine einzelne App"</string>
-    <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"Beim Teilen, Aufnehmen oder Übertragen hat <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> Zugriff auf alle Inhalte, die auf dem Bildschirm sichtbar sind oder auf dem Gerät wiedergegeben werden. Sei daher mit Passwörtern, Zahlungsdetails, Nachrichten oder anderen vertraulichen Informationen vorsichtig."</string>
-    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Beim Teilen, Aufnehmen oder Übertragen einer App hat <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> Zugriff auf alle Inhalte, die in dieser App sichtbar sind oder wiedergegeben werden. Sei daher mit Passwörtern, Zahlungsdetails, Nachrichten oder anderen vertraulichen Informationen vorsichtig."</string>
+    <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"Beim Teilen, Aufnehmen oder Übertragen hat <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> Zugriff auf alle Inhalte, die auf dem Bildschirm sichtbar sind oder auf dem Gerät wiedergegeben werden. Sei daher vorsichtig mit Passwörtern, Zahlungsdetails, Nachrichten oder anderen vertraulichen Informationen."</string>
+    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Beim Teilen, Aufnehmen oder Übertragen einer App hat <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> Zugriff auf alle Inhalte, die in dieser App sichtbar sind oder wiedergegeben werden. Sei daher vorsichtig mit Passwörtern, Zahlungsdetails, Nachrichten oder anderen vertraulichen Informationen."</string>
     <string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Weiter"</string>
     <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"App teilen oder aufnehmen"</string>
     <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Dieser App das Teilen oder Aufnehmen erlauben?"</string>
-    <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Beim Teilen, Aufnehmen oder Übertragen hat diese App Zugriff auf alle Inhalte, die auf dem Bildschirm sichtbar sind oder auf dem Gerät wiedergegeben werden. Sei daher mit Passwörtern, Zahlungsdetails, Nachrichten oder anderen vertraulichen Informationen vorsichtig."</string>
-    <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Beim Teilen, Aufnehmen oder Übertragen einer App hat diese App Zugriff auf alle Inhalte, die in dieser App sichtbar sind oder wiedergegeben werden. Sei daher mit Passwörtern, Zahlungsdetails, Nachrichten oder anderen vertraulichen Informationen vorsichtig."</string>
+    <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Beim Teilen, Aufnehmen oder Übertragen hat diese App Zugriff auf alle Inhalte, die auf dem Bildschirm sichtbar sind oder auf dem Gerät wiedergegeben werden. Sei daher vorsichtig mit Passwörtern, Zahlungsdetails, Nachrichten oder anderen vertraulichen Informationen."</string>
+    <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Beim Teilen, Aufnehmen oder Übertragen einer App hat diese App Zugriff auf alle Inhalte, die in dieser App sichtbar sind oder wiedergegeben werden. Sei daher vorsichtig mit Passwörtern, Zahlungsdetails, Nachrichten oder anderen vertraulichen Informationen."</string>
     <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Vom IT-Administrator blockiert"</string>
     <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Bildschirmaufnahme ist durch die Geräterichtlinien deaktiviert"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Alle löschen"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"WLAN ist deaktiviert"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth ist deaktiviert"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"„Bitte nicht stören“ ist deaktiviert"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"„Bitte nicht stören“ aktiviert"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"„Bitte nicht stören“ wurde von einer automatischen Regel aktiviert (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"„Bitte nicht stören“ wurde von einer App aktiviert (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"„Bitte nicht stören“ wurde von einer automatischen Regel oder einer App aktiviert."</string>
@@ -849,10 +853,14 @@
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="SONG_NAME">%1$s</xliff:g> von <xliff:g id="ARTIST_NAME">%2$s</xliff:g> über <xliff:g id="APP_LABEL">%3$s</xliff:g> wiedergeben"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> über <xliff:g id="APP_LABEL">%2$s</xliff:g> wiedergeben"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Rückgängig machen"</string>
-    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Gehe für die Wiedergabe näher an <xliff:g id="DEVICENAME">%1$s</xliff:g> heran"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Platziere für die Wiedergabe dein Gerät näher an „<xliff:g id="DEVICENAME">%1$s</xliff:g>“"</string>
-    <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Wird auf „<xliff:g id="DEVICENAME">%1$s</xliff:g>“ abgespielt"</string>
+    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Gehe für die Wiedergabe näher an „<xliff:g id="DEVICENAME">%1$s</xliff:g>“ heran"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
+    <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Wiedergabe läuft auf „<xliff:g id="DEVICENAME">%1$s</xliff:g>“"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Es gab ein Problem. Versuch es noch einmal."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Wird geladen"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv – sieh in der App nach"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nicht gefunden"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Steuerelement nicht verfügbar"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Für die Audioausgabe verfügbare Geräte."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Lautstärke"</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">"Lautsprecher &amp; Displays"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Funktionsweise von Nachrichten an alle"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Nachricht an alle"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Personen, die in der Nähe sind und kompatible Bluetooth-Geräten haben, können sich die Medien anhören, die du per Nachricht an alle sendest"</string>
@@ -998,24 +1009,22 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> öffnen"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Wenn du die <xliff:g id="APPNAME">%1$s</xliff:g> App als eine Verknüpfung hinzufügen möchtest, müssen folgende Bedingungen erfüllt sein"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Die App ist eingerichtet"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Wallet wurde mindestens eine Karte hinzugefügt"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Kamera-App ist installiert"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Die App ist eingerichtet"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Mindestens ein Gerät ist verfügbar"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Verknüpfung berühren &amp; halten"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Abbrechen"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Jetzt umdrehen"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Für ein besseres Selfie Smartphone öffnen"</string>
     <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Für ein besseres Selfie Frontbildschirm verwenden?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Verwende die Rückkamera, um Fotos mit einem weiteren Blickwinkel und höherer Auflösung aufzunehmen."</string>
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Dieses Display wird dann ausgeschaltet"</b></string>
-    <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
+    <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Faltbares Gerät wird geöffnet"</string>
+    <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Faltbares Gerät wird umgeklappt"</string>
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
     <skip />
-    <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
-    <skip />
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 54f162b..fce50e5 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -85,11 +85,14 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Κοινοποίηση στιγμιότυπου οθόνης"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Λήψη περισσότερων"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Παράβλεψη στιγμιότυπου οθόνης"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Παράβλεψη μηνύματος προφίλ εργασίας"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Προεπισκόπηση στιγμιότυπου οθόνης"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Επάνω όριο <xliff:g id="PERCENT">%1$d</xliff:g> τοις εκατό"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Κάτω όριο <xliff:g id="PERCENT">%1$d</xliff:g> τοις εκατό"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Αριστερό όριο <xliff:g id="PERCENT">%1$d</xliff:g> τοις εκατό"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Δεξί όριο <xliff:g id="PERCENT">%1$d</xliff:g> τοις εκατό"</string>
+    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Τα στιγμιότυπα οθόνης εργασίας αποθηκεύονται στην εφαρμογή <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Αρχεία"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Εγγραφή οθόνης"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Επεξεργασία εγγραφής οθόνης"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ειδοποίηση σε εξέλιξη για μια περίοδο λειτουργίας εγγραφής οθόνης"</string>
@@ -731,8 +734,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Το Wi-Fi είναι ανενεργό"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Το Bluetooth είναι ανενεργό"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Η λειτουργία \"Μην ενοχλείτε\" είναι ανενεργή"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Η λειτουργία Μην ενοχλείτε είναι ενεργή"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Η λειτουργία \"Μην ενοχλείτε\" ενεργοποιήθηκε από έναν αυτόματο κανόνα (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Η λειτουργία \"Μην ενοχλείτε\" ενεργοποιήθηκε από μια εφαρμογή (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Η λειτουργία \"Μην ενοχλείτε\" ενεργοποιήθηκε από έναν αυτόματο κανόνα ή μια εφαρμογή."</string>
@@ -850,9 +852,12 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Αναπαραγωγή του <xliff:g id="SONG_NAME">%1$s</xliff:g> στην εφαρμογή <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Αναίρεση"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Πλησιάστε για αναπαραγωγή στη συσκευή <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Μετακινηθείτε πιο κοντά στη συσκευή <xliff:g id="DEVICENAME">%1$s</xliff:g> για αναπαραγωγή εδώ"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Αναπαραγωγή στη συσκευή <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Παρουσιάστηκε κάποιο πρόβλημα. Δοκιμάστε ξανά."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Φόρτωση"</string>
+    <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Ανενεργό, έλεγχος εφαρμογής"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Δεν βρέθηκε."</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Μη διαθέσιμο στοιχείο ελέγχου"</string>
@@ -875,6 +880,8 @@
     <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">"Ηχεία και οθόνες"</string>
+    <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Προτεινόμενες συσκευές"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Πώς λειτουργεί η μετάδοση"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Μετάδοση"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Οι άνθρωποι με συμβατές συσκευές Bluetooth που βρίσκονται κοντά σας μπορούν να ακούσουν το μέσο που μεταδίδετε."</string>
@@ -998,14 +1005,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"ώ:λλ"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:λλ"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Άνοιγμα <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Για να προσθέσετε την εφαρμογή <xliff:g id="APPNAME">%1$s</xliff:g> ως συντόμευση, βεβαιωθείτε ότι"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Η εφαρμογή έχει ρυθμιστεί"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Έχει προστεθεί τουλάχιστον μία κάρτα στο Πορτοφόλι"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Εγκαταστήσατε μια εφαρμογή κάμερας"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Η εφαρμογή έχει ρυθμιστεί"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Είναι διαθέσιμη τουλάχιστον μία συσκευή"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Παρατεταμένο άγγιγμα συντόμευσης"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Ακύρωση"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Αναστροφή τώρα"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Ξεδιπλώστε το τηλέφωνο για καλύτερη selfie"</string>
@@ -1014,6 +1019,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"* Αυτή η οθόνη θα απενεργοποιηθεί"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Αναδιπλούμενη συσκευή που ξεδιπλώνει"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Αναδιπλούμενη συσκευή που διπλώνει"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 224d6fc..b0421c0 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -85,11 +85,14 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Share screenshot"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Capture more"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Dismiss screenshot"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Dismiss work profile message"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Screenshot preview"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Top boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Bottom boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Left boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Right boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
+    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Work screenshots are saved in the <xliff:g id="APP">%1$s</xliff:g> app"</string>
+    <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Screen Recorder"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
@@ -731,8 +734,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi is off"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth is off"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Do Not Disturb is off"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Do Not Disturb is on"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Do Not Disturb was turned on by an automatic rule (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Do Not Disturb was turned on by an app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Do Not Disturb was turned on by an automatic rule or app."</string>
@@ -850,9 +852,12 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Play <xliff:g id="SONG_NAME">%1$s</xliff:g> from <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Undo"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Move closer to play on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g> to play here"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Playing on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Something went wrong. Try again."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Loading"</string>
+    <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Control is unavailable"</string>
@@ -875,6 +880,8 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Available devices for audio output."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</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">"Speakers &amp; displays"</string>
+    <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Suggested devices"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"How broadcasting works"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"People near you with compatible Bluetooth devices can listen to the media that you\'re broadcasting"</string>
@@ -998,14 +1005,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Open <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"To add the <xliff:g id="APPNAME">%1$s</xliff:g> app as a shortcut, make sure"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• The app is set up"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• At least one card has been added to Wallet"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Install a camera app"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• The app is set up"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• At least one device is available"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Touch &amp; hold shortcut"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Flip now"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Unfold phone for a better selfie"</string>
@@ -1014,6 +1019,6 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ This screen will turn off"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
-    <skip />
+    <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> battery remaining"</string>
+    <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connect your stylus to a charger"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 6238b83..5e564c3 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -85,11 +85,14 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Share screenshot"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Capture more"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Dismiss screenshot"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Dismiss work profile message"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Screenshot preview"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Top boundary <xliff:g id="PERCENT">%1$d</xliff:g> percent"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Bottom boundary <xliff:g id="PERCENT">%1$d</xliff:g> percent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Left boundary <xliff:g id="PERCENT">%1$d</xliff:g> percent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Right boundary <xliff:g id="PERCENT">%1$d</xliff:g> percent"</string>
+    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Work screenshots are saved in the <xliff:g id="APP">%1$s</xliff:g> app"</string>
+    <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Screen Recorder"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
@@ -731,8 +734,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi is off"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth is off"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Do Not Disturb is off"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Do Not Disturb is on"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Do Not Disturb was turned on by an automatic rule (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Do Not Disturb was turned on by an app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Do Not Disturb was turned on by an automatic rule or app."</string>
@@ -850,9 +852,11 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Play <xliff:g id="SONG_NAME">%1$s</xliff:g> from <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Undo"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Move closer to play on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g> to play here"</string>
+    <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"To play here, move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Playing on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Something went wrong. Try again."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Loading"</string>
+    <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Control is unavailable"</string>
@@ -875,6 +879,8 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Available devices for audio output."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</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">"Speakers &amp; Displays"</string>
+    <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Suggested Devices"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"How broadcasting works"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"People near you with compatible Bluetooth devices can listen to the media you\'re broadcasting"</string>
@@ -998,13 +1004,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Open <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"To add the <xliff:g id="APPNAME">%1$s</xliff:g> app as a shortcut, make sure"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• The app is set up"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• At least one card has been added to Wallet"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Install a camera app"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• The app is set up"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• At least one device is available"</string>
-    <string name="keyguard_affordance_press_too_short" msgid="2687995216454987952">"Press and hold to activate"</string>
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Touch &amp; hold shortcut"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Flip now"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Unfold phone for a better selfie"</string>
@@ -1013,5 +1018,6 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ This screen will turn off"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
-    <string name="stylus_battery_low" msgid="7134370101603167096">"Stylus battery low"</string>
+    <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> battery remaining"</string>
+    <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connect your stylus to a charger"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 224d6fc..b0421c0 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -85,11 +85,14 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Share screenshot"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Capture more"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Dismiss screenshot"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Dismiss work profile message"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Screenshot preview"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Top boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Bottom boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Left boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Right boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
+    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Work screenshots are saved in the <xliff:g id="APP">%1$s</xliff:g> app"</string>
+    <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Screen Recorder"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
@@ -731,8 +734,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi is off"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth is off"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Do Not Disturb is off"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Do Not Disturb is on"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Do Not Disturb was turned on by an automatic rule (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Do Not Disturb was turned on by an app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Do Not Disturb was turned on by an automatic rule or app."</string>
@@ -850,9 +852,12 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Play <xliff:g id="SONG_NAME">%1$s</xliff:g> from <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Undo"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Move closer to play on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g> to play here"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Playing on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Something went wrong. Try again."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Loading"</string>
+    <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Control is unavailable"</string>
@@ -875,6 +880,8 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Available devices for audio output."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</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">"Speakers &amp; displays"</string>
+    <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Suggested devices"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"How broadcasting works"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"People near you with compatible Bluetooth devices can listen to the media that you\'re broadcasting"</string>
@@ -998,14 +1005,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Open <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"To add the <xliff:g id="APPNAME">%1$s</xliff:g> app as a shortcut, make sure"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• The app is set up"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• At least one card has been added to Wallet"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Install a camera app"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• The app is set up"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• At least one device is available"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Touch &amp; hold shortcut"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Flip now"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Unfold phone for a better selfie"</string>
@@ -1014,6 +1019,6 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ This screen will turn off"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
-    <skip />
+    <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> battery remaining"</string>
+    <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connect your stylus to a charger"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 224d6fc..b0421c0 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -85,11 +85,14 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Share screenshot"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Capture more"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Dismiss screenshot"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Dismiss work profile message"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Screenshot preview"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Top boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Bottom boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Left boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Right boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
+    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Work screenshots are saved in the <xliff:g id="APP">%1$s</xliff:g> app"</string>
+    <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Screen Recorder"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
@@ -731,8 +734,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi is off"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth is off"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Do Not Disturb is off"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Do Not Disturb is on"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Do Not Disturb was turned on by an automatic rule (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Do Not Disturb was turned on by an app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Do Not Disturb was turned on by an automatic rule or app."</string>
@@ -850,9 +852,12 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Play <xliff:g id="SONG_NAME">%1$s</xliff:g> from <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Undo"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Move closer to play on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g> to play here"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Playing on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Something went wrong. Try again."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Loading"</string>
+    <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Control is unavailable"</string>
@@ -875,6 +880,8 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Available devices for audio output."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</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">"Speakers &amp; displays"</string>
+    <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Suggested devices"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"How broadcasting works"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"People near you with compatible Bluetooth devices can listen to the media that you\'re broadcasting"</string>
@@ -998,14 +1005,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Open <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"To add the <xliff:g id="APPNAME">%1$s</xliff:g> app as a shortcut, make sure"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• The app is set up"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• At least one card has been added to Wallet"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Install a camera app"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• The app is set up"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• At least one device is available"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Touch &amp; hold shortcut"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Flip now"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Unfold phone for a better selfie"</string>
@@ -1014,6 +1019,6 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ This screen will turn off"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
-    <skip />
+    <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> battery remaining"</string>
+    <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connect your stylus to a charger"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 7bb3fd3..2ab012d 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -85,11 +85,14 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‎‎‎‏‏‎‎‎‏‎‏‏‎‏‏‎‎‎‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎‏‏‎‏‏‏‏‎‎‏‎‎‎Share screenshot‎‏‎‎‏‎"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‎‏‎‏‎‏‎‎‎‏‎‏‎‎‎‎‏‎‎‏‎‏‎‏‏‏‏‎‎‎‏‎‏‎‏‎‎‏‎‎‏‏‎‎‏‏‏‎‏‎‏‎‏‏‏‎Capture more‎‏‎‎‏‎"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‎‎‏‎‎‎‎‏‎‎‏‎‎‏‏‏‎‎‏‎‏‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‎‎‎‎‏‏‎‎‎‎‏‏‎‎‏‎‎Dismiss screenshot‎‏‎‎‏‎"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‏‎‏‎‏‏‎‏‏‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‏‏‎‎‎‎‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‎‏‎‏‎‏‎Dismiss work profile message‎‏‎‎‏‎"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‏‏‏‏‏‎‎‎‎‎‎‏‎‏‎‏‏‎‎‎‎‎‎‎‏‎‏‏‎‏‎‏‎‏‏‎‏‎‏‏‎‎‎‏‏‎‏‏‎‏‎‎Screenshot preview‎‏‎‎‏‎"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‏‎‎‏‎‏‎‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‏‎‏‏‏‎‎‏‎‏‏‎‎‎‎‎‎‎‏‏‏‎‎‏‏‎‎‏‎‎‎Top boundary ‎‏‎‎‏‏‎<xliff:g id="PERCENT">%1$d</xliff:g>‎‏‎‎‏‏‏‎ percent‎‏‎‎‏‎"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‏‏‎‏‏‎‏‏‏‎‎‏‎‏‎‎‏‏‏‎‎‎‏‎‏‏‏‎‏‎‏‎‎‎‎‏‎‏‏‏‎‏‏‏‎‏‎‏‎‏‏‏‎‎Bottom boundary ‎‏‎‎‏‏‎<xliff:g id="PERCENT">%1$d</xliff:g>‎‏‎‎‏‏‏‎ percent‎‏‎‎‏‎"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‎‎‏‏‏‎‏‎‎‎‎‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‏‎‏‏‏‎‏‏‎‏‎Left boundary ‎‏‎‎‏‏‎<xliff:g id="PERCENT">%1$d</xliff:g>‎‏‎‎‏‏‏‎ percent‎‏‎‎‏‎"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‎‏‎‏‏‎‏‎‏‏‎‎‎‎‎‏‏‎‏‎‏‏‎‏‎‎‎‏‏‎‏‎‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‏‏‏‎‎‏‎Right boundary ‎‏‎‎‏‏‎<xliff:g id="PERCENT">%1$d</xliff:g>‎‏‎‎‏‏‏‎ percent‎‏‎‎‏‎"</string>
+    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‎‎‏‎‏‎‎‎‏‏‏‎‏‏‎‎‎‏‏‎‎‏‏‏‏‎‏‎‎‏‎‏‎‎‏‎Work screenshots are saved in the ‎‏‎‎‏‏‎<xliff:g id="APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎ app‎‏‎‎‏‎"</string>
+    <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‎‏‎‏‎‎‎‏‏‎‎‏‏‎‏‎‏‎‏‏‏‏‎‏‎‏‎‏‎‎‎‏‏‎‎‎‎‎‏‎‏‎‎‎‏‏‏‎‎‎‎Files‎‏‎‎‏‎"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‎‏‎‎‎‎‏‎‎‎‏‎‏‎‎‏‎‏‎‎‎‎‎‏‎‎‎‏‎‏‎‎‏‎‎‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‏‎‎‎Screen Recorder‎‏‎‎‏‎"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‎‏‎‎‎‎‏‎‏‎‏‎‎‎‏‏‎‏‏‏‏‎‎‎‏‏‏‏‎‎‎‏‏‎‎‏‎‎Processing screen recording‎‏‎‎‏‎"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‏‎‏‎‏‏‎‎‎‎‎‏‎‏‎‏‏‎‏‎‎‎‏‏‎‏‏‏‎‎‏‎‎‎‎‎‎‏‏‎‎‎‏‏‏‏‎‏‏‏‏‎Ongoing notification for a screen record session‎‏‎‎‏‎"</string>
@@ -731,8 +734,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‎‎‏‎‏‏‏‎‏‏‎‎‏‎‎‏‎‎‎‏‏‎‏‏‎‏‎‎‎‏‎‏‎‎‏‏‏‏‎‎‎‎‎‎‏‎‏‎‏‏‏‏‏‏‎Wi-Fi is off‎‏‎‎‏‎"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‏‎‎‏‏‎‎‏‏‎‏‎‎‎‏‎‎‏‎‏‎‏‎‏‎‎‎‏‏‎‎‏‏‏‎‎‎‏‏‏‎‏‎‏‏‎‏‎‏‎‏‏‏‎Bluetooth is off‎‏‎‎‏‎"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‎‏‎‏‏‏‏‎‎‏‏‏‏‎‎‎‏‏‎‎‏‏‏‎‎‏‏‏‎‎‎‏‏‎‎‎‏‏‎‎‏‏‏‏‎‎‏‏‏‏‏‏‎Do Not Disturb is off‎‏‎‎‏‎"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎‎‏‏‎‎‏‎‎‎‏‏‏‎‎‏‏‏‎‎‎‎‎‎‏‏‎‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‏‎‎‎‏‎‎‏‏‏‎Do Not Disturb is on‎‏‎‎‏‎"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‏‎‎‎‎‏‎‎‎‎‎‏‎‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‎‏‏‎‏‎‏‏‎‏‏‏‎‏‏‏‎‎‎‎Do Not Disturb was turned on by an automatic rule (‎‏‎‎‏‏‎<xliff:g id="ID_1">%s</xliff:g>‎‏‎‎‏‏‏‎).‎‏‎‎‏‎"</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‎‏‏‎‏‎‎‎‎‎‏‏‏‎‏‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‏‏‏‎‏‎‏‎‎‎Do Not Disturb was turned on by an app (‎‏‎‎‏‏‎<xliff:g id="ID_1">%s</xliff:g>‎‏‎‎‏‏‏‎).‎‏‎‎‏‎"</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‏‏‎‎‎‏‏‎‏‏‏‎‎‏‎‏‎‎‎‎‏‎‏‏‎‏‏‏‎‏‏‏‏‎‏‏‎‏‎‎‏‏‎‎‎‏‏‎‏‎‎‎Do Not Disturb was turned on by an automatic rule or app.‎‏‎‎‏‎"</string>
@@ -850,9 +852,11 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‎‏‎‏‏‏‎‎‏‏‏‎‎‎‏‎‏‏‏‎‏‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‏‎‎‏‏‏‏‏‏‎‎‏‎‏‎Play ‎‏‎‎‏‏‎<xliff:g id="SONG_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ from ‎‏‎‎‏‏‎<xliff:g id="APP_LABEL">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‎‏‏‏‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‎‎‎‏‏‎‎‎‎‏‎‎‏‏‏‏‏‎‏‎‎‎‎‎‎Undo‎‏‎‎‏‎"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‎‏‏‎‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‎‏‏‎‎‏‎‏‏‏‏‏‏‎‎‎‎‎‎‏‏‎‎‏‏‏‏‎‏‏‏‎‎‎‎Move closer to play on ‎‏‎‎‏‏‎<xliff:g id="DEVICENAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‎‏‏‎‎‎‎‏‏‎‎‏‎‏‎‎‏‏‏‏‎‏‎‎‏‏‎‏‏‏‎‎‎‏‏‏‏‎‏‏‎‏‎‏‎‏‎‎‏‎‎‎‎Move closer to ‎‏‎‎‏‏‎<xliff:g id="DEVICENAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ to play here‎‏‎‎‏‎"</string>
+    <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‏‏‏‏‏‏‎‎‎‏‏‏‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‎‎‏‎‎‏‎‎To play here, move closer to ‎‏‎‎‏‏‎<xliff:g id="DEVICENAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‏‏‏‎‎‏‎‏‎‏‎‏‎‎‏‎‏‎‎‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‎‎‎‎‏‎‏‎‎Playing on ‎‏‎‎‏‏‎<xliff:g id="DEVICENAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‏‏‏‎‎‎‏‏‎‎‏‎‎‏‏‎‎‎‎‏‏‏‎‎‏‏‏‏‏‎‎‎‎‎‏‎‏‎‏‏‎‏‎‏‏‎‎‏‎‏‏‎Something went wrong. Try again.‎‏‎‎‏‎"</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‎‎‎‎‏‎‎‏‏‏‎‎‎‏‏‎‏‎‎‎‎‎‏‏‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‎‏‏‎‎‎‏‎‎‏‏‎‎Loading‎‏‎‎‏‎"</string>
+    <string name="media_ttt_default_device_type" msgid="4457646436153370169">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‎‏‏‏‏‎‏‏‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‎‎‏‏‎‏‎‏‎‎‏‎‎‏‏‎‎‎‏‏‏‎‎‏‎tablet‎‏‎‎‏‎"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‎‏‏‏‎‎‎‏‏‏‎‏‎‎‎‏‎‏‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‏‏‏‏‏‏‎‎Inactive, check app‎‏‎‎‏‎"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‎‏‎‎‏‎‏‎‎‎‎‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎‏‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‎Not found‎‏‎‎‏‎"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‎‏‏‎‎‎‏‎‎‏‎‏‎‎‏‎‏‎‎‎‎‎‏‎‏‎‎‏‎‎‎‎‏‎‎‏‏‎‎‏‎‏‎‎Control is unavailable‎‏‎‎‏‎"</string>
@@ -875,6 +879,8 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‏‏‎‎‎‏‏‏‎‎‎‏‎‏‎‏‏‎‎‎‏‎‏‏‎‎‏‎‏‎‏‏‎‏‎‏‎‎‎‎‎‏‎‏‏‎‏‎‏‎‎‎‎‎Available devices for audio output.‎‏‎‎‏‎"</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‎‎‎‏‎‏‎‏‏‎‏‏‏‎‎‏‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‏‏‎‏‏‏‏‎‏‎‎‏‎‎Volume‎‏‎‎‏‎"</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">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‎‎‎‏‎‎‏‎‏‎‎‎‎‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎Speakers &amp; Displays‎‏‎‎‏‎"</string>
+    <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‏‎‎‎‏‎‏‎‎‏‎‏‎‏‏‎‏‏‎‏‏‎‎‎‏‎‏‎‎‎‏‎‎‎‎‏‎‏‏‏‏‎‎‏‏‏‏‎‏‎‎‏‎‎Suggested Devices‎‏‎‎‏‎"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‎‎‏‎‏‎‎‎‎‏‎‎‏‏‏‎‏‏‏‎‏‎‏‎‎‎‏‎‏‏‏‏‎‎‎‎‎‏‏‎‏‏‏‎‎‏‏‏‏‏‏‎‎How broadcasting works‎‏‎‎‏‎"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‎‎‎‏‎‎‏‏‎‏‎‏‏‎‏‏‏‎‎‎‏‏‏‏‎‏‏‏‎Broadcast‎‏‎‎‏‎"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‏‎‏‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‎‎‏‎‎‎‎‏‎‏‏‎‎‏‏‏‏‎‏‎‎‏‏‏‏‎‎People near you with compatible Bluetooth devices can listen to the media you\'re broadcasting‎‏‎‎‏‎"</string>
@@ -998,13 +1004,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‎‏‏‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‏‎‏‎‏‎‏‎‏‏‎‎‎‎‏‎‏‎‎‏‏‏‏‎‏‎‎‏‎‎‏‎h:mm‎‏‎‎‏‎"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‎‏‏‎‎‏‎‏‏‎‏‎‎‎‏‏‎‏‎‏‏‎‏‏‎‏‎‎‏‎‏‎‎‏‎‏‎‏‎‎‏‏‏‎‎‏‏‎‏‏‎‏‎kk:mm‎‏‎‎‏‎"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‎‏‏‏‏‎‏‏‎‎‏‏‎‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‏‏‏‎‏‎‏‎‏‏‎‏‎‎‏‎‎‎‎‏‎‏‎‎‎‎Open ‎‏‎‎‏‏‎<xliff:g id="APPNAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‎‏‏‎‏‎‎‏‏‏‎‎‏‏‏‎‏‎‏‎‏‏‏‏‎‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‏‏‏‏‎‎‎‎‏‎‏‎To add the ‎‏‎‎‏‏‎<xliff:g id="APPNAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ app as a shortcut, make sure‎‏‎‎‏‎"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‏‎‏‏‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‎‎‎‏‏‏‎‎• The app is set up‎‏‎‎‏‎"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‏‏‏‎‎‎‏‏‏‏‎‎‎‎‎‏‎‏‎‎‎‎‏‏‏‎‏‏‎‎‏‎‏‏‏‎‎‏‎‏‏‎• At least one card has been added to Wallet‎‏‎‎‏‎"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‏‎‎‏‏‏‏‎‎‎‎‏‏‎‏‎‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‏‎‎‎‏‏‏‏‏‎‏‏‏‏‎• Install a camera app‎‏‎‎‏‎"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‎‏‏‏‎‎‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‏‎‎‎‎‏‏‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‏‎‎‏‎• The app is set up‎‏‎‎‏‎"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‏‏‎‏‏‏‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‎‏‎‎‏‎‎‏‏‏‎‏‎‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎• At least one device is available‎‏‎‎‏‎"</string>
-    <string name="keyguard_affordance_press_too_short" msgid="2687995216454987952">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‎‎‏‏‎‏‏‎‏‎‏‏‎‏‎‏‏‎‏‎‎‎‎‏‏‎‎‎‏‎‏‎‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‎‎‎‎‎Press and hold to activate‎‏‎‎‏‎"</string>
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‎‏‎‏‎‎‏‏‎‎‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‎‎‎‏‎‏‏‏‎‏‏‎‏‎‎‎‏‎‏‎‏‎‎‎‎‎Touch &amp; hold shortcut‎‏‎‎‏‎"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‎‏‎‏‎‏‏‎‎‏‏‏‎‎‏‏‎‎‎‎‏‎‎‏‏‎‏‏‏‎‏‏‎‎‎‎‎‎‎Cancel‎‏‎‎‏‎"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‎‏‎‎‏‏‎‎‏‏‏‏‏‎‎‎‏‏‎‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‎‏‎‏‏‏‏‏‎‎‏‎‎‏‎‏‏‎‎Flip now‎‏‎‎‏‎"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‎‏‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‏‎‏‏‏‎‏‎‎‎‎‎‏‏‏‎‎‎‏‏‏‎‏‏‎‎‎‎‎‎‏‏‎‎‎Unfold phone for a better selfie‎‏‎‎‏‎"</string>
@@ -1013,5 +1018,6 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‏‏‏‎‏‏‎‏‏‎‏‎‏‏‎‎‎‏‎‏‏‏‎‎‎‎‎‏‏‏‏‎‎‏‏‏‎‎‏‏‎‎‎‏‎‏‏‎‏‎‎‏‎‎‎‏‎‎‏‏‎"<b>"‎‏‎‎‏‏‏‎✱ This screen will turn off‎‏‎‎‏‏‎"</b>"‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‏‎‏‏‎‎‎‏‎‎‎‎‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎Foldable device being unfolded‎‏‎‎‏‎"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‎‎‏‎‎‎‏‎‎‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‏‏‎‏‎‏‎‏‎‎‏‎‏‏‏‎‎‎‎‏‏‎‎‏‎‎‎‎‎Foldable device being flipped around‎‏‎‎‏‎"</string>
-    <string name="stylus_battery_low" msgid="7134370101603167096">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‎‎‎‎‏‎‎‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‏‎‎‎‏‏‏‎‎‏‎‏‏‎‏‎‏‏‎‏‏‏‏‎‎‎‎Stylus battery low‎‏‎‎‏‎"</string>
+    <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‏‏‎‏‏‏‎‏‎‎‎‏‏‎‏‎‏‏‏‎‏‎‏‎‏‏‏‎‎‏‎‎‏‎‎‎‏‎‏‎‏‏‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="PERCENTAGE">%s</xliff:g>‎‏‎‎‏‏‏‎ battery remaining‎‏‎‎‏‎"</string>
+    <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‏‏‎‎‎‏‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‏‏‏‎‏‎‏‎‏‎‏‎‏‎‏‏‎‏‏‏‎‏‎‏‏‏‎‏‎‎‏‎Connect your stylus to a charger‎‏‎‎‏‎"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 75fdd0d..3d6419d 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Compartir captura"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Capturar más"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Descartar captura de pantalla"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Descartar mensaje del perfil de trabajo"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Vista previa de la captura de pantalla"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Límite superior: <xliff:g id="PERCENT">%1$d</xliff:g> por ciento"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Límite inferior: <xliff:g id="PERCENT">%1$d</xliff:g> por ciento"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Límite izquierdo: <xliff:g id="PERCENT">%1$d</xliff:g> por ciento"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Límite derecho: <xliff:g id="PERCENT">%1$d</xliff:g> por ciento"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Grabadora de pantalla"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Procesando grabación pantalla"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación constante para una sesión de grabación de pantalla"</string>
@@ -374,7 +379,7 @@
     <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"Pantalla completa"</string>
     <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"Una sola app"</string>
     <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"Cuando compartas, grabes o transmitas contenido, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> podrá acceder a todo aquel que sea visible en la pantalla o que reproduzcas en el dispositivo. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes y otra información sensible."</string>
-    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Cuando compartas, grabes o transmitas una app, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> podrá acceder a todo el contenido que se muestre o reproduzca en ella. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes y otra información sensible."</string>
+    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Cuando compartas, grabes o transmitas una app, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> podrá acceder a todo el contenido que se muestre o reproduzca en ella. Por lo tanto, debes tener cuidado con las contraseñas, los detalles de pagos, los mensajes y otra información sensible."</string>
     <string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Continuar"</string>
     <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Compartir o grabar una app"</string>
     <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"¿Quieres permitir que esta app comparta o grabe tu pantalla?"</string>
@@ -647,7 +652,7 @@
     <string name="right_keycode" msgid="2480715509844798438">"Clave de código derecho"</string>
     <string name="left_icon" msgid="5036278531966897006">"Ícono izquierdo"</string>
     <string name="right_icon" msgid="1103955040645237425">"Ícono derecho"</string>
-    <string name="drag_to_add_tiles" msgid="8933270127508303672">"Mantén presionado y arrastra para agregar mosaicos"</string>
+    <string name="drag_to_add_tiles" msgid="8933270127508303672">"Mantén presionado y arrastra para agregar tarjetas"</string>
     <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Mantén presionado y arrastra para reorganizar los mosaicos"</string>
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Arrastra aquí para quitar"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Necesitas al menos <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tarjetas"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi desactivado"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth desactivado"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"No interrumpir desactivado"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"No interrumpir está activado"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Se activó el modo No interrumpir con una regla automática (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Se activó el modo No interrumpir con una app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Se activó el modo No interrumpir con una app o regla automática."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Reproducir <xliff:g id="SONG_NAME">%1$s</xliff:g> en <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Deshacer"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Acércate para reproducir en <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Acércate a <xliff:g id="DEVICENAME">%1$s</xliff:g> para reproducir aquí"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Reproduciendo en <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Se produjo un error. Vuelve a intentarlo."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Cargando"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactivo. Verifica la app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"No se encontró"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"El control no está disponible"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dispositivos disponibles para salida de audio."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volumen"</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">"Bocinas y pantallas"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cómo funciona la transmisión"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Transmisión"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Las personas cercanas con dispositivos Bluetooth compatibles pueden escuchar el contenido multimedia que transmites"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Para agregar la app <xliff:g id="APPNAME">%1$s</xliff:g> como acceso directo, asegúrate que se cumplan los siguientes requisitos:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Se configuró la app."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Se agregó al menos una tarjeta a la Billetera."</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Se instaló la app de Cámara."</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Se configuró la app."</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Hay al menos un dispositivo disponible."</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Mantener presionado atajo"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Girar ahora"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Despliega el teléfono para tomar una selfie mejor"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Esta pantalla se apagará"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo plegable siendo desplegado"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo plegable siendo girado"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 8ebe61d..9839e50 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Compartir captura de pantalla"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Capturar más"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Cerrar captura de pantalla"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Cerrar mensaje del perfil de trabajo"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Vista previa de captura de pantalla"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"<xliff:g id="PERCENT">%1$d</xliff:g> por ciento del límite superior"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"<xliff:g id="PERCENT">%1$d</xliff:g> por ciento del límite inferior"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"<xliff:g id="PERCENT">%1$d</xliff:g> por ciento del límite izquierdo"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"<xliff:g id="PERCENT">%1$d</xliff:g> por ciento del límite derecho"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Grabación de pantalla"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Procesando grabación de pantalla"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación continua de una sesión de grabación de la pantalla"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi desactivado"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth desactivado"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"No molestar está desactivado"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Modo No molestar activado"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Una regla automática (<xliff:g id="ID_1">%s</xliff:g>) ha activado No molestar."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Una aplicación (<xliff:g id="ID_1">%s</xliff:g>) ha activado No molestar."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Una aplicación o una regla automática han activado No molestar."</string>
@@ -849,10 +853,14 @@
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Poner <xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> en <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Poner <xliff:g id="SONG_NAME">%1$s</xliff:g> en <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Deshacer"</string>
-    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Acércate a <xliff:g id="DEVICENAME">%1$s</xliff:g> para que se reproduzca en ese dispositivo"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Acércate a <xliff:g id="DEVICENAME">%1$s</xliff:g> para jugar aquí"</string>
+    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Acércate a <xliff:g id="DEVICENAME">%1$s</xliff:g> para reproducir contenido ahí"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Reproduciendo en <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Se ha producido un error. Inténtalo de nuevo."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Cargando"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactivo, comprobar aplicación"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"No se ha encontrado"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Control no disponible"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dispositivos disponibles para la salida de audio."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volumen"</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">"Altavoces y pantallas"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cómo funciona la emisión"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Emisión"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Las personas cercanas con dispositivos Bluetooth compatibles pueden escuchar el contenido multimedia que emites"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Para añadir la aplicación <xliff:g id="APPNAME">%1$s</xliff:g> como acceso directo:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• La aplicación debe estar configurada"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Se debe haber añadido al menos una tarjeta a Wallet"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Debes instalar una aplicación de cámara"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• La aplicación debe estar configurada"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Al menos un dispositivo debe estar disponible"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Mantén pulsado el acceso directo"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Girar ahora"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Despliega el teléfono para hacer un selfie mejor"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Esta pantalla se apagará"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo plegable desplegándose"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo plegable mostrado desde varios ángulos"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 5345e53..5a83eb6 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Jaga ekraanipilti"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Jäädvusta rohkem"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Ekraanipildist loobumine"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Loobu tööprofiili sõnumist"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Ekraanipildi eelvaade"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Ülapiir: <xliff:g id="PERCENT">%1$d</xliff:g> protsenti"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Alapiir: <xliff:g id="PERCENT">%1$d</xliff:g> protsenti"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Vasak piir: <xliff:g id="PERCENT">%1$d</xliff:g> protsenti"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Parem piir: <xliff:g id="PERCENT">%1$d</xliff:g> protsenti"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekraanisalvesti"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekraanisalvestuse töötlemine"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pooleli märguanne ekraanikuva salvestamise seansi puhul"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"WiFi on välja lülitatud"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth on välja lülitatud"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Funktsioon Mitte segada on välja lülitatud"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Režiim Mitte segada on sees"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Automaatne reegel (<xliff:g id="ID_1">%s</xliff:g>) lülitas funktsiooni Mitte segada sisse."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Rakendus (<xliff:g id="ID_1">%s</xliff:g>) lülitas funktsiooni Mitte segada sisse."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Automaatne reegel või rakendus lülitas funktsiooni Mitte segada sisse."</string>
@@ -849,10 +853,14 @@
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Esita lugu <xliff:g id="SONG_NAME">%1$s</xliff:g> esitajalt <xliff:g id="ARTIST_NAME">%2$s</xliff:g> rakenduses <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Esita lugu <xliff:g id="SONG_NAME">%1$s</xliff:g> rakenduses <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Võta tagasi"</string>
-    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Teisaldage lähemale, et seadmes <xliff:g id="DEVICENAME">%1$s</xliff:g> esitada"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Siin esitamiseks liigutage seadmele <xliff:g id="DEVICENAME">%1$s</xliff:g> lähemale"</string>
+    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Liikuge lähemale, et seadmes <xliff:g id="DEVICENAME">%1$s</xliff:g> esitada"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Esitatakse seadmes <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Midagi läks valesti. Proovige uuesti."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Laadimine"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Passiivne, vaadake rakendust"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Ei leitud"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Juhtelement pole saadaval"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Saadaolevad seadmed heli esitamiseks."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Helitugevus"</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">"Kõlarid ja ekraanid"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kuidas ülekandmine toimib?"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Ülekanne"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Teie läheduses olevad inimesed, kellel on ühilduvad Bluetooth-seadmed, saavad kuulata teie ülekantavat meediat"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Ava <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Rakenduse <xliff:g id="APPNAME">%1$s</xliff:g> otsetee lisamiseks veenduge järgmises."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Rakendus on seadistatud"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Vähemalt üks kaart on Walletisse lisatud"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Installige kaamerarakendus"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Rakendus on seadistatud"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Vähemalt üks seade on saadaval"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pikalt puudutamise otsetee"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Tühista"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Pööra kohe ümber"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Voltige telefon parema selfi jaoks lahti"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ See ekraan lülitatakse välja"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Volditava seadme lahtivoltimine"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Volditava seadme ümberpööramine"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 4ed4bc1..38db706 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Partekatu pantaila-argazkia"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Kapturatu eduki gehiago"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Baztertu pantaila-argazkia"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Baztertu laneko profilean jasotako mezua"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Pantaila-argazkiaren aurrebista"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Goiko ertza: ehuneko <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Beheko ertza: ehuneko <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Ezkerreko ertza: ehuneko <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Eskuineko ertza: ehuneko <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Pantaila-grabagailua"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Pantaila-grabaketa prozesatzen"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pantailaren grabaketa-saioaren jakinarazpen jarraitua"</string>
@@ -423,9 +428,9 @@
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Gailu hau <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> erakundearena da.\n\nIKT saileko administratzaileak gainbegiratu eta kudeatu egin ditzake ezarpenak, enpresa-sarbidea, aplikazioak, gailuarekin erlazionatutako datuak eta gailuaren kokapen-informazioa.\n\nInformazio gehiago lortzeko, jarri IKT saileko administratzailearekin harremanetan."</string>
     <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"Baliteke <xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> erakundeak gailu honekin erlazionatutako datuak atzitu, aplikazioak kudeatu eta gailuaren ezarpenak aldatu ahal izatea.\n\nGalderarik baduzu, jarri harremanetan <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g> erakundearekin."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Gailu hau zure erakundearena da.\n\nIKT saileko administratzaileak gainbegiratu eta kudeatu egin ditzake ezarpenak, enpresa-sarbidea, aplikazioak, gailuarekin erlazionatutako datuak eta gailuaren kokapen-informazioa.\n\nInformazio gehiago lortzeko, jarri IKT saileko administratzailearekin harremanetan."</string>
-    <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Erakundeak ziurtagiri-emaile bat instalatu du gailuan. Baliteke sareko trafiko segurua gainbegiratzea edo aldatzea."</string>
-    <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Erakundeak ziurtagiri-emaile bat instalatu dizu laneko profilean. Baliteke sareko trafiko segurua gainbegiratzea edo aldatzea."</string>
-    <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Ziurtagiri-emaile bat dago instalatuta gailuan. Baliteke sareko trafiko segurua gainbegiratzea edo aldatzea."</string>
+    <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Erakundeak autoritate ziurtagiri-emaile bat instalatu du gailuan. Baliteke sareko trafiko segurua gainbegiratzea edo aldatzea."</string>
+    <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Erakundeak autoritate ziurtagiri-emaile bat instalatu dizu laneko profilean. Baliteke sareko trafiko segurua gainbegiratzea edo aldatzea."</string>
+    <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Autoritate ziurtagiri-emaile bat dago instalatuta gailuan. Baliteke sareko trafiko segurua gainbegiratzea edo aldatzea."</string>
     <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Administratzaileak sarearen erregistroak aktibatu ditu; horrela, zure gailuko trafikoa gainbegira dezake."</string>
     <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Administratzaileak sarearen erregistroak aktibatu ditu; horrela, zure laneko profileko trafikoa gainbegira dezake, baina ez zure profil pertsonalekoa."</string>
     <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Gailua <xliff:g id="VPN_APP">%1$s</xliff:g> bidez dago konektatuta Internetera. IKT saileko administratzaileak laneko aplikazioen bidez egiten dituzun sareko jarduerak (mezu elektronikoak eta arakatze-datuak barne) ikusi ahalko ditu."</string>
@@ -689,7 +694,7 @@
     <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., jokoak, bideoak edo nabigazio-aplikazioak).\n	• Fitxategi handiak deskargatu edo kargatzea.\n	• Telefonoa giro beroetan erabiltzea."</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>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wifi-konexioa desaktibatuta dago"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth bidezko konexioa desaktibatuta dago"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Ez molestatzeko modua desaktibatuta dago"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Aktibatuta dago ez molestatzeko modua"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Ez molestatzeko modua aktibatu du arau automatiko batek (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Ez molestatzeko modua aktibatu du aplikazio batek (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Ez molestatzeko modua aktibatu du arau automatiko edo aplikazio batek."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Erreproduzitu <xliff:g id="SONG_NAME">%1$s</xliff:g> <xliff:g id="APP_LABEL">%2$s</xliff:g> bidez"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Desegin"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Gertura ezazu <xliff:g id="DEVICENAME">%1$s</xliff:g> gailuan erreproduzitzeko"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Gerturatu <xliff:g id="DEVICENAME">%1$s</xliff:g> gailura bertan erreproduzitzen ari dena hemen erreproduzitzeko"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> gailuan erreproduzitzen"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Arazoren bat izan da. Saiatu berriro."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Kargatzen"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Inaktibo; egiaztatu aplikazioa"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Ez da aurkitu"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Ez dago erabilgarri kontrolatzeko aukera"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Audio-irteerarako gailu erabilgarriak."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Bolumena"</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">"Bozgorailuak eta pantailak"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Nola funtzionatzen dute iragarpenek?"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Iragarri"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Bluetooth bidezko gailu bateragarriak dituzten inguruko pertsonek iragartzen ari zaren multimedia-edukia entzun dezakete"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Ireki <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"<xliff:g id="APPNAME">%1$s</xliff:g> aplikazioa lasterbide gisa gehitzeko, ziurtatu hauek betetzen direla:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Aplikazioa konfiguratuta dago."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Diru-zorroa zerbitzuan gutxienez txartel bat gehitu da."</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Kamera-aplikazio bat instalatu da."</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Aplikazioa konfiguratuta dago."</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Gutxienez gailu bat erabilgarri dago."</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Eduki sakatuta lasterbidea"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Utzi"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Irauli"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Ireki telefonoa autoargazki hobeak ateratzeko"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Pantaila itzali egingo da"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Gailu tolesgarria zabaltzen"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Gailu tolesgarria biratzen"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index d304821..9800da9 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"هم‌رسانی نماگرفت"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"ضبط محتوای بیشتر"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"رد کردن نماگرفت"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"رد کردن پیام نمایه کاری"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"پیش‌نمایش نماگرفت"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"مرز بالا <xliff:g id="PERCENT">%1$d</xliff:g> درصد"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"مرز پایین <xliff:g id="PERCENT">%1$d</xliff:g> درصد"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"مرز سمت چپ <xliff:g id="PERCENT">%1$d</xliff:g> درصد"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"مرز سمت راست <xliff:g id="PERCENT">%1$d</xliff:g> درصد"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"ضبط‌کننده صفحه‌نمایش"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"درحال پردازش ضبط صفحه‌نمایش"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"اعلان درحال انجام برای جلسه ضبط صفحه‌نمایش"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"‏Wi-Fi خاموش است"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"بلوتوث خاموش است"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"«مزاحم نشوید» خاموش است"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"«مزاحم نشوید» روشن است"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"قانون خودکاری (<xliff:g id="ID_1">%s</xliff:g>) «مزاحم نشوید» را روشن کرد."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"برنامه‌ای (<xliff:g id="ID_1">%s</xliff:g>) «مزاحم نشوید» را روشن کرد."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"برنامه یا قانون خودکاری، «مزاحم نشوید» را روشن کرد."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> را ازطریق <xliff:g id="APP_LABEL">%2$s</xliff:g> پخش کنید"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"واگرد"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"برای پخش در <xliff:g id="DEVICENAME">%1$s</xliff:g> به دستگاه نزدیک‌تر شوید"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"برای پخش در اینجا، به <xliff:g id="DEVICENAME">%1$s</xliff:g> نزدیک‌تر شوید"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"درحال پخش در <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"مشکلی پیش آمد. دوباره امتحان کنید."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"درحال بار کردن"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"غیرفعال، برنامه را بررسی کنید"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"پیدا نشد"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"کنترل دردسترس نیست"</string>
@@ -875,6 +883,9 @@
     <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">"بلندگوها و نمایشگرها"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"همه‌فرتستی چطور کار می‌کند"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"همه‌فرستی"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"‏افرادی که در اطرافتان دستگاه‌های Bluetooth سازگار دارند می‌توانند به رسانه‌ای که همه‌فرستی می‌کنید گوش کنند"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"باز کردن <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"برای افزودن برنامه <xliff:g id="APPNAME">%1$s</xliff:g> به‌عنوان میان‌بر، مطمئن شوید"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• برنامه راه‌اندازی شده باشد"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• حداقل یک کارت به «کیف پول» اضافه شده باشد"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• برنامه دوربین نصب شده باشد"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• برنامه راه‌اندازی شده باشد"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• حداقل یک دستگاه دردسترس باشد"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"میان‌بر را لمس کنید و نگه دارید"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"لغو کردن"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"اکنون چرخانده شود"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"برای خویش‌گرفت بهتر، تلفن را باز کنید"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ این صفحه‌نمایش خاموش خواهد شد"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"دستگاه تاشو درحال باز شدن"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"دستگاه تاشو درحال چرخش به اطراف"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 6922fb0..efdc9cb 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Jaa kuvakaappaus"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Kuvaa enemmän"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Hylkää kuvakaappaus"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Hylkää työprofiiliviesti"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Kuvakaappauksen esikatselu"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Yläreuna <xliff:g id="PERCENT">%1$d</xliff:g> prosenttia"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Alareuna <xliff:g id="PERCENT">%1$d</xliff:g> prosenttia"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Vasen reuna <xliff:g id="PERCENT">%1$d</xliff:g> prosenttia"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Oikea reuna <xliff:g id="PERCENT">%1$d</xliff:g> prosenttia"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Näytön tallentaja"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Näytön tallennusta käsitellään"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pysyvä ilmoitus näytön tallentamisesta"</string>
@@ -723,7 +728,7 @@
     <string name="instant_apps_title" msgid="8942706782103036910">"<xliff:g id="APP">%1$s</xliff:g> on käynnissä"</string>
     <string name="instant_apps_message" msgid="6112428971833011754">"Sovellus avattiin ilman asennusta."</string>
     <string name="instant_apps_message_with_help" msgid="1816952263531203932">"Sovellus avattiin ilman asennusta. Katso lisätietoja napauttamalla."</string>
-    <string name="app_info" msgid="5153758994129963243">"Sovelluksen tiedot"</string>
+    <string name="app_info" msgid="5153758994129963243">"Sovellustiedot"</string>
     <string name="go_to_web" msgid="636673528981366511">"Siirry selaimeen"</string>
     <string name="mobile_data" msgid="4564407557775397216">"Mobiilidata"</string>
     <string name="mobile_data_text_format" msgid="6806501540022589786">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi on pois päältä"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth ei ole käytössä"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Älä häiritse ‑tila on pois päältä"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Älä häiritse ‑tila on käytössä"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Automaattinen sääntö otti käyttöön Älä häiritse ‑tilan (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Sovellus otti käyttöön Älä häiritse ‑tilan (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Automaattinen sääntö tai sovellus otti käyttöön Älä häiritse ‑tilan."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Soita <xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="APP_LABEL">%2$s</xliff:g>)"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Kumoa"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Siirry lähemmäs, jotta <xliff:g id="DEVICENAME">%1$s</xliff:g> voi toistaa tämän"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Siirrä <xliff:g id="DEVICENAME">%1$s</xliff:g> lähemmäs toistaaksesi täällä"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Toistetaan: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Jotain meni pieleen. Yritä uudelleen."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Latautuminen"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Epäaktiivinen, tarkista sovellus"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Ei löydy"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Ohjain ei ole käytettävissä"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Käytettävissä olevat audiolaitteet"</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Äänenvoimakkuus"</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">"Kaiuttimet ja näytöt"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Miten lähetys toimii"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Lähetys"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Lähistöllä olevat ihmiset, joilla on yhteensopiva Bluetooth-laite, voivat kuunnella lähettämääsi mediaa"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Avaa <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Jos haluat, että <xliff:g id="APPNAME">%1$s</xliff:g> lisätään pikakuvakkeeksi, varmista nämä:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Sovellus on otettu käyttöön"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Ainakin yksi kortti on lisätty Walletiin"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Asenna kamerasovellus"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Sovellus on otettu käyttöön"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ainakin yksi laite on käytettävissä"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Kosketa pikakuvaketta pitkään"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Peru"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Käännä nyt"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Saat paremman selfien, kun levität puhelimen"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Tämä näyttö sammutetaan"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Taitettava laite taitetaan"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Taitettava laite käännetään ympäri"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 36453f8..5423c57 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Partagez la capture d\'écran"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Capturer plus"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Fermer la capture d\'écran"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Ignorer le message du profil professionnel"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Aperçu de la capture d\'écran"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Limite supérieure : <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Limite inférieure : <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Limite gauche : <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Limite droite : <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Enregistreur d\'écran"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Trait. de l\'enregist. d\'écran…"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notification en cours pour une session d\'enregistrement d\'écran"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Le Wi-Fi est désactivé"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Le Bluetooth est désactivé"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Le mode Ne pas déranger est désactivé"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Mode Ne pas déranger activé"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Le mode Ne pas déranger a été activé par une règle automatique (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Le mode Ne pas déranger a été activé par une application (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Le mode Ne pas déranger a été activé par une règle automatique ou une application."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Lecture de <xliff:g id="SONG_NAME">%1$s</xliff:g> à partir de <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Annuler"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Rapprochez-vous pour faire jouer le contenu sur <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Rapprochez-vous de <xliff:g id="DEVICENAME">%1$s</xliff:g> pour lire le contenu"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Lecture sur <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Un problème est survenu. Réessayez."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Chargement en cours…"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Délai expiré, vérifiez l\'appli"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Introuvable"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"La commande n\'est pas accessible"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Appareils disponibles pour la sortie audio."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</string>
     <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">"Haut-parleurs et écrans"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Fonctionnement de la diffusion"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Diffusion"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Les personnes à proximité disposant d\'appareils Bluetooth compatibles peuvent écouter le contenu multimédia que vous diffusez"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Ouvrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Pour ajouter l\'application <xliff:g id="APPNAME">%1$s</xliff:g> en tant que raccourci, assurez-vous"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• que cette application est configurée;"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• qu\'au moins une carte a été ajoutée à Portefeuille."</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• qu\'une application de caméra est installée;"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• que cette application est configurée;"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• qu\'au moins un appareil est utilisable;"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Maintenir le doigt sur raccourci"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annuler"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Retourner maintenant"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Déplier le téléphone pour un meilleur égoportrait"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"* Cet écran va s\'éteindre"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Appareil pliable en cours de dépliage"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Appareil pliable en train d\'être retourné"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 61ac4c4..c356d73 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Partager la capture d\'écran"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Capturer plus"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Fermer la capture d\'écran"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Ignorer le message du profil professionnel"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Aperçu de la capture d\'écran"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Limite supérieure : <xliff:g id="PERCENT">%1$d</xliff:g> pour cent"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Limite inférieure : <xliff:g id="PERCENT">%1$d</xliff:g> pour cent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Limite gauche : <xliff:g id="PERCENT">%1$d</xliff:g> pour cent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Limite droite : <xliff:g id="PERCENT">%1$d</xliff:g> pour cent"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Enregistreur d\'écran"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Enregistrement de l\'écran…"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notification en cours pour une session d\'enregistrement de l\'écran"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi désactivé"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth désactivé"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Mode \"Ne pas déranger\" désactivé"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Mode \"Ne pas déranger\" activé"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Le mode \"Ne pas déranger\" a été activé par une règle automatique (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Le mode \"Ne pas déranger\" a été activé par une application (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Le mode \"Ne pas déranger\" a été activé par une règle automatique ou une application."</string>
@@ -849,10 +853,14 @@
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Mets <xliff:g id="SONG_NAME">%1$s</xliff:g> par <xliff:g id="ARTIST_NAME">%2$s</xliff:g> depuis <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Mets <xliff:g id="SONG_NAME">%1$s</xliff:g> depuis <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Annuler"</string>
-    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Rapprochez-vous pour lire sur <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Rapprochez l\'appareil pour transférer la diffusion à votre <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Lecture sur <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
+    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Rapprochez-vous de votre <xliff:g id="DEVICENAME">%1$s</xliff:g> pour y lire le contenu"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
+    <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Lecture sur <xliff:g id="DEVICENAME">%1$s</xliff:g>…"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Un problème est survenu. Réessayez."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Chargement…"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Délai expiré, vérifier l\'appli"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Introuvable"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Commande indisponible"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Appareils disponibles pour la sortie audio."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</string>
     <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">"Enceintes et écrans"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Fonctionnement des annonces"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Annonce"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Les personnes à proximité équipées d\'appareils Bluetooth compatibles peuvent écouter le contenu multimédia que vous diffusez"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"hh:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Ouvrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Pour ajouter l\'appli <xliff:g id="APPNAME">%1$s</xliff:g> comme raccourci, procédez aux vérifications suivantes"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• L\'appli est configurée"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Au moins une carte a été ajoutée à Wallet"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Installer une appli d\'appareil photo"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• L\'appli est configurée"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Au moins un appareil est disponible"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Appuyez de manière prolongée sur raccourci"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annuler"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Retourner maintenant"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Déplier le téléphone pour un meilleur selfie"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Cet écran sera désactivé"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Appareil pliable qui est déplié"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Appareil pliable qui est retourné"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 249a783..4bc5123 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Compartir captura de pantalla"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Capturar máis"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Ignorar a captura de pantalla"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Pechar a mensaxe do perfil de traballo"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Vista previa da captura de pantalla"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Bordo superior: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Bordo inferior: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Bordo esquerdo: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Bordo dereito: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Gravadora da pantalla"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Procesando gravación pantalla"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación en curso sobre unha sesión de gravación de pantalla"</string>
@@ -382,7 +387,7 @@
     <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Cando compartes, gravas ou emites aplicacións, esta aplicación ten acceso a todo o que se vexa ou se reproduza nelas. Polo tanto, debes ter coidado cos contrasinais, os detalles de pago, as mensaxes ou outra información confidencial."</string>
     <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"O teu administrador de TI bloqueou esta aplicación"</string>
     <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"A política do dispositivo desactivou a opción de capturar a pantalla"</string>
-    <string name="clear_all_notifications_text" msgid="348312370303046130">"Eliminar todas"</string>
+    <string name="clear_all_notifications_text" msgid="348312370303046130">"Eliminar todo"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Xestionar"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Historial"</string>
     <string name="notification_section_header_incoming" msgid="850925217908095197">"Notificacións novas"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"A wifi está desactivada"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"O Bluetooth está desactivado"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"O modo Non molestar está desactivado"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Modo Non molestar activado"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Unha norma automática (<xliff:g id="ID_1">%s</xliff:g>) activou o modo Non molestar."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Unha aplicación (<xliff:g id="ID_1">%s</xliff:g>) activou o modo Non molestar."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Unha aplicación ou norma automática activou o modo Non molestar."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Reproduce <xliff:g id="SONG_NAME">%1$s</xliff:g> en <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Desfacer"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Achega o dispositivo para reproducir o contido en: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Achégate ao dispositivo (<xliff:g id="DEVICENAME">%1$s</xliff:g>) para reproducir o contido neste"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Reproducindo contido noutro dispositivo (<xliff:g id="DEVICENAME">%1$s</xliff:g>)"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Produciuse un erro. Téntao de novo."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Cargando"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactivo. Comproba a app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Non se atopou"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"O control non está dispoñible"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dispositivos dispoñibles para a saída de audio."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</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">"Altofalantes e pantallas"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Como funcionan as difusións?"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Difusión"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"As persoas que estean preto de ti e que dispoñan de dispositivos Bluetooth compatibles poden escoitar o contido multimedia que difundas"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Para engadir a aplicación <xliff:g id="APPNAME">%1$s</xliff:g> como atallo, asegúrate de que se cumpra o seguinte:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• A aplicación debe estar configurada"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Ten que haber polo menos unha tarxeta engadida a Wallet"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Debes instalar a aplicación de cámara"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• A aplicación debe estar configurada"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ten que haber polo menos un dispositivo dispoñible"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Mantén premido o atallo"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Voltear agora"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Desprega o teléfono para unha autofoto mellor"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Desactivarase esta pantalla"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo pregable abríndose"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo pregable xirando"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 8959442..3075f16 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"સ્ક્રીનશૉટ શેર કરો"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"વધુ કૅપ્ચર કરો"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"સ્ક્રીનશૉટ છોડી દો"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"ઑફિસની પ્રોફાઇલનો મેસેજ છોડી દો"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"સ્ક્રીનશૉટનો પ્રીવ્યૂ"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"ઉપરની સીમા <xliff:g id="PERCENT">%1$d</xliff:g> ટકા"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"નીચેની સીમા <xliff:g id="PERCENT">%1$d</xliff:g> ટકા"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ડાબી બાજુની સીમા <xliff:g id="PERCENT">%1$d</xliff:g> ટકા"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"જમણી બાજુની સીમા <xliff:g id="PERCENT">%1$d</xliff:g> ટકા"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"સ્ક્રીન રેકોર્ડર"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"સ્ક્રીન રેકૉર્ડિંગ ચાલુ છે"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"સ્ક્રીન રેકોર્ડિંગ સત્ર માટે ચાલુ નોટિફિકેશન"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"વાઇ-ફાઇ બંધ છે"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"બ્લૂટૂથ બંધ છે"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"ખલેલ પાડશો નહીં બંધ છે"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"ખલેલ પાડશો નહીં ચાલુ છે"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ખલેલ પાડશો નહીં એક સ્વચાલિત નિયમ દ્વારા ચાલુ કરાયું હતું (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"ખલેલ પાડશો નહીં એક ઍપ્લિકેશન દ્વારા ચાલુ કરાયું હતું (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ખલેલ પાડશો નહીં એક સ્વચાલિત નિયમ અથવા ઍપ્લિકેશન દ્વારા ચાલુ કરાયું હતું."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> પર <xliff:g id="SONG_NAME">%1$s</xliff:g> ગીત ચલાવો"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"છેલ્લો ફેરફાર રદ કરો"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> પર ચલાવવા માટે વધુ નજીક ખસેડો"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"આમાં ચલાવવા માટે ડિવાઇસને <xliff:g id="DEVICENAME">%1$s</xliff:g>ની નજીક ખસેડો"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> પર ચલાવવામાં આવી રહ્યું છે"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"કંઈક ખોટું થયું. ફરી પ્રયાસ કરો."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"લોડ થઈ રહ્યું છે"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"નિષ્ક્રિય, ઍપને ચેક કરો"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"મળ્યું નથી"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"નિયંત્રણ ઉપલબ્ધ નથી"</string>
@@ -875,6 +883,9 @@
     <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">"સ્પીકર અને ડિસ્પ્લે"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"બ્રોડકાસ્ટ પ્રક્રિયાની કામ કરવાની રીત"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"બ્રોડકાસ્ટ કરો"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"સુસંગત બ્લૂટૂથ ડિવાઇસ ધરાવતા નજીકના લોકો તમે જે મીડિયા બ્રોડકાસ્ટ કરી રહ્યાં છો તે સાંભળી શકે છે"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ખોલો"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"<xliff:g id="APPNAME">%1$s</xliff:g> ઍપને શૉર્ટકટ તરીકે ઉમેરવા માટે, આ બાબતોની ખાતરી કરો"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• ઍપનું સેટઅપ કરેલું છે"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• ઓછામાં ઓછું એક કાર્ડ વૉલેટમાં ઉમેરેલું છે"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• કૅમેરા ઍપ ઇન્સ્ટૉલ કરી છે"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• ઍપનું સેટઅપ કરેલું છે"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ઓછામાં ઓછું એક ડિવાઇસ ઉપલબ્ધ છે"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"શૉર્ટકટને ટચ વડે પળભર દબાવી રાખો"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"રદ કરો"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"હમણાં જ ફ્લિપ કરો"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"બહેતર સેલ્ફી લેવા માટે ફોન ખોલો"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ આ સ્ક્રીન બંધ થઈ જશે"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ફોલ્ડ કરી શકાય એવું ડિવાઇસ અનફોલ્ડ કરવામાં આવી રહ્યું છે"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ફોલ્ડ કરી શકાય એવું ડિવાઇસ ફ્લિપ કરવામાં આવી રહ્યું છે"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index c39563e..6828e8d 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"स्क्रीनशॉट शेयर करें"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"ज़्यादा कॉन्टेंट कैप्चर करें"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"स्क्रीनशॉट को खारिज करें"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"वर्क प्रोफ़ाइल मैसेज को खारिज करें"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"स्क्रीनशॉट की झलक"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"ऊपरी किनारे से <xliff:g id="PERCENT">%1$d</xliff:g> प्रतिशत"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"निचले किनारे से <xliff:g id="PERCENT">%1$d</xliff:g> प्रतिशत"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"बाएं किनारे से <xliff:g id="PERCENT">%1$d</xliff:g> प्रतिशत"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"दाएं किनारे से <xliff:g id="PERCENT">%1$d</xliff:g> प्रतिशत"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"स्क्रीन रिकॉर्डर"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रीन रिकॉर्डिंग को प्रोसेस किया जा रहा है"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"स्क्रीन रिकॉर्ड सेशन के लिए जारी सूचना"</string>
@@ -370,11 +375,11 @@
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"इस फ़ंक्शन को उपलब्ध कराने वाली सेवा, रिकॉर्ड या कास्ट करते समय, आपकी स्क्रीन पर दिखने वाली या चलाई जाने वाली जानकारी को ऐक्सेस कर सकती है. इसमें पासवर्ड, पैसे चुकाने से जुड़ी जानकारी, फ़ोटो, मैसेज, और चलाए जाने वाले ऑडियो शामिल हैं."</string>
     <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"रिकॉर्डिंग या कास्ट करना शुरू करें?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> का इस्तेमाल करके रिकॉर्ड और कास्ट करना शुरू करें?"</string>
-    <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> को शेयर या रिकॉर्ड करने की अनुमति दें?"</string>
+    <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"क्या आपको शेयर या रिकॉर्ड करने की <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> को अनुमति देनी है?"</string>
     <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"पूरी स्क्रीन"</string>
     <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"सिर्फ़ एक ऐप्लिकेशन"</string>
     <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"शेयर, रिकॉर्ड या कास्ट करते समय, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> के पास स्क्रीन पर दिख रही हर चीज़ या डिवाइस पर चल रहे हर मीडिया का ऐक्सेस होता है. इसलिए, शेयर, रिकॉर्ड या कास्ट करते समय, पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज या किसी और संवेदनशील जानकारी को लेकर खास सावधानी बरतें."</string>
-    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"शेयर, रिकॉर्ड या कास्ट करते समय, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> के पास उस ऐप्लिकेशन पर दिख रही हर चीज़ या उस पर चल रहे हर मीडिया का ऐक्सेस होता है. इसलिए, शेयर, रिकॉर्ड या कास्ट करते समय, पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज या किसी और संवेदनशील जानकारी को लेकर खास सावधानी बरतें."</string>
+    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"शेयर, रिकॉर्ड या कास्ट करते समय, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> के पास उस ऐप्लिकेशन पर दिख रही हर चीज़ या उस पर चल रहे हर मीडिया का ऐक्सेस होता है. इसलिए, पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज या किसी और संवेदनशील जानकारी को लेकर खास सावधानी बरतें."</string>
     <string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"जारी रखें"</string>
     <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"ऐप्लिकेशन शेयर करें या उसकी रिकॉर्डिंग करें"</string>
     <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"क्या इस ऐप्लिकेशन को शेयर या रिकॉर्ड करने की अनुमति देनी है?"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"वाई-फ़ाई बंद है"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"ब्लूटूथ बंद है"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"परेशान न करें बंद है"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"\'परेशान न करें\' सुविधा चालू है"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"एक ऑटोमैटिक नियम (<xliff:g id="ID_1">%s</xliff:g>) ने परेशान न करें को चालू कर दिया था."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"एक ऐप्लिकेशन (<xliff:g id="ID_1">%s</xliff:g>) ने परेशान न करें को चालू कर दिया था."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"एक ऑटोमैटिक नियम या ऐप्लिकेशन ने परेशान न करें को चालू कर दिया था."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> पर, <xliff:g id="SONG_NAME">%1$s</xliff:g> चलाएं"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"पहले जैसा करें"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> पर मीडिया चलाने के लिए, अपने डिवाइस को उसके पास ले जाएं"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"अपने डिवाइस पर मीडिया फ़ाइल ट्रांसफ़र करने के लिए, उसे <xliff:g id="DEVICENAME">%1$s</xliff:g> के पास ले जाएं"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> पर मीडिया चल रहा है"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"कोई गड़बड़ी हुई. फिर से कोशिश करें."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"लोड हो रहा है"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"काम नहीं कर रहा, ऐप जांचें"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"कंट्रोल नहीं है"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"कंट्रोल मौजूद नहीं है"</string>
@@ -875,6 +883,9 @@
     <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">"स्पीकर और डिसप्ले"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ब्रॉडकास्ट करने की सुविधा कैसे काम करती है"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ब्रॉडकास्ट करें"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"आपके आस-पास मौजूद लोग, ब्रॉडकास्ट किए जा रहे मीडिया को सुन सकते हैं. हालांकि, इसके लिए उनके पास ऐसे ब्लूटूथ डिवाइस होने चाहिए जिन पर मीडिया चलाया जा सके"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> खोलें"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"<xliff:g id="APPNAME">%1$s</xliff:g> ऐप्लिकेशन को शॉर्टकट के तौर पर जोड़ने के लिए, पक्का करें कि"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• ऐप्लिकेशन को सेट अप किया गया है"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Wallet में कम से कम एक कार्ड जोड़ा गया है"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• कैमरा ऐप्लिकेशन इंस्टॉल किया गया है"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• ऐप्लिकेशन को सेट अप किया गया है"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• कम से कम एक डिवाइस उपलब्ध है"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"शॉर्टकट को दबाकर रखें"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"रद्द करें"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"कैमरा अभी स्विच करें"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"बेहतर सेल्फ़ी के लिए फ़ोन को अनफ़ोल्ड करें"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ यह स्क्रीन बंद हो जाएगी"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"फ़ोल्ड किया जा सकने वाला डिवाइस अनफ़ोल्ड किया जा रहा है"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"फ़ोल्ड किया जा सकने वाला डिवाइस पलटा जा रहा है"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 920869b..484e3a4 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -85,11 +85,14 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Podijeli snimku zaslona"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Snimi više"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Odbacivanje snimke zaslona"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Odbacite poruku poslovnog profila"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Pregled snimke zaslona"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Gornji rub <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Donji rub <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Lijevi rub <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Desni rub <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
+    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Snimke zaslona s poslovnog profila spremaju se u aplikaciju <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Datoteke"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Snimač zaslona"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrada snimanja zaslona"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Tekuća obavijest za sesiju snimanja zaslona"</string>
@@ -376,7 +379,7 @@
     <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"Kad dijelite, snimate ili emitirate, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup svemu što je vidljivo na vašem zaslonu ili se reproducira na vašem uređaju. Stoga pazite na zaporke, podatke o plaćanju, poruke i druge osjetljive podatke."</string>
     <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Kad dijelite, snimate ili emitirate aplikaciju, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Stoga pazite na zaporke, podatke o plaćanju, poruke i druge osjetljive podatke."</string>
     <string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Nastavi"</string>
-    <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Dijeljenje ili snimanje pomoću aplikacije"</string>
+    <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Dijeljenje ili snimanje aplikacije"</string>
     <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Želite li ovoj aplikaciji omogućiti dijeljenje ili bilježenje?"</string>
     <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Kad dijelite, snimate ili emitirate, ova aplikacija ima pristup svemu što je vidljivo na vašem zaslonu ili se reproducira na vašem uređaju. Stoga pazite na zaporke, podatke o plaćanju, poruke i druge osjetljive podatke."</string>
     <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Kad dijelite, snimate ili emitirate aplikaciju, ova aplikacija ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Stoga pazite na zaporke, podatke o plaćanju, poruke i druge osjetljive podatke."</string>
@@ -731,8 +734,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi je isključen"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth je isključen"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Način Ne uznemiravaj isključen"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Način Ne uznemiravaj uključen"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Način Ne uznemiravaj uključilo je automatsko pravilo (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Način Ne uznemiravaj uključila je aplikacija (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Način Ne uznemiravaj uključilo je automatsko pravilo ili aplikacija."</string>
@@ -850,9 +852,12 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Pustite <xliff:g id="SONG_NAME">%1$s</xliff:g> putem aplikacije <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Poništi"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Približite se radi reprodukcije na uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Približite se uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g> da biste na njemu reproducirali"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Reproducira se na uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Nešto nije u redu. Pokušajte ponovo."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Učitavanje"</string>
+    <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, provjerite aplik."</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrola nije dostupna"</string>
@@ -875,6 +880,8 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dostupni uređaji za audioizlaz."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Glasnoća"</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">"Zvučnici i zasloni"</string>
+    <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Predloženi uređaji"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kako emitiranje funkcionira"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Emitiranje"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Osobe u blizini s kompatibilnim Bluetooth uređajima mogu slušati medije koje emitirate"</string>
@@ -998,14 +1005,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Otvorite <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Da biste dodali aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g> kao prečac, provjerite sljedeće"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Aplikacija je postavljena"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Najmanje jedna kartica dodana je u Wallet"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Instalirajte aplikaciju fotoaparata"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Aplikacija je postavljena"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Dostupan je najmanje jedan uređaj"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Prečac za dodirnuti i zadržati"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Odustani"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Okreni odmah"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Otvorite telefon da biste snimili bolji selfie"</string>
@@ -1014,6 +1019,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Ovaj će se zaslon isključiti"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Rasklopljen sklopivi uređaj"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Okretanje sklopivog uređaja sa svih strana"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 77d5799..cfa0577 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Képernyőkép megosztása"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Több rögzítése"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Képernyőkép elvetése"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Munkaprofil üzenetének elvetése"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Képernyőkép előnézete"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Felső rész <xliff:g id="PERCENT">%1$d</xliff:g> százaléka"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Alsó rész <xliff:g id="PERCENT">%1$d</xliff:g> százaléka"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Bal oldali rész <xliff:g id="PERCENT">%1$d</xliff:g> százaléka"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Jobb oldali rész <xliff:g id="PERCENT">%1$d</xliff:g> százaléka"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Képernyőrögzítő"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Képernyőrögzítés feldolgozása"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Folyamatban lévő értesítés képernyőrögzítési munkamenethez"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"A Wi-Fi ki van kapcsolva"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"A Bluetooth ki van kapcsolva"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"A „Ne zavarjanak” mód ki van kapcsolva"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Ne zavarjanak mód: bekapcsolva"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Az egyik automatikus szabály (<xliff:g id="ID_1">%s</xliff:g>) bekapcsolta a „Ne zavarjanak” módot."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Az egyik alkalmazás (<xliff:g id="ID_1">%s</xliff:g>) bekapcsolta a „Ne zavarjanak” módot."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Az egyik alkalmazás vagy automatikus szabály bekapcsolta a „Ne zavarjanak” módot."</string>
@@ -849,10 +853,14 @@
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> <xliff:g id="SONG_NAME">%1$s</xliff:g> című számának lejátszása innen: <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> lejátszása innen: <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Visszavonás"</string>
-    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Menjen közelebb a következőn való lejátszáshoz: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Menjen közelebb a(z) <xliff:g id="DEVICENAME">%1$s</xliff:g> eszközhöz, hogy itt játszhassa le a tartalmat"</string>
+    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Menjen közelebb, ha itt szeretné lejátszani: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Lejátszás folyamatban a(z) <xliff:g id="DEVICENAME">%1$s</xliff:g> eszközön"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Hiba történt. Próbálkozzon újra."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Betöltés…"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Inaktív, ellenőrizze az appot"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nem található"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Nem hozzáférhető vezérlő"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Rendelkezésre álló eszközök a hangkimenethez."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Hangerő"</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">"Hangfalak és kijelzők"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"A közvetítés működése"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Közvetítés"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"A közelben tartózkodó, kompatibilis Bluetooth-eszközzel rendelkező személyek meghallgathatják az Ön közvetített médiatartalmait"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"ó:pp"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"óó:pp"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"A(z) <xliff:g id="APPNAME">%1$s</xliff:g> megnyitása"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Ha szeretné felvenni a(z) <xliff:g id="APPNAME">%1$s</xliff:g> alkalmazást parancsikonként, gondoskodjon a következőkről:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Az alkalmazás be van állítva"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Legalább egy kártya hozzá lett adva a Wallethez"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Kameraalkalmazás telepítése"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Az alkalmazás be van állítva"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Legalább egy eszköz rendelkezésre áll"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Tartsa nyomva a parancsikont"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Mégse"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Átfordítás most"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Hajtsa ki a telefont jobb szelfi készítéséhez"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ A képernyő kikapcsol"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Összehajtható eszköz kihajtása"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Összehajtható eszköz körbeforgatása"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 6c770d3..8f7ecf6 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Ուղարկել սքրինշոթ"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Մեծացնել սքրինշոթի տարածքը"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Փակել սքրինշոթը"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Փակել աշխատանքային պրոֆիլի հաղորդագրությունը"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Սքրինշոթի նախադիտում"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Վերևի եզրագիծը՝ <xliff:g id="PERCENT">%1$d</xliff:g> տոկոս"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Ներքևի սահմանագիծը՝ <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Ձախ կողմի սահմանագիծը՝ <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Աջ կողմի սահմանագիծը՝ <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Էկրանի տեսագրիչ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Էկրանի տեսագրության մշակում"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Էկրանի տեսագրման աշխատաշրջանի ընթացիկ ծանուցում"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi-ն անջատված է"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth-ն անջատված է"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Չանհանգստացնելու ռեժիմն անջատված է"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"«Չանհանգստացնել» ռեժիմն ակտիվ է"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Չանհանգստացնել գործառույթը միացված է ավտոմատ կանոնի կողմից (<xliff:g id="ID_1">%s</xliff:g>):"</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Չանհանգստացնել գործառույթը միացված է հավելվածի կողմից (<xliff:g id="ID_1">%s</xliff:g>):"</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Չանհանգստացնել գործառույթը միացված է ավտոմատ կանոնի կամ հավելվածի կողմից:"</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Նվագարկել <xliff:g id="SONG_NAME">%1$s</xliff:g> երգը <xliff:g id="APP_LABEL">%2$s</xliff:g> հավելվածից"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Հետարկել"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Ավելի մոտ եկեք՝ <xliff:g id="DEVICENAME">%1$s</xliff:g> սարքում նվագարկելու համար"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Ավելի մոտեցեք «<xliff:g id="DEVICENAME">%1$s</xliff:g>» սարքին՝ նվագարկումը սկսելու համար"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Նվագարկվում է «<xliff:g id="DEVICENAME">%1$s</xliff:g>» սարքում"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Սխալ առաջացավ։ Նորից փորձեք։"</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Բեռնվում է"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Ակտիվ չէ, ստուգեք հավելվածը"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Չի գտնվել"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Կառավարման տարրը հասանելի չէ"</string>
@@ -875,6 +883,9 @@
     <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">"Բարձրախոսներ և էկրաններ"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Ինչպես է աշխատում հեռարձակումը"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Հեռարձակում"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Ձեր մոտակայքում գտնվող՝ համատեղելի Bluetooth սարքերով մարդիկ կարող են լսել մեդիա ֆայլերը, որոնք դուք հեռարձակում եք։"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Բացել <xliff:g id="APPNAME">%1$s</xliff:g> հավելվածը"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"<xliff:g id="APPNAME">%1$s</xliff:g> հավելվածի դյուրանցումն ավելացնելու համար համոզվեք, որ՝"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Հավելվածը կարգավորված է"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Առնվազն մեկ քարտ ավելացված է Wallet-ում"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• «Տեսախցիկ» հավելվածը տեղադրված է"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Հավելվածը կարգավորված է"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Հասանելի է առնվազն մեկ սարք"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Հպեք դյուրանցմանը և պահեք"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Չեղարկել"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Շրջել հիմա"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Բացեք հեռախոսի փեղկը՝ ավելի լավ սելֆի անելու համար"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Այս էկրանը կանջատվի"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Ծալովի սարք՝ բացված վիճակում"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Ծալովի սարք՝ շրջված վիճակում"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 3bbcc82..a427a2c 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Bagikan screenshot"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Ambil lebih banyak"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Menutup screenshot"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Tutup pesan profil kerja"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Pratinjau screenshot"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Batas atas <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Batas bawah <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Batas kiri <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Batas kanan <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Perekam Layar"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Memproses perekaman layar"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notifikasi yang sedang berjalan untuk sesi rekaman layar"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi nonaktif"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth nonaktif"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Fitur Jangan Ganggu nonaktif"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Mode Jangan Ganggu aktif"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Mode Jangan Ganggu diaktifkan oleh aturan otomatis (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Mode Jangan Ganggu diaktifkan oleh aplikasi (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Mode Jangan Ganggu diaktifkan oleh aturan otomatis atau aplikasi."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Putar <xliff:g id="SONG_NAME">%1$s</xliff:g> dari <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Urungkan"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Dekatkan untuk memutar di <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Dekatkan ke <xliff:g id="DEVICENAME">%1$s</xliff:g> untuk memutar di sini"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Diputar di <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Terjadi error. Coba lagi."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Memuat"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Nonaktif, periksa aplikasi"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Tidak ditemukan"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrol tidak tersedia"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Perangkat yang tersedia untuk output audio."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</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">"Speaker &amp; Layar"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cara kerja siaran"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Siaran"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Orang di dekat Anda dengan perangkat Bluetooth yang kompatibel dapat mendengarkan media yang sedang Anda siarkan"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Buka <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Untuk menambahkan aplikasi <xliff:g id="APPNAME">%1$s</xliff:g> sebagai pintasan, pastikan"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Aplikasi disiapkan"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Minimal satu kartu telah ditambahkan ke Wallet"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Menginstal aplikasi kamera"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Aplikasi disiapkan"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Tersedia minimal satu perangkat"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Sentuh lama pintasan"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Batal"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Balik sekarang"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Bentangkan ponsel untuk selfie yang lebih baik"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Layar ini akan dinonaktifkan"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Perangkat foldable sedang dibentangkan"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Perangkat foldable sedang dibalik"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index a42f42e..c12fb48 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Deila skjámynd"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Mynda meira"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Loka skjámynd"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Hunsa skilaboð vinnusniðs"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Forskoðun skjámyndar"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Efri mörk <xliff:g id="PERCENT">%1$d</xliff:g> prósent"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Neðri mörk <xliff:g id="PERCENT">%1$d</xliff:g> prósent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Vinstri mörk <xliff:g id="PERCENT">%1$d</xliff:g> prósent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Hægri mörk <xliff:g id="PERCENT">%1$d</xliff:g> prósent"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Skjáupptaka"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Vinnur úr skjáupptöku"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Áframhaldandi tilkynning fyrir skjáupptökulotu"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Slökkt á Wi-Fi"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Slökkt á Bluetooth"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Slökkt á „Ónáðið ekki“"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Kveikt er á „Ónáðið ekki“"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Sjálfvirk regla kveikti á „Ónáðið ekki“ (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Forrit kveikti á „Ónáðið ekki“ (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Sjálfvirk regla eða forrit kveikti á „Ónáðið ekki“"</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Spila <xliff:g id="SONG_NAME">%1$s</xliff:g> í <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Afturkalla"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Færðu nær til að spila í <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Færðu tækið nær <xliff:g id="DEVICENAME">%1$s</xliff:g> til að spila hér"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Í spilun í <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Eitthvað fór úrskeiðis. Reyndu aftur."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Hleður"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Óvirkt, athugaðu forrit"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Fannst ekki"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Stýring er ekki tiltæk"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Tæki í boði fyrir hljóðúttak."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Hljóðstyrkur"</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">"Hátalarar og skjáir"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Svona virkar útsending"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Útsending"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Fólk nálægt þér með samhæf Bluetooth-tæki getur hlustað á efnið sem þú sendir út"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"k:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Opna <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Til að bæta forritinu <xliff:g id="APPNAME">%1$s</xliff:g> við sem flýtileið skaltu ganga úr skugga um að"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Forritið er uppsett"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Að minnsta kosti einu korti var bætt við Veski"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Setja upp myndavélarforrit"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Forritið er uppsett"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Að minnsta kosti eitt tæki er tiltækt"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Haltu flýtilyklinum inni"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Hætta við"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Snúa núna"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Opnaðu símann til að taka betri sjálfsmynd"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Slökkt verður á þessum skjá"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Samanbrjótanlegt tæki opnað"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Samanbrjótanlegu tæki snúið við"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 8e0efa8..5c52bc1 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Condividi screenshot"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Acquisisci di più"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Ignora screenshot"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Chiudi il messaggio relativo al profilo di lavoro"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Anteprima screenshot"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Limite superiore, <xliff:g id="PERCENT">%1$d</xliff:g> percento"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Limite inferiore, <xliff:g id="PERCENT">%1$d</xliff:g> percento"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Limite sinistro, <xliff:g id="PERCENT">%1$d</xliff:g> percento"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Limite destro, <xliff:g id="PERCENT">%1$d</xliff:g> percento"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Registrazione dello schermo"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Elaboraz. registraz. schermo"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notifica costante per una sessione di registrazione dello schermo"</string>
@@ -370,7 +375,7 @@
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Il servizio che offre questa funzione avrà accesso a tutte le informazioni visibili sul tuo schermo o riprodotte dal tuo dispositivo durante la registrazione o la trasmissione. Sono incluse informazioni quali password, dettagli sui pagamenti, foto, messaggi e audio riprodotto."</string>
     <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Vuoi avviare la registrazione o la trasmissione?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"Vuoi avviare la registrazione o la trasmissione con <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
-    <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"Consenti a <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> di condividere o registrare?"</string>
+    <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"Consentire a <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> di condividere o registrare?"</string>
     <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"Schermo intero"</string>
     <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"Una sola app"</string>
     <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"Quando condividi, registri o trasmetti, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ha accesso a qualsiasi elemento visibile sul tuo schermo o in riproduzione sul tuo dispositivo. Presta quindi attenzione a password, dati di pagamento, messaggi o altre informazioni sensibili."</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi disattivato"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth non attivo"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Funzione Non disturbare disattivata"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Funzionalità Non disturbare attiva"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"La funzione Non disturbare è stata attivata da una regola automatica (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"La funzione Non disturbare è stata attivata da un\'app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"La funzione Non disturbare è stata attivata da una regola automatica o da un\'app."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Riproduci <xliff:g id="SONG_NAME">%1$s</xliff:g> da <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Annulla"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Avvicinati per riprodurre su <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Avvicinati a <xliff:g id="DEVICENAME">%1$s</xliff:g> per riprodurre i contenuti qui"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"In riproduzione su <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Si è verificato un errore. Riprova."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Caricamento in corso…"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Inattivo, controlla l\'app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Controllo non trovato"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Il controllo non è disponibile"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dispositivi disponibili per l\'uscita audio."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</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">"Speaker e display"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Come funziona la trasmissione"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Annuncio"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Le persone vicine a te che hanno dispositivi Bluetooth compatibili possono ascoltare i contenuti multimediali che stai trasmettendo"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Apri <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Per aggiungere l\'app <xliff:g id="APPNAME">%1$s</xliff:g> come scorciatoia, assicurati che:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• L\'app sia configurata"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Sia stata aggiunta almeno una carta a Wallet"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Sia installata un\'app fotocamera"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• L\'app sia configurata"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ci sia almeno un dispositivo disponibile"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Tocca scorciatoia/tieni premuto"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annulla"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Gira ora"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Apri il telefono per un selfie migliore"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Questo schermo verrà disattivato"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo pieghevole che viene aperto"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo pieghevole che viene capovolto"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 5f74a57..de95f2e 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -85,11 +85,14 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"שיתוף של צילום מסך"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"צילום תוכן נוסף"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"סגירת צילום מסך"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"סגירת ההודעה של פרופיל העבודה"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"תצוגה מקדימה של צילום מסך"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"<xliff:g id="PERCENT">%1$d</xliff:g> אחוז מהשוליים העליונים"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"<xliff:g id="PERCENT">%1$d</xliff:g> אחוז מהשוליים התחתונים"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"<xliff:g id="PERCENT">%1$d</xliff:g> אחוז מהשוליים השמאליים"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"<xliff:g id="PERCENT">%1$d</xliff:g> אחוז מהשוליים הימניים"</string>
+    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"צילומי מסך בפרופיל העבודה נשמרים באפליקציה <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"קבצים"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"מקליט המסך"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"מתבצע עיבוד של הקלטת מסך"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"התראה מתמשכת לסשן הקלטת מסך"</string>
@@ -97,8 +100,8 @@
     <string name="screenrecord_description" msgid="1123231719680353736">"‏בזמן ההקלטה, מערכת Android יכולה לתעד מידע רגיש שגלוי במסך או מופעל במכשיר שלך. מידע זה כולל סיסמאות, פרטי תשלום, תמונות, הודעות ואודיו."</string>
     <string name="screenrecord_option_entire_screen" msgid="1732437834603426934">"הקלטה של כל המסך"</string>
     <string name="screenrecord_option_single_app" msgid="5954863081500035825">"הקלטה של אפליקציה אחת"</string>
-    <string name="screenrecord_warning_entire_screen" msgid="8141407178104195610">"‏בזמן ההקלטה, תהיה ל-Android גישה לכל הפרטים שגלויים במסך שלך או מופעלים מהמכשיר שלך. כדאי להיזהר עם סיסמאות, פרטי תשלום, הודעות או מידע רגיש אחר."</string>
-    <string name="screenrecord_warning_single_app" msgid="7760723997065948283">"‏בזמן הקלטה של אפליקציה, תהיה ל-Android גישה לכל מה שגלוי באפליקציה או מופעל מהאפליקציה. כדאי להיזהר עם סיסמאות, פרטי תשלום, הודעות או מידע רגיש אחר."</string>
+    <string name="screenrecord_warning_entire_screen" msgid="8141407178104195610">"‏בזמן ההקלטה, תהיה ל-Android גישה לכל הפרטים שגלויים במסך שלך או מופעלים מהמכשיר שלך. חשוב להיזהר עם סיסמאות, פרטי תשלום, הודעות או מידע רגיש אחר."</string>
+    <string name="screenrecord_warning_single_app" msgid="7760723997065948283">"‏בזמן הקלטה של אפליקציה, תהיה ל-Android גישה לכל מה שגלוי באפליקציה או מופעל מהאפליקציה. חשוב להיזהר עם סיסמאות, פרטי תשלום, הודעות או מידע רגיש אחר."</string>
     <string name="screenrecord_start_recording" msgid="348286842544768740">"התחלת ההקלטה"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"הקלטת אודיו"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"אודיו מהמכשיר"</string>
@@ -373,8 +376,8 @@
     <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"לאפשר לאפליקציה <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> לשתף או להקליט?"</string>
     <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"כל המסך"</string>
     <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"אפליקציה אחת"</string>
-    <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"‏בזמן שיתוף, הקלטה או העברה (cast) תהיה ל-<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> גישה לכל הפרטים שגלויים במסך שלך או מופעלים מהמכשיר שלך. כדאי להיזהר עם סיסמאות, פרטי תשלום, הודעות או מידע רגיש אחר."</string>
-    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"‏בזמן שיתוף, הקלטה או העברה (cast) של אפליקציה, תהיה ל-<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> גישה לכל מה שגלוי באפליקציה או מופעל מהאפליקציה. כדאי להיזהר עם סיסמאות, פרטי תשלום, הודעות או מידע רגיש אחר."</string>
+    <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"‏בזמן שיתוף, הקלטה או העברה (cast) תהיה ל-<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> גישה לכל הפרטים שגלויים במסך שלך או מופעלים מהמכשיר שלך. חשוב להיזהר עם סיסמאות, פרטי תשלום, הודעות או מידע רגיש אחר."</string>
+    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"‏בזמן שיתוף, הקלטה או העברה (cast) של אפליקציה, תהיה ל-<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> גישה לכל מה שגלוי באפליקציה או מופעל מהאפליקציה. חשוב להיזהר עם סיסמאות, פרטי תשלום, הודעות או מידע רגיש אחר."</string>
     <string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"המשך"</string>
     <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"שיתוף או הקלטה של אפליקציה"</string>
     <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"לאפשר לאפליקציה הזו לשתף או להקליט?"</string>
@@ -731,8 +734,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"‏Wi-Fi כבוי"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"‏Bluetooth כבוי"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"מצב \'נא לא להפריע\' כבוי"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"מצב \'נא לא להפריע\' מופעל"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"מצב \'נא לא להפריע\' הופעל על ידי כלל אוטומטי (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"מצב \'נא לא להפריע\' הופעל על ידי אפליקציה (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"מצב \'נא לא להפריע\' הופעל על ידי אפליקציה או על ידי כלל אוטומטי."</string>
@@ -849,10 +851,13 @@
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"הפעלת <xliff:g id="SONG_NAME">%1$s</xliff:g> של <xliff:g id="ARTIST_NAME">%2$s</xliff:g> מ-<xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"הפעלת <xliff:g id="SONG_NAME">%1$s</xliff:g> מ-<xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"ביטול"</string>
-    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"צריך להתקרב כדי להפעיל מוזיקה במכשיר <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"צריך להתקרב אל <xliff:g id="DEVICENAME">%1$s</xliff:g> כדי להפעיל כאן"</string>
+    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"צריך להתקרב כדי להפעיל מדיה במכשיר <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"פועלת ב-<xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"משהו השתבש. יש לנסות שוב."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"בטעינה"</string>
+    <string name="media_ttt_default_device_type" msgid="4457646436153370169">"טאבלט"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"לא פעיל, יש לבדוק את האפליקציה"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"לא נמצא"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"הפקד לא זמין"</string>
@@ -875,6 +880,8 @@
     <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">"רמקולים ומסכים"</string>
+    <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"הצעות למכשירים"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"הסבר על שידורים"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"שידור"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"‏אנשים בקרבת מקום עם מכשירי Bluetooth תואמים יכולים להאזין למדיה שמשודרת על ידך"</string>
@@ -998,24 +1005,22 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"פתיחת <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"כדי להוסיף את האפליקציה <xliff:g id="APPNAME">%1$s</xliff:g> כקיצור דרך, צריך לוודא"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• האפליקציה מוגדרת"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"‏• לפחות כרטיס אחד נוסף ל-Wallet"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• התקנה של אפליקציית מצלמה"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• האפליקציה מוגדרת"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• יש לפחות מכשיר אחד זמין"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"מקש קיצור ללחיצה ארוכה"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ביטול"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"הפכת את המכשיר"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"כדי לצלם תמונת סלפי טובה יותר, פותחים את הטלפון"</string>
     <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"להפוך למסך הקדמי כדי לצלם תמונת סלפי טובה יותר?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"במצלמה האחורית אפשר לצלם תמונה רחבה יותר ברזולוציה גבוהה יותר."</string>
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ המסך יכבה"</b></string>
-    <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
+    <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"מכשיר מתקפל עובר למצב לא מקופל"</string>
+    <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"מכשיר מתקפל עובר למצב מהופך"</string>
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
     <skip />
-    <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
-    <skip />
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 485161f..3d4551c 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"スクリーンショットを共有"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"キャプチャ範囲を拡大"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"スクリーンショットを閉じます"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"仕事用プロファイルのメッセージを閉じます"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"スクリーンショットのプレビュー"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"上部の境界線 <xliff:g id="PERCENT">%1$d</xliff:g> パーセント"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"下部の境界線 <xliff:g id="PERCENT">%1$d</xliff:g> パーセント"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"左の境界線 <xliff:g id="PERCENT">%1$d</xliff:g> パーセント"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"右の境界線 <xliff:g id="PERCENT">%1$d</xliff:g> パーセント"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"スクリーン レコーダー"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"画面の録画を処理しています"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"画面の録画セッション中の通知"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi は OFF です"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth は OFF です"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"サイレント モードは OFF です"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"サイレント モード ON"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"サイレント モードが自動ルール(<xliff:g id="ID_1">%s</xliff:g>)によって ON になりました。"</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"サイレント モードがアプリ(<xliff:g id="ID_1">%s</xliff:g>)によって ON になりました。"</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"サイレント モードが自動ルールまたはアプリによって ON になりました。"</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> を <xliff:g id="APP_LABEL">%2$s</xliff:g> で再生"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"元に戻す"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>で再生するにはもっと近づけてください"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ここで再生するには<xliff:g id="DEVICENAME">%1$s</xliff:g>に近づいてください"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>で再生しています"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"エラーが発生しました。もう一度お試しください。"</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"読み込んでいます"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"無効: アプリをご確認ください"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"見つかりませんでした"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"コントロールを使用できません"</string>
@@ -875,6 +883,9 @@
     <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">"スピーカーとディスプレイ"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ブロードキャストの仕組み"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ブロードキャスト"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Bluetooth 対応デバイスを持っている付近のユーザーは、あなたがブロードキャストしているメディアを聴けます"</string>
@@ -998,13 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> を開く"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"<xliff:g id="APPNAME">%1$s</xliff:g> アプリをショートカットとして追加するための手順"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• アプリが設定されている"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• ウォーレットに追加されているカードが 1 枚以上ある"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• カメラアプリをインストールする"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• アプリが設定されている"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• 利用できるデバイスが 1 台以上ある"</string>
-    <string name="keyguard_affordance_press_too_short" msgid="2687995216454987952">"有効にするには長押ししてください"</string>
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ショートカットの長押しが必要です"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"キャンセル"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"切り替えましょう"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"高画質で撮るにはスマートフォンを開いてください"</string>
@@ -1013,5 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱この画面は OFF になります"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"折りたたみ式デバイスが広げられている"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"折りたたみ式デバイスがひっくり返されている"</string>
-    <string name="stylus_battery_low" msgid="7134370101603167096">"タッチペンのバッテリー残量が少なくなっています"</string>
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index f9e9b13..61280d3 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -85,11 +85,14 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"ეკრანის ანაბეჭდის გაზიარება"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"მეტის აღბეჭდვა"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ეკრანის ანაბეჭდის დახურვა"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"თქვენი სამსახურის პროფილის შეტყობინების უარყოფა"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ეკრანის ანაბეჭდის გადახედვა"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"ზედა ზღვარი: <xliff:g id="PERCENT">%1$d</xliff:g> პროცენტი"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"ქვედა ზღვარი: <xliff:g id="PERCENT">%1$d</xliff:g> პროცენტი"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"მარცხენა ზღვარი: <xliff:g id="PERCENT">%1$d</xliff:g> პროცენტი"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"მარჯვენა ზღვარი: <xliff:g id="PERCENT">%1$d</xliff:g> პროცენტი"</string>
+    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"სამუშაო ეკრანის ანაბეჭდები ინახება <xliff:g id="APP">%1$s</xliff:g> აპში"</string>
+    <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ფაილები"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"ეკრანის ჩამწერი"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ეკრანის ჩანაწერი მუშავდება"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"უწყვეტი შეტყობინება ეკრანის ჩაწერის სესიისთვის"</string>
@@ -97,7 +100,7 @@
     <string name="screenrecord_description" msgid="1123231719680353736">"ჩაწერის განმავლობაში Android სისტემას შეუძლია აღბეჭდოს ნებისმიერი სენსიტიური ინფორმაცია, რომელიც თქვენს ეკრანზე გამოჩნდება ან თქვენს მოწყობილობაზე დაიკვრება. აღნიშნული მოიცავს პაროლებს, გადახდის დეტალებს, ფოტოებს, შეტყობინებებსა და აუდიოს."</string>
     <string name="screenrecord_option_entire_screen" msgid="1732437834603426934">"მთელი ეკრანის ჩაწერა"</string>
     <string name="screenrecord_option_single_app" msgid="5954863081500035825">"ერთი აპის ჩაწერა"</string>
-    <string name="screenrecord_warning_entire_screen" msgid="8141407178104195610">"სანამ აპის ჩაწერას ახორციელებთ, Android-ს აქვს წვდომა ყველაფერზე, რაც ჩანს თქვენს ეკრანზე ან უკრავს თქვენი მოწყობილობის მეშვეობით. ამიტომ იყავით ფრთხილად პაროლებთან, გადახდის დეტალებთან, შეტყობინებებთან ან სხვა მგრძნობიარე ინფორმაციასთან."</string>
+    <string name="screenrecord_warning_entire_screen" msgid="8141407178104195610">"ჩაწერის განხორციელებისას Android-ს აქვს წვდომა ყველაფერზე, რაც თქვენს ეკრანზე ჩანს ან უკრავს თქვენი მოწყობილობის მეშვეობით. შესაბამისად, გამოიჩინეთ სიფრთხილე პაროლებთან, გადახდის დეტალებთან, შეტყობინებებთან თუ სხვა მგრძნობიარე ინფორმაციასთან დაკავშირებით."</string>
     <string name="screenrecord_warning_single_app" msgid="7760723997065948283">"სანამ აპის ჩაწერას ახორციელებთ, Android-ს აქვს წვდომა ყველაფერზე, რაც ჩანს აპში ან ითამაშეთ. ამიტომ იყავით ფრთხილად პაროლებთან, გადახდის დეტალებთან, შეტყობინებებთან ან სხვა მგრძნობიარე ინფორმაციასთან"</string>
     <string name="screenrecord_start_recording" msgid="348286842544768740">"ჩაწერის დაწყება"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"აუდიოს ჩაწერა"</string>
@@ -370,11 +373,11 @@
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"ამ ფუნქციის მომწოდებელ სერვისს ექნება წვდომა ყველა ინფორმაციაზე, რომელიც თქვენს ეკრანზე გამოჩნდება ან თქვენს მოწყობილობაზე დაიკვრება ჩაწერის ან ტრანსლირების განმავლობაში. აღნიშნული მოიცავს ისეთ ინფორმაციას, როგორიც არის პაროლები, გადახდის დეტალები, ფოტოები, შეტყობინებები და თქვენ მიერ დაკრული აუდიო."</string>
     <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"დაიწყოს ჩაწერა ან ტრანსლირება?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"დაიწყოს ჩაწერა ან ტრანსლირება <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>-ით?"</string>
-    <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"გსურთ დართოთ ნება <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> გაზიარების ან ჩაწერისთვის?"</string>
+    <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"გსურთ, დართოთ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>-ს გაზიარების ან ჩაწერის ნება?"</string>
     <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"მთელი ეკრანი"</string>
     <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"ერთი აპი"</string>
     <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"როდესაც თქვენ აზიარებთ, ჩაწერთ ან ტრანსლირებთ, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> აქვს წვდომა ყველაფერზე, რაც ჩანს თქვენს ეკრანზე ან უკრავს თქვენს მოწყობილობაზე. ამიტომ იყავით ფრთხილად პაროლებთან, გადახდის დეტალებთან, შეტყობინებებთან ან სხვა მგრძნობიარე ინფორმაციასთან."</string>
-    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"აპის გაზიარებისას, ჩაწერისას ან ტრანსლირებისას <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> აქვს წვდომა აქვს ყველაფერზე, რაც ჩანს აპში ან ითამაშეთ. ამიტომ იყავით ფრთხილად პაროლებთან, გადახდის დეტალებთან, შეტყობინებებთან ან სხვა მგრძნობიარე ინფორმაციასთან."</string>
+    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"აპის გაზიარებისას, ჩაწერისას ან ტრანსლირებისას <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>-ს აქვს წვდომა ყველაფერზე, რაც ამ აპში ჩანს და მასშია გაშვებული. შესაბამისად, გამოიჩინეთ სიფრთხილე პაროლებთან, გადახდის დეტალებთან, შეტყობინებებთან თუ სხვა მგრძნობიარე ინფორმაციასთან დაკავშირებით."</string>
     <string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"გაგრძელება"</string>
     <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"გააზიარეთ ან ჩაწერეთ აპი"</string>
     <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"გსურთ ამ აპისთვის გაზიარების ან ჩაწერის უფლების მიცემა?"</string>
@@ -731,8 +734,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi გამორთულია"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth გამორთულია"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"„არ შემაწუხოთ“ რეჟიმი გამორთულია"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"„არ შემაწუხოთ“ ჩართულია"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"„არ შემაწუხოთ“ ჩაირთო ავტომატური წესის მიხედვით (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"„არ შემაწუხოთ“ ჩაირთო აპის მიერ (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"„არ შემაწუხოთ“ ჩაირთო ავტომატური წესის მიხედვით ან აპის მიერ."</string>
@@ -850,9 +852,12 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"დაუკარით <xliff:g id="SONG_NAME">%1$s</xliff:g> <xliff:g id="APP_LABEL">%2$s</xliff:g>-დან"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"მოქმედების გაუქმება"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"მიიტანეთ უფრო ახლოს, რომ დაუკრათ <xliff:g id="DEVICENAME">%1$s</xliff:g>-ზე"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"მიუახლოვდით <xliff:g id="DEVICENAME">%1$s</xliff:g>-ს მისი მეშვეობით დასაკრავად"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"მიმდინარეობს დაკვრა <xliff:g id="DEVICENAME">%1$s</xliff:g>-ზე"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"რაღაც შეცდომა მოხდა. ცადეთ ხელახლა."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"იტვირთება"</string>
+    <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ტაბლეტი"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"არააქტიურია, გადაამოწმეთ აპი"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"ვერ მოიძებნა"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"კონტროლი მიუწვდომელია"</string>
@@ -875,6 +880,8 @@
     <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">"დინამიკები და დისპლეები"</string>
+    <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"შემოთავაზებული მოწყობილობები"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ტრანსლირების მუშაობის პრინციპი"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ტრანსლაცია"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"თქვენთან ახლოს მყოფ ხალხს თავსებადი Bluetooth მოწყობილობით შეუძლიათ თქვენ მიერ ტრანსლირებული მედიის მოსმენა"</string>
@@ -998,14 +1005,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"სთ:წთ"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"სთ:წთ"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> აპის გახსნა"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"<xliff:g id="APPNAME">%1$s</xliff:g> აპი რომ მალსახმობის სახით დაამატოთ, დარწმუნდით, რომ"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• აპი დაყენებულია"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• საფულეში დამატებულია მინიმუმ ერთი ბარათი"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• დააინსტალირეთ კამერის აპი"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• აპი დაყენებულია"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ხელმისაწვდომია მინიმუმ ერთი მოწყობილობა"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"შეხების დაamp; მოცდის მალსახმობი"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"გაუქმება"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"გადაატრიალეთ ახლა"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"გაშალეთ ტელეფონი უკეთესი სელფისთვის"</string>
@@ -1014,6 +1019,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ეს ეკრანი გამოირთვება"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"დასაკეცი მოწყობილობა იხსნება"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"დასაკეცი მოწყობილობა ტრიალებს"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 8619a95..1e96422 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Скриншотты бөлісу"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Тағы суретке түсіру"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Скриншотты жабу"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Жұмыс профилі хабарын жабу"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Скриншотты алдын ала көру"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Жоғарғы шектік сызық: <xliff:g id="PERCENT">%1$d</xliff:g> пайыз"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Төменгі шектік сызық: <xliff:g id="PERCENT">%1$d</xliff:g> пайыз"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Сол жақ шектік сызық: <xliff:g id="PERCENT">%1$d</xliff:g> пайыз"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Оң жақ шектік сызық: <xliff:g id="PERCENT">%1$d</xliff:g> пайыз"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Экран жазғыш"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Экран жазғыш бейнесін өңдеу"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Экранды бейнеге жазудың ағымдағы хабарландыруы"</string>
@@ -301,16 +306,16 @@
     <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"Микрофон бөгелген"</string>
     <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"Камера бөгелген"</string>
     <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_title" msgid="195236134743281973">"Микрофон мен камера бөгелген"</string>
-    <string name="sensor_privacy_start_use_mic_blocked_dialog_content" msgid="2138318880682877747">"Бөгеуді алу үшін құрылғыдағы құпиялылық ауыстырғышын микрофонға жылжытыңыз, оның қалпы микрофонды пайдалануға мүмкіндік беруі тиіс. Құрылғыдағы құпиялылық ауыстырғышының орналасқан жерін құрылғы нұсқаулығынан қараңыз."</string>
-    <string name="sensor_privacy_start_use_camera_blocked_dialog_content" msgid="7216015168047965948">"Бөгеуді алу үшін құрылғыдағы құпиялылық ауыстырғышын камераға жылжытыңыз, оның қалпы камераны пайдалануға мүмкіндік беруі тиіс. Құрылғыдағы құпиялылық ауыстырғышының орналасқан жерін құрылғы нұсқаулығынан қараңыз."</string>
-    <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_content" msgid="3960837827570483762">"Оның бөгеуін алу үшін құрылғыдағы құпиялылық ауыстырғышын ашық қалыпқа жылжытып, пайдалану мүмкіндігін қамтамасыз етіңіз. Құрылғыдағы құпиялылық ауыстырғышының орналасқан жерін құрылғы нұсқаулығынан қараңыз."</string>
+    <string name="sensor_privacy_start_use_mic_blocked_dialog_content" msgid="2138318880682877747">"Бөгеуді алу үшін құрылғыдағы құпиялық ауыстырғышын микрофонға жылжытыңыз, оның қалпы микрофонды пайдалануға мүмкіндік беруі тиіс. Құрылғыдағы құпиялық ауыстырғышының орналасқан жерін құрылғы нұсқаулығынан қараңыз."</string>
+    <string name="sensor_privacy_start_use_camera_blocked_dialog_content" msgid="7216015168047965948">"Бөгеуді алу үшін құрылғыдағы құпиялық ауыстырғышын камераға жылжытыңыз, оның қалпы камераны пайдалануға мүмкіндік беруі тиіс. Құрылғыдағы құпиялық ауыстырғышының орналасқан жерін құрылғы нұсқаулығынан қараңыз."</string>
+    <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_content" msgid="3960837827570483762">"Оның бөгеуін алу үшін құрылғыдағы құпиялық ауыстырғышын ашық қалыпқа жылжытып, пайдалану мүмкіндігін қамтамасыз етіңіз. Құрылғыдағы құпиялық ауыстырғышының орналасқан жерін құрылғы нұсқаулығынан қараңыз."</string>
     <string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"Микрофон қолжетімді"</string>
     <string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"Камера қолжетімді"</string>
     <string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"Микрофон мен камера қолжетімді"</string>
     <string name="media_seamless_other_device" msgid="4654849800789196737">"Басқа құрылғы"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Шолуды қосу/өшіру"</string>
     <string name="zen_priority_introduction" msgid="3159291973383796646">"Оятқыш, еске салғыш, іс-шара мен өзіңіз көрсеткен контактілердің қоңырауларынан басқа дыбыстар мен дірілдер мазаламайтын болады. Музыка, бейне және ойын сияқты медиафайлдарды қоссаңыз, оларды естисіз."</string>
-    <string name="zen_alarms_introduction" msgid="3987266042682300470">"Дабылдардан басқа ешқандай дыбыстар мен дірілдер мазаламайтын болады. Музыка, бейне және ойындар сияқты ойнатылатын мазмұндарды ести алатын боласыз."</string>
+    <string name="zen_alarms_introduction" msgid="3987266042682300470">"Дабылдардан басқа ешқандай дыбыстар мен дірілдер мазаламайтын болады. Музыка, бейне және ойындар сияқты ойнатылатын контентті ести алатын боласыз."</string>
     <string name="zen_priority_customize_button" msgid="4119213187257195047">"Реттеу"</string>
     <string name="zen_silence_introduction_voice" msgid="853573681302712348">"Дабыл, музыка, бейнелер мен ойындарды қоса алғанда, барлық дыбыстар мен дірілдер бөгелетін болады. Қоңырау шала беруіңізге болады."</string>
     <string name="zen_silence_introduction" msgid="6117517737057344014">"БАРЛЫҚ, соның ішінде дабылдардың, музыканың, бейнелердің және ойындардың дыбыстары мен дірілдері өшіріледі."</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi өшірулі"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth өшірулі"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Мазаламау режимі өшірулі"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Мазаламау режимі қосулы"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Мазаламау режимі (<xliff:g id="ID_1">%s</xliff:g>) автоматты ережесі арқылы қосылды."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Мазаламау режимі (<xliff:g id="ID_1">%s</xliff:g>) қолданбасы арқылы қосылды."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Мазаламау режимі автоматты ереже немесе қолданба арқылы қосылды."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> қолданбасында \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" әнін ойнату"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Қайтару"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> құрылғысында музыка ойнату үшін оған жақындаңыз."</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Осы жерде ойнау үшін <xliff:g id="DEVICENAME">%1$s</xliff:g> құрылғысына жақындаңыз"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> құрылғысында ойнатылуда."</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Бірдеңе дұрыс болмады. Қайталап көріңіз."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Жүктеліп жатыр"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Өшірулі. Қолданба тексеріңіз."</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Табылмады"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Басқару виджеті қолжетімсіз"</string>
@@ -875,6 +883,9 @@
     <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">"Динамиктер мен дисплейлер"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Тарату қалай жүзеге асады"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Тарату"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Үйлесімді Bluetooth құрылғылары бар маңайдағы адамдар сіз таратып жатқан медиамазмұнды тыңдай алады."</string>
@@ -914,7 +925,7 @@
     <string name="game_status" msgid="1340694320630973259">"Ойнатылуда"</string>
     <string name="empty_user_name" msgid="3389155775773578300">"Достар"</string>
     <string name="empty_status" msgid="5938893404951307749">"Кешке чатта сөйлесейік!"</string>
-    <string name="status_before_loading" msgid="1500477307859631381">"Мазмұн жақында көрсетіледі."</string>
+    <string name="status_before_loading" msgid="1500477307859631381">"Контент жақында көрсетіледі."</string>
     <string name="missed_call" msgid="4228016077700161689">"Өткізіп алған қоңырау"</string>
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Соңғы хабарлар, өткізіп алған қоңыраулар мен статустың жаңаруы көрсетіледі."</string>
@@ -972,7 +983,7 @@
     <string name="clipboard_text_hidden" msgid="7926899867471812305">"Көру үшін түртіңіз."</string>
     <string name="clipboard_text_copied" msgid="5100836834278976679">"Мәтін көшірілді."</string>
     <string name="clipboard_image_copied" msgid="3793365360174328722">"Сурет көшірілді."</string>
-    <string name="clipboard_content_copied" msgid="144452398567828145">"Мазмұн көшірілді."</string>
+    <string name="clipboard_content_copied" msgid="144452398567828145">"Контент көшірілді."</string>
     <string name="clipboard_editor" msgid="2971197550401892843">"Буфер редакторы"</string>
     <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Буфер"</string>
     <string name="clipboard_image_preview" msgid="2156475174343538128">"Суретті алдын ала көру"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ашу"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"<xliff:g id="APPNAME">%1$s</xliff:g> қолданбасын таңбаша ретінде қосу үшін келесі әрекеттерді орындауды ұмытпаңыз:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Қолданба реттелген"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Wallet-ке кемінде бір карта қосылған"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Камера қолданбасын орнатыңыз"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Қолданба реттелген"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Кемінде бір құрылғы қолжетімді"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Таңбашаны басып тұрыңыз."</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Бас тарту"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Айналдыру"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Жақсырақ селфи түсіру үшін телефонды жазыңыз"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Бұл экран өшіріледі."</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Бүктемелі құрылғы ашылып жатыр."</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Бүктемелі құрылғы аударылып жатыр."</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 6914431..2559877 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"ចែករំលែករូបថតអេក្រង់"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"ថត​ច្រើនទៀត"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ច្រានចោល​រូបថត​អេក្រង់"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"ច្រានចោល​សារ​កម្រងព័ត៌មានការងារ"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ការមើល​រូបថត​អេក្រង់​សាកល្បង"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"បន្ទាត់បែងចែក​ខាងលើ <xliff:g id="PERCENT">%1$d</xliff:g> ភាគរយ"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"បន្ទាត់បែងចែក​ខាងក្រោម <xliff:g id="PERCENT">%1$d</xliff:g> ភាគរយ"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"បន្ទាត់បែងចែក​ខាងឆ្វេង <xliff:g id="PERCENT">%1$d</xliff:g> ភាគរយ"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"បន្ទាត់បែងចែក​ខាងស្ដាំ <xliff:g id="PERCENT">%1$d</xliff:g> ភាគរយ"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"មុខងារថត​វីដេអូអេក្រង់"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"កំពុង​ដំណើរការ​ការថតអេក្រង់"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ការជូនដំណឹង​ដែល​កំពុង​ដំណើរការ​សម្រាប់​រយៈពេលប្រើ​ការថត​សកម្មភាព​អេក្រង់"</string>
@@ -370,7 +375,7 @@
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"សេវាកម្មដែល​ផ្ដល់​មុខងារ​នេះ​នឹងមាន​សិទ្ធិ​ចូលប្រើ​ព័ត៌មាន​ទាំងអស់​ដែល​អាច​មើលឃើញ​នៅលើ​អេក្រង់​របស់អ្នក ឬ​ដែលចាក់​ពីឧបករណ៍​របស់អ្នក នៅពេល​កំពុង​ថត ឬភ្ជាប់។ ព័ត៌មាន​នេះមាន​ដូចជា ពាក្យសម្ងាត់ ព័ត៌មាន​លម្អិត​អំពីការទូទាត់​ប្រាក់ រូបថត សារ និង​សំឡេង​ដែល​អ្នកចាក់​ជាដើម។"</string>
     <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"ចាប់ផ្ដើម​ថត ឬភ្ជាប់​មែនទេ?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"ចាប់ផ្ដើម​ថត ឬភ្ជាប់​ដោយប្រើ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ឬ?"</string>
-    <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"អនុញ្ញាតឱ្យ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ចែករំលែក ឬថតទេ?"</string>
+    <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"អនុញ្ញាតឱ្យ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ចែករំលែក ឬថត?"</string>
     <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"អេក្រង់ទាំងមូល"</string>
     <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"កម្មវិធីតែមួយ"</string>
     <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"នៅពេលអ្នកកំពុងចែករំលែក ថត ឬបញ្ជូន <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> មានសិទ្ធិចូលប្រើប្រាស់អ្វីៗដែលបង្ហាញឱ្យឃើញនៅលើអេក្រង់របស់អ្នក ឬលេងនៅលើឧបករណ៍របស់អ្នក។ ដូច្នេះ សូមប្រុងប្រយ័ត្នចំពោះពាក្យសម្ងាត់ ព័ត៌មាន​លម្អិតអំពី​ការ​ទូទាត់ប្រាក់ សារ ឬព័ត៌មានរសើបផ្សេងទៀត។"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi បាន​បិទ"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"ប៊្លូធូស​បាន​បិទ"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"មុខងារ​កុំរំខាន​បាន​បិទ"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"មុខងារកុំរំខាន​ត្រូវបានបើក"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"មុខងារ​កុំ​រំខាន​ត្រូវបាន​បើកដោយច្បាប់​ស្វ័យ​ប្រវត្តិ (<xliff:g id="ID_1">%s</xliff:g>)។"</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"មុខងារ​កុំ​រំខាន​ត្រូវបាន​បើកដោយកម្មវិធី (<xliff:g id="ID_1">%s</xliff:g>)។"</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"មុខងារ​កុំ​រំខាន​ត្រូវបាន​បើកដោយច្បាប់​ស្វ័យ​ប្រវត្តិ ឬ​កម្មវិធី។"</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"ចាក់ <xliff:g id="SONG_NAME">%1$s</xliff:g> ពី <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"ត្រឡប់វិញ"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"រំកិលឱ្យកាន់តែជិត ដើម្បីចាក់នៅលើ <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"រំកិលឱ្យកាន់តែជិត <xliff:g id="DEVICENAME">%1$s</xliff:g> ដើម្បីចាក់នៅទីនេះ"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"កំពុង​ចាក់​​នៅ​លើ <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"មានអ្វីមួយខុសប្រក្រតី។ សូមព្យាយាមម្ដងទៀត។"</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"កំពុងផ្ទុក"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"អសកម្ម ពិនិត្យមើល​កម្មវិធី"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"រកមិន​ឃើញទេ"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"មិនអាច​គ្រប់គ្រង​បានទេ"</string>
@@ -875,6 +883,9 @@
     <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">"ឧបករណ៍បំពងសំឡេង និងផ្ទាំងអេក្រង់"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"របៀបដែលការផ្សាយដំណើរការ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ការ​ផ្សាយ"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"មនុស្សនៅជិត​អ្នកដែលមាន​ឧបករណ៍ប៊្លូធូស​ត្រូវគ្នា​អាចស្តាប់​មេឌៀ​ដែលអ្នកកំពុងផ្សាយបាន"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"បើក <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"ដើម្បីបញ្ចូលកម្មវិធី <xliff:g id="APPNAME">%1$s</xliff:g> ជាផ្លូវកាត់ សូមប្រាកដថា"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• កម្មវិធីត្រូវបានរៀបចំ"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• កាតយ៉ាងតិចមួយត្រូវបានបញ្ចូលទៅក្នុង Wallet"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• ដំឡើងកម្មវិធីកាមេរ៉ា"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• កម្មវិធីត្រូវបានរៀបចំ"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ឧបករណ៍យ៉ាងតិចមួយអាចប្រើបាន"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ចុចឱ្យជាប់លើផ្លូវកាត់"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"បោះបង់"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ត្រឡប់ឥឡូវនេះ"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"លាតទូរសព្ទ ដើម្បីសែលហ្វីកាន់តែប្រសើរ"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ អេក្រង់នេះនឹងបិទ"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ឧបករណ៍អាច​បត់បានកំពុងត្រូវបានលា"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ឧបករណ៍អាច​បត់បានកំពុងត្រូវបានលា"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 2691a70..12d96c3 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ಅನ್ನು ಹಂಚಿಕೊಳ್ಳಿ"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"ಇನ್ನಷ್ಟು ಕ್ಯಾಪ್ಚರ್ ಮಾಡಿ"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ಅನ್ನು ವಜಾಗೊಳಿಸಿ"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ ಸಂದೇಶವನ್ನು ವಜಾಗೊಳಿಸಿ"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ಸ್ಕ್ರೀನ್‍ಶಾಟ್‍ನ ಪೂರ್ವವೀಕ್ಷಣೆ"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"ಮೇಲಿನ ಬೌಂಡರಿ ಶೇಕಡಾ <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"ಕೆಳಗಿನ ಬೌಂಡರಿ ಶೇಕಡಾ <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ಎಡಭಾಗದ ಬೌಂಡರಿ ಶೇಕಡಾ <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"ಬಲಭಾಗದ ಬೌಂಡರಿ ಶೇಕಡಾ <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡರ್"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಆಗುತ್ತಿದೆ"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಸೆಶನ್‌ಗಾಗಿ ಚಾಲ್ತಿಯಲ್ಲಿರುವ ಅಧಿಸೂಚನೆ"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"ವೈ-ಫೈ ಆಫ್ ಆಗಿದೆ"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"ಬ್ಲೂಟೂತ್‌ ಆಫ್ ಆಗಿದೆ"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಆಫ್ ಆಗಿದೆ"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಮೋಡ್ ಆನ್ ಆಗಿದೆ"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"(<xliff:g id="ID_1">%s</xliff:g>) ಸ್ವಯಂಚಾಲಿತ ನಿಯಮದ ಮೂಲಕ ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಆನ್ ಆಗಿದೆ."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"(<xliff:g id="ID_1">%s</xliff:g>) ಅಪ್ಲಿಕೇಶನ್‌ ಮೂಲಕ ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಆನ್ ಆಗಿದೆ."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ಸ್ವಯಂಚಾಲಿತ ನಿಯಮ ಅಥವಾ ಅಪ್ಲಿಕೇಶನ್‌ ಮೂಲಕ ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಆನ್ ಆಗಿದೆ."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ಹಾಡನ್ನು <xliff:g id="APP_LABEL">%2$s</xliff:g> ನಲ್ಲಿ ಪ್ಲೇ ಮಾಡಿ"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"ರದ್ದುಗೊಳಿಸಿ"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> ನಲ್ಲಿ ಪ್ಲೇ ಮಾಡಲು ಅದರ ಹತ್ತಿರಕ್ಕೆ ಸರಿಯಿರಿ"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ಇಲ್ಲಿ ಪ್ಲೇ ಮಾಡಲು <xliff:g id="DEVICENAME">%1$s</xliff:g> ಸಮೀಪಕ್ಕೆ ಹೋಗಿ"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> ನಲ್ಲಿ ಪ್ಲೇ ಆಗುತ್ತಿದೆ"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"ಏನೋ ತಪ್ಪಾಗಿದೆ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"ಲೋಡ್ ಆಗುತ್ತಿದೆ"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"ನಿಷ್ಕ್ರಿಯ, ಆ್ಯಪ್ ಪರಿಶೀಲಿಸಿ"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"ಕಂಡುಬಂದಿಲ್ಲ"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"ನಿಯಂತ್ರಣ ಲಭ್ಯವಿಲ್ಲ"</string>
@@ -875,6 +883,9 @@
     <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">"ಸ್ಪೀಕರ್‌ಗಳು ಮತ್ತು ಡಿಸ್‌ಪ್ಲೇಗಳು"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ಪ್ರಸಾರವು ಹೇಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ಪ್ರಸಾರ"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ಹೊಂದಾಣಿಕೆಯಾಗುವ ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳನ್ನು ಹೊಂದಿರುವ ಸಮೀಪದಲ್ಲಿರುವ ಜನರು ನೀವು ಪ್ರಸಾರ ಮಾಡುತ್ತಿರುವ ಮಾಧ್ಯಮವನ್ನು ಆಲಿಸಬಹುದು"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ಅನ್ನು ತೆರೆಯಿರಿ"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"<xliff:g id="APPNAME">%1$s</xliff:g> ಆ್ಯಪ್ ಅನ್ನು ಶಾರ್ಟ್‌ಕಟ್ ಆಗಿ ಸೇರಿಸಲು ಕೆಳಗಿನವುಗಳನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• ಆ್ಯಪ್ ಅನ್ನು ಸೆಟಪ್ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• ವಾಲೆಟ್‌ಗೆ ಕನಿಷ್ಠ ಒಂದು ಕಾರ್ಡ್ ಅನ್ನು ಸೇರಿಸಲಾಗಿದೆ"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• ಕ್ಯಾಮರಾ ಆ್ಯಪ್ ಒಂದನ್ನು ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿ"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• ಆ್ಯಪ್ ಅನ್ನು ಸೆಟಪ್ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ಕನಿಷ್ಠ ಒಂದು ಸಾಧನ ಲಭ್ಯವಿದೆ"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ಸ್ಪರ್ಶಿಸಿ ಹೋಲ್ಡ್ ಮಾಡಿ ಶಾರ್ಟ್‌ಕಟ್"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ರದ್ದುಗೊಳಿಸಿ"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ಈಗ ಫ್ಲಿಪ್ ಮಾಡಿ"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ಉತ್ತಮ ಸೆಲ್ಫೀಗಾಗಿ ಫೋನ್ ಅನ್ನು ಅನ್‌ಫೋಲ್ಡ್ ಮಾಡಿ"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ಈ ಸ್ಕ್ರೀನ್ ಆಫ್ ಆಗುತ್ತದೆ"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ಫೋಲ್ಡ್ ಮಾಡಬಹುದಾದ ಸಾಧನವನ್ನು ಅನ್‌ಫೋಲ್ಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ಫೋಲ್ಡ್ ಮಾಡಬಹುದಾದ ಸಾಧನವನ್ನು ಸುತ್ತಲೂ ತಿರುಗಿಸಲಾಗುತ್ತಿದೆ"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index f3f0426..e42e10e 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"스크린샷 공유"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"더 캡처하기"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"스크린샷 닫기"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"직장 프로필 메시지 닫기"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"스크린샷 미리보기"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"상단 가장자리 <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"하단 가장자리 <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"왼쪽 가장자리 <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"오른쪽 가장자리 <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"화면 녹화"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"화면 녹화 처리 중"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"화면 녹화 세션에 관한 지속적인 알림"</string>
@@ -370,11 +375,11 @@
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"이 기능을 제공하는 서비스는 녹화 또는 전송 중에 화면에 표시되거나 기기에서 재생되는 모든 정보에 액세스할 수 있습니다. 여기에는 비밀번호, 결제 세부정보, 사진, 메시지, 재생하는 오디오 같은 정보가 포함됩니다."</string>
     <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"녹화 또는 전송을 시작하시겠습니까?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>으로 녹화 또는 전송을 시작하시겠습니까?"</string>
-    <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>에서 공유 또는 녹화를 허용할까요?"</string>
+    <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>에서 공유 또는 녹화하도록 허용할까요?"</string>
     <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"전체 화면"</string>
     <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"단일 앱"</string>
     <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"공유하거나 녹화하거나 전송할 때 <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 앱에서 화면에 표시되거나 기기에서 재생되는 모든 항목에 액세스할 수 있습니다. 따라서 비밀번호, 결제 세부정보, 메시지 등 민감한 정보가 노출되지 않도록 주의하세요."</string>
-    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"앱을 공유하거나 녹화하거나 전송할 때는 <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>에서 해당 앱에 표시되거나 재생되는 모든 항목에 액세스할 수 있으므로 비밀번호, 결제 세부정보, 메시지 등 민감한 정보가 노출되지 않도록 주의하세요."</string>
+    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"앱을 공유하거나 녹화하거나 전송할 때는 <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>에서 해당 앱에 표시되거나 앱에서 재생되는 모든 항목에 액세스할 수 있으므로 비밀번호, 결제 세부정보, 메시지 등 민감한 정보가 노출되지 않도록 주의하세요."</string>
     <string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"계속"</string>
     <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"앱 공유 또는 녹화"</string>
     <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"앱에서 공유하거나 기록하도록 허용하시겠습니까?"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi가 사용 중지됨"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"블루투스가 사용 중지됨"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"방해 금지 모드가 사용 중지됨"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"방해 금지 모드 사용 중"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"방해 금지 모드가 자동 규칙(<xliff:g id="ID_1">%s</xliff:g>)에 의해 사용 설정되었습니다."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"방해 금지 모드가 앱(<xliff:g id="ID_1">%s</xliff:g>)에 의해 사용 설정되었습니다."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"방해 금지 모드가 자동 규칙 또는 앱에 의해 사용 설정되었습니다."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g>에서 <xliff:g id="SONG_NAME">%1$s</xliff:g> 재생"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"실행취소"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>에서 재생하려면 기기를 더 가까이로 옮기세요."</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"현재 기기에서 재생하려면 <xliff:g id="DEVICENAME">%1$s</xliff:g>에 더 가까이 이동합니다."</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>에서 재생 중"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"문제가 발생했습니다. 다시 시도해 주세요."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"로드 중"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"비활성. 앱을 확인하세요."</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"찾을 수 없음"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"컨트롤을 사용할 수 없음"</string>
@@ -875,6 +883,9 @@
     <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">"스피커 및 디스플레이"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"브로드캐스팅 작동 원리"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"브로드캐스트"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"호환되는 블루투스 기기를 가진 근처의 사용자가 내가 브로드캐스트 중인 미디어를 수신 대기할 수 있습니다."</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> 열기"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"<xliff:g id="APPNAME">%1$s</xliff:g> 앱을 바로가기로 추가하려면 다음을 확인하세요."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• 앱이 설정되어 있습니다."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• 1개 이상의 카드가 월렛에 추가되어 있습니다."</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• 카메라 앱이 설치되어 있습니다."</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• 앱이 설정되어 있습니다."</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• 1대 이상의 기기를 사용할 수 있습니다."</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"바로가기를 길게 터치하세요."</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"취소"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"지금 뒤집기"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"휴대전화를 열어서 더 나은 셀카를 찍어보세요"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ 이 화면이 꺼집니다."</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"폴더블 기기를 펼치는 모습"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"폴더블 기기를 뒤집는 모습"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 6f64f45..ec9e962 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Скриншотту бөлүшүү"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Көбүрөөк тартуу"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Скриншотту четке кагуу"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Жумуш профилинин билдирүүсүн жабуу"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Скриншотту алдын ала көрүү"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Өйдө жагы <xliff:g id="PERCENT">%1$d</xliff:g> пайызга"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Ылдый жагы <xliff:g id="PERCENT">%1$d</xliff:g> пайызга"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Сол жагы <xliff:g id="PERCENT">%1$d</xliff:g> пайызга"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Оң жагы <xliff:g id="PERCENT">%1$d</xliff:g> пайызга"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"экрандан видео жаздырып алуу"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Экрандан жаздырылып алынган видео иштетилүүдө"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Экранды жаздыруу сеансы боюнча учурдагы билдирме"</string>
@@ -370,16 +375,16 @@
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Жаздырып же тышкы экранга чыгарып жатканда, бул колдонмо экраныңыздагы бардык маалыматты же түзмөктө ойнолуп жаткан бардык нерселерди (сырсөздөрдү, төлөмдүн чоо-жайын, сүрөттөрдү, билдирүүлөрдү жана угуп жаткан аудиофайлдарды) көрө алат."</string>
     <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Жаздырып же тышкы экранга чыгарып баштайсызбы?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> колдонмосу аркылуу жаздырып же тышкы экранга чыгарып баштайсызбы?"</string>
-    <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> колдонмосуна бөлүшүүгө же жаздырууга уруксат бересизби?"</string>
+    <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> колдонмосуна экранды бөлүшүүгө же андан видео тартууга уруксат бересизби?"</string>
     <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"Бүтүндөй экран"</string>
     <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"Жалгыз колдонмо"</string>
-    <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"Бөлүшүп, жаздырып же тышкы экранда бөлүшкөндө <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> экраныңызда көрүнүп жана түзмөктө ойнотулуп жаткан нерселерге мүмкүнчүлүк алат. Андыктан сырсөздөрдү, төлөм маалыматын, билдирүүлөрдү жана башка купуя маалыматты көрсөтүп албаңыз."</string>
-    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Бөлүшүп, жаздырып же тышкы экранда бөлүшкөндө <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ал колдонмодо көрүнүп жана ойнотулуп жаткан нерселерге мүмкүнчүлүк алат. Андыктан сырсөздөрдү, төлөм маалыматын, билдирүүлөрдү жана башка купуя маалыматты көрсөтүп албаңыз."</string>
+    <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"Экранды көрсөтүп, тышка чыгарып же андан видео тартып жатканда, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> түзмөктүн экранындагы нерселердин баарын көрө алат. Андыктан сырсөздөр, төлөм маалыматы, билдирүүлөр сыяктуу купуя маалыматты киргизүүдө же көрүүдө этият болуңуз."</string>
+    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Экранды көрсөтүп, тышка чыгарып же андан видео тартып жатканда, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> түзмөктүн экранындагы нерселердин баарын көрө алат. Андыктан сырсөздөр, төлөм маалыматы, билдирүүлөр сыяктуу купуя маалыматты киргизүүдө же көрүүдө этият болуңуз."</string>
     <string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Улантуу"</string>
     <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Колдонмону бөлүшүү же жаздыруу"</string>
     <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Бул колдонмого бөлүшүп же жаздырууга уруксат бересизби?"</string>
-    <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Бөлүшүп, жаздырып же тышкы экранга чыгарганда бул колдонмо экраныңызда көрүнүп жана түзмөктө ойнотулуп жаткан нерселерге мүмкүнчүлүк алат. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү жана башка купуя маалыматты көрсөтүп албаңыз."</string>
-    <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Бөлүшүп, жаздырып же тышкы экранга чыгарганда бул колдонмо ал колдонмодо көрсөтүлүп жана ойнотулуп жаткан нерселерге мүмкүнчүлүк алат. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү жана башка купуя маалыматты көрсөтүп албаңыз."</string>
+    <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Экранды көрсөтүп, тышка чыгарып же андан видео тартып жатканда, бул колдонмо түзмөктүн экранындагы нерселердин баарын көрө алат. Андыктан сырсөздөр, төлөм маалыматы, билдирүүлөр сыяктуу купуя маалыматты киргизүүдө же көрүүдө этият болуңуз."</string>
+    <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Экранды көрсөтүп, тышка чыгарып же андан видео тартып жатканда, бул колдонмо түзмөктүн экранындагы нерселердин баарын көрө алат. Андыктан сырсөздөр, төлөм маалыматы, билдирүүлөр сыяктуу купуя маалыматты киргизүүдө же көрүүдө этият болуңуз."</string>
     <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"IT администраторуңуз бөгөттөп койгон"</string>
     <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Түзмөк саясаты экрандагыны тартып алууну өчүрүп койгон"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Баарын тазалап салуу"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi өчүк"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth өчүк"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"\"Тынчымды алба\" режими өчүк"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"\"Тынчымды алба\" режими күйүк"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Автоматтык эреже \"Тынчымды алба\" режимин күйгүздү (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Колдонмо \"Тынчымды алба\" режимин күйгүздү (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Автоматтык эреже же колдонмо \"Тынчымды алба\" режимин күйгүздү."</string>
@@ -745,7 +749,7 @@
     <string name="auto_data_switch_disable_message" msgid="5885533647399535852">"Жеткиликтүү болгондо мобилдик Интернет автоматтык түрдө которулбайт"</string>
     <string name="auto_data_switch_dialog_negative_button" msgid="2370876875999891444">"Жок, рахмат"</string>
     <string name="auto_data_switch_dialog_positive_button" msgid="8531782041263087564">"Ооба, которулуу"</string>
-    <string name="touch_filtered_warning" msgid="8119511393338714836">"Уруксат берүү сурамыңыз көрүнбөй калгандыктан, Жөндөөлөр жообуңузду ырастай албай жатат."</string>
+    <string name="touch_filtered_warning" msgid="8119511393338714836">"Уруксат берүү сурамыңыз көрүнбөй калгандыктан, Параметрлер жообуңузду ырастай албай жатат."</string>
     <string name="slice_permission_title" msgid="3262615140094151017">"<xliff:g id="APP_0">%1$s</xliff:g> колдонмосуна <xliff:g id="APP_2">%2$s</xliff:g> үлгүлөрүн көрсөтүүгө уруксат берилсинби?"</string>
     <string name="slice_permission_text_1" msgid="6675965177075443714">"- <xliff:g id="APP">%1$s</xliff:g> колдонмосунун маалыматын окуйт"</string>
     <string name="slice_permission_text_2" msgid="6758906940360746983">"- <xliff:g id="APP">%1$s</xliff:g> колдонмосунда аракеттерди аткарат"</string>
@@ -788,10 +792,10 @@
     <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Атайын мүмкүнчүлүктөрдү ачуу үчүн басыңыз. Бул баскычты Жөндөөлөрдөн өзгөртүңүз.\n\n"<annotation id="link">"Жөндөөлөрдү көрүү"</annotation></string>
     <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Баскычты убактылуу жашыра туруу үчүн экрандын четине жылдырыңыз"</string>
     <string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"Жогорку сол жакка жылдыруу"</string>
-    <string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"Жогорку оң жакка жылдырыңыз"</string>
+    <string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"Жогорку оң жакка жылдыруу"</string>
     <string name="accessibility_floating_button_action_move_bottom_left" msgid="8063394111137429725">"Төмөнкү сол жакка жылдыруу"</string>
-    <string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Төмөнкү оң жакка жылдырыңыз"</string>
-    <string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Ичине жылдырып, көрсөтүңүз"</string>
+    <string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Төмөнкү оң жакка жылдыруу"</string>
+    <string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Четке жылдырып, жашыруу"</string>
     <string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Сыртка жылдырып, көрсөтүңүз"</string>
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"өчүрүү/күйгүзүү"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Түзмөктү башкаруу элементтери"</string>
@@ -836,7 +840,7 @@
     <string name="controls_media_active_session" msgid="3146882316024153337">"Учурдагы медиа сеансын жашыруу мүмкүн эмес."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Жашыруу"</string>
     <string name="controls_media_resume" msgid="1933520684481586053">"Улантуу"</string>
-    <string name="controls_media_settings_button" msgid="5815790345117172504">"Жөндөөлөр"</string>
+    <string name="controls_media_settings_button" msgid="5815790345117172504">"Параметрлер"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ыры (аткаруучу: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>) <xliff:g id="APP_LABEL">%3$s</xliff:g> колдонмосунан ойнотулуп жатат"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> ичинен <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Ойнотуу"</string>
@@ -849,10 +853,14 @@
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ырын (аткаруучу: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>) <xliff:g id="APP_LABEL">%3$s</xliff:g> колдонмосунан ойнотуу"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ырын <xliff:g id="APP_LABEL">%2$s</xliff:g> колдонмосунан ойнотуу"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Кайтаруу"</string>
-    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> түзмөгүндө ойнотуу үчүн жакыныраак жылдырыңыз"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Бул жерде ойнотуу үчүн <xliff:g id="DEVICENAME">%1$s</xliff:g> түзмөгүнө жакындатыңыз"</string>
+    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> түзмөгүндө ойнотуу үчүн жакындатыңыз"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> аркылуу ойнотулууда"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Бир жерден ката кетти. Кайра аракет кылыңыз."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Жүктөлүүдө"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Жигерсиз. Колдонмону текшериңиз"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Табылган жок"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Башкара албайсыз"</string>
@@ -875,6 +883,9 @@
     <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">"Динамиктер жана дисплейлер"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Кабарлоо кантип иштейт"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Кабарлоо"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Шайкеш Bluetooth түзмөктөрү болгон жакын жердеги кишилер кабарлап жаткан медиаңызды уга алышат"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ачуу"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"<xliff:g id="APPNAME">%1$s</xliff:g> колдонмосун ыкчам баскыч катары кошуу үчүн төмөнкүлөрдү аткарыңыз:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Колдонмо туураланды"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Капчыкка кеминде бир карта кошулду"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Камера колдонмосун орнотуу"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Колдонмо туураланды"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Кеминде бир түзмөк жеткиликтүү"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Ыкчам баскычты басып туруңуз"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Токтотуу"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Азыр которуу"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Жакшы селфи тартуу үчүн негизги камерага которуңуз"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Бул экран өчөт"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Ачылып турган бүктөлмө түзмөк"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Оодарылып жаткан бүктөлмө түзмөк"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index 49ef330..fff2544 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -40,6 +40,10 @@
     <dimen name="biometric_dialog_button_negative_max_width">140dp</dimen>
     <dimen name="biometric_dialog_button_positive_max_width">116dp</dimen>
 
+    <!-- Lock pattern view size, align sysui biometric_auth_pattern_view_size -->
+    <dimen name="biometric_auth_pattern_view_size">248dp</dimen>
+    <dimen name="biometric_auth_pattern_view_max_size">348dp</dimen>
+
     <dimen name="global_actions_power_dialog_item_height">130dp</dimen>
     <dimen name="global_actions_power_dialog_item_bottom_margin">35dp</dimen>
 
diff --git a/packages/SystemUI/res/values-land/styles.xml b/packages/SystemUI/res/values-land/styles.xml
index aefd998..a0e721e 100644
--- a/packages/SystemUI/res/values-land/styles.xml
+++ b/packages/SystemUI/res/values-land/styles.xml
@@ -29,11 +29,11 @@
 
     <style name="AuthCredentialPatternContainerStyle">
         <item name="android:gravity">center</item>
-        <item name="android:maxHeight">320dp</item>
-        <item name="android:maxWidth">320dp</item>
-        <item name="android:minHeight">200dp</item>
-        <item name="android:minWidth">200dp</item>
-        <item name="android:paddingHorizontal">60dp</item>
+        <item name="android:maxHeight">@dimen/biometric_auth_pattern_view_max_size</item>
+        <item name="android:maxWidth">@dimen/biometric_auth_pattern_view_max_size</item>
+        <item name="android:minHeight">@dimen/biometric_auth_pattern_view_size</item>
+        <item name="android:minWidth">@dimen/biometric_auth_pattern_view_size</item>
+        <item name="android:paddingHorizontal">32dp</item>
         <item name="android:paddingVertical">20dp</item>
     </style>
 
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 8573f69..0b8a9de 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"ແບ່ງປັນຮູບໜ້າຈໍ"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"ຖ່າຍຮູບເພີ່ມເຕີມ"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ປິດຮູບໜ້າຈໍ"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"ປິດຂໍ້ຄວາມໂປຣໄຟລ໌ບ່ອນເຮັດວຽກໄວ້"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ຕົວຢ່າງຮູບໜ້າຈໍ"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"ຂອບເຂດທາງເທິງ <xliff:g id="PERCENT">%1$d</xliff:g> ເປີເຊັນ"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"ຂອບເຂດທາງລຸ່ມ <xliff:g id="PERCENT">%1$d</xliff:g> ເປີເຊັນ"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ຂອບເຂດທາງຊ້າຍ <xliff:g id="PERCENT">%1$d</xliff:g> ເປີເຊັນ"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"ຂອບເຂດທາງຂວາ <xliff:g id="PERCENT">%1$d</xliff:g> ເປີເຊັນ"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"ໂປຣແກຣມບັນທຶກໜ້າຈໍ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ກຳລັງປະມວນຜົນການບັນທຶກໜ້າຈໍ"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ການແຈ້ງເຕືອນສຳລັບເຊດຊັນການບັນທຶກໜ້າຈໍໃດໜຶ່ງ"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi ປິດຢູ່"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth ປິດຢູ່"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"ຫ້າມລົບກວນ ປິດຢູ່"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"ເປີດໂໝດຫ້າມລົບກວນແລ້ວ"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ໂໝດຫ້າມລົບກວນຖືກເປີດໃຊ້ໂດຍກົດອັດຕະໂນມັດ (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"ມີແອັບເປີດໃຊ້ໂໝດຫ້າມລົບກວນ (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ໂໝດຫ້າມລົບກວນຖືກເປີດໃຊ້ໂດຍກົດອັດຕະໂນມັດ ຫຼື ແອັບໃດໜຶ່ງ."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"ຫຼິ້ນ <xliff:g id="SONG_NAME">%1$s</xliff:g> ຈາກ <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"ຍົກເລີກ"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"ຍ້າຍໄປໃກ້ຂຶ້ນເພື່ອຫຼິ້ນຢູ່ <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ກະລຸນາຍ້າຍເຂົ້າໃກ້ <xliff:g id="DEVICENAME">%1$s</xliff:g> ເພື່ອຫຼິ້ນຢູ່ບ່ອນນີ້"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"ກຳລັງຫຼິ້ນຢູ່ <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"ມີບາງຢ່າງຜິດພາດເກີດຂຶ້ນ. ກະລຸນາລອງໃໝ່."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"ກຳລັງໂຫຼດ"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"ບໍ່ເຮັດວຽກ, ກະລຸນາກວດສອບແອັບ"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"ບໍ່ພົບ"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"ບໍ່ສາມາດໃຊ້ການຄວບຄຸມໄດ້"</string>
@@ -875,6 +883,9 @@
     <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">"ລຳໂພງ ແລະ ຈໍສະແດງຜົນ"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ການອອກອາກາດເຮັດວຽກແນວໃດ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ອອກອາກາດ"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ຄົນທີ່ຢູ່ໃກ້ທ່ານທີ່ມີອຸປະກອນ Bluetooth ທີ່ເຂົ້າກັນໄດ້ຈະສາມາດຟັງມີເດຍທີ່ທ່ານກຳລັງອອກອາກາດຢູ່ໄດ້"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"ຊມ:ນທ"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"ຊມ:ນທ"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"ເປີດ <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"ເພື່ອເພີ່ມແອັບ <xliff:g id="APPNAME">%1$s</xliff:g> ເປັນທາງລັດ, ກະລຸນາກວດສອບໃຫ້ແນ່ໃຈວ່າ"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• ແອັບໄດ້ຮັບການຕັ້ງຄ່າແລ້ວ"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• ມີການເພີ່ມຢ່າງໜ້ອຍ 1 ບັດໃສ່ໃນ Wallet"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• ຕິດຕັ້ງແອັບກ້ອງຖ່າຍຮູບ"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• ແອັບໄດ້ຮັບການຕັ້ງຄ່າແລ້ວ"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ມີຢ່າງໜ້ອຍ 1 ອຸປະກອນພ້ອມໃຫ້ນຳໃຊ້"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ແຕະທາງລັດຄ້າງໄວ້"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ຍົກເລີກ"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ປີ້ນດຽວນີ້"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ກາງໂທລະສັບອອກເພື່ອການຖ່າຍເຊວຟີທີ່ດີຂຶ້ນ"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ໜ້າຈໍນີ້ຈະປິດ"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ອຸປະກອນທີ່ພັບໄດ້ກຳລັງກາງອອກ"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ອຸປະກອນທີ່ພັກໄດ້ກຳລັງປີ້ນໄປມາ"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 3af4eb0..9017732 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Bendrinti ekrano kopiją"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Fiksuoti daugiau"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Praleisti ekrano kopiją"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Atsisakyti darbo profilio pranešimo"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Ekrano kopijos peržiūra"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Viršutinė riba – <xliff:g id="PERCENT">%1$d</xliff:g> proc."</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Apatinė riba – <xliff:g id="PERCENT">%1$d</xliff:g> proc."</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Kairioji riba – <xliff:g id="PERCENT">%1$d</xliff:g> proc."</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Dešinioji riba – <xliff:g id="PERCENT">%1$d</xliff:g> proc."</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekrano vaizdo įrašytuvas"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Apdorojam. ekrano vaizdo įraš."</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Šiuo metu rodomas ekrano įrašymo sesijos pranešimas"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"„Wi-Fi“ išjungtas"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"„Bluetooth“ išjungtas"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Netrukdymo režimas išjungtas"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Netrukdymo režimas įjungtas"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Netrukdymo režimą įjungė automatinė taisyklė (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Netrukdymo režimą įjungė programa (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Netrukdymo režimą įjungė automatinė taisyklė arba programa."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Leisti „<xliff:g id="SONG_NAME">%1$s</xliff:g>“ iš „<xliff:g id="APP_LABEL">%2$s</xliff:g>“"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Anuliuoti"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Prieikite arčiau, kad galėtumėte leisti įrenginyje „<xliff:g id="DEVICENAME">%1$s</xliff:g>“"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Perkelkite arčiau „<xliff:g id="DEVICENAME">%1$s</xliff:g>“, kad būtų galima leisti čia"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Leidžiama įrenginyje „<xliff:g id="DEVICENAME">%1$s</xliff:g>“"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Kažkas ne taip. Bandykite dar kartą."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Įkeliama"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Neaktyvu, patikrinkite progr."</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nerasta"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Valdiklis nepasiekiamas"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Pasiekiami garso išvesties įrenginiai."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Garsumas"</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">"Garsiakalbiai ir ekranai"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kaip veikia transliacija"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Transliacija"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Netoliese esantys žmonės, turintys suderinamus „Bluetooth“ įrenginius, gali klausyti jūsų transliuojamos medijos"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Atidaryti „<xliff:g id="APPNAME">%1$s</xliff:g>“"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Jei norite pridėti programą „<xliff:g id="APPNAME">%1$s</xliff:g>“ kaip šaukinį, įsitikinkite, kad atitinkate reikalavimus."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Programa nustatyta"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Prie „Wallet“ pridėta bent viena kortelė"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Įdiekite Fotoaparato programą"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Programa nustatyta"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Pasiekiamas bent vienas įrenginys"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Paliesk. ir palaik. spart. klav."</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Atšaukti"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Apversti dabar"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Užfiksuokite geresnę asmenukę atlenkę telefoną"</string>
@@ -1014,6 +1023,6 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Šis ekranas išsijungs"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Lankstomasis įrenginys išlankstomas"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Lankstomasis įrenginys apverčiamas"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
-    <skip />
+    <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Liko akumuliatoriaus įkrovos: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
+    <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Prijunkite rašiklį prie kroviklio"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index cec24a4..c4cdc06 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Kopīgot ekrānuzņēmumu"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Tvert vairāk"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Nerādīt ekrānuzņēmumu"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Noraidīt darba profila ziņojumu"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Ekrānuzņēmuma priekšskatījums"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Augšmala: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Apakšmala: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Kreisā mala: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Labā mala: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekrāna ierakstītājs"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekrāna ieraksta apstrāde"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Aktīvs paziņojums par ekrāna ierakstīšanas sesiju"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi ir izslēgts"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth ir izslēgts"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Režīms “Netraucēt” ir izslēgts"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Režīms “Netraucēt” ir ieslēgts"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Režīmu “Netraucēt” ieslēdza automātiska kārtula (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Režīmu “Netraucēt” ieslēdza lietotne (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Režīmu “Netraucēt” ieslēdza automātiska kārtula vai lietotne."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Atskaņojiet failu “<xliff:g id="SONG_NAME">%1$s</xliff:g>” no lietotnes <xliff:g id="APP_LABEL">%2$s</xliff:g>."</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Atsaukt"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Pārvietojiet savu ierīci tuvāk, lai atskaņotu mūziku ierīcē “<xliff:g id="DEVICENAME">%1$s</xliff:g>”."</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Pārvietojieties tuvāk ierīcei “<xliff:g id="DEVICENAME">%1$s</xliff:g>”, lai atskaņotu šeit"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Notiek atskaņošana ierīcē <xliff:g id="DEVICENAME">%1$s</xliff:g>."</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Radās kļūda. Mēģiniet vēlreiz."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Notiek ielāde"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Neaktīva, pārbaudiet lietotni"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Netika atrasta"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Vadīkla nav pieejama"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Audio izvadei pieejamās ierīces."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Skaļums"</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">"Skaļruņi un displeji"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kā darbojas apraide"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Apraide"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Tuvumā esošās personas ar saderīgām Bluetooth ierīcēm var klausīties jūsu apraidīto multivides saturu."</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"hh:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Atvērt lietotni <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Lai pievienotu lietotni <xliff:g id="APPNAME">%1$s</xliff:g> kā saīsni, jābūt izpildītiem tālāk minētajiem nosacījumiem."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Lietotne ir iestatīta."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Makam ir pievienota vismaz viena karte."</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Ir instalēta kameras lietotne."</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Lietotne ir iestatīta."</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ir pieejama vismaz viena ierīce."</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pieskarieties saīsnei un turiet."</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Atcelt"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Apvērst tūlīt"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Labākas pašbildes uzņemšana, atlokot tālruni"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Šis ekrāns tiks izslēgts."</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Salokāma ierīce tiek atlocīta"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Salokāma ierīce tiek apgriezta"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index fff051b..cbdee20 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -85,11 +85,14 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Споделете слика од екранот"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Сними повеќе"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Отфрлете ја сликата од екранот"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Отфрлете ја пораката за работен профил"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Преглед на слика од екранот"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Горна граница <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Долна граница <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Лева граница <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Десна граница <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
+    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Сликите од екранот во работниот профил се зачувуваат во апликацијата <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Датотеки"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Снимач на екран"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Се обработува снимка од екран"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Тековно известување за сесија за снимање на екранот"</string>
@@ -731,8 +734,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi е исклучено"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth е исклучен"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"„Не вознемирувај“ е исклучено"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Вклучено е „Не вознемирувај“"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Едно автоматско правило (<xliff:g id="ID_1">%s</xliff:g>) ја вклучи „Не вознемирувај“."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Една апликација (<xliff:g id="ID_1">%s</xliff:g>) ја вклучи „Не вознемирувај“."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Едно автоматско правило или апликација ја вклучи „Не вознемирувај“."</string>
@@ -850,9 +852,12 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Пуштете <xliff:g id="SONG_NAME">%1$s</xliff:g> на <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Врати"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Приближете се за да пуштите на <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Приближете се до <xliff:g id="DEVICENAME">%1$s</xliff:g> за да пуштите тука"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Пуштено на <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Нешто не е во ред. Обидете се повторно."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Се вчитува"</string>
+    <string name="media_ttt_default_device_type" msgid="4457646436153370169">"таблет"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Неактивна, провери апликација"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Не е најдено"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Контролата не е достапна"</string>
@@ -875,6 +880,8 @@
     <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">"Звучници и екрани"</string>
+    <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Предложени уреди"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Како функционира емитувањето"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Емитување"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Луѓето во ваша близина со компатибилни уреди со Bluetooth може да ги слушаат аудиозаписите што ги емитувате"</string>
@@ -998,14 +1005,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Отворете ја <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"За да ја додадете апликацијата <xliff:g id="APPNAME">%1$s</xliff:g> како кратенка, треба да бидат исполнети следниве услови"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• апликацијата е поставена"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• најмалку една картичка е додадена во Wallet"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• инсталирана е апликација за камера"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• апликацијата е поставена"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• достапен е најмалку еден уред"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Допрете и задржете ја кратенката"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Откажи"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Префрли сега"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Отворете го телефонот за подобро селфи"</string>
@@ -1014,6 +1019,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Екранов ќе се исклучи"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Преклопувачки уред се отклопува"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Преклопувачки уред се врти"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 6f52102..ac5c074 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -85,11 +85,14 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"സ്‌ക്രീൻഷോട്ട് പങ്കിടുക"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"കൂടുതൽ ക്യാപ്‌ചർ ചെയ്യുക"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"സ്ക്രീൻഷോട്ട് ഡിസ്‌മിസ് ചെയ്യുക"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"ഔദ്യോഗിക പ്രൊഫൈൽ സന്ദേശം ഡിസ്‌മിസ് ചെയ്യുക"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"സ്‌ക്രീൻഷോട്ട് പ്രിവ്യു"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"മുകളിലെ അതിർത്തി <xliff:g id="PERCENT">%1$d</xliff:g> ശതമാനം"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"താഴെയുള്ള അതിർത്തി <xliff:g id="PERCENT">%1$d</xliff:g> ശതമാനം"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ഇടത് വശത്തെ അതിർത്തി <xliff:g id="PERCENT">%1$d</xliff:g> ശതമാനം"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"വലത് വശത്തെ അതിർത്തി <xliff:g id="PERCENT">%1$d</xliff:g> ശതമാനം"</string>
+    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"ഔദ്യോഗിക പ്രൊഫൈലിന്റെ സ്ക്രീന്‍ഷോട്ടുകൾ <xliff:g id="APP">%1$s</xliff:g> ആപ്പിൽ സംരക്ഷിച്ചു"</string>
+    <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ഫയലുകൾ"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"സ്ക്രീൻ റെക്കോർഡർ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"സ്ക്രീൻ റെക്കോർഡിംഗ് പ്രോസസുചെയ്യുന്നു"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ഒരു സ്ക്രീൻ റെക്കോർഡിംഗ് സെഷനായി നിലവിലുള്ള അറിയിപ്പ്"</string>
@@ -731,8 +734,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"വൈഫൈ ഓഫാണ്"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth ഓഫാണ്"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"\'ശല്യപ്പെടുത്തരുത്\' ഓഫാണ്"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"\'ശല്യപ്പെടുത്തരുത്\' ഓണാണ്"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"സ്വയമേവയുള്ള ഒരു നയം (<xliff:g id="ID_1">%s</xliff:g>) \'ശല്യപ്പെടുത്തരുത്\' ഓണാക്കിയിരിക്കുന്നു."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"ഒരു ആപ്പ് (<xliff:g id="ID_1">%s</xliff:g>) \'ശല്യപ്പെടുത്തരുത്\' ഓണാക്കിയിരിക്കുന്നു."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"സ്വയമേവയുള്ള ഒരു നയമോ ആപ്പോ \'ശല്യപ്പെടുത്തരുത്\' ഓണാക്കിയിരിക്കുന്നു."</string>
@@ -850,9 +852,12 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> എന്ന ഗാനം <xliff:g id="APP_LABEL">%2$s</xliff:g> ആപ്പിൽ പ്ലേ ചെയ്യുക"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"പഴയപടിയാക്കുക"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> എന്നതിൽ പ്ലേ ചെയ്യാൻ അടുത്തേക്ക് നീക്കുക"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ഇവിടെ പ്ലേ ചെയ്യാൻ <xliff:g id="DEVICENAME">%1$s</xliff:g> എന്നതിന് അടുത്തേക്ക് നീക്കുക"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> എന്നതിൽ പ്ലേ ചെയ്യുന്നു"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"എന്തോ കുഴപ്പമുണ്ടായി. വീണ്ടും ശ്രമിക്കുക."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"ലോഡ് ചെയ്യുന്നു"</string>
+    <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ടാബ്‌ലെറ്റ്"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"നിഷ്‌ക്രിയം, ആപ്പ് പരിശോധിക്കൂ"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"കണ്ടെത്തിയില്ല"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"നിയന്ത്രണം ലഭ്യമല്ല"</string>
@@ -875,6 +880,8 @@
     <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">"സ്‌പീക്കറുകളും ഡിസ്പ്ലേകളും"</string>
+    <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"നിർദ്ദേശിച്ച ഉപകരണങ്ങൾ"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ബ്രോഡ്‌കാസ്‌റ്റ് എങ്ങനെയാണ് പ്രവർത്തിക്കുന്നത്"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ബ്രോഡ്‌കാസ്റ്റ്"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"അനുയോജ്യമായ Bluetooth ഉപകരണങ്ങളോടെ സമീപമുള്ള ആളുകൾക്ക് നിങ്ങൾ ബ്രോഡ്‌കാസ്‌റ്റ് ചെയ്യുന്ന മീഡിയ കേൾക്കാനാകും"</string>
@@ -998,14 +1005,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> തുറക്കുക"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"കുറുക്കുവഴിയായി <xliff:g id="APPNAME">%1$s</xliff:g> ആപ്പ് ചേർക്കാൻ, ഇനിപ്പറയുന്ന കാര്യങ്ങൾ ഉറപ്പാക്കുക"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• ആപ്പ് സജ്ജീകരിച്ചിട്ടുണ്ട്"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Wallet-ലേക്ക് ഒരു കാർഡെങ്കിലും ചേർത്തിട്ടുണ്ട്"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• ഒരു ക്യാമറാ ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്തിട്ടുണ്ട്"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• ആപ്പ് സജ്ജീകരിച്ചിട്ടുണ്ട്"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ഒരു ഉപകരണമെങ്കിലും ലഭ്യമാണ്"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"സ്പർശിച്ച് പിടിക്കുക കുറുക്കുവഴി"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"റദ്ദാക്കുക"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ഇപ്പോൾ ഫ്ലിപ്പ് ചെയ്യൂ"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"കൂടുതൽ മികച്ച സെൽഫി ലഭിക്കാൻ ഫോൺ അൺഫോൾഡ് ചെയ്യൂ"</string>
@@ -1014,6 +1019,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ഈ സ്ക്രീൻ ഓഫാകും"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ഫോൾഡ് ചെയ്യാവുന്ന ഉപകരണം അൺഫോൾഡ് ആകുന്നു"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ഫോൾഡ് ചെയ്യാവുന്ന ഉപകരണം, കറങ്ങുന്ന വിധത്തിൽ ഫ്ലിപ്പ് ആകുന്നു"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 0540abf..cb77336 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Дэлгэцийн агшныг хуваалцах"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Ихийг багтаасан зураг авах"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Дэлгэцийн агшныг хаах"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Ажлын профайлын мессежийг хаах"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Дэлгэцийн агшныг урьдчилан үзэх"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Дээд талын хязгаар <xliff:g id="PERCENT">%1$d</xliff:g> хувь"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Доод талын хязгаар <xliff:g id="PERCENT">%1$d</xliff:g> хувь"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Зүүн талын хязгаар <xliff:g id="PERCENT">%1$d</xliff:g> хувь"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Баруун талын хязгаар <xliff:g id="PERCENT">%1$d</xliff:g> хувь"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Дэлгэцийн үйлдэл бичигч"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Дэлгэц бичлэг боловсруулж байна"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Дэлгэц бичих горимын үргэлжилж буй мэдэгдэл"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi унтраалттай байна"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth унтраалттай байна"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Бүү саад бол горим унтраалттай байна"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Бүү саад бол горим асаалттай байна"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Автомат дүрэм (<xliff:g id="ID_1">%s</xliff:g>) Бүү саад бол горимыг асаасан."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Апп (<xliff:g id="ID_1">%s</xliff:g>) Бүү саад бол горимыг асаасан."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Автомат дүрэм эсвэл апп Бүү саад бол горимыг асаасан."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g>-г <xliff:g id="APP_LABEL">%2$s</xliff:g> дээр тоглуулах"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Болих"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> дээр тоглуулахын тулд төхөөрөмжөө ойртуулна уу"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Энд тоглуулахын тулд <xliff:g id="DEVICENAME">%1$s</xliff:g>-д ойртоно уу"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> дээр тоглуулж байна"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Алдаа гарлаа. Дахин оролдоно уу."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Ачаалж байна"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Идэвхгүй байна, аппыг шалгана уу"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Олдсонгүй"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Хяналт боломжгүй байна"</string>
@@ -875,6 +883,9 @@
     <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">"Чанга яригч ба дэлгэц"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Нэвтрүүлэлт хэрхэн ажилладаг вэ?"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Нэвтрүүлэлт"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Тохиромжтой Bluetooth төхөөрөмжүүдтэй таны ойролцоох хүмүүс таны нэвтрүүлж буй медиаг сонсох боломжтой"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g>-г нээх"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"<xliff:g id="APPNAME">%1$s</xliff:g> аппыг товчлолоор нэмэхийн тулд дараахыг баталгаажуулна уу"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Аппыг тохируулсан"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Дор хаяж нэг картыг Wallet-д нэмсэн"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Камер аппыг суулгах"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Аппыг тохируулсан"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Дор хаяж нэг төхөөрөмж боломжтой"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Товчлолд хүрээд удаан дарна уу"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Цуцлах"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Одоо хөнтрөх"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Илүү сайн селфи хийхийн тулд утсаа дэлгэнэ үү"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Энэ дэлгэц унтарна"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Эвхэгддэг төхөөрөмжийг дэлгэж байна"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Эвхэгддэг төхөөрөмжийг хөнтөрч байна"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 2a33bc1..4f0b83f 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"स्क्रीनशॉट शेअर करा"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"आणखी गोष्टी कॅप्चर करा"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"स्क्रीनशॉट डिसमिस करा"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"कार्य प्रोफाइलसंबंधित मेसेज डिसमिस करा"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"स्क्रीनशॉटचे पूर्वावलोकन"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"वरील सीमेपासून <xliff:g id="PERCENT">%1$d</xliff:g> टक्के"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"खालील सीमेपासून <xliff:g id="PERCENT">%1$d</xliff:g> टक्के"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"डाव्या सीमेपासून <xliff:g id="PERCENT">%1$d</xliff:g> टक्के"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"उजव्या सीमेपासून <xliff:g id="PERCENT">%1$d</xliff:g> टक्के"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"स्क्रीन रेकॉर्डर"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रीन रेकॉर्डिंग प्रोसेस सुरू"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"स्क्रीन रेकॉर्ड सत्रासाठी सुरू असलेली सूचना"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"वाय-फाय बंद आहे"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"ब्लूटूथ बंद आहे"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"व्यत्यय आणू नका बंद आहे"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"व्यत्यय आणू नका सुरू आहे"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"व्यत्यय आणू नका एका <xliff:g id="ID_1">%s</xliff:g> स्वयंचलित नियमाने सुरू केले."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"व्यत्यय आणू नका (<xliff:g id="ID_1">%s</xliff:g>) ॲपने सुरू केले."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"व्यत्यय आणू नका एका स्वयंचलित नियमाने किंवा ॲपने सुरू केले."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> मध्ये <xliff:g id="SONG_NAME">%1$s</xliff:g> प्ले करा"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"पहिल्यासारखे करा"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> वर प्ले करण्यासाठी जवळ जा"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"येथे प्ले करण्यासाठी <xliff:g id="DEVICENAME">%1$s</xliff:g> च्या जवळ जा"</string>
-    <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> वर प्ले केला जात आहे"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
+    <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> वर प्ले होत आहे"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"काहीतरी चूक झाली. पुन्हा प्रयत्न करा."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"लोड करत आहे"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"निष्क्रिय, ॲप तपासा"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"आढळले नाही"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"नियंत्रण उपलब्ध नाही"</string>
@@ -875,6 +883,9 @@
     <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">"स्पीकर आणि डिस्प्ले"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ब्रॉडकास्टिंग कसे काम करते"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ब्रॉडकास्ट करा"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"कंपॅटिबल ब्लूटूथ डिव्‍हाइस असलेले तुमच्या जवळपासचे लोक हे तुम्ही ब्रॉडकास्ट करत असलेला मीडिया ऐकू शकतात"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> उघडा"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"<xliff:g id="APPNAME">%1$s</xliff:g> हे अ‍ॅप शॉर्टकट म्हणून जोडण्यासाठी, पुढील गोष्टींची खात्री करा"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• अ‍ॅप सेट करणे"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Wallet मध्ये किमान एक कार्ड जोडणे"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• कॅमेरा अ‍ॅप इंस्टॉल करणे"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• अ‍ॅप सेट करणे"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• किमान एक डिव्हाइस उपलब्ध करणे"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"स्पर्श करा आणि धरून ठेवा शॉर्टकट"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"रद्द करा"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"आता फ्लिप करा"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"आणखी चांगल्या सेल्फीसाठी फोनबद्दल अधिक जाणून घ्या"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ही स्क्रीन बंद होईल"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"फोल्ड करता येण्यासारखे डिव्हाइस अनफोल्ड केले जात आहे"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"फोल्ड करता येण्यासारखे डिव्हाइस आजूबाजूला फ्लिप केले जात आहे"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index b595d39..f08f6a6 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Kongsi tangkapan skrin"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Tangkap lebih banyak"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Ketepikan tangkapan skrin"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Ketepikan mesej profil kerja"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Pratonton tangkapan skrin"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Sempadan atas <xliff:g id="PERCENT">%1$d</xliff:g> peratus"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Sempadan bawah <xliff:g id="PERCENT">%1$d</xliff:g> peratus"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Sempadan kiri <xliff:g id="PERCENT">%1$d</xliff:g> peratus"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Sempadan kanan <xliff:g id="PERCENT">%1$d</xliff:g> peratus"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Perakam Skrin"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Memproses rakaman skrin"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pemberitahuan breterusan untuk sesi rakaman skrin"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi dimatikan"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth dimatikan"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Jangan Ganggu dimatikan"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Jangan Ganggu dihidupkan"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Jangan Ganggu dihidupkan oleh peraturan automatik (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Jangan Ganggu dihidupkan oleh apl (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Jangan Ganggu dihidupkan oleh peraturan automatik atau apl."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Mainkan <xliff:g id="SONG_NAME">%1$s</xliff:g> daripada <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Buat asal"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Alihkan lebih dekat untuk bermain pada<xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Dekatkan dengan <xliff:g id="DEVICENAME">%1$s</xliff:g> untuk bermain di sini"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Dimainkan pada <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Kesilapan telah berlaku. Cuba lagi."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Memuatkan"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Tidak aktif, semak apl"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Tidak ditemukan"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kawalan tidak tersedia"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Peranti tersedia untuk audio output."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Kelantangan"</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">"Pembesar Suara &amp; Paparan"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cara siaran berfungsi"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Siarkan"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Orang berdekatan anda dengan peranti Bluetooth yang serasi boleh mendengar media yang sedang anda siarkan"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Buka <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Untuk menambahkan apl <xliff:g id="APPNAME">%1$s</xliff:g> sebagai pintasan, pastikan"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Apl disediakan"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Sekurang-kurangnya satu kad telah ditambahkan pada Wallet"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Pasang apl kamera"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Apl disediakan"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Sekurang-kurangnya satu peranti tersedia"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pintasan sentuh &amp; tahan"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Batal"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Balikkan sekarang"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Buka telefon untuk swafoto yang lebih baik"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Skrin ini akan dimatikan"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Peranti boleh lipat dibuka"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Peranti boleh lipat diterbalikkan"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 627dd77..9b6e95c 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"ဖန်သားပြင်ဓာတ်ပုံကို မျှဝေနိုင်သည်"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"နောက်ထပ် ရိုက်ကူးရန်"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ဖန်သားပြင်ဓာတ်ပုံကို ပယ်သည်"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"အလုပ်ပရိုဖိုင်မက်ဆေ့ဂျ်ကို ပယ်ရန်"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ဖန်သားပြင်ဓာတ်ပုံ အစမ်းကြည့်ရှုခြင်း"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"ထိပ်ပိုင်းအနားသတ် <xliff:g id="PERCENT">%1$d</xliff:g> ရာခိုင်နှုန်း"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"အောက်ခြေအနားသတ် <xliff:g id="PERCENT">%1$d</xliff:g> ရာခိုင်နှုန်း"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ဘယ်ဘက်အနားသတ် <xliff:g id="PERCENT">%1$d</xliff:g> ရာခိုင်နှုန်း"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"ညာဘက်အနားသတ် <xliff:g id="PERCENT">%1$d</xliff:g> ရာခိုင်နှုန်း"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"ဖန်သားပြင် ရိုက်ကူးမှု"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"စကရင်ရိုက်ကူးမှု အပြီးသတ်နေသည်"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ဖန်သားပြင် ရိုက်ကူးသည့် စက်ရှင်အတွက် ဆက်တိုက်လာနေသော အကြောင်းကြားချက်"</string>
@@ -509,8 +514,8 @@
     <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"ဟော့စပေါ့"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"အလုပ် ပရိုဖိုင်"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"အချို့သူများ အတွက် ပျော်စရာ ဖြစ်ပေမဲ့ အားလုံး အတွက် မဟုတ်ပါ"</string>
-    <string name="tuner_warning" msgid="1861736288458481650">"စနစ် UI ဖမ်းစက်က သင့်အတွက် Android အသုံးပြုသူ အင်တာဖေ့စ်ကို ပြောင်းကြည့်ရန် နှင့် စိတ်ကြိုက်ပြုလုပ်ရန် နည်းလမ်း အပိုများကို သင့်အတွက် စီစဉ်ပေးသည်။ ဤ စမ်းသပ်ရေး အင်္ဂါရပ်များမှာ ပြောင်းလဲ၊ ကျိုးပျက် သို့မဟုတ် ပျောက်ကွယ် သွားနိုင်သည်။ သတိထားလျက် ဆက်လက် ဆောင်ရွက်ပါ။"</string>
-    <string name="tuner_persistent_warning" msgid="230466285569307806">"ဤ စမ်းသပ်ရေး အင်္ဂါရပ်များမှာ ပြောင်းလဲ၊ ကျိုးပျက် သို့မဟုတ် ပျောက်ကွယ် သွားနိုင်သည်။ သတိထားလျက် ဆက်လက် ဆောင်ရွက်ပါ။"</string>
+    <string name="tuner_warning" msgid="1861736288458481650">"စနစ် UI Tuner က သင့်အတွက် Android အသုံးပြုသူ အင်တာဖေ့စ်ကို ပြောင်းရန်နှင့် စိတ်ကြိုက်ပြုလုပ်ရန် နည်းလမ်း အပိုများကို သင့်အတွက် စီစဉ်ပေးသည်။ အနာဂတ်ဗားရှင်းများတွင် ဤစမ်းသပ်အင်္ဂါရပ်များမှာ ပြောင်းလဲ၊ ပျက်စီး သို့မဟုတ် ပျောက်ကွယ်သွားနိုင်သည်။ သတိဖြင့် ရှေ့ဆက်ပါ။"</string>
+    <string name="tuner_persistent_warning" msgid="230466285569307806">"အနာဂတ် ဗားရှင်းများတွင် ဤစမ်းသပ်အင်္ဂါရပ်များမှာ ပြောင်းလဲ၊ ပျက်စီး သို့မဟုတ် ပျောက်ကွယ်သွားနိုင်သည်။ သတိဖြင့် ရှေ့ဆက်ပါ။"</string>
     <string name="got_it" msgid="477119182261892069">"ရပါပြီ"</string>
     <string name="tuner_toast" msgid="3812684836514766951">"ဂုဏ်ပြုပါရစေ! စနစ် UI ဖမ်းစက်ကို ဆက်တင်ထဲသို့ ထည့်ပြီးပြီ။"</string>
     <string name="remove_from_settings" msgid="633775561782209994">"ဆက်တင် အထဲမှ ဖယ်ရှားရန်"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi ပိတ်ထားသည်"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"ဘလူးတုသ်ကို ပိတ်ထားသည်"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"\"မနှောင့်ယှက်ရ\" ကို ပိတ်ထားသည်"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"‘မနှောင့်ယှက်ရ’ ဖွင့်ထားသည်"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"\"မနှောင့်ယှက်ရ\" ကို အလိုအလျောက်စည်းမျဉ်း (<xliff:g id="ID_1">%s</xliff:g>) က ဖွင့်ခဲ့သည်။"</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"\"မနှောင့်ယှက်ရ\" ကို အက်ပ် (<xliff:g id="ID_1">%s</xliff:g>) က ဖွင့်ခဲ့သည်။"</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"\"မနှောင့်ယှက်ရ\" ကို အလိုအလျောက်စည်းမျဉ်းတစ်ခု သို့မဟုတ် အက်ပ်တစ်ခုက ဖွင့်ခဲ့သည်။"</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ကို <xliff:g id="APP_LABEL">%2$s</xliff:g> တွင် ဖွင့်ပါ"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"နောက်ပြန်ရန်"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> တွင်ဖွင့်ရန် အနီးသို့ရွှေ့ပါ"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ဤနေရာတွင်ဖွင့်ရန် <xliff:g id="DEVICENAME">%1$s</xliff:g> အနီးသို့တိုးပါ"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> တွင် ဖွင့်နေသည်"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"တစ်ခုခုမှားသွားသည်။ ထပ်စမ်းကြည့်ပါ။"</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"ဖွင့်နေသည်"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"ရပ်နေသည်၊ အက်ပ်ကို စစ်ဆေးပါ"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"မတွေ့ပါ"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"ထိန်းချုပ်မှု မရနိုင်ပါ"</string>
@@ -875,6 +883,9 @@
     <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">"စပီကာနှင့် ဖန်သားပြင်များ"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ထုတ်လွှင့်မှုဆောင်ရွက်ပုံ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ထုတ်လွှင့်ခြင်း"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"အနီးရှိတွဲသုံးနိုင်သော ဘလူးတုသ်သုံးစက် အသုံးပြုသူများက သင်ထုတ်လွှင့်နေသော မီဒီယာကို နားဆင်နိုင်သည်"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ဖွင့်ရန်"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"<xliff:g id="APPNAME">%1$s</xliff:g> အက်ပ်ကို ဖြတ်လမ်းလင့်ခ်အဖြစ် ထည့်ရန် အောက်ပါတို့နှင့်ကိုက်ညီရမည်"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• အက်ပ်ကို စနစ်ထည့်သွင်းထားရမည်"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Wallet တွင် အနည်းဆုံးကတ်တစ်ခု ထည့်ထားရမည်"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• ကင်မရာအက်ပ် ထည့်သွင်းထားရမည်"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• အက်ပ်ကို စနစ်ထည့်သွင်းထားရမည်"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• အနည်းဆုံး စက်တစ်ခုသုံးနိုင်ရမည်"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ဖြတ်လမ်းလင့်ခ်ကို ထိပြီးဖိထားပါ"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"မလုပ်တော့"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ယခုလှည့်လိုက်ပါ"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ပိုကောင်းသော ဆယ်လ်ဖီအတွက် ဖုန်းကိုဖြန့်လိုက်ပါ"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ဤဖန်သားပြင်ကို ပိတ်လိုက်မည်"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ခေါက်နိုင်သောစက်ကို ဖြန့်လိုက်သည်"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ခေါက်နိုင်သောစက်ကို တစ်ဘက်သို့ လှန်လိုက်သည်"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 8dbdd2f..7cc0a1a 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Del skjermdumpen"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Utvidet skjermdump"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Avvis skjermdumpen"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Avvis melding fra jobbprofilen"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Forhåndsvisning av skjermdump"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Øvre grense <xliff:g id="PERCENT">%1$d</xliff:g> prosent"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Nedre grense <xliff:g id="PERCENT">%1$d</xliff:g> prosent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Venstre grense <xliff:g id="PERCENT">%1$d</xliff:g> prosent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Høyre grense <xliff:g id="PERCENT">%1$d</xliff:g> prosent"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Skjermopptaker"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Behandler skjermopptaket"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Vedvarende varsel for et skjermopptak"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wifi er av"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth er av"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Ikke forstyrr er av"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Ikke forstyrr er på"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Ikke forstyrr ble slått på av en automatisk regel (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Ikke forstyrr ble slått på av en app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Ikke forstyrr ble slått på av en automatisk regel eller en app."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Spill av <xliff:g id="SONG_NAME">%1$s</xliff:g> fra <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Angre"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Flytt nærmere for å spille av på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Flytt deg nærmere <xliff:g id="DEVICENAME">%1$s</xliff:g> for å spille av her"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Spilles av på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Noe gikk galt. Prøv på nytt."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Laster inn"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv. Sjekk appen"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Ikke funnet"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrollen er utilgjengelig"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Tilgjengelige enheter for lydutgang."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volum"</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">"Høyttalere og skjermer"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Slik fungerer kringkasting"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Kringkasting"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Folk i nærheten med kompatible Bluetooth-enheter kan lytte til mediene du kringkaster"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Åpne <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"For å legge til <xliff:g id="APPNAME">%1$s</xliff:g>-appen som en snarvei må du sørge for at"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• appen er konfigurert"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• minst ett kort er lagt til i Wallet"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• en kameraapp er installert"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• appen er konfigurert"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• minst én enhet er tilgjengelig"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Trykk på og hold inne snarveien"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Avbryt"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Vend nå"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Brett ut telefonen for å ta bedre selfier"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Denne skjermen slås av"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"En sammenleggbar enhet blir brettet ut"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"En sammenleggbar enhet blir snudd"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 00e52a1..f8deac6 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"स्क्रिनसट सेयर गर्नुहोस्"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"अन्य कुराहरू खिच्नुहोस्"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"स्क्रिनसट हटाउनुहोस्"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"कार्य प्रोफाइलमा प्राप्त भएको म्यासेज हटाउनुहोस्"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"स्क्रिनसटको पूर्वावलोकन"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"सिरानबाट <xliff:g id="PERCENT">%1$d</xliff:g> प्रतिशत"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"फेदबाट <xliff:g id="PERCENT">%1$d</xliff:g> प्रतिशत"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"बायाँ किनाराबाट <xliff:g id="PERCENT">%1$d</xliff:g> प्रतिशत"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"दायाँ किनाराबाट <xliff:g id="PERCENT">%1$d</xliff:g> प्रतिशत"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"स्क्रिन रेकर्डर"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रिन रेकर्डिङको प्रक्रिया अघि बढाइँदै"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"कुनै स्क्रिन रेकर्ड गर्ने सत्रका लागि चलिरहेको सूचना"</string>
@@ -371,10 +376,10 @@
     <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"रेकर्ड गर्न वा cast गर्न थाल्ने हो?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> मार्फत रेकर्ड गर्न वा cast गर्न थाल्ने हो?"</string>
     <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> लाई सेयर गर्न वा रेकर्ड गर्न दिने हो?"</string>
-    <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"पूर्ण स्क्रिन"</string>
+    <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"सबै स्क्रिन"</string>
     <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"एकल एप"</string>
-    <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"तपाईंले सेयर गर्दा, रेकर्ड गर्दा वा कास्ट गर्दा<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ले तपाईंको स्क्रिनमा देखिने वा डिभाइसमा प्ले गरिएका सबै कुरा खिच्न सक्छ। त्यसैले सेयर, रेकर्ड वा कास्ट गर्दा पासवर्ड, भुक्तानीको विवरण, म्यासेज वा अन्य संवेदनशील जानकारी सुरक्षित राख्नुहोला।"</string>
-    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"तपाईंले सेयर गर्दा, रेकर्ड गर्दा वा कास्ट गर्दा<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ले तपाईंको स्क्रिनमा देखिने वा डिभाइसमा प्ले गरिएका सबै कुरा खिच्न सक्छ। त्यसैले पासवर्ड, भुक्तानीको विवरण, म्यासेज वा अन्य संवेदनशील जानकारी सुरक्षित राख्नुहोला।"</string>
+    <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"तपाईंले सेयर गर्दा, रेकर्ड गर्दा वा कास्ट गर्दा <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ले तपाईंको स्क्रिनमा देखिने वा डिभाइसमा प्ले गरिएका सबै कुरा खिच्न सक्छ। त्यसैले सेयर, रेकर्ड वा कास्ट गर्दा  पासवर्ड, भुक्तानीको विवरण, म्यासेज वा अन्य संवेदनशील जानकारी सुरक्षित राख्नुहोला।"</string>
+    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"तपाईंले सेयर गर्दा, रेकर्ड गर्दा वा कास्ट गर्दा <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ले तपाईंको स्क्रिनमा देखिने वा डिभाइसमा प्ले गरिएका सबै कुरा खिच्न सक्छ। त्यसैले पासवर्ड, भुक्तानीको विवरण, म्यासेज वा अन्य संवेदनशील जानकारी सुरक्षित राख्नुहोला।"</string>
     <string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"जारी राख्नुहोस्"</string>
     <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"सेयर वा रेकर्ड गर्नका लागि एप चयन गर्नुहोस्"</string>
     <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"यो एपलाई सेयर गर्न वा रेकर्ड गर्न दिने हो?"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi‑Fi अफ छ"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"ब्लुटुथ निष्क्रिय छ"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"बाधा नपुर्‍याउनुहोस् नामक विकल्प निष्क्रिय छ"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Do Not Disturb अन छ"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"कुनै स्वचालित नियमले बाधा नपुऱ्याउनुहोस् नामक विकल्पलाई सक्रियो गऱ्यो (<xliff:g id="ID_1">%s</xliff:g>)।"</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"कुनै अनुप्रयोगले बाधा नपुऱ्याउनुहोस् नामक विकल्पलाई सक्रिय गऱ्यो (<xliff:g id="ID_1">%s</xliff:g>)।"</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"कुनै स्वचालित नियम वा अनुप्रयोगले बाधा नपुऱ्याउनुहोस् नामक विकल्पलाई सक्रिय गऱ्यो।"</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> बोलको गीत <xliff:g id="APP_LABEL">%2$s</xliff:g> मा बजाउनुहोस्"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"अन्डू गर्नुहोस्"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> मा प्ले गर्न आफ्नो डिभाइस नजिकै लैजानुहोस्"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"तपाईं यहाँ प्ले गर्न चाहनुहुन्छ भने आफ्नो डिभाइसलाई <xliff:g id="DEVICENAME">%1$s</xliff:g> नजिकै लैजानुहोस्"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> मा प्ले गरिँदै छ"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"केही चिज गडबड भयो। फेरि प्रयास गर्नुहोस्।"</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"लोड हुँदै छ"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"निष्क्रिय छ, एप जाँच गर्नु…"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"फेला परेन"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"नियन्त्रण उपलब्ध छैन"</string>
@@ -875,6 +883,9 @@
     <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">"स्पिकर तथा डिस्प्लेहरू"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"प्रसारण गर्ने सुविधाले कसरी काम गर्छ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"प्रसारण"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"कम्प्याटिबल ब्लुटुथ डिभाइस भएका नजिकैका मान्छेहरू तपाईंले प्रसारण गरिरहनुभएको मिडिया सुन्न सक्छन्"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> खोल्नुहोस्"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"<xliff:g id="APPNAME">%1$s</xliff:g> एपलाई सर्टकटका रूपमा हाल्न, निम्न कुराको सुनिश्चित गर्नुहोस्:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• एप सेटअप गरिएको छ"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Wallet मा कम्तीमा एउटा कार्ड हालिएको छ"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• क्यामेरा एप इन्स्टल गरिएको छ"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• एप सेटअप गरिएको छ"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• कम्तीमा एउटा डिभाइस उपलब्ध छ"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"सर्टकट थिचिराख्नुहोस्"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"रद्द गर्नुहोस्"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"अहिले नै फ्लिप गर्नुहोस्"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"अझ राम्रो सेल्फी खिच्न फोन अनफोल्ड गर्नुहोस्"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ यो स्क्रिन अफ हुने छ"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"फोल्ड गर्न मिल्ने डिभाइस अनफोल्ड गरेको देखाइएको एनिमेसन"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"फोल्ड गर्न मिल्ने डिभाइस यताउता पल्टाएर देखाइएको एनिमेसन"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 6171235..7a0b6d3 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Screenshot delen"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Meer opnemen"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Screenshot sluiten"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Bericht over werkprofiel sluiten"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Voorbeeld van screenshot"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Bovengrens <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Ondergrens <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Linkergrens <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Rechtergrens <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Schermopname"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Schermopname verwerken"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Doorlopende melding voor een schermopname-sessie"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wifi staat uit"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth staat uit"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Niet storen staat uit"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Niet storen staat aan"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Niet storen is aangezet door een automatische regel (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Niet storen is aangezet door een app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Niet storen is aangezet door een automatische regel of app."</string>
@@ -849,10 +853,14 @@
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="SONG_NAME">%1$s</xliff:g> van <xliff:g id="ARTIST_NAME">%2$s</xliff:g> afspelen via <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> afspelen via <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Ongedaan maken"</string>
-    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Ga dichter naar <xliff:g id="DEVICENAME">%1$s</xliff:g> toe om af te spelen"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Ga dichter bij <xliff:g id="DEVICENAME">%1$s</xliff:g> staan om hier af te spelen"</string>
+    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Houd dichter bij <xliff:g id="DEVICENAME">%1$s</xliff:g> om af te spelen"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Afspelen op <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Er is iets misgegaan. Probeer het opnieuw."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Laden"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactief, check de app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Niet gevonden"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Beheeroptie niet beschikbaar"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Beschikbare apparaten voor audio-uitvoer."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</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">"Speakers en schermen"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Hoe uitzenden werkt"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Uitzending"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Mensen bij jou in de buurt met geschikte bluetooth-apparaten kunnen luisteren naar de media die je uitzendt"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"u:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> openen"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Zorg voor het volgende om de <xliff:g id="APPNAME">%1$s</xliff:g>-app toe te voegen als snelkoppeling:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• De app is ingesteld"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Er is ten minste één kaart aan Wallet toegevoegd"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Er moet een camera-app zijn geïnstalleerd"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• De app is ingesteld"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Er is ten minste één apparaat beschikbaar"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Houd de sneltoets ingedrukt"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annuleren"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Nu omkeren"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Klap de telefoon open voor een betere selfie"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Dit scherm gaat uit"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Opvouwbaar apparaat wordt uitgevouwen"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Opvouwbaar apparaat wordt gedraaid"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 40b335a..6a3a282 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"ସ୍କ୍ରିନସଟ ସେୟାର କରନ୍ତୁ"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"ଅଧିକ କ୍ୟାପଚର୍ କରନ୍ତୁ"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ସ୍କ୍ରିନସଟ୍ ଖାରଜ କରନ୍ତୁ"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"ୱାର୍କ ପ୍ରୋଫାଇଲ ମେସେଜକୁ ଖାରଜ କରନ୍ତୁ"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ସ୍କ୍ରିନସଟର ପ୍ରିଭ୍ୟୁ"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"ଶୀର୍ଷ ସୀମାରେଖା <xliff:g id="PERCENT">%1$d</xliff:g> ଶତକଡ଼ା"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"ନିମ୍ନ ସୀମାରେଖା <xliff:g id="PERCENT">%1$d</xliff:g> ଶତକଡ଼ା"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ବାମ ସୀମାରେଖା <xliff:g id="PERCENT">%1$d</xliff:g> ଶତକଡ଼ା"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"ଡାହାଣ ସୀମାରେଖା <xliff:g id="PERCENT">%1$d</xliff:g> ଶତକଡ଼ା"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"ସ୍କ୍ରିନ୍ ରେକର୍ଡର୍"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ସ୍କ୍ରିନ ରେକର୍ଡିଂର ପ୍ରକ୍ରିୟାକରଣ"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ଏକ ସ୍କ୍ରି‍ନ୍‍ ରେକର୍ଡ୍‍ ସେସନ୍‍ ପାଇଁ ଚାଲୁଥିବା ବିଜ୍ଞପ୍ତି"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"ୱାଇ-ଫାଇ ବନ୍ଦ ଅଛି"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"ବ୍ଲୁଟୂଥ୍‍‌ ଅଫ୍ ଅଛି"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଅଫ୍‍ ଅଛି"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଚାଲୁ ଅଛି"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ଏକ (<xliff:g id="ID_1">%s</xliff:g>) ନିୟମ ଦ୍ୱାରା \"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ସ୍ୱଚାଳିତ ଭାବେ ଅନ୍‍ କରାଗଲା।"</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"ଏକ ଆପ୍‍ (<xliff:g id="ID_1">%s</xliff:g>) ଦ୍ୱାରା \"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଅନ୍‌ କରାଗଲା।"</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ଏକ ସ୍ୱଚାଳିତ ନିୟମ କିମ୍ବା ଆପ୍‍ ଦ୍ୱାରା \"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଅନ୍‍ କରାଗଲା।"</string>
@@ -849,10 +853,14 @@
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g>ରୁ <xliff:g id="ARTIST_NAME">%2$s</xliff:g>ଙ୍କ <xliff:g id="SONG_NAME">%1$s</xliff:g> ଚଲାନ୍ତୁ"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g>ରୁ <xliff:g id="SONG_NAME">%1$s</xliff:g> ଚଲାନ୍ତୁ"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"ପୂର୍ବବତ୍ କରନ୍ତୁ"</string>
-    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>ରେ ଚଲାଇବା ପାଇଁ ପାଖକୁ ମୁଭ କରନ୍ତୁ"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ଏଠାରେ ଚଲାଇବା ପାଇଁ <xliff:g id="DEVICENAME">%1$s</xliff:g>ର ପାଖକୁ ମୁଭ କରନ୍ତୁ"</string>
-    <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>ରେ ଚାଲୁଛି"</string>
+    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>ରେ ପ୍ଲେ କରିବା ପାଇଁ ପାଖକୁ ମୁଭ କରନ୍ତୁ"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
+    <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>ରେ ପ୍ଲେ ହେଉଛି"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"କିଛି ତ୍ରୁଟି ହୋଇଛି। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"ଲୋଡ ହେଉଛି"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"ନିଷ୍କ୍ରିୟ ଅଛି, ଆପ ଯାଞ୍ଚ କରନ୍ତୁ"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"ମିଳିଲା ନାହିଁ"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"ନିୟନ୍ତ୍ରଣ ଉପଲବ୍ଧ ନାହିଁ"</string>
@@ -875,6 +883,9 @@
     <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">"ସ୍ପିକର ଏବଂ ଡିସପ୍ଲେଗୁଡ଼ିକ"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ବ୍ରଡକାଷ୍ଟିଂ କିପରି କାମ କରେ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ବ୍ରଡକାଷ୍ଟ"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ଆପଣଙ୍କ ଆଖପାଖର କମ୍ପାଟିବଲ ବ୍ଲୁଟୁଥ ଡିଭାଇସ ଥିବା ଲୋକମାନେ ଆପଣ ବ୍ରଡକାଷ୍ଟ କରୁଥିବା ମିଡିଆ ଶୁଣିପାରିବେ"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ଖୋଲନ୍ତୁ"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"ଏକ ସର୍ଟକଟ ଭାବେ <xliff:g id="APPNAME">%1$s</xliff:g> ଆପ ଯୋଗ କରିବାକୁ, ଏହା ସୁନିଶ୍ଚିତ କରନ୍ତୁ"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• ଆପ ସେଟ ଅପ କରାଯାଇଥିବା"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Walletରେ ଅତିକମରେ ଗୋଟିଏ କାର୍ଡ ଯୋଗ କରାଯାଇଥିବା"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• ଏକ କେମେରା ଆପ ଇନଷ୍ଟଲ କରିବା"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• ଆପ ସେଟ ଅପ କରାଯାଇଛି"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ଅତିକମରେ ଗୋଟିଏ ଡିଭାଇସ ଉପଲବ୍ଧ ଅଛି"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ସର୍ଟକଟକୁ ସ୍ପର୍ଶ କରି ଧରି ରଖନ୍ତୁ"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ବାତିଲ କରନ୍ତୁ"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ବର୍ତ୍ତମାନ ଫ୍ଲିପ କରନ୍ତୁ"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ଏକ ଉନ୍ନତ ସେଲ୍ଫି ପାଇଁ ଫୋନକୁ ଅନଫୋଲ୍ଡ କରନ୍ତୁ"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ଏହି ସ୍କ୍ରିନ ବନ୍ଦ ହୋଇଯିବ"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ଫୋଲ୍ଡ କରାଯାଇପାରୁଥିବା ଡିଭାଇସକୁ ଅନଫୋଲ୍ଡ କରାଯାଉଛି"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ଫୋଲ୍ଡ କରାଯାଇପାରୁଥିବା ଡିଭାଇସକୁ ଫ୍ଲିପ କରାଯାଉଛି"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index b6d9121..c4dd6b4 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਸਾਂਝਾ ਕਰੋ"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"ਹੋਰ ਕੈਪਚਰ ਕਰੋ"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਖਾਰਜ ਕਰੋ"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਦੇ ਸੁਨੇਹੇ ਨੂੰ ਖਾਰਜ ਕਰੋ"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਪੂਰਵ-ਝਲਕ"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"ਉੱਪਰ ਦੀ ਸੀਮਾ <xliff:g id="PERCENT">%1$d</xliff:g> ਫ਼ੀਸਦ"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"ਹੇਠਾਂ ਦੀ ਸੀਮਾ <xliff:g id="PERCENT">%1$d</xliff:g> ਫ਼ੀਸਦ"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ਖੱਬੇ ਪਾਸੇ ਵਾਲੀ ਸੀਮਾ <xliff:g id="PERCENT">%1$d</xliff:g> ਫ਼ੀਸਦ"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"ਸੱਜੇ ਪਾਸੇ ਵਾਲੀ ਸੀਮਾ <xliff:g id="PERCENT">%1$d</xliff:g> ਫ਼ੀਸਦ"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਰ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਜਾਰੀ ਹੈ"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ਕਿਸੇ ਸਕ੍ਰੀਨ ਰਿਕਾਰਡ ਸੈਸ਼ਨ ਲਈ ਚੱਲ ਰਹੀ ਸੂਚਨਾ"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"ਵਾਈ-ਫਾਈ ਬੰਦ ਹੈ"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"ਬਲੂਟੁੱਥ ਬੰਦ ਹੈ"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਬੰਦ ਹੈ"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਚਾਲੂ ਹੈ"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ਸਵੈਚਲਿਤ ਨਿਯਮ (<xliff:g id="ID_1">%s</xliff:g>) ਦੁਆਰਾ \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਚਾਲੂ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"ਐਪ (<xliff:g id="ID_1">%s</xliff:g>) ਵੱਲੋਂ \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਚਾਲੂ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ਇੱਕ ਸਵੈਚਲਿਤ ਨਿਯਮ ਜਾਂ ਐਪ ਵੱਲੋਂ \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਚਾਲੂ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> ਤੋਂ <xliff:g id="SONG_NAME">%1$s</xliff:g> ਚਲਾਓ"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"ਅਣਕੀਤਾ ਕਰੋ"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> \'ਤੇ ਚਲਾਉਣ ਲਈ ਨੇੜੇ ਲਿਜਾਓ"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ਇੱਥੇ ਚਲਾਉਣ ਲਈ <xliff:g id="DEVICENAME">%1$s</xliff:g> ਦੇ ਨੇੜੇ ਜਾਓ"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> \'ਤੇ ਚਲਾਇਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"ਕੋਈ ਗੜਬੜ ਹੋ ਗਈ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"ਲੋਡ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"ਅਕਿਰਿਆਸ਼ੀਲ, ਐਪ ਦੀ ਜਾਂਚ ਕਰੋ"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"ਨਹੀਂ ਮਿਲਿਆ"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"ਕੰਟਰੋਲ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
@@ -875,6 +883,9 @@
     <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">"ਸਪੀਕਰ ਅਤੇ ਡਿਸਪਲੇਆਂ"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ਪ੍ਰਸਾਰਨ ਕਿਵੇਂ ਕੰਮ ਕਰਦਾ ਹੈ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ਪ੍ਰਸਾਰਨ"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ਅਨੁਰੂਪ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ ਨਾਲ ਨਜ਼ਦੀਕੀ ਲੋਕ ਤੁਹਾਡੇ ਵੱਲੋਂ ਪ੍ਰਸਾਰਨ ਕੀਤੇ ਜਾ ਰਹੇ ਮੀਡੀਆ ਨੂੰ ਸੁਣ ਸਕਦੇ ਹਨ"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ਖੋਲ੍ਹੋ"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"<xliff:g id="APPNAME">%1$s</xliff:g> ਐਪ ਨੂੰ ਸ਼ਾਰਟਕੱਟ ਵਜੋਂ ਸ਼ਾਮਲ ਕਰਨ ਲਈ, ਪੱਕਾ ਕਰੋ ਕਿ"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• ਐਪ ਦਾ ਸੈੱਟਅੱਪ ਹੋ ਗਿਆ ਹੈ"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• ਘੱਟੋ-ਘੱਟ ਇੱਕ ਕਾਰਡ ਨੂੰ Wallet ਵਿੱਚ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• ਕੈਮਰਾ ਐਪ ਸਥਾਪਤ ਕਰੋ"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• ਐਪ ਦਾ ਸੈੱਟਅੱਪ ਹੋ ਗਿਆ ਹੈ"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ਘੱਟੋ-ਘੱਟ ਇੱਕ ਡੀਵਾਈਸ ਉਪਲਬਧ ਹੈ"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ਸ਼ਾਰਟਕੱਟ ਨੂੰ ਸਪਰਸ਼ ਕਰ ਕੇ ਰੱਖੋ"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ਰੱਦ ਕਰੋ"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ਹੁਣੇ ਫਲਿੱਪ ਕਰੋ"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ਬਿਹਤਰ ਸੈਲਫ਼ੀ ਲਈ ਫ਼ੋਨ ਨੂੰ ਖੋਲ੍ਹੋ"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ਇਹ ਸਕ੍ਰੀਨ ਬੰਦ ਹੋ ਜਾਵੇਗੀ"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ਮੋੜਨਯੋਗ ਡੀਵਾਈਸ ਨੂੰ ਖੋਲ੍ਹਿਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ਮੋੜਨਯੋਗ ਡੀਵਾਈਸ ਨੂੰ ਆਲੇ-ਦੁਆਲੇ ਫਲਿੱਪ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 5f71cc6..08a7ba1 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Udostępnij zrzut ekranu"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Zarejestruj więcej danych"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Zamknij zrzut ekranu"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Zamknij komunikat profilu służbowego"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Podgląd zrzutu ekranu"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Przycięcie górnej krawędzi o <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Przycięcie dolnej krawędzi o <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Przycięcie lewej krawędzi o <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Przycięcie prawej krawędzi o <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Nagrywanie ekranu"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Przetwarzam nagrywanie ekranu"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Stałe powiadomienie o sesji rejestrowania zawartości ekranu"</string>
@@ -376,7 +381,7 @@
     <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"Podczas udostępniania, nagrywania lub przesyłania treści aplikacja <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ma dostęp do wszystkiego, co jest widoczne na ekranie lub odtwarzane na urządzeniu. Zachowaj ostrożność w przypadku haseł, danych do płatności, wiadomości i innych informacji poufnych."</string>
     <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Podczas udostępniania, nagrywania lub przesyłania treści aplikacja <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ma dostęp do wszystkiego, co jest w niej wyświetlane lub odtwarzane. Zachowaj ostrożność w przypadku haseł, danych do płatności, wiadomości i innych informacji poufnych."</string>
     <string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Dalej"</string>
-    <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Udostępnianie i nagrywanie za pomocą aplikacji"</string>
+    <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Udostępnianie i nagrywanie aplikacji"</string>
     <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Zezwolić tej aplikacji na udostępnianie lub nagrywanie?"</string>
     <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Podczas udostępniania, nagrywania lub przesyłania treści ta aplikacja ma dostęp do wszystkiego, co jest widoczne na ekranie lub odtwarzane na urządzeniu. Zachowaj ostrożność w przypadku haseł, danych do płatności, wiadomości i innych informacji poufnych."</string>
     <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Podczas udostępniania, nagrywania lub przesyłania treści ta aplikacja ma dostęp do wszystkiego, co jest w niej wyświetlane lub odtwarzane. Zachowaj ostrożność w przypadku haseł, danych do płatności, wiadomości i innych informacji poufnych."</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi jest wyłączone"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth jest wyłączony"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Tryb Nie przeszkadzać jest wyłączony"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Tryb Nie przeszkadzać jest włączony"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Tryb Nie przeszkadzać został włączony przez regułę automatyczną (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Tryb Nie przeszkadzać został włączony przez aplikację (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Tryb Nie przeszkadzać został włączony przez regułę automatyczną lub aplikację."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Odtwórz utwór <xliff:g id="SONG_NAME">%1$s</xliff:g> w aplikacji <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Cofnij"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Przysuń się bliżej, aby odtwarzać na urządzeniu <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Zbliż do urządzenia <xliff:g id="DEVICENAME">%1$s</xliff:g>, aby na nim odtwarzać"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Odtwarzam na ekranie <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Coś poszło nie tak. Spróbuj ponownie."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Wczytuję"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Nieaktywny, sprawdź aplikację"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nie znaleziono"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Element jest niedostępny"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dostępne urządzenia do odtwarzania dźwięku."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Głośność"</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">"Głośniki i wyświetlacze"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Jak działa transmitowanie"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Transmisja"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Osoby w pobliżu ze zgodnymi urządzeniami Bluetooth mogą słuchać transmitowanych przez Ciebie multimediów"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Otwórz: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Aby dodać aplikację <xliff:g id="APPNAME">%1$s</xliff:g> jako skrót, upewnij się, że spełnione zostały te warunki:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Aplikacja została skonfigurowana."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Do Portfela została dodana co najmniej 1 karta."</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Zainstalowano aplikację aparatu."</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Aplikacja została skonfigurowana."</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Dostępne jest co najmniej 1 urządzenie."</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Skrót – naciśnij i przytrzymaj"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Anuluj"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Przełącz teraz"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Rozłóż telefon, aby uzyskać lepszej jakości selfie"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"* Ekran się wyłączy"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Składane urządzenie jest rozkładane"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Składane urządzenie jest obracane"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 11a4c69..fa5e83f 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -85,11 +85,14 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Compartilhar captura de tela"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Capturar mais"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Dispensar captura de tela"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Dispensar mensagem do perfil de trabalho"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Visualização de captura de tela"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Borda superior em <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Borda inferior em <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Borda esquerda em <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Borda direita em <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string>
+    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Capturas de tela do trabalho são salvas no app <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Gravador de tela"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processando gravação de tela"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificação contínua para uma sessão de gravação de tela"</string>
@@ -449,7 +452,7 @@
     <string name="screen_pinning_title" msgid="9058007390337841305">"O app está fixado"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Ela é mantida à vista até que seja liberada. Toque em Voltar e em Visão geral e mantenha essas opções pressionadas para liberar."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Ela é mantida à vista até que seja liberada. Toque em Voltar e em Início e mantenha essas opções pressionadas para liberar."</string>
-    <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Ele é mantido à vista até que seja liberado. Deslize para cima e mantenha pressionado para liberar."</string>
+    <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Ele é mantido à vista até que seja liberado. Deslize para cima pressione para liberar."</string>
     <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"Ela é mantida à vista até que seja liberada. Toque em Visão geral e mantenha essa opção pressionada para liberar."</string>
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Ela é mantida à vista até que seja liberada. Toque em Início e mantenha essa opção pressionada para liberar."</string>
     <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Dados pessoais podem ficar acessíveis (como contatos e conteúdo de e-mail)."</string>
@@ -731,8 +734,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"O Wi-Fi está desativado"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth desativado"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"O recurso Não perturbe está desativado"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"O \"Não perturbe\" está ativado"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"O recurso Não perturbe foi ativado por uma regra automática (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"O recurso Não perturbe foi ativado por um app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"O recurso Não perturbe foi ativado por uma regra automática ou app."</string>
@@ -850,9 +852,12 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Tocar <xliff:g id="SONG_NAME">%1$s</xliff:g> no app <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Desfazer"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Aproxime os dispositivos para tocar a mídia neste: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Aproxime-se do dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g> para abrir a mídia aqui"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Mídia aberta no dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Algo deu errado. Tente novamente."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Carregando"</string>
+    <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inativo, verifique o app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Não encontrado"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"O controle está indisponível"</string>
@@ -875,6 +880,8 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dispositivos disponíveis para saída de áudio."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</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">"Alto-falantes e telas"</string>
+    <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispositivos sugeridos"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Como funciona a transmissão"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Transmitir"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"As pessoas próximas a você com dispositivos Bluetooth compatíveis podem ouvir a mídia que você está transmitindo"</string>
@@ -998,14 +1005,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Para adicionar o app <xliff:g id="APPNAME">%1$s</xliff:g> como um atalho, verifique se:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• O app está disponível"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Pelo menos um cartão foi adicionado à Carteira"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Um app de câmera está instalado"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• O app está disponível"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Pelo menos um dispositivo está disponível"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Mantenha o atalho pressionado"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Virar agora"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Abra o smartphone para tirar uma selfie melhor"</string>
@@ -1014,6 +1019,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Esta tela vai ser desativada"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo dobrável sendo aberto"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo dobrável sendo virado"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 30410fd..fbedb3a 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -85,11 +85,14 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Partilhar captura de ecrã"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Capturar mais"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Ignorar captura de ecrã"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Ignore a mensagem do perfil de trabalho"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Pré-visualização da captura de ecrã"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Limite superior de <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Limite inferior de <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Limite esquerdo de <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Limite direito de <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string>
+    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"As capturas de ecrã do trabalho são guardadas na app <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Ficheiros"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Gravador de ecrã"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"A processar a gravação de ecrã"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificação persistente de uma sessão de gravação de ecrã"</string>
@@ -731,8 +734,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi desativado"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth desativado"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Não incomodar desativado"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Modo Não incomodar ativado"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"O modo Não incomodar foi ativado por uma regra automática (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"O modo Não incomodar foi ativado por uma app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"O modo Não incomodar foi ativado por uma regra automática ou por uma app."</string>
@@ -850,9 +852,12 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Reproduzir <xliff:g id="SONG_NAME">%1$s</xliff:g> a partir da app <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Anular"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Aproxime-se para reproduzir no dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Aproxime-se do dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g> para reproduzir aqui"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"A reproduzir no dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Algo correu mal. Tente novamente."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"A carregar"</string>
+    <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inativa. Consulte a app."</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Não encontrado."</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"O controlo está indisponível"</string>
@@ -875,6 +880,8 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dispositivos disponíveis para a saída de áudio."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</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">"Altifalantes e ecrãs"</string>
+    <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispositivos sugeridos"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Como funciona a transmissão"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Transmissão"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"As pessoas próximas de si com dispositivos Bluetooth compatíveis podem ouvir o conteúdo multimédia que está a transmitir"</string>
@@ -998,14 +1005,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Para adicionar a app <xliff:g id="APPNAME">%1$s</xliff:g> como um atalho, garanta"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• A app está configurada"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Foi adicionado, pelo menos, um cartão à Carteira"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Instale uma app de câmara"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• A app está configurada"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Está disponível, pelo menos, um dispositivo"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Toque sem soltar no atalho"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Inverter agora"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Desdobre o telemóvel para uma selfie melhor"</string>
@@ -1014,6 +1019,6 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Este ecrã vai ser desligado"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo dobrável a ser desdobrado"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo dobrável a ser virado ao contrário"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
-    <skip />
+    <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> de bateria restante"</string>
+    <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Ligue a caneta stylus a um carregador"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 11a4c69..fa5e83f 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -85,11 +85,14 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Compartilhar captura de tela"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Capturar mais"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Dispensar captura de tela"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Dispensar mensagem do perfil de trabalho"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Visualização de captura de tela"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Borda superior em <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Borda inferior em <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Borda esquerda em <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Borda direita em <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string>
+    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Capturas de tela do trabalho são salvas no app <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Gravador de tela"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processando gravação de tela"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificação contínua para uma sessão de gravação de tela"</string>
@@ -449,7 +452,7 @@
     <string name="screen_pinning_title" msgid="9058007390337841305">"O app está fixado"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Ela é mantida à vista até que seja liberada. Toque em Voltar e em Visão geral e mantenha essas opções pressionadas para liberar."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Ela é mantida à vista até que seja liberada. Toque em Voltar e em Início e mantenha essas opções pressionadas para liberar."</string>
-    <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Ele é mantido à vista até que seja liberado. Deslize para cima e mantenha pressionado para liberar."</string>
+    <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Ele é mantido à vista até que seja liberado. Deslize para cima pressione para liberar."</string>
     <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"Ela é mantida à vista até que seja liberada. Toque em Visão geral e mantenha essa opção pressionada para liberar."</string>
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Ela é mantida à vista até que seja liberada. Toque em Início e mantenha essa opção pressionada para liberar."</string>
     <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Dados pessoais podem ficar acessíveis (como contatos e conteúdo de e-mail)."</string>
@@ -731,8 +734,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"O Wi-Fi está desativado"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth desativado"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"O recurso Não perturbe está desativado"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"O \"Não perturbe\" está ativado"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"O recurso Não perturbe foi ativado por uma regra automática (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"O recurso Não perturbe foi ativado por um app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"O recurso Não perturbe foi ativado por uma regra automática ou app."</string>
@@ -850,9 +852,12 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Tocar <xliff:g id="SONG_NAME">%1$s</xliff:g> no app <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Desfazer"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Aproxime os dispositivos para tocar a mídia neste: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Aproxime-se do dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g> para abrir a mídia aqui"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Mídia aberta no dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Algo deu errado. Tente novamente."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Carregando"</string>
+    <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inativo, verifique o app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Não encontrado"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"O controle está indisponível"</string>
@@ -875,6 +880,8 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dispositivos disponíveis para saída de áudio."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</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">"Alto-falantes e telas"</string>
+    <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispositivos sugeridos"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Como funciona a transmissão"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Transmitir"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"As pessoas próximas a você com dispositivos Bluetooth compatíveis podem ouvir a mídia que você está transmitindo"</string>
@@ -998,14 +1005,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Para adicionar o app <xliff:g id="APPNAME">%1$s</xliff:g> como um atalho, verifique se:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• O app está disponível"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Pelo menos um cartão foi adicionado à Carteira"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Um app de câmera está instalado"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• O app está disponível"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Pelo menos um dispositivo está disponível"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Mantenha o atalho pressionado"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Virar agora"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Abra o smartphone para tirar uma selfie melhor"</string>
@@ -1014,6 +1019,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Esta tela vai ser desativada"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo dobrável sendo aberto"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo dobrável sendo virado"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 86f6205..deef076 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Trimite captura de ecran"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Surprinde mai mult"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Închide captura de ecran"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Mesaj de închidere a profilului de serviciu"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Previzualizare a capturii de ecran"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Marginea de sus la <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Marginea de jos la <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Marginea stângă la <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Marginea dreaptă la <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Recorder pentru ecran"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Se procesează înregistrarea"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificare în curs pentru o sesiune de înregistrare a ecranului"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Conexiunea Wi-Fi este dezactivată"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Funcția Bluetooth este dezactivată"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Funcția Nu deranja este dezactivată"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Funcția Nu deranja este activată"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Funcția Nu deranja a fost activată de o regulă automată (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Funcția Nu deranja a fost activată de o aplicație (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Funcția Nu deranja a fost activată de o regulă automată sau de o aplicație."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Redă <xliff:g id="SONG_NAME">%1$s</xliff:g> în <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Anulează"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Apropie-te pentru a reda pe <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Apropie-te de <xliff:g id="DEVICENAME">%1$s</xliff:g> ca să redai acolo"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Se redă pe <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"A apărut o eroare. Încearcă din nou."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Se încarcă"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactiv, verifică aplicația"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nu s-a găsit"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Comanda este indisponibilă"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dispozitive disponibile pentru ieșire audio."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volum"</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">"Difuzoare și afișaje"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cum funcționează transmisia"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Transmite"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Persoanele din apropiere cu dispozitive Bluetooth compatibile pot asculta conținutul pe care îl transmiți"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Deschide <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Pentru a adăuga aplicația <xliff:g id="APPNAME">%1$s</xliff:g> drept comandă rapidă, asigură-te"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Aplicația este configurată"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Cel puțin un card a fost adăugat în Portofel"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Instalează o aplicație pentru camera foto"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Aplicația este configurată"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Este disponibil cel puțin un dispozitiv"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Atinge lung comanda rapidă"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Anulează"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Întoarce-l acum"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Desfă telefonul pentru un selfie mai bun"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Acest ecran se va dezactiva"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispozitiv pliabil care este desfăcut"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispozitiv pliabil care este întors"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 28d5f40..97d0d70 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Поделиться скриншотом"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Увеличить площадь скриншота"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Закрыть скриншот"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Закрыть сообщение рабочего профиля"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Предварительный просмотр скриншота"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Граница сверху: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Граница снизу: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Граница слева: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Граница справа: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Запись видео с экрана"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обработка записи с экрана…"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Текущее уведомление для записи видео с экрана"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Модуль Wi-Fi отключен"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Модуль Bluetooth отключен"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Режим \"Не беспокоить\" отключен"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Режим \"Не беспокоить\" включен"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Режим \"Не беспокоить\" был включен специальным правилом (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Режим \"Не беспокоить\" был включен приложением (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Режим \"Не беспокоить\" был включен специальным правилом или приложением."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Воспроизвести медиафайл \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" из приложения \"<xliff:g id="APP_LABEL">%2$s</xliff:g>\""</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Отменить"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Чтобы начать трансляцию на устройстве \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\", подойдите к нему ближе."</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Для воспроизведения на этом устройстве подойдите ближе к другому (<xliff:g id="DEVICENAME">%1$s</xliff:g>)."</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Воспроизводится на устройстве \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\"."</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Произошла ошибка. Повторите попытку."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Загрузка…"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Нет ответа. Проверьте приложение."</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Не найдено."</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Управление недоступно"</string>
@@ -875,6 +883,9 @@
     <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">"Колонки и дисплеи"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Как работают трансляции"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Трансляция"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Находящиеся рядом с вами люди с совместимыми устройствами Bluetooth могут слушать медиафайлы, которые вы транслируете."</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Открыть \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Для добавления ярлыка приложения \"<xliff:g id="APPNAME">%1$s</xliff:g>\" должны выполняться следующие условия:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Приложение установлено."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• В Кошельке есть хотя бы одна карта."</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Установлено приложение камеры."</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Приложение установлено."</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Доступно хотя бы одно устройство."</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Нажмите и удерживайте ярлык"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Отмена"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Перевернуть сейчас"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Разложите телефон, чтобы селфи получилось лучше"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Этот экран отключится"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Складное устройство в разложенном виде"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Перевернутое складное устройство"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index f7cdcb10..63acd77 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"තිර රුව බෙදා ගන්න"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"තව ග්‍රහණය කරන්න"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"තිර රුව ඉවත ලන්න"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"කාර්යාල පැතිකඩ පණිවිඩය අස් කරන්න"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"තිර රූ පෙර දසුන"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"ඉහළ සීමාව සියයට <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"පහළ සීමාව සියයට <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"වම් සීමාව සියයට <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"දකුණු සීමාව සියයට <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"තිර රෙකෝඩරය"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"තිර පටිගත කිරීම සකසමින්"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"තිර පටිගත කිරීමේ සැසියක් සඳහා කෙරෙන දැනුම් දීම"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi ක්‍රියා විරහිතයි"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"බ්ලූටූත් ක්‍රියා විරහිතයි"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"බාධා නොකරන්න ක්‍රියා විරහිතයි"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"බාධා නොකරන්න ක්‍රියාත්මකයි"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ස්වයංක්‍රිය රීතියක් මගින් බාධා නොකරන්න ක්‍රියාත්මක කරන ලදී (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"යෙදුමක් මගින් බාධා නොකරන්න ක්‍රියාත්මක කරන ලදී (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ස්වයංක්‍රිය රීතියක් හෝ යෙදුමක් මගින් බාධා නොකරන්න ක්‍රියාත්මක කරන ලදී."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> <xliff:g id="APP_LABEL">%2$s</xliff:g> වෙතින් වාදනය කරන්න"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"පසුගමනය කරන්න"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> හි වාදනය කිරීමට වඩාත් ළං වන්න"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"මෙහි ක්‍රීඩා කිරීමට <xliff:g id="DEVICENAME">%1$s</xliff:g> වෙත වඩා සමීප වන්න"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> හි වාදනය කරමින්"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"යම් දෙයක් වැරදිණි. නැවත උත්සාහ කරන්න."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"පූරණය වේ"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"අක්‍රියයි, යෙදුම පරීක්ෂා කරන්න"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"හමු නොවිණි"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"පාලනය ලබා ගත නොහැකිය"</string>
@@ -875,6 +883,9 @@
     <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">"ස්පීකර් සහ සංදර්ශක"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"විකාශනය ක්‍රියා කරන ආකාරය"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"විකාශනය"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ගැළපෙන බ්ලූටූත් උපාංග සහිත ඔබ අවට සිටින පුද්ගලයින්ට ඔබ විකාශනය කරන මාධ්‍යයට සවන් දිය හැකිය"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> විවෘත කරන්න"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"කෙටිමඟක් ලෙස <xliff:g id="APPNAME">%1$s</xliff:g> එක් කිරීමට, තහවුරු කර ගන්න"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• යෙදුම සකසා ඇත"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Wallet වෙත අවම වශයෙන් එක කාඩ්පතක් එක් කර ඇත"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• කැමරා යෙදුමක් ස්ථාපන කරන්න"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• යෙදුම සකසා ඇත"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• අවම වශයෙන් එක උපාංගයක් ලැබේ"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ස්පර්ශ කර අල්ලා සිටීමේ කෙටිමඟ"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"අවලංගු කරන්න"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"දැන් පෙරළන්න"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"වඩා හොඳ සෙල්ෆියක් සඳහා දුරකථනය දිගහරින්න"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ මෙම තිරය ක්‍රියා විරහිත වනු ඇත"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"දිග හැරෙමින් පවතින නැමිය හැකි උපාංගය"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"වටා පෙරළෙමින් තිබෙන නැමිය හැකි උපාංගය"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index b2586f1..5a5d87a 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Zdieľať snímku obrazovky"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Zachytiť viac"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Zavrieť snímku obrazovky"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Zavrieť správu pracovného profilu"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Ukážka snímky obrazovky"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"<xliff:g id="PERCENT">%1$d</xliff:g> %% hornej hranice"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"<xliff:g id="PERCENT">%1$d</xliff:g> %% dolnej hranice"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"<xliff:g id="PERCENT">%1$d</xliff:g> %% ľavej hranice"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"<xliff:g id="PERCENT">%1$d</xliff:g> %% pravej hranice"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Rekordér obrazovky"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Spracúva sa záznam obrazovky"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Zobrazuje sa upozornenie týkajúce sa relácie záznamu obrazovky"</string>
@@ -374,9 +379,9 @@
     <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"Celá obrazovka"</string>
     <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"Jedna aplikácia"</string>
     <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"Počas zdieľania, nahrávania alebo prenosu bude mať <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> prístup k všetkému na obrazovke, prípadne k obsahu, ktorý sa bude v zariadení prehrávať. Preto venujte zvýšenú pozornosť heslám, platobným údajom, správam a ďalším citlivým údajom."</string>
-    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Počas zdieľania, nahrávania alebo prenosu bude mať aplikácia <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> prístup k všetkému obsahu, ktorý sa v nej bude zobrazovať alebo prehrávať. Preto venujte zvýšenú pozornosť heslám, platobným údajom, správam a ďalším citlivým údajom."</string>
+    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Keď zdieľate, nahrávate alebo prenášate nejakú aplikáciu, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> má prístup k všetkému obsahu, ktorý sa v aplikácii zobrazuje alebo prehráva. Dajte preto pozor na heslá, platobné údaje, osobné správy a iné citlivé údaje."</string>
     <string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Pokračovať"</string>
-    <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Aplikácia na zdieľanie alebo nahrávanie"</string>
+    <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Vyberte aplikáciu, ktorú chcete zdieľať alebo nahrávať"</string>
     <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Chcete povoliť tejto aplikácii zdieľať alebo nahrávať?"</string>
     <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Počas zdieľania, nahrávania alebo prenosu bude mať táto aplikácia prístup k všetkému na obrazovke, prípadne k obsahu, ktorý sa bude v zariadení prehrávať. Venujte preto zvýšenú pozornosť heslám, platobným údajom, správam a ďalším citlivým údajom."</string>
     <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Počas zdieľania, nahrávania alebo prenosu bude mať táto aplikácia prístup k všetkému obsahu, ktorý sa v nej bude zobrazovať alebo prehrávať. Venujte preto zvýšenú pozornosť heslám, platobným údajom, správam či ďalším citlivým údajom."</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Pripojenie Wi‑Fi je vypnuté"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Rozhranie Bluetooth je vypnuté"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Režim bez vyrušení je vypnutý"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Je zapnutý režim bez vyrušení"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Režim bez vyrušení bol zapnutý automatickým pravidlom (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Režim bez vyrušení bol zapnutý aplikáciou (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Režim bez vyrušení bol zapnutý automatickým pravidlom alebo aplikáciou."</string>
@@ -849,10 +853,14 @@
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Prehrať skladbu <xliff:g id="SONG_NAME">%1$s</xliff:g> od interpreta <xliff:g id="ARTIST_NAME">%2$s</xliff:g> z aplikácie <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Prehrať skladbu <xliff:g id="SONG_NAME">%1$s</xliff:g> z aplikácie <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Späť"</string>
-    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Ak chcete prehrávať v zariadení <xliff:g id="DEVICENAME">%1$s</xliff:g>, priblížte sa"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Ak chcete prehrávať v zariadení <xliff:g id="DEVICENAME">%1$s</xliff:g>, priblížte sa k nemu"</string>
+    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Ak chcete prehrávať v zariadení <xliff:g id="DEVICENAME">%1$s</xliff:g>, priblížte sa k nemu"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Prehráva sa v zariadení <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Niečo sa pokazilo. Skúste to znova."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Načítava sa"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Neaktívne, preverte aplikáciu"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nenájdené"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Ovládač nie je k dispozícii"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dostupné zariadenia pre zvukový výstup."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Hlasitosť"</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">"Reproduktory a obrazovky"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Ako vysielanie funguje"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Vysielanie"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Ľudia v okolí s kompatibilnými zariadeniami s rozhraním Bluetooth si môžu vypočuť médiá, ktoré vysielate"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Otvoriť <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Ak chcete aplikáciu <xliff:g id="APPNAME">%1$s</xliff:g> pridať ako odkaz, uistite sa, že"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Aplikácia je nastavená"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Do Peňaženky bola pridaná minimálne jedna karta"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Nainštalujte si aplikáciu kamery"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Aplikácia je nastavená"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• K dispozícii je minimálne jedno zariadenie"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pridržte skratku"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Zrušiť"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Prevráťte"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Ak chcete lepšie selfie, rozložte telefón"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Táto obrazovka sa vypne"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Rozloženie skladacieho zariadenia"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Prevrátenie skladacieho zariadenia"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index a52fede..c16bf23 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Deljenje posnetka zaslona"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Zajemi več"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Opusti posnetek zaslona"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Opustitev sporočila o delovnem profilu"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Predogled posnetka zaslona"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Meja zgoraj <xliff:g id="PERCENT">%1$d</xliff:g> odstotkov"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Meja spodaj <xliff:g id="PERCENT">%1$d</xliff:g> odstotkov"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Meja levo <xliff:g id="PERCENT">%1$d</xliff:g> odstotkov"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Meja desno <xliff:g id="PERCENT">%1$d</xliff:g> odstotkov"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Snemalnik zaslona"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obdelava videoposnetka zaslona"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Nenehno obveščanje o seji snemanja zaslona"</string>
@@ -374,7 +379,7 @@
     <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"Celoten zaslon"</string>
     <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"Posamezna aplikacija"</string>
     <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"Pri deljenju, snemanju ali predvajanju ima aplikacija <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> dostop do vsega, kar je prikazano na zaslonu ali se predvaja v napravi. Zato bodite previdni z gesli, podatki za plačilo, sporočili ali drugimi občutljivimi podatki."</string>
-    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Pri deljenju, snemanju ali predvajanju aplikacije ima aplikacija <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> dostop do vsega, kar je prikazano ali predvajano v tej aplikaciji, zato bodite previdni z gesli, podatki za plačilo, sporočili ali drugimi občutljivimi podatki."</string>
+    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Pri deljenju, snemanju ali predvajanju aplikacije ima <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> dostop do vsega, kar je prikazano ali predvajano v tej aplikaciji, zato bodite previdni z gesli, podatki za plačilo, sporočili ali drugimi občutljivimi podatki."</string>
     <string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Naprej"</string>
     <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Deljenje ali snemanje aplikacije"</string>
     <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Ali tej aplikaciji dovolite deljenje ali snemanje?"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi je izklopljen."</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth je izklopljen"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Način »ne moti« je izklopljen"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Način »Ne moti« je vklopljen"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Samodejno pravilo (<xliff:g id="ID_1">%s</xliff:g>) je vklopilo način »ne moti«."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Aplikacija (<xliff:g id="ID_1">%s</xliff:g>) je vklopila način »ne moti«."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Način »ne moti« je bil vklopljen zaradi samodejnega pravila ali aplikacije."</string>
@@ -849,10 +853,14 @@
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Predvajaj skladbo <xliff:g id="SONG_NAME">%1$s</xliff:g> izvajalca <xliff:g id="ARTIST_NAME">%2$s</xliff:g> iz aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Predvajaj skladbo <xliff:g id="SONG_NAME">%1$s</xliff:g> iz aplikacije <xliff:g id="APP_LABEL">%2$s</xliff:g>."</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Razveljavi"</string>
-    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Za predvajanje v napravi <xliff:g id="DEVICENAME">%1$s</xliff:g> bolj približajte telefon."</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Približajte napravi <xliff:g id="DEVICENAME">%1$s</xliff:g> za predvajanje v tej napravi"</string>
+    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Za predvajanje v napravi <xliff:g id="DEVICENAME">%1$s</xliff:g> bolj približajte telefon"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Predvajanje v napravi <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Prišlo je do napake. Poskusite znova."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Nalaganje"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, poglejte aplikacijo"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Ni mogoče najti"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrolnik ni na voljo"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Razpoložljive naprave za zvočni izhod"</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Glasnost"</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">"Zvočniki in zasloni"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kako deluje oddajanje"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Oddajanje"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Osebe v bližini z združljivo napravo Bluetooth lahko poslušajo predstavnost, ki jo oddajate."</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Odpri aplikacijo <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Če želite aplikacijo <xliff:g id="APPNAME">%1$s</xliff:g> dodati kot bližnjico, zagotovite naslednje:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Aplikacija mora biti nastavljena."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Vsaj ena kartica mora biti dodana v Denarnico."</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Namestite fotografsko aplikacijo."</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Aplikacija mora biti nastavljena."</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Na voljo mora biti vsaj ena naprava."</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pridržite bližnjico"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Prekliči"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Obrnite"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Razprite telefon za boljši selfi"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Ta zaslon se bo izklopil."</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Razpiranje zložljive naprave"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Obračanje zložljive naprave"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index e9ae54a..e9a6e8c 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Ndaj pamjen e ekranit"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Regjistro më shumë"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Hiq pamjen e ekranit"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Hiqe mesazhin në lidhje me profilin e punës"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Pamja paraprake e imazhit"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Kufiri i sipërm <xliff:g id="PERCENT">%1$d</xliff:g> për qind"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Kufiri i poshtëm <xliff:g id="PERCENT">%1$d</xliff:g> për qind"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Kufiri i majtë <xliff:g id="PERCENT">%1$d</xliff:g> për qind"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Kufiri i djathtë <xliff:g id="PERCENT">%1$d</xliff:g> për qind"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Regjistruesi i ekranit"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Regjistrimi i ekranit po përpunohet"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Njoftim i vazhdueshëm për një seancë regjistrimi të ekranit"</string>
@@ -371,7 +376,7 @@
     <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Do të fillosh regjistrimin ose transmetimin?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"Fillo regjistrimin ose transmetimin me <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
     <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"Të lejohet <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> të shpërndajë ose regjistrojë?"</string>
-    <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"Ekran i plotë"</string>
+    <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"Të gjithë ekranin"</string>
     <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"Vetëm një aplikacion"</string>
     <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"Gjatë shpërndarjes, regjistrimit ose transmetimit, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ka qasje te çdo gjë e dukshme në ekranin tënd ose që po luhet në pajisjen tënde. Prandaj ki kujdes me fjalëkalimet, detajet e pagesës, mesazhet ose informacione të tjera të ndjeshme."</string>
     <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Gjatë shpërndarjes, regjistrimit ose transmetimit të një aplikacioni, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ka qasje te çdo gjë e dukshme në ekranin tënd ose që po luhet në atë aplikacion. Prandaj, ki kujdes me fjalëkalimet, detajet e pagesës, mesazhet ose informacione të tjera të ndjeshme."</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi është joaktiv"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth-i është joaktiv"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Modaliteti \"Mos shqetëso\" është joaktiv"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"\"Mos shqetëso\" është aktiv"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Modaliteti \"Mos shqetëso\" është aktivizuar nga një rregull automatik (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Modaliteti \"Mos shqetëso\" është aktivizuar nga një aplikacion (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Modaliteti \"Mos shqetëso\" është aktivizuar nga një rregull automatik ose një aplikacion."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Luaj <xliff:g id="SONG_NAME">%1$s</xliff:g> nga <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Zhbëj"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Afrohu për të luajtur në <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Afrohu te <xliff:g id="DEVICENAME">%1$s</xliff:g> për ta luajtur këtu"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Po luhet në <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Ndodhi një gabim. Provo përsëri."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Po ngarkohet"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Joaktive, kontrollo aplikacionin"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nuk u gjet"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrolli është i padisponueshëm"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Pajisjet që ofrohen për daljen e audios."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volumi"</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">"Altoparlantët dhe ekranet"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Si funksionon transmetimi"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Transmetimi"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Personat në afërsi me ty me pajisje të përputhshme me Bluetooth mund të dëgjojnë median që ti po transmeton"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Hap \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Për të shtuar aplikacionin \"<xliff:g id="APPNAME">%1$s</xliff:g>\" si një shkurtore, sigurohu që"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Aplikacioni është konfiguruar"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Të paktën një kartë të jetë shtuar në \"Portofol\""</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Të instalosh një aplikacion të kamerës"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Aplikacioni është konfiguruar"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ofrohet të paktën një pajisje"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Prek dhe mbaj shtypur shkurtoren"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Anulo"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"U kthye tani"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Shpalos telefonin për një selfi më të mirë"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Ky ekran do të fiket"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Pajisja e palosshme duke u hapur"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Pajisja e palosshme duke u rrotulluar"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index f3c3de3..153ebbf 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Делите снимак екрана"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Снимите још"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Одбаците снимак екрана"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Одбаци поруку пословног профила"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Преглед снимка екрана"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Горња ивица <xliff:g id="PERCENT">%1$d</xliff:g> посто"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Доња ивица <xliff:g id="PERCENT">%1$d</xliff:g> посто"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Лева ивица <xliff:g id="PERCENT">%1$d</xliff:g> посто"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Десна ивица <xliff:g id="PERCENT">%1$d</xliff:g> посто"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Снимач екрана"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обрађујемо видео снимка екрана"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Обавештење о сесији снимања екрана је активно"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"WiFi је искључен"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth је искључен"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Режим Не узнемиравај је искључен"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Режим Не узнемиравај је укључен"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Аутоматско правило (<xliff:g id="ID_1">%s</xliff:g>) је укључило режим Не узнемиравај."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Апликација (<xliff:g id="ID_1">%s</xliff:g>) је укључила режим Не узнемиравај."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Аутоматско правило или апликација су укључили режим Не узнемиравај."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Пустите <xliff:g id="SONG_NAME">%1$s</xliff:g> из апликације <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Опозови"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Приближите да бисте пуштали музику на: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Приближите се уређају <xliff:g id="DEVICENAME">%1$s</xliff:g> да бисте на њему пуштали"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Пушта се на уређају <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Дошло је до грешке. Пробајте поново."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Учитава се"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Неактивно. Видите апликацију"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Није пронађено"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Контрола није доступна"</string>
@@ -875,6 +883,9 @@
     <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">"Звучници и екрани"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Како функционише емитовање"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Емитовање"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Људи у близини са компатибилним Bluetooth уређајима могу да слушају медијски садржај који емитујете"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"с:мин"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"ч:мин"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Отворите: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Да бисте додали апликацију <xliff:g id="APPNAME">%1$s</xliff:g> као пречицу, уверите се:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• да је апликација подешена"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• да је у Новчаник додата барем једна картица"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• да сте инсталирали апликацију за камеру"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• да је апликација подешена"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• да је доступан барем један уређај"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Додирните и задржите пречицу"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Откажи"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Обрните"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Отворите телефон за бољи селфи"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Овај екран ће се искључити"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Уређај на преклоп се отвара"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Уређај на преклоп се обрће"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index ae40b7b..38c7719 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -85,11 +85,14 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Dela skärmbild"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Fånga mer"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Stäng skärmbild"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Stäng meddelandet om jobbprofilen"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Förhandsgranskning av skärmbild"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Övre gräns: <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Nedre gräns: <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Vänster gräns: <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Höger gräns: <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
+    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Jobbskärmbilder sparas i <xliff:g id="APP">%1$s</xliff:g>-appen"</string>
+    <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Filer"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Skärminspelare"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Behandlar skärminspelning"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Avisering om att skärminspelning pågår"</string>
@@ -731,8 +734,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"wifi är inaktiverat"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth är inaktiverat"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Stör ej är inaktiverat"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Stör ej har aktiverats"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Stör ej aktiverades via en automatisk regel (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Stör ej aktiverades via en app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Stör ej aktiverades via en automatisk regel eller en app."</string>
@@ -850,9 +852,12 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Spela upp <xliff:g id="SONG_NAME">%1$s</xliff:g> från <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Ångra"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Flytta närmare för att spela upp på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Flytta dig närmare <xliff:g id="DEVICENAME">%1$s</xliff:g> om du vill spela här"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Spelas upp på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Något gick fel. Försök igen."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Läser in"</string>
+    <string name="media_ttt_default_device_type" msgid="4457646436153370169">"surfplatta"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv, kolla appen"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Hittades inte"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Styrning är inte tillgänglig"</string>
@@ -875,6 +880,8 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Enheter som är tillgängliga för ljudutdata."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volym"</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">"Högtalare och skärmar"</string>
+    <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Förslag på enheter"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Så fungerar utsändning"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Utsändning"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Personer i närheten med kompatibla Bluetooth-enheter kan lyssna på medieinnehåll som du sänder ut"</string>
@@ -998,14 +1005,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h.mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk.mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Öppna <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Om du vill lägga till <xliff:g id="APPNAME">%1$s</xliff:g>-appen som en genväg ser du till att"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• appen har konfigurerats"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• minst ett kort har lagts till i Wallet"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• installera en kameraapp"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• appen har konfigurerats"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• minst en enhet är tillgänglig"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Tryck länge på genvägen"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Avbryt"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Vänd nu"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Vik upp telefonen för att ta en bättre selfie"</string>
@@ -1014,6 +1019,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Den här skärmen inaktiveras"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"En vikbar enhet viks upp"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"En vikbar enhet vänds"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index f13afb8..e43acb8 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Shiriki picha ya skrini"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Nasa zaidi"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Ondoa picha ya skrini"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Ondoa ujumbe wa wasifu wa kazini"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Onyesho la kukagua picha ya skrini"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Mpaka wa sehemu ya juu wa asilimia <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Mpaka wa sehemu ya chini wa asilimia <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Mpaka wa sehemu ya kushoto wa asilimia <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Mpaka wa sehemu ya kulia wa asilimia <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Kinasa Skrini"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Inachakata rekodi ya skrini"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Arifa inayoendelea ya kipindi cha kurekodi skrini"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi imezimwa"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth imezimwa"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Kipengele cha Usinisumbue kimezimwa"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Umewasha kipengele cha Usinisumbue"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Kipengele cha Usinisumbue kimewashwa na sheria ya kiotomatiki <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Kipengele cha usinisumbue kimewashwa na programu (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Kipengele cha Usinisumbue kimewashwa na sheria ya kiotomatiki au programu."</string>
@@ -849,10 +853,14 @@
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Cheza <xliff:g id="SONG_NAME">%1$s</xliff:g> ulioimbwa na <xliff:g id="ARTIST_NAME">%2$s</xliff:g> katika <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Cheza <xliff:g id="SONG_NAME">%1$s</xliff:g> katika <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Tendua"</string>
-    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Sogea karibu ili ucheze kwenye <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Sogeza karibu na <xliff:g id="DEVICENAME">%1$s</xliff:g> ili kucheza hapa"</string>
+    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Sogeza karibu ili ucheze kwenye <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Inacheza kwenye <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Hitilafu fulani imetokea. Jaribu tena."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Inapakia"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Haitumiki, angalia programu"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Hakipatikani"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kidhibiti hakipatikani"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Vifaa vya kutoa sauti vilivyopo"</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Sauti"</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">"Spika na Skrini"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Jinsi utangazaji unavyofanya kazi"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Tangaza"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Watu walio karibu nawe wenye vifaa oanifu vya Bluetooth wanaweza kusikiliza maudhui unayoyatangaza"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"saa:dk"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:dk"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Fungua <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Ili kuweka programu ya <xliff:g id="APPNAME">%1$s</xliff:g> kuwa njia ya mkato, hakikisha"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Programu hii imewekewa mipangilio"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Angalau kadi moja imewekwa kwenye Pochi"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Sakinisha programu ya kamera"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Programu hii imewekewa mipangilio"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Angalau kifaa kimoja kinapatikana"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Gusa na ushikilie njia ya mkato"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Ghairi"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Geuza kifaa sasa"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Kunjua simu ili upige selfi iliyo bora"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Skrini hii itajizima"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Kifaa kinachokunjwa kikikunjuliwa"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Kifaa kinachokunjwa kikigeuzwa"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sw360dp/dimens.xml b/packages/SystemUI/res/values-sw360dp/dimens.xml
index 65ca70b..03365b3 100644
--- a/packages/SystemUI/res/values-sw360dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw360dp/dimens.xml
@@ -25,5 +25,8 @@
 
     <!-- Home Controls -->
     <dimen name="global_actions_side_margin">12dp</dimen>
+
+    <!-- Biometric Auth pattern view size, better to align keyguard_security_width -->
+    <dimen name="biometric_auth_pattern_view_size">298dp</dimen>
 </resources>
 
diff --git a/packages/SystemUI/res/values-sw392dp-land/dimens.xml b/packages/SystemUI/res/values-sw392dp-land/dimens.xml
new file mode 100644
index 0000000..1e26a69
--- /dev/null
+++ b/packages/SystemUI/res/values-sw392dp-land/dimens.xml
@@ -0,0 +1,21 @@
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<resources>
+    <!-- Lock pattern view size, align sysui biometric_auth_pattern_view_size -->
+    <dimen name="biometric_auth_pattern_view_size">248dp</dimen>
+    <dimen name="biometric_auth_pattern_view_max_size">248dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-sw392dp/dimens.xml b/packages/SystemUI/res/values-sw392dp/dimens.xml
index 78279ca..96af3c1 100644
--- a/packages/SystemUI/res/values-sw392dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw392dp/dimens.xml
@@ -24,5 +24,8 @@
 
     <!-- Home Controls -->
     <dimen name="global_actions_side_margin">16dp</dimen>
+
+    <!-- Biometric Auth pattern view size, better to align keyguard_security_width -->
+    <dimen name="biometric_auth_pattern_view_size">298dp</dimen>
 </resources>
 
diff --git a/packages/SystemUI/res/values-sw410dp-land/dimens.xml b/packages/SystemUI/res/values-sw410dp-land/dimens.xml
new file mode 100644
index 0000000..c4d9b9b
--- /dev/null
+++ b/packages/SystemUI/res/values-sw410dp-land/dimens.xml
@@ -0,0 +1,21 @@
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<resources>
+    <!-- Lock pattern view size, align sysui biometric_auth_pattern_view_size -->
+    <dimen name="biometric_auth_pattern_view_size">248dp</dimen>
+    <dimen name="biometric_auth_pattern_view_max_size">348dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-sw410dp/dimens.xml b/packages/SystemUI/res/values-sw410dp/dimens.xml
index 7da47e5..ff6e005 100644
--- a/packages/SystemUI/res/values-sw410dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw410dp/dimens.xml
@@ -27,4 +27,6 @@
     <dimen name="global_actions_grid_item_side_margin">12dp</dimen>
     <dimen name="global_actions_grid_item_height">72dp</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-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
index 6c7cab5..5d78e4e 100644
--- a/packages/SystemUI/res/values-sw600dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
@@ -28,6 +28,7 @@
 
     <!-- QS-->
     <dimen name="qs_panel_padding_top">16dp</dimen>
+    <dimen name="qs_panel_padding">24dp</dimen>
     <dimen name="qs_content_horizontal_padding">24dp</dimen>
     <dimen name="qs_horizontal_margin">24dp</dimen>
     <!-- in split shade qs_tiles_page_horizontal_margin should be equal of qs_horizontal_margin/2,
diff --git a/packages/SystemUI/res/values-sw600dp-land/styles.xml b/packages/SystemUI/res/values-sw600dp-land/styles.xml
index 8148d3d..c535c64 100644
--- a/packages/SystemUI/res/values-sw600dp-land/styles.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/styles.xml
@@ -18,10 +18,10 @@
 
     <style name="AuthCredentialPatternContainerStyle">
         <item name="android:gravity">center</item>
-        <item name="android:maxHeight">420dp</item>
-        <item name="android:maxWidth">420dp</item>
-        <item name="android:minHeight">200dp</item>
-        <item name="android:minWidth">200dp</item>
+        <item name="android:maxHeight">@dimen/biometric_auth_pattern_view_max_size</item>
+        <item name="android:maxWidth">@dimen/biometric_auth_pattern_view_max_size</item>
+        <item name="android:minHeight">@dimen/biometric_auth_pattern_view_size</item>
+        <item name="android:minWidth">@dimen/biometric_auth_pattern_view_size</item>
         <item name="android:paddingHorizontal">120dp</item>
         <item name="android:paddingVertical">40dp</item>
     </style>
diff --git a/packages/SystemUI/res/values-sw600dp-port/styles.xml b/packages/SystemUI/res/values-sw600dp-port/styles.xml
index 771de08..32eefa7 100644
--- a/packages/SystemUI/res/values-sw600dp-port/styles.xml
+++ b/packages/SystemUI/res/values-sw600dp-port/styles.xml
@@ -26,10 +26,10 @@
 
     <style name="AuthCredentialPatternContainerStyle">
         <item name="android:gravity">center</item>
-        <item name="android:maxHeight">420dp</item>
-        <item name="android:maxWidth">420dp</item>
-        <item name="android:minHeight">200dp</item>
-        <item name="android:minWidth">200dp</item>
+        <item name="android:maxHeight">@dimen/biometric_auth_pattern_view_max_size</item>
+        <item name="android:maxWidth">@dimen/biometric_auth_pattern_view_max_size</item>
+        <item name="android:minHeight">@dimen/biometric_auth_pattern_view_size</item>
+        <item name="android:minWidth">@dimen/biometric_auth_pattern_view_size</item>
         <item name="android:paddingHorizontal">180dp</item>
         <item name="android:paddingVertical">80dp</item>
     </style>
diff --git a/packages/SystemUI/res/values-sw600dp/config.xml b/packages/SystemUI/res/values-sw600dp/config.xml
index f4434e8..ea3c012 100644
--- a/packages/SystemUI/res/values-sw600dp/config.xml
+++ b/packages/SystemUI/res/values-sw600dp/config.xml
@@ -36,4 +36,15 @@
     <integer name="qs_security_footer_maxLines">1</integer>
 
     <bool name="config_use_large_screen_shade_header">true</bool>
+
+    <!-- A collection of defaults for the quick affordances on the lock screen. Each item must be a
+    string with two parts: the ID of the slot and the comma-delimited list of affordance IDs,
+    separated by a colon ':' character. For example: <item>bottom_end:home,wallet</item>. The
+    default is displayed by System UI as long as the user hasn't made a different choice for that
+    slot. If the user did make a choice, even if the choice is the "None" option, the default is
+    ignored. -->
+    <string-array name="config_keyguardQuickAffordanceDefaults" translatable="false">
+        <item>bottom_start:home</item>
+        <item>bottom_end:create_note</item>
+    </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index 599bf30..db7fb48 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -30,10 +30,6 @@
     <!-- Margin on the left side of the carrier text on Keyguard -->
     <dimen name="keyguard_carrier_text_margin">24dp</dimen>
 
-    <!-- The width/height of the phone/camera/unlock icon on keyguard. -->
-    <dimen name="keyguard_affordance_height">80dp</dimen>
-    <dimen name="keyguard_affordance_width">120dp</dimen>
-
     <!-- Screen pinning request width -->
     <dimen name="screen_pinning_request_width">400dp</dimen>
     <!-- Screen pinning request bottom button circle widths -->
@@ -92,4 +88,6 @@
     <dimen name="lockscreen_shade_status_bar_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
     <dimen name="lockscreen_shade_keyguard_transition_distance">@dimen/lockscreen_shade_media_transition_distance</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-sw720dp-land/dimens.xml b/packages/SystemUI/res/values-sw720dp-land/dimens.xml
index 3fc59e3..122806a 100644
--- a/packages/SystemUI/res/values-sw720dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp-land/dimens.xml
@@ -27,7 +27,7 @@
 
     <dimen name="status_view_margin_horizontal">24dp</dimen>
 
-    <dimen name="qs_media_session_height_expanded">251dp</dimen>
+    <dimen name="qs_media_session_height_expanded">184dp</dimen>
     <dimen name="qs_content_horizontal_padding">40dp</dimen>
     <dimen name="qs_horizontal_margin">40dp</dimen>
     <!-- in split shade qs_tiles_page_horizontal_margin should be equal of qs_horizontal_margin/2,
@@ -36,8 +36,8 @@
     <dimen name="qs_tiles_page_horizontal_margin">20dp</dimen>
 
     <!-- Size of Smartspace media recommendations cards in the QSPanel carousel -->
-    <dimen name="qs_media_rec_icon_top_margin">27dp</dimen>
-    <dimen name="qs_media_rec_album_size">152dp</dimen>
+    <dimen name="qs_media_rec_icon_top_margin">16dp</dimen>
+    <dimen name="qs_media_rec_album_size">112dp</dimen>
     <dimen name="qs_media_rec_album_side_margin">16dp</dimen>
 
     <dimen name="lockscreen_shade_max_over_scroll_amount">42dp</dimen>
diff --git a/packages/SystemUI/res/values-sw720dp-land/styles.xml b/packages/SystemUI/res/values-sw720dp-land/styles.xml
index f9ed67d..6a70ebd 100644
--- a/packages/SystemUI/res/values-sw720dp-land/styles.xml
+++ b/packages/SystemUI/res/values-sw720dp-land/styles.xml
@@ -18,10 +18,10 @@
 
     <style name="AuthCredentialPatternContainerStyle">
         <item name="android:gravity">center</item>
-        <item name="android:maxHeight">420dp</item>
-        <item name="android:maxWidth">420dp</item>
-        <item name="android:minHeight">200dp</item>
-        <item name="android:minWidth">200dp</item>
+        <item name="android:maxHeight">@dimen/biometric_auth_pattern_view_max_size</item>
+        <item name="android:maxWidth">@dimen/biometric_auth_pattern_view_max_size</item>
+        <item name="android:minHeight">@dimen/biometric_auth_pattern_view_size</item>
+        <item name="android:minWidth">@dimen/biometric_auth_pattern_view_size</item>
         <item name="android:paddingHorizontal">120dp</item>
         <item name="android:paddingVertical">40dp</item>
     </style>
diff --git a/packages/SystemUI/res/values-sw720dp-port/styles.xml b/packages/SystemUI/res/values-sw720dp-port/styles.xml
index 78d299c..0a46e08 100644
--- a/packages/SystemUI/res/values-sw720dp-port/styles.xml
+++ b/packages/SystemUI/res/values-sw720dp-port/styles.xml
@@ -26,10 +26,10 @@
 
     <style name="AuthCredentialPatternContainerStyle">
         <item name="android:gravity">center</item>
-        <item name="android:maxHeight">420dp</item>
-        <item name="android:maxWidth">420dp</item>
-        <item name="android:minHeight">200dp</item>
-        <item name="android:minWidth">200dp</item>
+        <item name="android:maxHeight">@dimen/biometric_auth_pattern_view_max_size</item>
+        <item name="android:maxWidth">@dimen/biometric_auth_pattern_view_max_size</item>
+        <item name="android:minHeight">@dimen/biometric_auth_pattern_view_size</item>
+        <item name="android:minWidth">@dimen/biometric_auth_pattern_view_size</item>
         <item name="android:paddingHorizontal">240dp</item>
         <item name="android:paddingVertical">120dp</item>
     </style>
diff --git a/packages/SystemUI/res/values-sw720dp/dimens.xml b/packages/SystemUI/res/values-sw720dp/dimens.xml
index 0705017..927059a 100644
--- a/packages/SystemUI/res/values-sw720dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp/dimens.xml
@@ -22,5 +22,8 @@
     <dimen name="controls_padding_horizontal">75dp</dimen>
 
     <dimen name="large_screen_shade_header_height">56dp</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-sw800dp/dimens.xml b/packages/SystemUI/res/values-sw800dp/dimens.xml
new file mode 100644
index 0000000..0d82217
--- /dev/null
+++ b/packages/SystemUI/res/values-sw800dp/dimens.xml
@@ -0,0 +1,24 @@
+<?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.
+  -->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources>
+
+    <!-- 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 ef01766..cc58ddb 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"ஸ்கிரீன்ஷாட்டைப் பகிர்"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"கூடுதலாகப் படமெடு"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ஸ்கிரீன்ஷாட்டை நிராகரிக்கும்"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"பணிக் கணக்கு மெசேஜை மூடும்"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ஸ்கிரீன்ஷாட்டின் மாதிரிக்காட்சி"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"மேல் எல்லை <xliff:g id="PERCENT">%1$d</xliff:g> சதவீதம்"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"கீழ் எல்லை <xliff:g id="PERCENT">%1$d</xliff:g> சதவீதம்"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"இடது எல்லை <xliff:g id="PERCENT">%1$d</xliff:g> சதவீதம்"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"வலது எல்லை <xliff:g id="PERCENT">%1$d</xliff:g> சதவீதம்"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"ஸ்கிரீன் ரெக்கார்டர்"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ஸ்க்ரீன் ரெக்கார்டிங் செயலாக்கப்படுகிறது"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"திரை ரெக்கார்டிங் அமர்விற்கான தொடர் அறிவிப்பு"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"வைஃபை முடக்கத்தில் உள்ளது"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"புளூடூத் முடக்கத்தில் உள்ளது"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"\"தொந்தரவு செய்ய வேண்டாம்\" முடக்கத்தில் உள்ளது"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"தொந்தரவு செய்ய வேண்டாம் அம்சம் இயக்கப்பட்டுள்ளது"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"\"தொந்தரவு செய்ய வேண்டாம்\" எனும் பயன்முறையை, தானியங்கு விதி (<xliff:g id="ID_1">%s</xliff:g>) இயக்கியுள்ளது."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"\"தொந்தரவு செய்ய வேண்டாம்\" எனும் பயன்முறையை, ஆப்ஸ் (<xliff:g id="ID_1">%s</xliff:g>) இயக்கியுள்ளது."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"\"தொந்தரவு செய்ய வேண்டாம்\" எனும் பயன்முறையை, தானியங்கு விதி அல்லது ஆப்ஸ் இயக்கியுள்ளது."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> பாடலை <xliff:g id="APP_LABEL">%2$s</xliff:g> ஆப்ஸில் பிளேசெய்"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"செயல்தவிர்"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> சாதனத்தில் இயக்க உங்கள் சாதனத்தை அருகில் எடுத்துச் செல்லுங்கள்"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"இங்கு பிளே செய்ய உங்கள் சாதனத்தை <xliff:g id="DEVICENAME">%1$s</xliff:g> சாதனத்திற்கு அருகில் நகர்த்துங்கள்"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> சாதனத்தில் பிளே ஆகிறது"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"ஏதோ தவறாகிவிட்டது. மீண்டும் முயலவும்."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"ஏற்றுகிறது"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"செயலில் இல்லை , சரிபார்க்கவும்"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"இல்லை"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"கட்டுப்பாடு இல்லை"</string>
@@ -875,6 +883,9 @@
     <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>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"பிராட்காஸ்ட் எவ்வாறு செயல்படுகிறது?"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"பிராட்காஸ்ட்"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"நீங்கள் பிராட்காஸ்ட் செய்யும் மீடியாவை அருகிலுள்ளவர்கள் இணக்கமான புளூடூத் சாதனங்கள் மூலம் கேட்கலாம்"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ஆப்ஸைத் திற"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"<xliff:g id="APPNAME">%1$s</xliff:g> ஆப்ஸை ஷார்ட்கட்டாகச் சேர்க்க, இவற்றைச் செய்திருப்பதை உறுதிசெய்து கொள்ளவும்:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• இந்த ஆப்ஸ் அமைக்கப்பட்டிருக்க வேண்டும்"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Walletடில் குறைந்தபட்சம் ஒரு கார்டாவது சேர்க்கப்பட்டிருக்க வேண்டும்"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• கேமரா ஆப்ஸ் நிறுவப்பட்டிருக்க வேண்டும்"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• இந்த ஆப்ஸ் அமைக்கப்பட்டிருக்க வேண்டும்"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• குறைந்தபட்சம் ஒரு சாதனமாவது கிடைக்க வேண்டும்"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ஷார்ட்கட்டை தொட்டுப் பிடிக்கவும்"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ரத்துசெய்"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"இப்போது மாற்றவும்"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"சிறந்த செல்ஃபிக்கு மொபைலை மடக்காதீர்கள்"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ இந்தத் திரை ஆஃப் ஆகிவிடும்"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"மடக்கத்தக்க சாதனம் திறக்கப்படுகிறது"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"மடக்கத்தக்க சாதனம் ஃபிளிப் செய்யப்பட்டு திருப்பப்படுகிறது"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 2a2bba5..1df7542 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -85,11 +85,14 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"స్క్రీన్‌షాట్‌ను షేర్ చేయండి"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"మరిన్ని క్యాప్చర్ చేయండి"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"స్క్రీన్‌షాట్‌ను విస్మరించు"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"వర్క్ ప్రొఫైల్ మెసేజ్‌ను విస్మరిస్తుంది"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"స్క్రీన్‌షాట్ ప్రివ్యూ"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"ఎగువ సరిహద్దు <xliff:g id="PERCENT">%1$d</xliff:g> శాతం"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"దిగువ సరిహద్దు <xliff:g id="PERCENT">%1$d</xliff:g> శాతం"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ఎడమ వైపు సరిహద్దు <xliff:g id="PERCENT">%1$d</xliff:g> శాతం"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"కుడి వైపు సరిహద్దు <xliff:g id="PERCENT">%1$d</xliff:g> శాతం"</string>
+    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"వర్క్ స్క్రీన్‌షాట్‌లు <xliff:g id="APP">%1$s</xliff:g> యాప్‌లో సేవ్ చేయబడతాయి"</string>
+    <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ఫైల్స్"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"స్క్రీన్ రికార్డర్"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"స్క్రీన్ రికార్డింగ్ అవుతోంది"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"స్క్రీన్ రికార్డ్ సెషన్ కోసం ఆన్‌గోయింగ్ నోటిఫికేషన్"</string>
@@ -144,9 +147,9 @@
     <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>
-    <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"పిన్‌ను ఉపయోగించు"</string>
-    <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ఆకృతిని ఉపయోగించు"</string>
-    <string name="biometric_dialog_use_password" msgid="3445033859393474779">"పాస్‌వర్డ్‌ను ఉపయోగించు"</string>
+    <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"పిన్‌ను ఉపయోగించండి"</string>
+    <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ఆకృతిని ఉపయోగించండి"</string>
+    <string name="biometric_dialog_use_password" msgid="3445033859393474779">"పాస్‌వర్డ్‌ను ఉపయోగించండి"</string>
     <string name="biometric_dialog_wrong_pin" msgid="1878539073972762803">"పిన్ తప్పు"</string>
     <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"ఆకృతి తప్పు"</string>
     <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"పాస్‌వర్డ్ తప్పు"</string>
@@ -639,7 +642,7 @@
     <item msgid="7453955063378349599">"ఎడమవైపుకు వాలుగా"</item>
     <item msgid="5874146774389433072">"కుడివైపుకు వాలుగా"</item>
   </string-array>
-    <string name="save" msgid="3392754183673848006">"సేవ్ చేయి"</string>
+    <string name="save" msgid="3392754183673848006">"సేవ్ చేయండి"</string>
     <string name="reset" msgid="8715144064608810383">"రీసెట్ చేయండి"</string>
     <string name="clipboard" msgid="8517342737534284617">"క్లిప్‌బోర్డ్"</string>
     <string name="accessibility_key" msgid="3471162841552818281">"అనుకూల నావిగేషన్ బటన్"</string>
@@ -731,8 +734,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi ఆఫ్‌లో ఉంది"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"బ్లూటూత్ ఆఫ్‌లో ఉంది"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"అంతరాయం కలిగించవద్దు ఆఫ్‌లో ఉంది"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"\"అంతరాయం కలిగించవద్దు\" ఆన్‌లో ఉంది"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ఆటోమేటిక్‌ నియమం (<xliff:g id="ID_1">%s</xliff:g>) ద్వారా అంతరాయం కలిగించవద్దు ఆన్ చేయబడింది."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"యాప్ (<xliff:g id="ID_1">%s</xliff:g>) ద్వారా అంతరాయం కలిగించవద్దు ఆన్ చేయబడింది."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ఆటోమేటిక్‌ నియమం లేదా యాప్ ద్వారా అంతరాయం కలిగించవద్దు ఆన్ చేయబడింది."</string>
@@ -850,9 +852,12 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> నుండి <xliff:g id="SONG_NAME">%1$s</xliff:g>‌ను ప్లే చేయండి"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"చర్య రద్దు"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>‌లో ప్లే చేయడానికి దగ్గరగా వెళ్లండి"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ఇక్కడ ప్లే చేయడానికి <xliff:g id="DEVICENAME">%1$s</xliff:g>కి దగ్గరగా వెళ్లండి"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>లో ప్లే అవుతోంది"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"ఏదో తప్పు జరిగింది. మళ్లీ ట్రై చేయండి."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"లోడ్ అవుతోంది"</string>
+    <string name="media_ttt_default_device_type" msgid="4457646436153370169">"టాబ్లెట్"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"ఇన్‌యాక్టివ్, యాప్ చెక్ చేయండి"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"కనుగొనబడలేదు"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"కంట్రోల్ అందుబాటులో లేదు"</string>
@@ -875,6 +880,8 @@
     <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_suggested_device" msgid="4157186235837903826">"సూచించబడిన పరికరాలు"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ప్రసారం కావడం అనేది ఎలా పని చేస్తుంది"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ప్రసారం"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"మీకు సమీపంలో ఉన్న వ్యక్తులు అనుకూలత ఉన్న బ్లూటూత్ పరికరాలతో మీరు ప్రసారం చేస్తున్న మీడియాను వినగలరు"</string>
@@ -998,14 +1005,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g>‌ను తెరవండి"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"<xliff:g id="APPNAME">%1$s</xliff:g> యాప్‌ను షార్ట్‌కట్‌గా జోడించడానికి, వీటిని నిర్ధారించుకోండి"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• యాప్ సెటప్ చేయబడి ఉందని"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Walletకు కనీసం ఒక కార్డ్ అయినా జోడించబడి ఉందని"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• కెమెరా యాప్ ఇన్‌స్టాల్ చేసి ఉందని"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• యాప్ సెటప్ చేయబడి ఉందని"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• కనీసం ఒక పరికరమైనా అందుబాటులో ఉందని"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"షార్ట్‌కట్‌ను తాకి, నొక్కి ఉంచు"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"రద్దు చేయండి"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ఇప్పుడే తిప్పండి"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"మెరుగైన సెల్ఫీ కోసం ఫోన్‌ను అన్‌ఫోల్డ్ చేయండి"</string>
@@ -1014,6 +1019,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ఈ స్క్రీన్ ఆఫ్ అవుతుంది"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"మడవగల పరికరం విప్పబడుతోంది"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"మడవగల పరికరం చుట్టూ తిప్పబడుతోంది"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 736bd68..771a906 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -85,11 +85,14 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"แชร์ภาพหน้าจอ"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"จับภาพได้มากขึ้น"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ปิดภาพหน้าจอ"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"ปิดข้อความจากโปรไฟล์งาน"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ตัวอย่างภาพหน้าจอ"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"ขอบเขตด้านบน <xliff:g id="PERCENT">%1$d</xliff:g> เปอร์เซ็นต์"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"ขอบเขตด้านล่าง <xliff:g id="PERCENT">%1$d</xliff:g> เปอร์เซ็นต์"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ขอบเขตด้านซ้าย <xliff:g id="PERCENT">%1$d</xliff:g> เปอร์เซ็นต์"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"ขอบเขตด้านขวา <xliff:g id="PERCENT">%1$d</xliff:g> เปอร์เซ็นต์"</string>
+    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"ภาพหน้าจองานจะบันทึกอยู่ในแอป <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ไฟล์"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"โปรแกรมบันทึกหน้าจอ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"กำลังประมวลผลการอัดหน้าจอ"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"การแจ้งเตือนต่อเนื่องสำหรับเซสชันการบันทึกหน้าจอ"</string>
@@ -731,8 +734,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi ปิดอยู่"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"บลูทูธปิดอยู่"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"\"ห้ามรบกวน\" ปิดอยู่"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"โหมดห้ามรบกวนเปิดอยู่"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"มีการเปิด \"ห้ามรบกวน\" โดยกฎอัตโนมัติ (<xliff:g id="ID_1">%s</xliff:g>)"</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"มีการเปิด \"ห้ามรบกวน\" โดยแอป (<xliff:g id="ID_1">%s</xliff:g>)"</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"มีการเปิด \"ห้ามรบกวน\" โดยกฎอัตโนมัติหรือแอป"</string>
@@ -849,10 +851,13 @@
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"เปิดเพลง <xliff:g id="SONG_NAME">%1$s</xliff:g> ของ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> จาก <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"เปิดเพลง <xliff:g id="SONG_NAME">%1$s</xliff:g> จาก <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"เลิกทำ"</string>
-    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"ขยับเข้ามาใกล้ขึ้นเพื่อเล่นใน <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ขยับไปใกล้ <xliff:g id="DEVICENAME">%1$s</xliff:g> มากขึ้นเพื่อเล่นที่นี่"</string>
+    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"ขยับไปใกล้มากขึ้นเพื่อเล่นใน <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"กำลังเล่นใน <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"เกิดข้อผิดพลาด โปรดลองอีกครั้ง"</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"กำลังโหลด"</string>
+    <string name="media_ttt_default_device_type" msgid="4457646436153370169">"แท็บเล็ต"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"ไม่มีการใช้งาน โปรดตรวจสอบแอป"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"ไม่พบ"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"ใช้การควบคุมไม่ได้"</string>
@@ -875,6 +880,8 @@
     <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">"ลำโพงและจอแสดงผล"</string>
+    <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"อุปกรณ์ที่แนะนำ"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"วิธีการทำงานของการออกอากาศ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ประกาศ"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ผู้ที่อยู่ใกล้คุณและมีอุปกรณ์บลูทูธที่รองรับสามารถรับฟังสื่อที่คุณกำลังออกอากาศได้"</string>
@@ -998,14 +1005,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"HH:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"เปิด <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"หากต้องการเพิ่มแอป <xliff:g id="APPNAME">%1$s</xliff:g> เป็นทางลัด โปรดตรวจสอบดังต่อไปนี้"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• แอปได้รับการตั้งค่าแล้ว"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• มีการเพิ่มบัตรลงใน Wallet อย่างน้อย 1 รายการ"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• ติดตั้งแอปกล้อง"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• แอปได้รับการตั้งค่าแล้ว"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• มีอุปกรณ์พร้อมใช้งานอย่างน้อย 1 รายการ"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"แตะแป้นพิมพ์ลัดค้างไว้"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ยกเลิก"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"พลิกเลย"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"กางโทรศัพท์เพื่อเซลฟีที่ดียิ่งขึ้น"</string>
@@ -1014,6 +1019,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ หน้าจอนี้จะปิดไป"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"อุปกรณ์ที่พับได้กำลังกางออก"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"อุปกรณ์ที่พับได้กำลังพลิกไปมา"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 51e42dd..aa58d00 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -85,11 +85,14 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Ibahagi ang screenshot"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Mag-capture pa"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"I-dismiss ang screenshot"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"I-dismiss ang mensahe sa profile sa trabaho"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Preview ng screenshot"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"<xliff:g id="PERCENT">%1$d</xliff:g> (na) porsyento sa hangganan sa itaas"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"<xliff:g id="PERCENT">%1$d</xliff:g> (na) porsyento sa hangganan sa ibaba"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"<xliff:g id="PERCENT">%1$d</xliff:g> (na) porsyento sa hangganan sa kaliwa"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"<xliff:g id="PERCENT">%1$d</xliff:g> (na) porsyento sa hangganan sa kanan"</string>
+    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Naka-save ang mga screenshot sa trabaho sa <xliff:g id="APP">%1$s</xliff:g> app"</string>
+    <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Mga File"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Recorder ng Screen"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Pinoproseso screen recording"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Kasalukuyang notification para sa session ng pag-record ng screen"</string>
@@ -731,8 +734,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Naka-off ang Wi-Fi"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Naka-off ang Bluetooth"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Naka-off ang Huwag Istorbohin"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Naka-on ang Huwag Istorbohin"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Na-on ang Huwag Istorbohin dahil sa isang awtomatikong panuntunan (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Na-on ang Huwag Istorbohin dahil sa isang app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Na-on ang Huwag Istorbohin dahil sa isang awtomatikong panuntunan o app."</string>
@@ -850,9 +852,12 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"I-play ang <xliff:g id="SONG_NAME">%1$s</xliff:g> mula sa <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"I-undo"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Lumapit pa para mag-play sa <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Lumapit sa <xliff:g id="DEVICENAME">%1$s</xliff:g> para mag-play rito"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Nagpe-play sa <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Nagkaproblema. Subukan ulit."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Naglo-load"</string>
+    <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Hindi aktibo, tingnan ang app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Hindi nahanap"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Hindi available ang kontrol"</string>
@@ -875,6 +880,8 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Mga available na device para sa audio output."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</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">"Mga Speaker at Display"</string>
+    <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Mga Iminumungkahing Device"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Paano gumagana ang pag-broadcast"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Makakapakinig ang mga taong malapit sa iyo na may mga compatible na Bluetooth device sa media na bino-broadcast mo"</string>
@@ -998,14 +1005,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Buksan ang <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Para idagdag ang <xliff:g id="APPNAME">%1$s</xliff:g> app bilang shortcut, siguraduhing"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Na-set up ang app"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• May kahit isang card na idinagdag sa Wallet"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Mag-install ng camera app"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Na-set up ang app"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• May kahit isang device na available"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pindutin nang matagal: shortcut"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Kanselahin"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"I-flip na ngayon"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"I-unfold ang telepono para sa mas magandang selfie"</string>
@@ -1014,6 +1019,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Mag-o-off ang screen na ito"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Ina-unfold na foldable na device"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Fini-flip na foldable na device"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index bb718ff..2ee29cf 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Ekranı paylaş"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Alanı genişlet"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Ekran görüntüsünü kapat"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"İş profili mesajını kapatın"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Ekran görüntüsü önizlemesi"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Üst sınır yüzde <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Alt sınır yüzde <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Sol sınır yüzde <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Sağ sınır yüzde <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekran Kaydedicisi"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran kaydı işleniyor"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekran kaydı oturumu için devam eden bildirim"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Kablosuz bağlantı kapalı"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth kapalı"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Rahatsız Etmeyin kapalı"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Rahatsız Etmeyin modu açık"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Rahatsız Etmeyin ayarı bir otomatik kural (<xliff:g id="ID_1">%s</xliff:g>) tarafından açıldı."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Rahatsız Etmeyin ayarı bir uygulama (<xliff:g id="ID_1">%s</xliff:g>) tarafından açıldı."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Rahatsız Etmeyin ayarı bir otomatik kural veya uygulama tarafından açıldı."</string>
@@ -849,10 +853,14 @@
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> uygulamasından <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, <xliff:g id="SONG_NAME">%1$s</xliff:g> şarkısını çal"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> uygulamasından <xliff:g id="SONG_NAME">%1$s</xliff:g> şarkısını çal"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Geri al"</string>
-    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> cihazında çalmak için yaklaşın"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Burada oynatmak için <xliff:g id="DEVICENAME">%1$s</xliff:g> cihazına yaklaşın"</string>
+    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> cihazında oynatmak için yaklaşın"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> cihazında oynatılıyor"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Bir sorun oldu. Tekrar deneyin."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Yükleme"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Devre dışı, uygulamaya bakın"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Bulunamadı"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrol kullanılamıyor"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Ses çıkışı için kullanılabilir cihazlar."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Ses düzeyi"</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">"Hoparlörler ve Ekranlar"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Yayınlamanın işleyiş şekli"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Anons"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Yakınınızda ve uyumlu Bluetooth cihazları olan kişiler yayınladığınız medya içeriğini dinleyebilir"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:dd"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> uygulamasını aç"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"<xliff:g id="APPNAME">%1$s</xliff:g> uygulamasını kısayol olarak ekleyebilmeniz için gerekenler"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Uygulama kurulmuş olmalıdır"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Cüzdan\'a en az bir kart eklenmelidir"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Kamera uygulaması yüklenmelidir"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Uygulama kurulmuş olmalıdır"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• En az bir cihaz mevcut olmalıdır"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Kısayola dokunup basılı tutun"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"İptal"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Şimdi çevirin"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Daha iyi selfie çekmek için telefonu açın"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ * Bu ekran kapatılacak"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Katlanabilir cihaz açılıyor"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Katlanabilir cihaz döndürülüyor"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 4e30515..ae22d08 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Поділитися знімком екрана"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Включити більше деталей"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Закрити знімок екрана"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Закрити повідомлення робочого профілю"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Перегляд знімка екрана"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Зверху на <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Знизу на <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Зліва на <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Справа на <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Запис відео з екрана"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обробка записування екрана"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Сповіщення про сеанс запису екрана"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi вимкнено"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth вимкнено"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Режим \"Не турбувати\" вимкнено"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Режим \"Не турбувати\" ввімкнено"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Автоматичне правило ввімкнуло режим \"Не турбувати\" (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Додаток увімкнув режим \"Не турбувати\" (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Автоматичне правило або додаток увімкнули режим \"Не турбувати\"."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Увімкнути пісню \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" у додатку <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Відмінити"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Щоб відтворити контент на пристрої <xliff:g id="DEVICENAME">%1$s</xliff:g>, наблизьтеся до нього"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Наблизьтеся до пристрою <xliff:g id="DEVICENAME">%1$s</xliff:g>, щоб відтворити медіафайли на ньому"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Відтворюється на пристрої <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Сталася помилка. Повторіть спробу."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Завантаження"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Неактивно, перейдіть у додаток"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Не знайдено"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Елемент керування недоступний"</string>
@@ -875,6 +883,9 @@
     <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">"Колонки й екрани"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Як працює трансляція"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Трансляція"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Люди поблизу, які мають сумісні пристрої з Bluetooth, можуть слухати медіаконтент, який ви транслюєте."</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Відкрити <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Щоб додати можливість швидкого ввімкнення додатка <xliff:g id="APPNAME">%1$s</xliff:g>, переконайтеся, що виконано вимоги нижче."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Додаток налаштовано"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Принаймні одну картку додано в Гаманець"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Встановлено додаток для камери"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Додаток налаштовано"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Принаймні один пристрій доступний"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Натисніть і утримуйте ярлик"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Скасувати"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Перевернути"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Розгорніть телефон, щоб зробити краще селфі"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Цей екран вимкнеться"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Розкладний пристрій у розкладеному стані"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Розкладний пристрій обертається"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 8b249ca..f02797b 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"اسکرین شاٹ کا اشتراک کریں"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"مزید کیپچر کریں"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"اسکرین شاٹ برخاست کریں"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"دفتری پروفائل کے پیغام کو برخاست کریں"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"اسکرین شاٹ کا پیش منظر"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"اوپر کا احاطہ <xliff:g id="PERCENT">%1$d</xliff:g> فیصد"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"نیچے کا احاطہ <xliff:g id="PERCENT">%1$d</xliff:g> فیصد"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"بایاں احاطہ <xliff:g id="PERCENT">%1$d</xliff:g> فیصد"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"دایاں احاطہ <xliff:g id="PERCENT">%1$d</xliff:g> فیصد"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"اسکرین ریکارڈر"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"سکرین ریکارڈنگ پروسیس ہورہی ہے"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"اسکرین ریکارڈ سیشن کیلئے جاری اطلاع"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"‏Wi-Fi آف ہے"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"بلوٹوتھ آف ہے"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"\'ڈسٹرب نہ کریں\' آف ہے"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"\"ڈسٹرب نہ کریں\" آن ہے"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"\'ڈسٹرب نہ کریں\' کسی خودکار اصول (<xliff:g id="ID_1">%s</xliff:g>) کے ذریعہ آن ہو گیا تھا۔"</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"\'ڈسٹرب نہ کریں\' کسی ایپ (<xliff:g id="ID_1">%s</xliff:g>) کے ذریعہ آن ہو گیا تھا۔"</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"\'ڈسٹرب نہ کریں\' کسی خودکار اصول یا ایپ کے ذریعے آن ہو گیا تھا۔"</string>
@@ -849,10 +853,14 @@
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> سے <xliff:g id="ARTIST_NAME">%2$s</xliff:g> کا <xliff:g id="SONG_NAME">%1$s</xliff:g> چلائیں"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> سے <xliff:g id="SONG_NAME">%1$s</xliff:g> چلائیں"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"کالعدم کریں"</string>
-    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> پر چلانے کے لیے قریب کریں"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"یہاں چلانے کے ليے <xliff:g id="DEVICENAME">%1$s</xliff:g> کے قریب جائیں"</string>
-    <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> پر چل رہا ہے"</string>
+    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"‫<xliff:g id="DEVICENAME">%1$s</xliff:g> پر چلانے کے لیے قریب کریں"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
+    <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"‫<xliff:g id="DEVICENAME">%1$s</xliff:g> پر چل رہا ہے"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"کچھ غلط ہوگیا۔ پھر کوشش کریں۔"</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"لوڈ ہو رہا ہے"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"غیر فعال، ایپ چیک کریں"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"نہیں ملا"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"کنٹرول دستیاب نہیں ہے"</string>
@@ -875,6 +883,9 @@
     <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">"اسپیکرز اور ڈسپلیز"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"براڈکاسٹنگ کیسے کام کرتا ہے"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"براڈکاسٹ"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"موافق بلوٹوتھ آلات کے ساتھ آپ کے قریبی لوگ آپ کے نشر کردہ میڈیا کو سن سکتے ہیں"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> کھولیں"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"<xliff:g id="APPNAME">%1$s</xliff:g> ایپ کو شارٹ کٹ کے طور پر شامل کرنے کے لیے درج ذیل کو یقینی بنائیں"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• ایپ سیٹ اپ ہو گئی ہے"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• والٹ میں کم از کم ایک کارڈ شامل کیا گیا ہے"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• کیمرا ایپ انسٹال کریں"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• ایپ سیٹ اپ ہو گئی ہے"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• کم از کم ایک آلہ دستیاب ہے"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"شارٹ کٹ ٹچ کریں اور دبائے رکھیں"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"منسوخ کریں"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"اب پلٹائیں"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"بہتر سیلفی کے لیے فون کھولیں"</string>
@@ -1014,6 +1023,6 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ یہ اسکرین آف ہو جائے گی"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"فولڈ ہونے والے آلے کو کھولا جا رہا ہے"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"فولڈ ہونے والے آلے کو گھمایا جا رہا ہے"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
-    <skip />
+    <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> بیٹری باقی ہے"</string>
+    <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"اپنے اسٹائلس کو چارجر منسلک کریں"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 74f29e5..0d5ad60 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -85,11 +85,14 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Skrinshot yuborish"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Skrinshot sohasini kengaytirish"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Skrinshotni yopish"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Ish profili xabarini yopish"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Skrinshotga razm solish"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Yuqori chegara <xliff:g id="PERCENT">%1$d</xliff:g> foiz"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Quyi chegara <xliff:g id="PERCENT">%1$d</xliff:g> foiz"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Chap chegara <xliff:g id="PERCENT">%1$d</xliff:g> foiz"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Oʻng chegara <xliff:g id="PERCENT">%1$d</xliff:g> foiz"</string>
+    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Ish skrinshotlari <xliff:g id="APP">%1$s</xliff:g> ilovasida saqlanadi"</string>
+    <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fayllar"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekrandan yozib olish"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran yozib olinmoqda"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekrandan yozib olish seansi uchun joriy bildirishnoma"</string>
@@ -731,8 +734,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi o‘chiq"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth o‘chiq"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Bezovta qilinmasin rejimi o‘chiq"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Bezovta qilinmasin rejimi yoniq"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Bezovta qilinmasin rejimi avtomatik qoida (<xliff:g id="ID_1">%s</xliff:g>) tomonidan yoqilgan."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Bezovta qilinmasin rejimi ilova (<xliff:g id="ID_1">%s</xliff:g>) tomonidan yoqilgan."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Bezovta qilinmasin rejimi ilova yoki avtomatik qoida tomonidan yoqilgan."</string>
@@ -849,10 +851,12 @@
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> ilovasida ijro etish: <xliff:g id="SONG_NAME">%1$s</xliff:g> – <xliff:g id="ARTIST_NAME">%2$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> ilovasida ijro etilmoqda: <xliff:g id="SONG_NAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Qaytarish"</string>
-    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>da ijro etish uchun yaqinroq keling"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Bu yerda ijro qilish uchun <xliff:g id="DEVICENAME">%1$s</xliff:g>qurilmasiga yaqinlashtiring"</string>
+    <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> qurilmasida ijro qilish uchun unga yaqinlashing"</string>
+    <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Shu yerda ijro qilish uchun <xliff:g id="DEVICENAME">%1$s</xliff:g>ga yaqinroq suring"</string>
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> qurilmasida ijro qilinmoqda"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Xatolik yuz berdi. Qayta urining."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Yuklanmoqda"</string>
+    <string name="media_ttt_default_device_type" msgid="4457646436153370169">"planshet"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Nofaol. Ilovani tekshiring"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Topilmadi"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Boshqarish imkonsiz"</string>
@@ -875,6 +879,8 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Audio chiqish uchun mavjud qurilmalar."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Tovush balandligi"</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">"Karnaylar va displeylar"</string>
+    <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Taklif qilingan qurilmalar"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Translatsiya qanday ishlaydi"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Translatsiya"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Atrofingizdagi mos Bluetooth qurilmasiga ega foydalanuvchilar siz translatsiya qilayotgan mediani tinglay olishadi"</string>
@@ -998,14 +1004,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"s:dd"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Ochish: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"<xliff:g id="APPNAME">%1$s</xliff:g> ilovasini yorliq sifatida qoʻshish uchun"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Ilova sozlangan"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Kamida bitta kartochka Wallet xizmatiga qoʻshilgan"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Kamera ilovasini oʻrnating"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Ilova sozlangan"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Kamida bitta qurilma mavjud"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Bosib turish yorligʻi"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Bekor qilish"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Hozir aylantirish"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Yaxshiroq selfi olish uchun telefonni yoying"</string>
@@ -1014,6 +1018,6 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Bu ekran oʻchiriladi"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Buklanadigan qurilma ochilmoqda"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Buklanadigan qurilma aylantirilmoqda"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
-    <skip />
+    <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Batareya quvvati: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
+    <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Stilusni quvvat manbaiga ulang"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 94c814c..c2e27d4 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Chia sẻ ảnh chụp màn hình"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Chụp thêm"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Đóng ảnh chụp màn hình"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Đóng thông báo về hồ sơ công việc"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Xem trước ảnh chụp màn hình"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Cạnh trên cùng <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Cạnh dưới cùng <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Cạnh trái <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Cạnh phải <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Trình ghi màn hình"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Đang xử lý video ghi màn hình"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Thông báo đang diễn ra về phiên ghi màn hình"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi đang tắt"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth tắt"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Không làm phiền tắt"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Chế độ Không làm phiền đang bật"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Không làm phiền đã được một quy tắc tự động (<xliff:g id="ID_1">%s</xliff:g>) bật."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Không làm phiền đã được một ứng dụng (<xliff:g id="ID_1">%s</xliff:g>) bật."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Không làm phiền đã được một quy tắc tự động hoặc ứng dụng bật."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Phát <xliff:g id="SONG_NAME">%1$s</xliff:g> trên <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Hủy"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Đưa thiết bị đến gần hơn để phát trên <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Di chuyển đến gần <xliff:g id="DEVICENAME">%1$s</xliff:g> hơn để phát tại đây"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Đang phát trên <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Đã xảy ra lỗi. Hãy thử lại."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Đang tải"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Không hoạt động, hãy kiểm tra ứng dụng"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Không tìm thấy"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Không có chức năng điều khiển"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Các thiết bị có sẵn để xuất âm thanh."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Âm lượng"</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">"Loa và màn hình"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cách tính năng truyền hoạt động"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Truyền"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Những người ở gần có thiết bị Bluetooth tương thích có thể nghe nội dung nghe nhìn bạn đang truyền"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Mở <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Để tạo lối tắt cho ứng dụng <xliff:g id="APPNAME">%1$s</xliff:g>, hãy đảm bảo"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Ứng dụng được thiết lập"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Thêm ít nhất một thẻ vào Wallet"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Cài đặt một ứng dụng máy ảnh"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Ứng dụng được thiết lập"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Có ít nhất một thiết bị đang hoạt động"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Chạm và giữ phím tắt"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Huỷ"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Lật ngay"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Mở điện thoại ra để tự chụp ảnh chân dung đẹp hơn"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Màn hình này sẽ tắt"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Thiết bị có thể gập lại đang được mở ra"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Thiết bị có thể gập lại đang được lật ngược"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 082cfb4..b401a8c 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"分享屏幕截图"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"截取更多内容"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"关闭屏幕截图"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"关闭工作资料消息"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"屏幕截图预览"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"顶部边界百分之 <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"底部边界百分之 <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"左侧边界百分之 <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"右侧边界百分之 <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"屏幕录制器"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"正在处理屏幕录制视频"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"持续显示屏幕录制会话通知"</string>
@@ -373,8 +378,8 @@
     <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"允许 <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 分享或录制吗?"</string>
     <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"整个屏幕"</string>
     <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"单个应用"</string>
-    <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"在您进行分享、录制或投射时,<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 可以访问您的屏幕显示或设备播放的所有内容。因此,请注意保护密码、付款信息、消息或其他敏感信息。"</string>
-    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"在您进行分享、录制或投射时,<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 可以访问通过此应用显示或播放的所有内容。因此,请注意保护密码、付款信息、消息或其他敏感信息。"</string>
+    <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"当您进行分享、录制或投屏时,<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 可以访问您的屏幕上显示的或设备上播放的所有内容。因此,请注意保护密码、付款信息、消息或其他敏感信息。"</string>
+    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"当您对一款应用进行分享、录制或投屏时,<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 可以访问该应用中显示或播放的所有内容。因此,请注意保护密码、付款信息、消息或其他敏感信息。"</string>
     <string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"继续"</string>
     <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"分享或录制应用"</string>
     <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"是否允许此应用进行分享或录制?"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"WLAN 已关闭"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"蓝牙已关闭"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"“勿扰”模式已关闭"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"“勿扰”模式已开启"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"某个自动规则(<xliff:g id="ID_1">%s</xliff:g>)已开启勿扰模式。"</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"某个应用(<xliff:g id="ID_1">%s</xliff:g>)已开启勿扰模式。"</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"某个自动规则或应用已开启勿扰模式。"</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"通过<xliff:g id="APP_LABEL">%2$s</xliff:g>播放《<xliff:g id="SONG_NAME">%1$s</xliff:g>》"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"撤消"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"若要在“<xliff:g id="DEVICENAME">%1$s</xliff:g>”上播放,请靠近这台设备"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"若要在此设备上播放,请靠近“<xliff:g id="DEVICENAME">%1$s</xliff:g>”"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"正在“<xliff:g id="DEVICENAME">%1$s</xliff:g>”上播放"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"出了点问题,请重试。"</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"正在加载"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"无效,请检查应用"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"未找到"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"控件不可用"</string>
@@ -875,6 +883,9 @@
     <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">"音箱和显示屏"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"广播的运作方式"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"广播"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"附近使用兼容蓝牙设备的用户可以收听您广播的媒体内容"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"打开<xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"若要将<xliff:g id="APPNAME">%1$s</xliff:g>应用添加为快捷方式,请确保:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• 应用已设置完毕"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• 至少已将一张银行卡添加到钱包"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• 安装相机应用"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• 应用已设置完毕"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• 至少有一台设备可用"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"轻触并按住快捷方式"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"取消"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"立即翻转"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"展开手机可拍出更好的自拍照"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ 此屏幕将会关闭"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展开可折叠设备"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"正在翻转可折叠设备"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 092fe34..0d54f6b 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -85,18 +85,21 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"分享螢幕截圖"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"擷取更大範圍的螢幕內容"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"關閉螢幕截圖"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"關閉工作設定檔訊息"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"螢幕截圖預覽"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"上方邊界 <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"下方邊界 <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"左方邊界 <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"右方邊界 <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
+    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"工作的螢幕截圖會儲存在「<xliff:g id="APP">%1$s</xliff:g>」應用程式"</string>
+    <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"檔案"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"螢幕畫面錄影工具"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"正在處理螢幕錄影內容"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"持續顯示錄影畫面工作階段通知"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"要開始錄製嗎?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"錄影時,Android 系統可擷取螢幕上顯示或裝置播放的任何敏感資料,包括密碼、付款資料、相片、訊息和音訊。"</string>
     <string name="screenrecord_option_entire_screen" msgid="1732437834603426934">"錄製整個螢幕畫面"</string>
-    <string name="screenrecord_option_single_app" msgid="5954863081500035825">"錄製單一應用程式"</string>
+    <string name="screenrecord_option_single_app" msgid="5954863081500035825">"錄製一個應用程式"</string>
     <string name="screenrecord_warning_entire_screen" msgid="8141407178104195610">"進行錄製時,Android 可存取顯示在螢幕畫面上或在裝置上播放的所有內容。因此請謹慎處理密碼、付款資料、訊息或其他敏感資料。"</string>
     <string name="screenrecord_warning_single_app" msgid="7760723997065948283">"錄製應用程式時,Android 可存取在該應用程式中顯示或播放的所有內容。因此請謹慎處理密碼、付款資料、訊息或其他敏感資料。"</string>
     <string name="screenrecord_start_recording" msgid="348286842544768740">"開始錄製"</string>
@@ -372,8 +375,8 @@
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"要使用「<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>」開始錄影或投放嗎?"</string>
     <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"允許 <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 分享或錄製嗎?"</string>
     <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"整個螢幕畫面"</string>
-    <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"單一應用程式"</string>
-    <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"進行分享、錄製或投放時,<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 可存取顯示在螢幕畫面上或在裝置上播放的所有內容。因此請謹慎處理密碼、付款資料、訊息或其他敏感資料。"</string>
+    <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"一個應用程式"</string>
+    <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"當您分享、錄製或投放應用程式時,<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 可存取在螢幕畫面上顯示或在裝置上播放的所有內容。因此請小心保管密碼、付款資料、訊息或其他敏感資料。"</string>
     <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"進行分享、錄製或投放時,<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 可存取顯示在螢幕畫面上或在裝置上播放的所有內容。因此請謹慎處理密碼、付款資料、訊息或其他敏感資料。"</string>
     <string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"繼續"</string>
     <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"分享或錄製應用程式"</string>
@@ -731,8 +734,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi 已關閉"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"藍牙已關閉"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"「請勿騷擾」已關閉"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"「請勿騷擾」已開啟"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"「<xliff:g id="ID_1">%s</xliff:g>」自動規則已開啟「請勿騷擾」功能。"</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"「<xliff:g id="ID_1">%s</xliff:g>」應用程式已開啟「請勿騷擾」功能。"</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"某個自動規則或應用程式已開啟「請勿騷擾」功能。"</string>
@@ -850,9 +852,12 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"在 <xliff:g id="APP_LABEL">%2$s</xliff:g> 播放《<xliff:g id="SONG_NAME">%1$s</xliff:g>》"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"復原"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"如要在「<xliff:g id="DEVICENAME">%1$s</xliff:g>」上播放,請靠近一點"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"如要在此裝置上播放,請靠近「<xliff:g id="DEVICENAME">%1$s</xliff:g>」"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"正在「<xliff:g id="DEVICENAME">%1$s</xliff:g>」上播放"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"發生錯誤,請再試一次。"</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"載入中"</string>
+    <string name="media_ttt_default_device_type" msgid="4457646436153370169">"平板電腦"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"已停用,請檢查應用程式"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"找不到"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"無法使用控制功能"</string>
@@ -875,6 +880,8 @@
     <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">"喇叭和螢幕"</string>
+    <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"建議的裝置"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"廣播運作方式"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"廣播"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"附近有兼容藍牙裝置的人可收聽您正在廣播的媒體內容"</string>
@@ -998,22 +1005,22 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"開啟「<xliff:g id="APPNAME">%1$s</xliff:g>」"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"如要新增「<xliff:g id="APPNAME">%1$s</xliff:g>」應用程式為快速鍵,請確保:"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• 應用程式已完成設定"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• 已新增至少一張卡至「錢包」"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• 安裝相機應用程式"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• 應用程式已完成設定"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• 至少一部裝置可用"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"輕觸並按住快速鍵"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"取消"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"立即翻轉"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"打開手機,即可拍攝更出色的自拍"</string>
     <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"要翻轉至前方螢幕拍攝更出色的自拍嗎?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"使用後置鏡頭,拍攝更廣角、解像度更高的相片。"</string>
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ 此螢幕將關閉"</b></string>
-    <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展開的折疊式裝置"</string>
+    <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展開折疊式裝置"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"正在翻轉折疊式裝置"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index e098882..6a78a93 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -85,11 +85,14 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"分享螢幕截圖"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"擴大螢幕截圖範圍"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"關閉螢幕截圖"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"關閉工作資料夾訊息"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"螢幕截圖預覽"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"上方邊界百分之 <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"下方邊界百分之 <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"左側邊界百分之 <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"右側邊界百分之 <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"工作的螢幕截圖會儲存在「<xliff:g id="APP">%1$s</xliff:g>」應用程式"</string>
+    <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"檔案"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"螢幕錄影器"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"處理螢幕錄影內容"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"持續顯示螢幕畫面錄製工作階段通知"</string>
@@ -373,8 +376,8 @@
     <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"允許 <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 分享或錄製?"</string>
     <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"整個螢幕畫面"</string>
     <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"單一應用程式"</string>
-    <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"進行分享、錄製或投放時,<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 可以存取顯示在螢幕畫面上或在裝置上播放的所有內容。因此請謹慎處理密碼、付款資料、訊息或其他機密資訊。"</string>
-    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"進行分享、錄製或投放應用程式時,<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 可以存取在該應用程式中顯示或播放的所有內容。因此請謹慎處理密碼、付款資料、訊息或其他機密資訊。"</string>
+    <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"分享、錄製或投放時,<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 可以存取顯示在螢幕畫面上或在裝置上播放的所有內容。因此請謹慎處理密碼、付款資料、訊息或其他機密資訊。"</string>
+    <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"分享、錄製或投放應用程式時,<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 可以存取在應用程式中顯示或播放的所有內容。因此請謹慎處理密碼、付款資料、訊息或其他機密資訊。"</string>
     <string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"繼續"</string>
     <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"分享或錄製應用程式"</string>
     <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"要允許這個應用程式分享或錄製嗎?"</string>
@@ -731,8 +734,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi 已關閉"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"藍牙已關閉"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"零打擾模式已關閉"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"已開啟零打擾模式"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"「<xliff:g id="ID_1">%s</xliff:g>」自動規則已將零打擾模式開啟。"</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"「<xliff:g id="ID_1">%s</xliff:g>」應用程式已將零打擾模式開啟。"</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"某個自動規則或應用程式已將零打擾模式開啟。"</string>
@@ -850,9 +852,12 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"透過「<xliff:g id="APP_LABEL">%2$s</xliff:g>」播放〈<xliff:g id="SONG_NAME">%1$s</xliff:g>〉"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"復原"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"如要在「<xliff:g id="DEVICENAME">%1$s</xliff:g>」上播放,請靠近一點"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"如要在這部裝置上播放,請移到更靠近「<xliff:g id="DEVICENAME">%1$s</xliff:g>」的位置"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"正在「<xliff:g id="DEVICENAME">%1$s</xliff:g>」上播放"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"發生錯誤,請再試一次。"</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"載入中"</string>
+    <string name="media_ttt_default_device_type" msgid="4457646436153370169">"平板電腦"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"無效,請查看應用程式"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"找不到控制項"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"無法使用控制項"</string>
@@ -875,6 +880,8 @@
     <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">"喇叭和螢幕"</string>
+    <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"建議的裝置"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"廣播功能的運作方式"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"廣播"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"如果附近的人有相容的藍牙裝置,就可以聽到你正在廣播的媒體內容"</string>
@@ -998,14 +1005,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"開啟「<xliff:g id="APPNAME">%1$s</xliff:g>」"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"如要將「<xliff:g id="APPNAME">%1$s</xliff:g>」應用程式新增為捷徑,必須滿足以下條件"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• 完成應用程式設定"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• 錢包中至少要有一張卡片"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• 安裝相機應用程式"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• 完成應用程式設定"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• 至少要有一部可用裝置"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"按住快速鍵"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"取消"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"立即翻轉"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"打開手機自拍效果較佳"</string>
@@ -1014,6 +1019,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ 這麼做會關閉這個螢幕"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展開的折疊式裝置"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"正在翻轉折疊式裝置"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 0a2aa8b..311fe8b 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -85,11 +85,16 @@
     <string name="screenshot_share_description" msgid="2861628935812656612">"Yabelana ngesithombe-skrini"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Thwebula okuningi"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Cashisa isithombe-skrini"</string>
+    <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Chitha umyalezo wephrofayela yomsebenzi"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Ukubuka kuqala isithombe-skrini"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Iphesenti elingu-<xliff:g id="PERCENT">%1$d</xliff:g> lomngcele ophezulu"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Iphesenti elingu-<xliff:g id="PERCENT">%1$d</xliff:g> lomngcele ophansi"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Iphesenti elingu-<xliff:g id="PERCENT">%1$d</xliff:g> lomngcele ongakwesobunxele"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Iphesenti elingu-<xliff:g id="PERCENT">%1$d</xliff:g> lomngcele ongakwesokudla"</string>
+    <!-- no translation found for screenshot_work_profile_notification (2812417845875653929) -->
+    <skip />
+    <!-- no translation found for screenshot_default_files_app_name (8721579578575161912) -->
+    <skip />
     <string name="screenrecord_name" msgid="2596401223859996572">"Irekhoda yesikrini"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Icubungula okokuqopha iskrini"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Isaziso esiqhubekayo seseshini yokurekhoda isikrini"</string>
@@ -731,8 +736,7 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"I-Wi-Fi ivaliwe"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"I-Bluetooth ivaliwe"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Ungaphazamisi kuvaliwe"</string>
-    <!-- no translation found for dnd_is_on (7009368176361546279) -->
-    <skip />
+    <string name="dnd_is_on" msgid="7009368176361546279">"Ukungaphazamisi kuvuliwe"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Okuthi ungaphazamisi kuvulwe umthetho ozenzakalelayo (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Okuthi ungaphazamisi kuvulwe uhlelo lokusebenza (<xliff:g id="ID_1">%s</xliff:g>)."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Okuthi ungaphazamisi kuvulwe umthetho ozenzakalelayo noma uhlelo lokusebenza."</string>
@@ -850,9 +854,13 @@
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Dlala i-<xliff:g id="SONG_NAME">%1$s</xliff:g> kusuka ku-<xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Hlehlisa"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Sondeza eduze ukudlala ku-<xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
-    <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Sondela eduze ne-<xliff:g id="DEVICENAME">%1$s</xliff:g> ukuze udlale lapha"</string>
+    <!-- no translation found for media_move_closer_to_end_cast (7302555909119374738) -->
+    <skip />
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Idlala ku-<xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Kukhona okungahambanga kahle. Zama futhi."</string>
+    <string name="media_transfer_loading" msgid="5544017127027152422">"Iyalayisha"</string>
+    <!-- no translation found for media_ttt_default_device_type (4457646436153370169) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Akusebenzi, hlola uhlelo lokusebenza"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Ayitholakali"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Ukulawula akutholakali"</string>
@@ -875,6 +883,9 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Amadivayisi atholakalayo okukhipha umsindo."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Ivolumu"</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">"Izipikha Neziboniso"</string>
+    <!-- no translation found for media_output_group_title_suggested_device (4157186235837903826) -->
+    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Indlela ukusakaza okusebenza ngayo"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Sakaza"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Abantu abaseduze nawe abanamadivayisi e-Bluetooth ahambisanayo bangalalela imidiya oyisakazayo"</string>
@@ -998,14 +1009,12 @@
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Vula i-<xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Ukwengeza i-app ye-<xliff:g id="APPNAME">%1$s</xliff:g> njengesinqamuleli, qinisekisa"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• I-app isethiwe"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Okungenani ikhadi elilodwa lengeziwe ku-Wallet"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Faka i-app yekhamera"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• I-app isethiwe"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Okungenani idivayisi eyodwa iyatholakala"</string>
-    <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
-    <skip />
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Thinta futhi ubambe isinqamuleli"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Khansela"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Phendula manje"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Vula ifoni ukuze ube nesithombe ozishuthe sona esingcono"</string>
@@ -1014,6 +1023,8 @@
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Lesi sikrini sizovala"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Idivayisi egoqekayo iyembulwa"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Idivayisi egoqekayo iphendulwa nxazonke"</string>
-    <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+    <!-- no translation found for stylus_battery_low_percentage (1620068112350141558) -->
+    <skip />
+    <!-- no translation found for stylus_battery_low_subtitle (3583843128908823273) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index f0cc42e..e8a5e7e 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -437,6 +437,11 @@
          This name is in the ComponentName flattened format (package/class)  -->
     <string name="config_screenshotEditor" translatable="false"></string>
 
+    <!-- ComponentName for the file browsing app that the system would expect to be used in work
+         profile. The icon for this app will be shown to the user when informing them that a
+         screenshot has been saved to work profile. If blank, a default icon will be shown. -->
+    <string name="config_sceenshotWorkProfileFilesApp" translatable="false"></string>
+
     <!-- Remote copy default activity.  Must handle REMOTE_COPY_ACTION intents.
      This name is in the ComponentName flattened format (package/class)  -->
     <string name="config_remoteCopyPackage" translatable="false"></string>
@@ -658,9 +663,21 @@
         <item>7</item> <!-- WAKE_REASON_WAKE_MOTION -->
         <item>9</item> <!-- WAKE_REASON_LID -->
         <item>10</item> <!-- WAKE_REASON_DISPLAY_GROUP_ADDED -->
-        <item>12</item> <!-- WAKE_REASON_UNFOLD_DEVICE -->
+        <item>15</item> <!-- WAKE_REASON_TAP -->
+        <item>16</item> <!-- WAKE_REASON_LIFT -->
+        <item>17</item> <!-- WAKE_REASON_BIOMETRIC -->
     </integer-array>
 
+    <!-- Whether to support posture listening for face auth, default is 0(DEVICE_POSTURE_UNKNOWN)
+         means systemui will try listening on all postures.
+         0 : DEVICE_POSTURE_UNKNOWN
+         1 : DEVICE_POSTURE_CLOSED
+         2 : DEVICE_POSTURE_HALF_OPENED
+         3 : DEVICE_POSTURE_OPENED
+         4 : DEVICE_POSTURE_FLIPPED
+    -->
+    <integer name="config_face_auth_supported_posture">0</integer>
+
     <!-- Whether the communal service should be enabled -->
     <bool name="config_communalServiceEnabled">false</bool>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index ecb6560..1ef0206 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -334,15 +334,22 @@
     <dimen name="overlay_action_chip_spacing">8dp</dimen>
     <dimen name="overlay_action_chip_text_size">14sp</dimen>
     <dimen name="overlay_offset_x">16dp</dimen>
+    <!-- Used for both start and bottom margin of the preview, relative to the action container -->
+    <dimen name="overlay_preview_container_margin">8dp</dimen>
     <dimen name="overlay_action_container_margin_horizontal">8dp</dimen>
+    <dimen name="overlay_action_container_margin_bottom">4dp</dimen>
     <dimen name="overlay_bg_protection_height">242dp</dimen>
     <dimen name="overlay_action_container_corner_radius">18dp</dimen>
     <dimen name="overlay_action_container_padding_vertical">4dp</dimen>
     <dimen name="overlay_action_container_padding_right">8dp</dimen>
+    <dimen name="overlay_action_container_padding_end">8dp</dimen>
     <dimen name="overlay_dismiss_button_tappable_size">48dp</dimen>
     <dimen name="overlay_dismiss_button_margin">8dp</dimen>
+    <!-- must be kept aligned with overlay_border_width_neg, below;
+         overlay_border_width = overlay_border_width_neg * -1 -->
     <dimen name="overlay_border_width">4dp</dimen>
-    <!-- need a negative margin for some of the constraints. should be overlay_border_width * -1 -->
+    <!-- some constraints use a negative margin. must be aligned with overlay_border_width, above;
+         overlay_border_width_neg = overlay_border_width * -1 -->
     <dimen name="overlay_border_width_neg">-4dp</dimen>
 
     <dimen name="clipboard_preview_size">@dimen/overlay_x_scale</dimen>
@@ -755,12 +762,10 @@
     <dimen name="go_to_full_shade_appearing_translation">200dp</dimen>
 
     <!-- The width/height of the keyguard bottom area icon view on keyguard. -->
-    <dimen name="keyguard_affordance_height">48dp</dimen>
-    <dimen name="keyguard_affordance_width">48dp</dimen>
-
     <dimen name="keyguard_affordance_fixed_height">48dp</dimen>
     <dimen name="keyguard_affordance_fixed_width">48dp</dimen>
     <dimen name="keyguard_affordance_fixed_radius">24dp</dimen>
+
     <!-- Amount the button should shake when it's not long-pressed for long enough. -->
     <dimen name="keyguard_affordance_shake_amplitude">8dp</dimen>
 
@@ -966,6 +971,10 @@
     <!-- Biometric Auth Credential values -->
     <dimen name="biometric_auth_icon_size">48dp</dimen>
 
+    <!-- Biometric Auth pattern view size, better to align keyguard_security_width -->
+    <dimen name="biometric_auth_pattern_view_size">348dp</dimen>
+    <dimen name="biometric_auth_pattern_view_max_size">348dp</dimen>
+
     <!-- Starting text size in sp of batteryLevel for wireless charging animation -->
     <item name="wireless_charging_anim_battery_level_text_size_start" format="float" type="dimen">
         0
@@ -1030,8 +1039,6 @@
 
     <dimen name="ongoing_appops_dialog_side_padding">16dp</dimen>
 
-    <!-- Size of the RAT type for CellularTile -->
-
     <!-- Size of media cards in the QSPanel carousel -->
     <dimen name="qs_media_padding">16dp</dimen>
     <dimen name="qs_media_album_radius">14dp</dimen>
@@ -1046,6 +1053,7 @@
     <dimen name="qs_media_disabled_seekbar_height">1dp</dimen>
     <dimen name="qs_media_enabled_seekbar_height">2dp</dimen>
     <dimen name="qs_media_app_icon_size">24dp</dimen>
+    <dimen name="qs_media_explicit_indicator_icon_size">13dp</dimen>
 
     <dimen name="qs_media_session_enabled_seekbar_vertical_padding">15dp</dimen>
     <dimen name="qs_media_session_disabled_seekbar_vertical_padding">16dp</dimen>
@@ -1079,6 +1087,7 @@
          (112 - 40) / 2 = 36dp -->
     <dimen name="media_ttt_generic_icon_padding">36dp</dimen>
     <dimen name="media_ttt_receiver_vert_translation">40dp</dimen>
+    <dimen name="media_ttt_receiver_icon_bottom_margin">10dp</dimen>
 
     <!-- Window magnification -->
     <dimen name="magnification_border_drag_size">35dp</dimen>
@@ -1279,6 +1288,15 @@
     <!-- OCCLUDED -> LOCKSCREEN transition: Amount to shift lockscreen content on entering -->
     <dimen name="occluded_to_lockscreen_transition_lockscreen_translation_y">40dp</dimen>
 
+    <!-- LOCKSCREEN -> DREAMING transition: Amount to shift lockscreen content on entering -->
+    <dimen name="lockscreen_to_dreaming_transition_lockscreen_translation_y">-40dp</dimen>
+
+    <!-- GONE -> DREAMING transition: Amount to shift lockscreen content on entering -->
+    <dimen name="gone_to_dreaming_transition_lockscreen_translation_y">-40dp</dimen>
+
+    <!-- LOCKSCREEN -> OCCLUDED transition: Amount to shift lockscreen content on entering -->
+    <dimen name="lockscreen_to_occluded_transition_lockscreen_translation_y">-40dp</dimen>
+
     <!-- The amount of vertical offset for the keyguard during the full shade transition. -->
     <dimen name="lockscreen_shade_keyguard_transition_vertical_offset">0dp</dimen>
 
@@ -1617,6 +1635,8 @@
     <dimen name="dream_overlay_status_bar_ambient_text_shadow_dx">0.5dp</dimen>
     <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/strings.xml b/packages/SystemUI/res/values/strings.xml
index 29369cd..066b185 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -240,7 +240,9 @@
     <!-- Content description for the right boundary of the screenshot being cropped, with the current position as a percentage. [CHAR LIMIT=NONE] -->
     <string name="screenshot_right_boundary_pct">Right boundary <xliff:g id="percent" example="50">%1$d</xliff:g> percent</string>
     <!-- Notification displayed when a screenshot is saved in a work profile. [CHAR LIMIT=NONE] -->
-    <string name="screenshot_work_profile_notification" translatable="false">Work screenshots are saved in the work <xliff:g id="app" example="Files">%1$s</xliff:g> app</string>
+    <string name="screenshot_work_profile_notification">Work screenshots are saved in the <xliff:g id="app" example="Work Files">%1$s</xliff:g> app</string>
+    <!-- Default name referring to the app on the device that lets the user browse stored files. [CHAR LIMIT=NONE] -->
+    <string name="screenshot_default_files_app_name">Files</string>
 
     <!-- Notification title displayed for screen recording [CHAR LIMIT=50]-->
     <string name="screenrecord_name">Screen Recorder</string>
@@ -1453,10 +1455,10 @@
     <string name="notification_conversation_summary_low">No sound or vibration and appears lower in conversation section</string>
 
     <!-- [CHAR LIMIT=150] Notification Importance title: normal importance level summary -->
-    <string name="notification_channel_summary_default">May ring or vibrate based on phone settings</string>
+    <string name="notification_channel_summary_default">May ring or vibrate based on device settings</string>
 
     <!-- [CHAR LIMIT=150] Conversation Notification Importance title: normal conversation level, with bubbling summary -->
-    <string name="notification_channel_summary_default_with_bubbles">May ring or vibrate based on phone settings. Conversations from <xliff:g id="app_name" example="YouTube">%1$s</xliff:g> bubble by default.</string>
+    <string name="notification_channel_summary_default_with_bubbles">May ring or vibrate based on device settings. Conversations from <xliff:g id="app_name" example="YouTube">%1$s</xliff:g> bubble by default.</string>
 
     <!-- [CHAR LIMIT=150] Notification Importance title: automatic importance level summary -->
     <string name="notification_channel_summary_automatic">Have the system determine if this notification should make sound or vibration</string>
@@ -2357,11 +2359,15 @@
     <!-- Text to ask the user to move their device closer to a different device (deviceName) in order to play media on the different device. [CHAR LIMIT=75] -->
     <string name="media_move_closer_to_start_cast">Move closer to play on <xliff:g id="deviceName" example="My Tablet">%1$s</xliff:g></string>
     <!-- Text to ask the user to move their device closer to a different device (deviceName) in order to transfer media from the different device and back onto the current device. [CHAR LIMIT=75] -->
-    <string name="media_move_closer_to_end_cast">Move closer to <xliff:g id="deviceName" example="My Tablet">%1$s</xliff:g> to play here</string>
+    <string name="media_move_closer_to_end_cast">To play here, move closer to <xliff:g id="deviceName" example="tablet">%1$s</xliff:g></string>
     <!-- Text informing the user that their media is now playing on a different device (deviceName). [CHAR LIMIT=50] -->
     <string name="media_transfer_playing_different_device">Playing on <xliff:g id="deviceName" example="My Tablet">%1$s</xliff:g></string>
-    <!-- Text informing the user that the media transfer has failed because something went wrong. [CHAR LIsMIT=50] -->
+    <!-- Text informing the user that the media transfer has failed because something went wrong. [CHAR LIMIT=50] -->
     <string name="media_transfer_failed">Something went wrong. Try again.</string>
+    <!-- Text to indicate that a media transfer is currently in-progress, aka loading. [CHAR LIMIT=NONE] -->
+    <string name="media_transfer_loading">Loading</string>
+    <!-- Default name of the device. [CHAR LIMIT=30] -->
+    <string name="media_ttt_default_device_type">tablet</string>
 
     <!-- Error message indicating that a control timed out while waiting for an update [CHAR_LIMIT=30] -->
     <string name="controls_error_timeout">Inactive, check app</string>
@@ -2410,6 +2416,8 @@
     <string name="media_output_dialog_volume_percentage"><xliff:g id="percentage" example="10">%1$d</xliff:g>%%</string>
     <!-- Title for Speakers and Displays group. [CHAR LIMIT=NONE] -->
     <string name="media_output_group_title_speakers_and_displays">Speakers &amp; Displays</string>
+    <!-- Title for Suggested Devices group. [CHAR LIMIT=NONE] -->
+    <string name="media_output_group_title_suggested_device">Suggested Devices</string>
 
     <!-- Media Output Broadcast Dialog -->
     <!-- Title for Broadcast First Notify Dialog [CHAR LIMIT=60] -->
@@ -2707,12 +2715,6 @@
     <string name="keyguard_affordance_enablement_dialog_action_template">Open <xliff:g id="appName" example="Wallet">%1$s</xliff:g></string>
 
     <!--
-    Template for a message shown right before a list of instructions that tell the user what to do
-    in order to enable a shortcut to a specific app. [CHAR LIMIT=NONE]
-    -->
-    <string name="keyguard_affordance_enablement_dialog_message">To add the <xliff:g id="appName" example="Wallet">%1$s</xliff:g> app as a shortcut, make sure</string>
-
-    <!--
     Requirement for the wallet app to be available for the user to use. This is shown as part of a
     bulleted list of requirements. When all requirements are met, the app can be accessed through a
     shortcut button on the lock screen. [CHAR LIMIT=NONE].
@@ -2748,10 +2750,10 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2">&#8226; At least one device is available</string>
 
     <!--
-    Error message shown when a button should be pressed and held to activate it, usually shown when
-    the user attempted to tap the button or held it for too short a time. [CHAR LIMIT=32].
+    Error message shown when a shortcut must be pressed and held to activate it, usually shown when
+    the user tried to tap the shortcut or held it for too short a time. [CHAR LIMIT=32].
     -->
-    <string name="keyguard_affordance_press_too_short">Touch &amp; hold to open</string>
+    <string name="keyguard_affordance_press_too_short">Touch &amp; hold shortcut</string>
 
     <!-- Text for education page of cancel button to hide the page. [CHAR_LIMIT=NONE] -->
     <string name="rear_display_bottom_sheet_cancel">Cancel</string>
@@ -2770,6 +2772,30 @@
     <!-- Text for education page content description for unfolded animation. [CHAR_LIMIT=NONE] -->
     <string name="rear_display_accessibility_unfolded_animation">Foldable device being flipped around</string>
 
+    <!-- Title for notification of low stylus battery with percentage. "percentage" is
+        the value of the battery capacity remaining [CHAR LIMIT=none]-->
+    <string name="stylus_battery_low_percentage"><xliff:g id="percentage" example="16%">%s</xliff:g> battery remaining</string>
+    <!-- Subtitle for the notification sent when a stylus battery is low. [CHAR LIMIT=none]-->
+    <string name="stylus_battery_low_subtitle">Connect your stylus to a charger</string>
+
     <!-- Title for notification of low stylus battery. [CHAR_LIMIT=NONE] -->
     <string name="stylus_battery_low">Stylus battery low</string>
+
+    <!-- Label for a lock screen shortcut to start the camera in video mode. [CHAR_LIMIT=16] -->
+    <string name="video_camera">Video camera</string>
+
+    <!-- Switch to work profile dialer app for placing a call dialog. -->
+    <!-- Text for Switch to work profile dialog's Title. Switch to work profile dialog guide users to make call from work
+    profile dialer app as it's not possible to make call from current profile due to an admin policy. [CHAR LIMIT=60] -->
+    <string name="call_from_work_profile_title">Can\'t call from this profile</string>
+    <!-- Text for switch to work profile for call dialog to guide users to make call from work
+    profile dialer app as it's not possible to make call from current profile due to an admin policy. [CHAR LIMIT=NONE]
+    -->
+    <string name="call_from_work_profile_text">Your work policy allows you to make phone calls only from the work profile</string>
+    <!-- Label for the button to switch to work profile for placing call. Switch to work profile dialog guide users to make call from work
+    profile dialer app as it's not possible to make call from current profile due to an admin policy.[CHAR LIMIT=60] -->
+    <string name="call_from_work_profile_action">Switch to work profile</string>
+    <!-- Label for the close button on switch to work profile dialog. Switch to work profile dialog guide users to make call from work
+    profile dialer app as it's not possible to make call from current profile due to an admin policy.[CHAR LIMIT=60] -->
+    <string name="call_from_work_profile_close">Close</string>
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index b11b6d6..9846fc2 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -251,11 +251,12 @@
 
     <style name="AuthCredentialPatternContainerStyle">
         <item name="android:gravity">center</item>
-        <item name="android:maxHeight">420dp</item>
-        <item name="android:maxWidth">420dp</item>
-        <item name="android:minHeight">200dp</item>
-        <item name="android:minWidth">200dp</item>
-        <item name="android:padding">20dp</item>
+        <item name="android:maxHeight">@dimen/biometric_auth_pattern_view_max_size</item>
+        <item name="android:maxWidth">@dimen/biometric_auth_pattern_view_max_size</item>
+        <item name="android:minHeight">@dimen/biometric_auth_pattern_view_size</item>
+        <item name="android:minWidth">@dimen/biometric_auth_pattern_view_size</item>
+        <item name="android:paddingHorizontal">32dp</item>
+        <item name="android:paddingVertical">20dp</item>
     </style>
 
     <style name="AuthCredentialPinPasswordContainerStyle">
diff --git a/packages/SystemUI/res/xml/large_screen_shade_header.xml b/packages/SystemUI/res/xml/large_screen_shade_header.xml
index 06d425c..bf576dc 100644
--- a/packages/SystemUI/res/xml/large_screen_shade_header.xml
+++ b/packages/SystemUI/res/xml/large_screen_shade_header.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
   ~ Copyright (C) 2021 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,105 +14,73 @@
   ~ limitations under the License.
   -->
 
-<ConstraintSet
-    xmlns:android="http://schemas.android.com/apk/res/android"
+<ConstraintSet xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/large_screen_header_constraint">
 
-    <Constraint
-        android:id="@+id/clock">
+    <Constraint android:id="@+id/clock">
         <Layout
             android:layout_width="wrap_content"
             android:layout_height="0dp"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toTopOf="parent"
             app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintEnd_toStartOf="@id/date"
-            app:layout_constraintHorizontal_bias="0"
-        />
-        <Transform
-            android:scaleX="1"
-            android:scaleY="1"
-            />
+            app:layout_constraintStart_toEndOf="@id/begin_guide"
+            app:layout_constraintTop_toTopOf="parent" />
+        <PropertySet android:alpha="1" />
     </Constraint>
 
-    <Constraint
-        android:id="@+id/date">
+    <Constraint android:id="@+id/date">
         <Layout
             android:layout_width="wrap_content"
             android:layout_height="0dp"
+            android:layout_marginStart="8dp"
+            app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintStart_toEndOf="@id/clock"
-            app:layout_constraintEnd_toStartOf="@id/carrier_group"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintHorizontal_bias="0"
-        />
+            app:layout_constraintTop_toTopOf="parent" />
+        <PropertySet android:alpha="1" />
     </Constraint>
 
-    <Constraint
-        android:id="@+id/carrier_group">
+    <Constraint android:id="@+id/carrier_group">
         <Layout
-            app:layout_constraintWidth_min="48dp"
             android:layout_width="0dp"
             android:layout_height="0dp"
-            app:layout_constrainedWidth="true"
             android:layout_gravity="end|center_vertical"
-            android:layout_marginStart="8dp"
-            app:layout_constraintStart_toEndOf="@id/date"
-            app:layout_constraintEnd_toStartOf="@id/statusIcons"
-            app:layout_constraintTop_toTopOf="@id/clock"
             app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintHorizontal_bias="1"
-            />
-        <PropertySet
-            android:alpha="1"
-        />
+            app:layout_constraintEnd_toStartOf="@id/statusIcons"
+            app:layout_constraintStart_toEndOf="@id/date"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintWidth_default="wrap"
+            app:layout_constraintWidth_min="48dp" />
+        <PropertySet android:alpha="1" />
     </Constraint>
 
-    <Constraint
-        android:id="@+id/statusIcons">
+    <Constraint android:id="@+id/statusIcons">
         <Layout
-            app:layout_constraintHeight_min="@dimen/large_screen_shade_header_min_height"
             android:layout_width="wrap_content"
             android:layout_height="@dimen/large_screen_shade_header_min_height"
-            app:layout_constraintStart_toEndOf="@id/carrier_group"
-            app:layout_constraintEnd_toStartOf="@id/batteryRemainingIcon"
-            app:layout_constraintTop_toTopOf="@id/clock"
             app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintHorizontal_bias="1"
-            />
-        <PropertySet
-            android:alpha="1"
-        />
+            app:layout_constraintEnd_toStartOf="@id/batteryRemainingIcon"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintEnd_toEndOf="@id/carrier_group"/>
+        <PropertySet android:alpha="1" />
     </Constraint>
 
-    <Constraint
-        android:id="@+id/batteryRemainingIcon">
+    <Constraint android:id="@+id/batteryRemainingIcon">
         <Layout
             android:layout_width="wrap_content"
             android:layout_height="0dp"
             app:layout_constraintHeight_min="@dimen/large_screen_shade_header_min_height"
-            app:layout_constraintStart_toEndOf="@id/statusIcons"
-            app:layout_constraintEnd_toStartOf="@id/privacy_container"
-            app:layout_constraintTop_toTopOf="@id/clock"
             app:layout_constraintBottom_toBottomOf="parent"
-        />
-        <PropertySet
-            android:alpha="1"
-        />
+            app:layout_constraintEnd_toStartOf="@id/privacy_container"
+            app:layout_constraintTop_toTopOf="parent" />
+        <PropertySet android:alpha="1" />
     </Constraint>
 
-    <Constraint
-        android:id="@+id/privacy_container">
+    <Constraint android:id="@+id/privacy_container">
         <Layout
             android:layout_width="wrap_content"
             android:layout_height="@dimen/large_screen_shade_header_min_height"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toTopOf="@id/date"
-            app:layout_constraintBottom_toBottomOf="@id/date"
-            app:layout_constraintStart_toEndOf="@id/batteryRemainingIcon"
-            app:layout_constraintHorizontal_bias="1"
-        />
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toStartOf="@id/end_guide"
+            app:layout_constraintTop_toTopOf="parent" />
     </Constraint>
-
 </ConstraintSet>
\ No newline at end of file
diff --git a/packages/SystemUI/res/xml/media_session_collapsed.xml b/packages/SystemUI/res/xml/media_session_collapsed.xml
index 1eb621e..d9c81af 100644
--- a/packages/SystemUI/res/xml/media_session_collapsed.xml
+++ b/packages/SystemUI/res/xml/media_session_collapsed.xml
@@ -66,6 +66,21 @@
         app:layout_constraintTop_toBottomOf="@id/icon"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintHorizontal_bias="0" />
+
+    <Constraint
+        android:id="@+id/media_explicit_indicator"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/qs_media_info_spacing"
+        android:layout_marginBottom="@dimen/qs_media_padding"
+        android:layout_marginTop="0dp"
+        app:layout_constraintStart_toStartOf="@id/header_title"
+        app:layout_constraintEnd_toStartOf="@id/header_artist"
+        app:layout_constraintTop_toTopOf="@id/header_artist"
+        app:layout_constraintBottom_toTopOf="@id/media_action_barrier_top"
+        app:layout_constraintHorizontal_bias="0"
+        app:layout_constraintHorizontal_chainStyle="packed" />
+
     <Constraint
         android:id="@+id/header_artist"
         android:layout_width="wrap_content"
@@ -75,9 +90,8 @@
         app:layout_constraintEnd_toStartOf="@id/action_button_guideline"
         app:layout_constrainedWidth="true"
         app:layout_constraintTop_toBottomOf="@id/header_title"
-        app:layout_constraintStart_toStartOf="@id/header_title"
-        app:layout_constraintVertical_bias="0"
-        app:layout_constraintHorizontal_bias="0" />
+        app:layout_constraintStart_toEndOf="@id/media_explicit_indicator"
+        app:layout_constraintVertical_bias="0" />
 
     <Constraint
         android:id="@+id/actionPlayPause"
diff --git a/packages/SystemUI/res/xml/media_session_expanded.xml b/packages/SystemUI/res/xml/media_session_expanded.xml
index 7de0a5e..0cdc0f9 100644
--- a/packages/SystemUI/res/xml/media_session_expanded.xml
+++ b/packages/SystemUI/res/xml/media_session_expanded.xml
@@ -58,6 +58,21 @@
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintBottom_toTopOf="@id/header_artist"
         app:layout_constraintHorizontal_bias="0" />
+
+    <Constraint
+        android:id="@+id/media_explicit_indicator"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/qs_media_info_spacing"
+        android:layout_marginBottom="@dimen/qs_media_padding"
+        android:layout_marginTop="0dp"
+        app:layout_constraintStart_toStartOf="@id/header_title"
+        app:layout_constraintEnd_toStartOf="@id/header_artist"
+        app:layout_constraintTop_toTopOf="@id/header_artist"
+        app:layout_constraintBottom_toTopOf="@id/media_action_barrier_top"
+        app:layout_constraintHorizontal_bias="0"
+        app:layout_constraintHorizontal_chainStyle="packed"/>
+
     <Constraint
         android:id="@+id/header_artist"
         android:layout_width="wrap_content"
@@ -67,10 +82,9 @@
         android:layout_marginTop="0dp"
         app:layout_constrainedWidth="true"
         app:layout_constraintEnd_toStartOf="@id/actionPlayPause"
-        app:layout_constraintStart_toStartOf="@id/header_title"
+        app:layout_constraintStart_toEndOf="@id/media_explicit_indicator"
         app:layout_constraintBottom_toTopOf="@id/media_action_barrier_top"
-        app:layout_constraintVertical_bias="0"
-        app:layout_constraintHorizontal_bias="0" />
+        app:layout_constraintVertical_bias="0" />
 
     <Constraint
         android:id="@+id/actionPlayPause"
diff --git a/packages/SystemUI/res/xml/qs_header.xml b/packages/SystemUI/res/xml/qs_header.xml
index eca2b2a..d97031f 100644
--- a/packages/SystemUI/res/xml/qs_header.xml
+++ b/packages/SystemUI/res/xml/qs_header.xml
@@ -56,13 +56,9 @@
         <Layout
             android:layout_width="wrap_content"
             android:layout_height="@dimen/new_qs_header_non_clickable_element_height"
-            app:layout_constrainedWidth="true"
             app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintEnd_toStartOf="@id/space"
             app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintTop_toBottomOf="@id/carrier_group"
-            app:layout_constraintHorizontal_bias="0"
-            app:layout_constraintHorizontal_chainStyle="spread_inside"
         />
     </Constraint>
 
@@ -87,39 +83,27 @@
     <Constraint
         android:id="@+id/statusIcons">
         <Layout
-            android:layout_width="wrap_content"
+            android:layout_width="0dp"
             android:layout_height="@dimen/new_qs_header_non_clickable_element_height"
-            app:layout_constraintStart_toEndOf="@id/space"
+            app:layout_constraintWidth_default="wrap"
+            app:layout_constraintStart_toEndOf="@id/date"
             app:layout_constraintEnd_toStartOf="@id/batteryRemainingIcon"
             app:layout_constraintTop_toTopOf="@id/date"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintHorizontal_bias="1"
+            app:layout_constraintBottom_toBottomOf="@id/date"
             />
     </Constraint>
 
     <Constraint
         android:id="@+id/batteryRemainingIcon">
         <Layout
-            android:layout_width="wrap_content"
+            android:layout_width="0dp"
             android:layout_height="@dimen/new_qs_header_non_clickable_element_height"
+            app:layout_constraintWidth_default="wrap"
             app:layout_constraintHeight_min="@dimen/new_qs_header_non_clickable_element_height"
-            app:layout_constraintStart_toEndOf="@id/statusIcons"
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintTop_toTopOf="@id/date"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintHorizontal_bias="1"
-            app:layout_constraintHorizontal_chainStyle="spread_inside"
+            app:layout_constraintBottom_toBottomOf="@id/date"
             />
     </Constraint>
 
-
-    <Constraint
-        android:id="@id/space">
-        <Layout
-            android:layout_width="0dp"
-            android:layout_height="0dp"
-            app:layout_constraintStart_toEndOf="@id/date"
-            app:layout_constraintEnd_toStartOf="@id/statusIcons"
-            />
-    </Constraint>
 </ConstraintSet>
\ No newline at end of file
diff --git a/packages/SystemUI/shared/Android.bp b/packages/SystemUI/shared/Android.bp
index b679cfa1..b7d9df9 100644
--- a/packages/SystemUI/shared/Android.bp
+++ b/packages/SystemUI/shared/Android.bp
@@ -85,6 +85,9 @@
     static_libs: [
         "SystemUI-flag-types",
     ],
+    optimize: {
+        proguard_flags_files: ["proguard_flags.flags"],
+    },
     java_version: "1.8",
     min_sdk_version: "current",
 }
diff --git a/packages/SystemUI/shared/proguard_flags.flags b/packages/SystemUI/shared/proguard_flags.flags
new file mode 100644
index 0000000..08859cd
--- /dev/null
+++ b/packages/SystemUI/shared/proguard_flags.flags
@@ -0,0 +1 @@
+-keep class * implements com.android.systemui.flags.ParcelableFlag
\ No newline at end of file
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/hardware/InputDevice.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/hardware/InputDevice.kt
new file mode 100644
index 0000000..a9a5cf9
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/hardware/InputDevice.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.shared.hardware
+
+import android.view.InputDevice
+
+/**
+ * Returns true if [InputDevice] is electronic components to allow a user to use an active stylus in
+ * the host device or a passive stylus is detected by the host device.
+ */
+val InputDevice.isInternalStylusSource: Boolean
+    get() = isAnyStylusSource && !isExternal
+
+/** Returns true if [InputDevice] is an active stylus. */
+val InputDevice.isExternalStylusSource: Boolean
+    get() = isAnyStylusSource && isExternal
+
+/**
+ * Returns true if [InputDevice] supports any stylus source.
+ *
+ * @see InputDevice.isInternalStylusSource
+ * @see InputDevice.isExternalStylusSource
+ */
+val InputDevice.isAnyStylusSource: Boolean
+    get() = supportsSource(InputDevice.SOURCE_STYLUS)
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/hardware/InputManager.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/hardware/InputManager.kt
new file mode 100644
index 0000000..f020b4e
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/hardware/InputManager.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.systemui.shared.hardware
+
+import android.hardware.input.InputManager
+import android.view.InputDevice
+
+/**
+ * Gets information about all input devices in the system and returns as a lazy [Sequence].
+ *
+ * For performance reasons, it is preferred to operate atop the returned [Sequence] to ensure each
+ * operation is executed on an element-per-element basis yet customizable.
+ *
+ * For example:
+ * ```kotlin
+ * val stylusDevices = inputManager.getInputDeviceSequence().filter {
+ *   it.supportsSource(InputDevice.SOURCE_STYLUS)
+ * }
+ *
+ * val hasInternalStylus = stylusDevices.any { it.isInternal }
+ * val hasExternalStylus = stylusDevices.any { !it.isInternal }
+ * ```
+ *
+ * @return a [Sequence] of [InputDevice].
+ */
+fun InputManager.getInputDeviceSequence(): Sequence<InputDevice> =
+    inputDeviceIds.asSequence().mapNotNull { getInputDevice(it) }
+
+/**
+ * Returns the first [InputDevice] matching the given predicate, or null if no such [InputDevice]
+ * was found.
+ */
+fun InputManager.findInputDevice(predicate: (InputDevice) -> Boolean): InputDevice? =
+    getInputDeviceSequence().find { predicate(it) }
+
+/**
+ * Returns true if [any] [InputDevice] matches with [predicate].
+ *
+ * For example:
+ * ```kotlin
+ * val hasStylusSupport = inputManager.hasInputDevice { it.isStylusSupport() }
+ * val hasStylusPen = inputManager.hasInputDevice { it.isStylusPen() }
+ * ```
+ */
+fun InputManager.hasInputDevice(predicate: (InputDevice) -> Boolean): Boolean =
+    getInputDeviceSequence().any { predicate(it) }
+
+/** Returns true if host device has any [InputDevice] where [InputDevice.isInternalStylusSource]. */
+fun InputManager.hasInternalStylusSource(): Boolean = hasInputDevice { it.isInternalStylusSource }
+
+/** Returns true if host device has any [InputDevice] where [InputDevice.isExternalStylusSource]. */
+fun InputManager.hasExternalStylusSource(): Boolean = hasInputDevice { it.isExternalStylusSource }
+
+/** Returns true if host device has any [InputDevice] where [InputDevice.isAnyStylusSource]. */
+fun InputManager.hasAnyStylusSource(): Boolean = hasInputDevice { it.isAnyStylusSource }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginActionManager.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginActionManager.java
index b057fe4..cc3d7a8 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginActionManager.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginActionManager.java
@@ -57,7 +57,7 @@
 
     private static final boolean DEBUG = false;
 
-    private static final String TAG = "PluginInstanceManager";
+    private static final String TAG = "PluginActionManager";
     public static final String PLUGIN_PERMISSION = "com.android.systemui.permission.PLUGIN";
 
     private final Context mContext;
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl
index abefeba..a71fb56 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl
@@ -46,8 +46,9 @@
 
     /**
      * Sent when device assistant changes its default assistant whether it is available or not.
+     * @param longPressHomeEnabled if 3-button nav assistant can be invoked or not
      */
-    void onAssistantAvailable(boolean available) = 13;
+    void onAssistantAvailable(boolean available, boolean longPressHomeEnabled) = 13;
 
     /**
      * Sent when the assistant changes how visible it is to the user.
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
index 1c532fe..b8bddd1 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
@@ -22,6 +22,7 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.view.MotionEvent;
+import com.android.internal.util.ScreenshotRequest;
 
 import com.android.systemui.shared.recents.model.Task;
 
@@ -87,12 +88,6 @@
     void notifyPrioritizedRotation(int rotation) = 25;
 
     /**
-     * Handle the provided image as if it was a screenshot.
-     */
-    void handleImageBundleAsScreenshot(in Bundle screenImageBundle, in Rect locationInScreen,
-              in Insets visibleInsets, in Task.TaskKey task) = 28;
-
-    /**
      * Notifies to expand notification panel.
      */
     void expandNotificationPanel() = 29;
@@ -125,5 +120,10 @@
      */
     void toggleNotificationPanel() = 50;
 
-    // Next id = 51
+    /**
+     * Handle the screenshot request.
+     */
+    void takeScreenshot(in ScreenshotRequest request) = 51;
+
+    // Next id = 52
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java
index 8ee893c..359da13 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java
@@ -249,7 +249,8 @@
     }
 
     public void setRotationLockedAtAngle(int rotationSuggestion) {
-        RotationPolicy.setRotationLockAtAngle(mContext, true, rotationSuggestion);
+        RotationPolicy.setRotationLockAtAngle(mContext, /* enabled= */ isRotationLocked(),
+                /* rotation= */ rotationSuggestion);
     }
 
     public boolean isRotationLocked() {
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/shadow/DoubleShadowTextView.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/shadow/DoubleShadowTextView.kt
index 25d2721..9b73cc3 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/shadow/DoubleShadowTextView.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/shadow/DoubleShadowTextView.kt
@@ -48,48 +48,28 @@
         val drawableInsetSize: Int
         try {
             val keyShadowBlur =
-                attributes.getDimensionPixelSize(R.styleable.DoubleShadowTextView_keyShadowBlur, 0)
+                attributes.getDimension(R.styleable.DoubleShadowTextView_keyShadowBlur, 0f)
             val keyShadowOffsetX =
-                attributes.getDimensionPixelSize(
-                    R.styleable.DoubleShadowTextView_keyShadowOffsetX,
-                    0
-                )
+                attributes.getDimension(R.styleable.DoubleShadowTextView_keyShadowOffsetX, 0f)
             val keyShadowOffsetY =
-                attributes.getDimensionPixelSize(
-                    R.styleable.DoubleShadowTextView_keyShadowOffsetY,
-                    0
-                )
+                attributes.getDimension(R.styleable.DoubleShadowTextView_keyShadowOffsetY, 0f)
             val keyShadowAlpha =
                 attributes.getFloat(R.styleable.DoubleShadowTextView_keyShadowAlpha, 0f)
             mKeyShadowInfo =
-                ShadowInfo(
-                    keyShadowBlur.toFloat(),
-                    keyShadowOffsetX.toFloat(),
-                    keyShadowOffsetY.toFloat(),
-                    keyShadowAlpha
-                )
+                ShadowInfo(keyShadowBlur, keyShadowOffsetX, keyShadowOffsetY, keyShadowAlpha)
             val ambientShadowBlur =
-                attributes.getDimensionPixelSize(
-                    R.styleable.DoubleShadowTextView_ambientShadowBlur,
-                    0
-                )
+                attributes.getDimension(R.styleable.DoubleShadowTextView_ambientShadowBlur, 0f)
             val ambientShadowOffsetX =
-                attributes.getDimensionPixelSize(
-                    R.styleable.DoubleShadowTextView_ambientShadowOffsetX,
-                    0
-                )
+                attributes.getDimension(R.styleable.DoubleShadowTextView_ambientShadowOffsetX, 0f)
             val ambientShadowOffsetY =
-                attributes.getDimensionPixelSize(
-                    R.styleable.DoubleShadowTextView_ambientShadowOffsetY,
-                    0
-                )
+                attributes.getDimension(R.styleable.DoubleShadowTextView_ambientShadowOffsetY, 0f)
             val ambientShadowAlpha =
                 attributes.getFloat(R.styleable.DoubleShadowTextView_ambientShadowAlpha, 0f)
             mAmbientShadowInfo =
                 ShadowInfo(
-                    ambientShadowBlur.toFloat(),
-                    ambientShadowOffsetX.toFloat(),
-                    ambientShadowOffsetY.toFloat(),
+                    ambientShadowBlur,
+                    ambientShadowOffsetX,
+                    ambientShadowOffsetY,
                     ambientShadowAlpha
                 )
             drawableSize =
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
index fd41cb06..6bfaf5e 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
@@ -283,17 +283,6 @@
     }
 
     /**
-     * @return whether screen pinning is active.
-     */
-    public boolean isScreenPinningActive() {
-        try {
-            return getService().getLockTaskModeState() == LOCK_TASK_MODE_PINNED;
-        } catch (RemoteException e) {
-            return false;
-        }
-    }
-
-    /**
      * @return whether screen pinning is enabled.
      */
     public boolean isScreenPinningEnabled() {
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
index 8af934f..dd52cfb 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.shared.system;
 
+import android.annotation.NonNull;
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.ActivityTaskManager;
 import android.app.TaskStackListener;
@@ -27,6 +28,8 @@
 import android.util.Log;
 import android.window.TaskSnapshot;
 
+import androidx.annotation.VisibleForTesting;
+
 import com.android.internal.os.SomeArgs;
 import com.android.systemui.shared.recents.model.ThumbnailData;
 
@@ -43,15 +46,51 @@
 
     private final Impl mImpl;
 
+    /**
+     * Proxies calls to the given handler callback synchronously for testing purposes.
+     */
+    private static class TestSyncHandler extends Handler {
+        private Handler.Callback mCb;
+
+        public TestSyncHandler() {
+            super(Looper.getMainLooper());
+        }
+
+        public void setCallback(Handler.Callback cb) {
+            mCb = cb;
+        }
+
+        @Override
+        public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
+            return mCb.handleMessage(msg);
+        }
+    }
+
     private TaskStackChangeListeners() {
         mImpl = new Impl(Looper.getMainLooper());
     }
 
+    private TaskStackChangeListeners(Handler h) {
+        mImpl = new Impl(h);
+    }
+
     public static TaskStackChangeListeners getInstance() {
         return INSTANCE;
     }
 
     /**
+     * Returns an instance of the listeners that can be called upon synchronously for testsing
+     * purposes.
+     */
+    @VisibleForTesting
+    public static TaskStackChangeListeners getTestInstance() {
+        TestSyncHandler h = new TestSyncHandler();
+        TaskStackChangeListeners l = new TaskStackChangeListeners(h);
+        h.setCallback(l.mImpl);
+        return l;
+    }
+
+    /**
      * Registers a task stack listener with the system.
      * This should be called on the main thread.
      */
@@ -71,7 +110,15 @@
         }
     }
 
-    private static class Impl extends TaskStackListener implements Handler.Callback {
+    /**
+     * Returns an instance of the listener to call upon from tests.
+     */
+    @VisibleForTesting
+    public TaskStackListener getListenerImpl() {
+        return mImpl;
+    }
+
+    private class Impl extends TaskStackListener implements Handler.Callback {
 
         private static final int ON_TASK_STACK_CHANGED = 1;
         private static final int ON_TASK_SNAPSHOT_CHANGED = 2;
@@ -104,10 +151,14 @@
         private final Handler mHandler;
         private boolean mRegistered;
 
-        Impl(Looper looper) {
+        private Impl(Looper looper) {
             mHandler = new Handler(looper, this);
         }
 
+        private Impl(Handler handler) {
+            mHandler = handler;
+        }
+
         public void addListener(TaskStackChangeListener listener) {
             synchronized (mTaskStackListeners) {
                 mTaskStackListeners.add(listener);
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/system/ActivityManagerActivityTypeProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/ActivityManagerActivityTypeProvider.kt
index 7f2933e..c9e57b4 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/system/ActivityManagerActivityTypeProvider.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/ActivityManagerActivityTypeProvider.kt
@@ -15,21 +15,51 @@
 package com.android.systemui.unfold.system
 
 import android.app.ActivityManager
+import android.app.ActivityManager.RunningTaskInfo
 import android.app.WindowConfiguration
+import android.os.Trace
+import com.android.systemui.shared.system.TaskStackChangeListener
+import com.android.systemui.shared.system.TaskStackChangeListeners
 import com.android.systemui.unfold.util.CurrentActivityTypeProvider
 import javax.inject.Inject
 import javax.inject.Singleton
 
 @Singleton
-class ActivityManagerActivityTypeProvider @Inject constructor(
-    private val activityManager: ActivityManager
-) : CurrentActivityTypeProvider {
+class ActivityManagerActivityTypeProvider
+@Inject
+constructor(private val activityManager: ActivityManager) : CurrentActivityTypeProvider {
 
     override val isHomeActivity: Boolean?
-        get() {
-            val activityType = activityManager.getRunningTasks(/* maxNum= */ 1)
-                    ?.getOrNull(0)?.topActivityType ?: return null
+        get() = _isHomeActivity
 
-            return activityType == WindowConfiguration.ACTIVITY_TYPE_HOME
+    private var _isHomeActivity: Boolean? = null
+
+
+    override fun init() {
+        _isHomeActivity = activityManager.isOnHomeActivity()
+        TaskStackChangeListeners.getInstance().registerTaskStackListener(taskStackChangeListener)
+    }
+
+    override fun uninit() {
+        TaskStackChangeListeners.getInstance().unregisterTaskStackListener(taskStackChangeListener)
+    }
+
+    private val taskStackChangeListener =
+        object : TaskStackChangeListener {
+            override fun onTaskMovedToFront(taskInfo: RunningTaskInfo) {
+                _isHomeActivity = taskInfo.isHomeActivity()
+            }
         }
+
+    private fun RunningTaskInfo.isHomeActivity(): Boolean =
+        topActivityType == WindowConfiguration.ACTIVITY_TYPE_HOME
+
+    private fun ActivityManager.isOnHomeActivity(): Boolean? {
+        try {
+            Trace.beginSection("isOnHomeActivity")
+            return getRunningTasks(/* maxNum= */ 1)?.firstOrNull()?.isHomeActivity()
+        } finally {
+            Trace.endSection()
+        }
+    }
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/system/SystemUnfoldSharedModule.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/SystemUnfoldSharedModule.kt
index 24ae42a..fe607e1 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/system/SystemUnfoldSharedModule.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/SystemUnfoldSharedModule.kt
@@ -19,7 +19,7 @@
 import com.android.systemui.dagger.qualifiers.UiBackground
 import com.android.systemui.unfold.config.ResourceUnfoldTransitionConfig
 import com.android.systemui.unfold.config.UnfoldTransitionConfig
-import com.android.systemui.unfold.dagger.UnfoldBackground
+import com.android.systemui.unfold.dagger.UnfoldSingleThreadBg
 import com.android.systemui.unfold.dagger.UnfoldMain
 import com.android.systemui.unfold.updates.FoldProvider
 import com.android.systemui.unfold.util.CurrentActivityTypeProvider
@@ -56,6 +56,6 @@
     abstract fun mainHandler(@Main handler: Handler): Handler
 
     @Binds
-    @UnfoldBackground
+    @UnfoldSingleThreadBg
     abstract fun backgroundExecutor(@UiBackground executor: Executor): Executor
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
index 8f38e58..a45ce42 100644
--- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
@@ -38,9 +38,11 @@
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.lifecycle.repeatWhenAttached
-import com.android.systemui.log.dagger.KeyguardClockLog
+import com.android.systemui.log.dagger.KeyguardSmallClockLog
+import com.android.systemui.log.dagger.KeyguardLargeClockLog
 import com.android.systemui.plugins.ClockController
 import com.android.systemui.plugins.log.LogBuffer
+import com.android.systemui.plugins.log.LogLevel.DEBUG
 import com.android.systemui.shared.regionsampling.RegionSampler
 import com.android.systemui.statusbar.policy.BatteryController
 import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback
@@ -73,16 +75,18 @@
     private val context: Context,
     @Main private val mainExecutor: Executor,
     @Background private val bgExecutor: Executor,
-    @KeyguardClockLog private val logBuffer: LogBuffer?,
+    @KeyguardSmallClockLog private val smallLogBuffer: LogBuffer?,
+    @KeyguardLargeClockLog private val largeLogBuffer: LogBuffer?,
     private val featureFlags: FeatureFlags
 ) {
     var clock: ClockController? = null
         set(value) {
             field = value
             if (value != null) {
-                if (logBuffer != null) {
-                    value.setLogBuffer(logBuffer)
-                }
+                smallLogBuffer?.log(TAG, DEBUG, {}, { "New Clock" })
+                value.smallClock.logBuffer = smallLogBuffer
+                largeLogBuffer?.log(TAG, DEBUG, {}, { "New Clock" })
+                value.largeClock.logBuffer = largeLogBuffer
 
                 value.initialize(resources, dozeAmount, 0f)
                 updateRegionSamplers(value)
@@ -325,4 +329,8 @@
             }
         }
     }
+
+    companion object {
+        private val TAG = ClockEventController::class.simpleName!!
+    }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt b/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt
index 5bb9367..e0cf7b6 100644
--- a/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt
+++ b/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt
@@ -50,6 +50,7 @@
 import com.android.keyguard.InternalFaceAuthReasons.KEYGUARD_VISIBILITY_CHANGED
 import com.android.keyguard.InternalFaceAuthReasons.NON_STRONG_BIOMETRIC_ALLOWED_CHANGED
 import com.android.keyguard.InternalFaceAuthReasons.OCCLUDING_APP_REQUESTED
+import com.android.keyguard.InternalFaceAuthReasons.POSTURE_CHANGED
 import com.android.keyguard.InternalFaceAuthReasons.PRIMARY_BOUNCER_SHOWN
 import com.android.keyguard.InternalFaceAuthReasons.PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN
 import com.android.keyguard.InternalFaceAuthReasons.RETRY_AFTER_HW_UNAVAILABLE
@@ -126,6 +127,7 @@
     const val STRONG_AUTH_ALLOWED_CHANGED = "Face auth stopped because strong auth allowed changed"
     const val NON_STRONG_BIOMETRIC_ALLOWED_CHANGED =
         "Face auth stopped because non strong biometric allowed changed"
+    const val POSTURE_CHANGED = "Face auth started/stopped due to device posture changed."
 }
 
 /**
@@ -173,6 +175,7 @@
             return PowerManager.wakeReasonToString(extraInfo)
         }
     },
+    @UiEvent(doc = POSTURE_CHANGED) FACE_AUTH_UPDATED_POSTURE_CHANGED(1265, POSTURE_CHANGED),
     @Deprecated(
         "Not a face auth trigger.",
         ReplaceWith(
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index 62babad..4acbb0a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -7,7 +7,6 @@
 import android.content.Context;
 import android.graphics.Rect;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
@@ -20,11 +19,15 @@
 import com.android.systemui.R;
 import com.android.systemui.animation.Interpolators;
 import com.android.systemui.plugins.ClockController;
+import com.android.systemui.plugins.log.LogBuffer;
+import com.android.systemui.plugins.log.LogLevel;
 
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
+import kotlin.Unit;
+
 /**
  * Switch to show plugin clock when plugin is connected, otherwise it will show default clock.
  */
@@ -87,6 +90,7 @@
     private int mClockSwitchYAmount;
     @VisibleForTesting boolean mChildrenAreLaidOut = false;
     @VisibleForTesting boolean mAnimateOnLayout = true;
+    private LogBuffer mLogBuffer = null;
 
     public KeyguardClockSwitch(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -113,6 +117,14 @@
         onDensityOrFontScaleChanged();
     }
 
+    public void setLogBuffer(LogBuffer logBuffer) {
+        mLogBuffer = logBuffer;
+    }
+
+    public LogBuffer getLogBuffer() {
+        return mLogBuffer;
+    }
+
     void setClock(ClockController clock, int statusBarState) {
         mClock = clock;
 
@@ -121,12 +133,16 @@
         mLargeClockFrame.removeAllViews();
 
         if (clock == null) {
-            Log.e(TAG, "No clock being shown");
+            if (mLogBuffer != null) {
+                mLogBuffer.log(TAG, LogLevel.ERROR, "No clock being shown");
+            }
             return;
         }
 
         // Attach small and big clock views to hierarchy.
-        Log.i(TAG, "Attached new clock views to switch");
+        if (mLogBuffer != null) {
+            mLogBuffer.log(TAG, LogLevel.INFO, "Attached new clock views to switch");
+        }
         mSmallClockFrame.addView(clock.getSmallClock().getView());
         mLargeClockFrame.addView(clock.getLargeClock().getView());
         updateClockTargetRegions();
@@ -152,8 +168,18 @@
     }
 
     private void updateClockViews(boolean useLargeClock, boolean animate) {
-        Log.i(TAG, "updateClockViews; useLargeClock=" + useLargeClock + "; animate=" + animate
-                + "; mChildrenAreLaidOut=" + mChildrenAreLaidOut);
+        if (mLogBuffer != null) {
+            mLogBuffer.log(TAG, LogLevel.DEBUG, (msg) -> {
+                msg.setBool1(useLargeClock);
+                msg.setBool2(animate);
+                msg.setBool3(mChildrenAreLaidOut);
+                return Unit.INSTANCE;
+            }, (msg) -> "updateClockViews"
+                    + "; useLargeClock=" + msg.getBool1()
+                    + "; animate=" + msg.getBool2()
+                    + "; mChildrenAreLaidOut=" + msg.getBool3());
+        }
+
         if (mClockInAnim != null) mClockInAnim.cancel();
         if (mClockOutAnim != null) mClockOutAnim.cancel();
         if (mStatusAreaAnim != null) mStatusAreaAnim.cancel();
@@ -183,6 +209,7 @@
 
         if (!animate) {
             out.setAlpha(0f);
+            out.setVisibility(INVISIBLE);
             in.setAlpha(1f);
             in.setVisibility(VISIBLE);
             mStatusArea.setTranslationY(statusAreaYTranslation);
@@ -198,7 +225,10 @@
                         direction * -mClockSwitchYAmount));
         mClockOutAnim.addListener(new AnimatorListenerAdapter() {
             public void onAnimationEnd(Animator animation) {
-                mClockOutAnim = null;
+                if (mClockOutAnim == animation) {
+                    out.setVisibility(INVISIBLE);
+                    mClockOutAnim = null;
+                }
             }
         });
 
@@ -212,7 +242,9 @@
         mClockInAnim.setStartDelay(CLOCK_OUT_MILLIS / 2);
         mClockInAnim.addListener(new AnimatorListenerAdapter() {
             public void onAnimationEnd(Animator animation) {
-                mClockInAnim = null;
+                if (mClockInAnim == animation) {
+                    mClockInAnim = null;
+                }
             }
         });
 
@@ -225,7 +257,9 @@
         mStatusAreaAnim.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
         mStatusAreaAnim.addListener(new AnimatorListenerAdapter() {
             public void onAnimationEnd(Animator animation) {
-                mStatusAreaAnim = null;
+                if (mStatusAreaAnim == animation) {
+                    mStatusAreaAnim = null;
+                }
             }
         });
         mStatusAreaAnim.start();
@@ -269,7 +303,9 @@
     public void dump(PrintWriter pw, String[] args) {
         pw.println("KeyguardClockSwitch:");
         pw.println("  mSmallClockFrame: " + mSmallClockFrame);
+        pw.println("  mSmallClockFrame.alpha: " + mSmallClockFrame.getAlpha());
         pw.println("  mLargeClockFrame: " + mLargeClockFrame);
+        pw.println("  mLargeClockFrame.alpha: " + mLargeClockFrame.getAlpha());
         pw.println("  mStatusArea: " + mStatusArea);
         pw.println("  mDisplayedClockSize: " + mDisplayedClockSize);
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index 788f120..71cd18d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -38,8 +38,11 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
+import com.android.systemui.log.dagger.KeyguardClockLog;
 import com.android.systemui.plugins.ClockAnimations;
 import com.android.systemui.plugins.ClockController;
+import com.android.systemui.plugins.log.LogBuffer;
+import com.android.systemui.plugins.log.LogLevel;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shared.clocks.ClockRegistry;
 import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController;
@@ -62,6 +65,8 @@
  */
 public class KeyguardClockSwitchController extends ViewController<KeyguardClockSwitch>
         implements Dumpable {
+    private static final String TAG = "KeyguardClockSwitchController";
+
     private final StatusBarStateController mStatusBarStateController;
     private final ClockRegistry mClockRegistry;
     private final KeyguardSliceViewController mKeyguardSliceViewController;
@@ -70,6 +75,7 @@
     private final SecureSettings mSecureSettings;
     private final DumpManager mDumpManager;
     private final ClockEventController mClockEventController;
+    private final LogBuffer mLogBuffer;
 
     private FrameLayout mSmallClockFrame; // top aligned clock
     private FrameLayout mLargeClockFrame; // centered clock
@@ -119,7 +125,8 @@
             SecureSettings secureSettings,
             @Main Executor uiExecutor,
             DumpManager dumpManager,
-            ClockEventController clockEventController) {
+            ClockEventController clockEventController,
+            @KeyguardClockLog LogBuffer logBuffer) {
         super(keyguardClockSwitch);
         mStatusBarStateController = statusBarStateController;
         mClockRegistry = clockRegistry;
@@ -131,6 +138,8 @@
         mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
         mDumpManager = dumpManager;
         mClockEventController = clockEventController;
+        mLogBuffer = logBuffer;
+        mView.setLogBuffer(mLogBuffer);
 
         mClockChangedListener = () -> {
             setClock(mClockRegistry.createCurrentClock());
@@ -190,7 +199,7 @@
         }
 
         mSecureSettings.registerContentObserverForUser(
-                Settings.Secure.getUriFor(Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK),
+                Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK,
                 false, /* notifyForDescendants */
                 mDoubleLineClockObserver,
                 UserHandle.USER_ALL
@@ -337,10 +346,6 @@
             int clockHeight = clock.getLargeClock().getView().getHeight();
             return frameHeight / 2 + clockHeight / 2 + mKeyguardLargeClockTopMargin / -2;
         } else {
-            // This is only called if we've never shown the large clock as the frame is inflated
-            // with 'gone', but then the visibility is never set when it is animated away by
-            // KeyguardClockSwitch, instead it is removed from the view hierarchy.
-            // TODO(b/261755021): Cleanup Large Frame Visibility
             int clockHeight = clock.getSmallClock().getView().getHeight();
             return clockHeight + statusBarHeaderHeight + mKeyguardSmallClockTopMargin;
         }
@@ -358,15 +363,11 @@
         if (mLargeClockFrame.getVisibility() == View.VISIBLE) {
             return clock.getLargeClock().getView().getHeight();
         } else {
-            // Is not called except in certain edge cases, see comment in getClockBottom
-            // TODO(b/261755021): Cleanup Large Frame Visibility
             return clock.getSmallClock().getView().getHeight();
         }
     }
 
     boolean isClockTopAligned() {
-        // Returns false except certain edge cases, see comment in getClockBottom
-        // TODO(b/261755021): Cleanup Large Frame Visibility
         return mLargeClockFrame.getVisibility() != View.VISIBLE;
     }
 
@@ -378,6 +379,10 @@
     }
 
     private void setClock(ClockController clock) {
+        if (clock != null && mLogBuffer != null) {
+            mLogBuffer.log(TAG, LogLevel.INFO, "New Clock");
+        }
+
         mClockEventController.setClock(clock);
         mView.setClock(clock, mStatusBarStateController.getState());
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardFaceListenModel.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardFaceListenModel.kt
index deead19..1a06b5f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardFaceListenModel.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardFaceListenModel.kt
@@ -39,6 +39,7 @@
     var keyguardGoingAway: Boolean = false,
     var listeningForFaceAssistant: Boolean = false,
     var occludingAppRequestingFaceAuth: Boolean = false,
+    val postureAllowsListening: Boolean = false,
     var primaryUser: Boolean = false,
     var secureCameraLaunched: Boolean = false,
     var supportsDetect: Boolean = false,
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
index d4ca8e3..ea84438 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
@@ -29,6 +29,9 @@
 import android.view.View.OnKeyListener;
 import android.view.ViewTreeObserver;
 import android.widget.FrameLayout;
+import android.window.OnBackAnimationCallback;
+
+import androidx.annotation.NonNull;
 
 import com.android.keyguard.KeyguardSecurityContainer.SecurityCallback;
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
@@ -394,6 +397,14 @@
     }
 
     /**
+     * @return the {@link OnBackAnimationCallback} to animate this view during a back gesture.
+     */
+    @NonNull
+    public OnBackAnimationCallback getBackCallback() {
+        return mKeyguardSecurityContainerController.getBackCallback();
+    }
+
+    /**
      * Allows the media keys to work when the keyguard is showing.
      * The media keys should be of no interest to the actual keyguard view(s),
      * so intercepting them here should not be of any harm.
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
index 061ca4f..67e3400 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
@@ -177,6 +177,8 @@
 
     @Override
     public void startAppearAnimation() {
+        setAlpha(1f);
+        setTranslationY(0);
         if (mAppearAnimator.isRunning()) {
             mAppearAnimator.cancel();
         }
@@ -213,7 +215,6 @@
 
     /** Animate subviews according to expansion or time. */
     private void animate(float progress) {
-        setAlpha(progress);
         Interpolator standardDecelerate = Interpolators.STANDARD_DECELERATE;
         Interpolator legacyDecelerate = Interpolators.LEGACY_DECELERATE;
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 5d7a6f1..e4f85db 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -32,6 +32,7 @@
 import static androidx.constraintlayout.widget.ConstraintSet.TOP;
 import static androidx.constraintlayout.widget.ConstraintSet.WRAP_CONTENT;
 
+import static com.android.systemui.animation.InterpolatorsAndroidX.DECELERATE_QUINT;
 import static com.android.systemui.plugins.FalsingManager.LOW_PENALTY;
 
 import static java.lang.Integer.max;
@@ -73,6 +74,8 @@
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.TextView;
+import android.window.BackEvent;
+import android.window.OnBackAnimationCallback;
 
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
@@ -135,7 +138,9 @@
     private static final float MIN_DRAG_SIZE = 10;
     // How much to scale the default slop by, to avoid accidental drags.
     private static final float SLOP_SCALE = 4f;
-
+    @VisibleForTesting
+    // How much the view scales down to during back gestures.
+    static final float MIN_BACK_SCALE = 0.9f;
     @VisibleForTesting
     KeyguardSecurityViewFlipper mSecurityViewFlipper;
     private GlobalSettings mGlobalSettings;
@@ -240,6 +245,33 @@
                 }
             };
 
+    private final OnBackAnimationCallback mBackCallback = new OnBackAnimationCallback() {
+        @Override
+        public void onBackCancelled() {
+            // TODO(b/259608500): Remove once back API auto animates progress to 0 on cancel.
+            resetScale();
+        }
+
+        @Override
+        public void onBackInvoked() { }
+
+        @Override
+        public void onBackProgressed(BackEvent event) {
+            float progress = event.getProgress();
+            // TODO(b/263819310): Update the interpolator to match spec.
+            float scale = MIN_BACK_SCALE
+                    +  (1 - MIN_BACK_SCALE) * (1 - DECELERATE_QUINT.getInterpolation(progress));
+            setScale(scale);
+        }
+    };
+    /**
+     * @return the {@link OnBackAnimationCallback} to animate this view during a back gesture.
+     */
+    @NonNull
+    OnBackAnimationCallback getBackCallback() {
+        return mBackCallback;
+    }
+
     // Used to notify the container when something interesting happens.
     public interface SecurityCallback {
         /**
@@ -736,6 +768,15 @@
         mViewMode.onDensityOrFontScaleChanged();
     }
 
+    void resetScale() {
+        setScale(1);
+    }
+
+    private void setScale(float scale) {
+        setScaleX(scale);
+        setScaleY(scale);
+    }
+
     /**
      * Enscapsulates the differences between bouncer modes for the container.
      */
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index a72a484..57bfe54 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -40,7 +40,9 @@
 import android.util.Slog;
 import android.view.MotionEvent;
 import android.view.View;
+import android.window.OnBackAnimationCallback;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -479,6 +481,9 @@
     /** Called when the bouncer changes visibility. */
     public void onBouncerVisibilityChanged(@View.Visibility int visibility) {
         setBouncerVisible(visibility == View.VISIBLE);
+        if (visibility == View.INVISIBLE) {
+            mView.resetScale();
+        }
     }
 
     private void setBouncerVisible(boolean visible) {
@@ -588,6 +593,14 @@
     }
 
     /**
+     * @return the {@link OnBackAnimationCallback} to animate this view during a back gesture.
+     */
+    @NonNull
+    OnBackAnimationCallback getBackCallback() {
+        return mView.getBackCallback();
+    }
+
+    /**
      * Switches to the given security view unless it's already being shown, in which case
      * this is a no-op.
      *
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index aec3063..b53b868 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -20,6 +20,7 @@
 import android.util.Slog;
 
 import com.android.keyguard.KeyguardClockSwitch.ClockSize;
+import com.android.keyguard.logging.KeyguardLogger;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.ClockAnimations;
@@ -62,14 +63,16 @@
             ConfigurationController configurationController,
             DozeParameters dozeParameters,
             FeatureFlags featureFlags,
-            ScreenOffAnimationController screenOffAnimationController) {
+            ScreenOffAnimationController screenOffAnimationController,
+            KeyguardLogger logger) {
         super(keyguardStatusView);
         mKeyguardSliceViewController = keyguardSliceViewController;
         mKeyguardClockSwitchController = keyguardClockSwitchController;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mConfigurationController = configurationController;
         mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, keyguardStateController,
-                dozeParameters, screenOffAnimationController, /* animateYPos= */ true);
+                dozeParameters, screenOffAnimationController, /* animateYPos= */ true,
+                logger.getBuffer());
         mKeyguardVisibilityHelper.setOcclusionTransitionFlagEnabled(
                 featureFlags.isEnabled(Flags.UNOCCLUSION_TRANSITION));
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 93027c1..a9695dd 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -63,11 +63,13 @@
 import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_KEYGUARD_VISIBILITY_CHANGED;
 import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_ON_FACE_AUTHENTICATED;
 import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_ON_KEYGUARD_INIT;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_POSTURE_CHANGED;
 import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN;
 import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_STARTED_WAKING_UP;
 import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_STRONG_AUTH_CHANGED;
 import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_USER_SWITCHING;
 import static com.android.systemui.DejankUtils.whitelistIpcs;
+import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_UNKNOWN;
 
 import android.annotation.AnyThread;
 import android.annotation.MainThread;
@@ -84,7 +86,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
@@ -108,7 +109,6 @@
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.Trace;
 import android.os.UserHandle;
@@ -141,6 +141,7 @@
 import com.android.systemui.Dumpable;
 import com.android.systemui.R;
 import com.android.systemui.biometrics.AuthController;
+import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
@@ -154,6 +155,7 @@
 import com.android.systemui.shared.system.TaskStackChangeListeners;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.policy.DevicePostureController;
 import com.android.systemui.telephony.TelephonyListenerManager;
 import com.android.systemui.util.Assert;
 import com.android.systemui.util.settings.SecureSettings;
@@ -170,6 +172,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Optional;
 import java.util.Set;
 import java.util.TimeZone;
 import java.util.concurrent.Executor;
@@ -269,21 +272,6 @@
     private static final ComponentName FALLBACK_HOME_COMPONENT = new ComponentName(
             "com.android.settings", "com.android.settings.FallbackHome");
 
-    /**
-     * If true, the system is in the half-boot-to-decryption-screen state.
-     * Prudently disable lockscreen.
-     */
-    public static final boolean CORE_APPS_ONLY;
-
-    static {
-        try {
-            CORE_APPS_ONLY = IPackageManager.Stub.asInterface(
-                    ServiceManager.getService("package")).isOnlyCoreApps();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
     private final Context mContext;
     private final UserTracker mUserTracker;
     private final KeyguardUpdateMonitorLogger mLogger;
@@ -345,18 +333,17 @@
     private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
             mCallbacks = Lists.newArrayList();
     private ContentObserver mDeviceProvisionedObserver;
-    private ContentObserver mSfpsRequireScreenOnToAuthPrefObserver;
     private final ContentObserver mTimeFormatChangeObserver;
 
     private boolean mSwitchingUser;
 
     private boolean mDeviceInteractive;
-    private boolean mSfpsRequireScreenOnToAuthPrefEnabled;
     private final SubscriptionManager mSubscriptionManager;
     private final TelephonyListenerManager mTelephonyListenerManager;
     private final TrustManager mTrustManager;
     private final UserManager mUserManager;
     private final DevicePolicyManager mDevicePolicyManager;
+    private final DevicePostureController mPostureController;
     private final BroadcastDispatcher mBroadcastDispatcher;
     private final SecureSettings mSecureSettings;
     private final InteractionJankMonitor mInteractionJankMonitor;
@@ -374,6 +361,9 @@
     private final FaceManager mFaceManager;
     private final LockPatternUtils mLockPatternUtils;
     private final boolean mWakeOnFingerprintAcquiredStart;
+    @VisibleForTesting
+    @DevicePostureController.DevicePostureInt
+    protected int mConfigFaceAuthSupportedPosture;
 
     private KeyguardBypassController mKeyguardBypassController;
     private List<SubscriptionInfo> mSubscriptionInfo;
@@ -384,6 +374,8 @@
     private boolean mLogoutEnabled;
     private boolean mIsFaceEnrolled;
     private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+    private int mPostureState = DEVICE_POSTURE_UNKNOWN;
+    private FingerprintInteractiveToAuthProvider mFingerprintInteractiveToAuthProvider;
 
     /**
      * Short delay before restarting fingerprint authentication after a successful try. This should
@@ -711,8 +703,18 @@
      */
     public void setKeyguardGoingAway(boolean goingAway) {
         mKeyguardGoingAway = goingAway;
-        // This is set specifically to stop face authentication from running.
-        updateBiometricListeningState(BIOMETRIC_ACTION_STOP, FACE_AUTH_STOPPED_KEYGUARD_GOING_AWAY);
+        if (mKeyguardGoingAway) {
+            updateFaceListeningState(BIOMETRIC_ACTION_STOP,
+                    FACE_AUTH_STOPPED_KEYGUARD_GOING_AWAY);
+        }
+        updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
+    }
+
+    /**
+     * Whether keyguard is going away due to screen off or device entry.
+     */
+    public boolean isKeyguardGoingAway() {
+        return mKeyguardGoingAway;
     }
 
     /**
@@ -1784,6 +1786,17 @@
     };
 
     @VisibleForTesting
+    final DevicePostureController.Callback mPostureCallback =
+            new DevicePostureController.Callback() {
+                @Override
+                public void onPostureChanged(int posture) {
+                    mPostureState = posture;
+                    updateFaceListeningState(BIOMETRIC_ACTION_UPDATE,
+                            FACE_AUTH_UPDATED_POSTURE_CHANGED);
+                }
+            };
+
+    @VisibleForTesting
     CancellationSignal mFingerprintCancelSignal;
     @VisibleForTesting
     CancellationSignal mFaceCancelSignal;
@@ -1943,9 +1956,9 @@
                 cb.onFinishedGoingToSleep(arg1);
             }
         }
-        // This is set specifically to stop face authentication from running.
-        updateBiometricListeningState(BIOMETRIC_ACTION_STOP,
+        updateFaceListeningState(BIOMETRIC_ACTION_STOP,
                 FACE_AUTH_STOPPED_FINISHED_GOING_TO_SLEEP);
+        updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
     }
 
     private void handleScreenTurnedOff() {
@@ -2048,7 +2061,9 @@
             @Nullable FaceManager faceManager,
             @Nullable FingerprintManager fingerprintManager,
             @Nullable BiometricManager biometricManager,
-            FaceWakeUpTriggersConfig faceWakeUpTriggersConfig) {
+            FaceWakeUpTriggersConfig faceWakeUpTriggersConfig,
+            DevicePostureController devicePostureController,
+            Optional<FingerprintInteractiveToAuthProvider> interactiveToAuthProvider) {
         mContext = context;
         mSubscriptionManager = subscriptionManager;
         mUserTracker = userTracker;
@@ -2077,6 +2092,7 @@
         mDreamManager = dreamManager;
         mTelephonyManager = telephonyManager;
         mDevicePolicyManager = devicePolicyManager;
+        mPostureController = devicePostureController;
         mPackageManager = packageManager;
         mFpm = fingerprintManager;
         mFaceManager = faceManager;
@@ -2088,6 +2104,8 @@
                         R.array.config_face_acquire_device_entry_ignorelist))
                 .boxed()
                 .collect(Collectors.toSet());
+        mConfigFaceAuthSupportedPosture = mContext.getResources().getInteger(
+                R.integer.config_face_auth_supported_posture);
         mFaceWakeUpTriggersConfig = faceWakeUpTriggersConfig;
 
         mHandler = new Handler(mainLooper) {
@@ -2278,6 +2296,9 @@
                         FACE_AUTH_TRIGGERED_ENROLLMENTS_CHANGED));
             }
         });
+        if (mConfigFaceAuthSupportedPosture != DEVICE_POSTURE_UNKNOWN) {
+            mPostureController.addCallback(mPostureCallback);
+        }
         updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE, FACE_AUTH_UPDATED_ON_KEYGUARD_INIT);
 
         TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener);
@@ -2311,30 +2332,7 @@
                 Settings.System.getUriFor(Settings.System.TIME_12_24),
                 false, mTimeFormatChangeObserver, UserHandle.USER_ALL);
 
-        updateSfpsRequireScreenOnToAuthPref();
-        mSfpsRequireScreenOnToAuthPrefObserver = new ContentObserver(mHandler) {
-            @Override
-            public void onChange(boolean selfChange) {
-                updateSfpsRequireScreenOnToAuthPref();
-            }
-        };
-
-        mContext.getContentResolver().registerContentObserver(
-                mSecureSettings.getUriFor(
-                        Settings.Secure.SFPS_REQUIRE_SCREEN_ON_TO_AUTH_ENABLED),
-                false,
-                mSfpsRequireScreenOnToAuthPrefObserver,
-                getCurrentUser());
-    }
-
-    protected void updateSfpsRequireScreenOnToAuthPref() {
-        final int defaultSfpsRequireScreenOnToAuthValue =
-                mContext.getResources().getBoolean(
-                        com.android.internal.R.bool.config_requireScreenOnToAuthEnabled) ? 1 : 0;
-        mSfpsRequireScreenOnToAuthPrefEnabled = mSecureSettings.getIntForUser(
-                Settings.Secure.SFPS_REQUIRE_SCREEN_ON_TO_AUTH_ENABLED,
-                defaultSfpsRequireScreenOnToAuthValue,
-                getCurrentUser()) != 0;
+        mFingerprintInteractiveToAuthProvider = interactiveToAuthProvider.orElse(null);
     }
 
     private void initializeSimState() {
@@ -2729,8 +2727,11 @@
 
         boolean shouldListenSideFpsState = true;
         if (isSideFps) {
+            final boolean interactiveToAuthEnabled =
+                    mFingerprintInteractiveToAuthProvider != null &&
+                            mFingerprintInteractiveToAuthProvider.isEnabled(getCurrentUser());
             shouldListenSideFpsState =
-                    mSfpsRequireScreenOnToAuthPrefEnabled ? isDeviceInteractive() : true;
+                    interactiveToAuthEnabled ? isDeviceInteractive() && !mGoingToSleep : true;
         }
 
         boolean shouldListen = shouldListenKeyguardState && shouldListenUserState
@@ -2742,7 +2743,7 @@
                     user,
                     shouldListen,
                     biometricEnabledForUser,
-                        mPrimaryBouncerIsOrWillBeShowing,
+                    mPrimaryBouncerIsOrWillBeShowing,
                     userCanSkipBouncer,
                     mCredentialAttempted,
                     mDeviceInteractive,
@@ -2802,6 +2803,9 @@
         final boolean biometricEnabledForUser = mBiometricEnabledForUser.get(user);
         final boolean shouldListenForFaceAssistant = shouldListenForFaceAssistant();
         final boolean isUdfpsFingerDown = mAuthController.isUdfpsFingerDown();
+        final boolean isPostureAllowedForFaceAuth =
+                mConfigFaceAuthSupportedPosture == 0 /* DEVICE_POSTURE_UNKNOWN */ ? true
+                        : (mPostureState == mConfigFaceAuthSupportedPosture);
 
         // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
         // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
@@ -2818,7 +2822,8 @@
                 && faceAuthAllowedOrDetectionIsNeeded && mIsPrimaryUser
                 && (!mSecureCameraLaunched || mOccludingAppRequestingFace)
                 && faceAndFpNotAuthenticated
-                && !mGoingToSleep;
+                && !mGoingToSleep
+                && isPostureAllowedForFaceAuth;
 
         // Aggregate relevant fields for debug logging.
         logListenerModelData(
@@ -2838,6 +2843,7 @@
                     mKeyguardGoingAway,
                     shouldListenForFaceAssistant,
                     mOccludingAppRequestingFace,
+                    isPostureAllowedForFaceAuth,
                     mIsPrimaryUser,
                     mSecureCameraLaunched,
                     supportsDetect,
@@ -2923,7 +2929,7 @@
                 getKeyguardSessionId(),
                 faceAuthUiEvent.getExtraInfo()
         );
-
+        mLogger.logFaceUnlockPossible(unlockPossible);
         if (unlockPossible) {
             mFaceCancelSignal = new CancellationSignal();
 
@@ -3845,11 +3851,6 @@
             mContext.getContentResolver().unregisterContentObserver(mTimeFormatChangeObserver);
         }
 
-        if (mSfpsRequireScreenOnToAuthPrefObserver != null) {
-            mContext.getContentResolver().unregisterContentObserver(
-                    mSfpsRequireScreenOnToAuthPrefObserver);
-        }
-
         try {
             ActivityManager.getService().unregisterUserSwitchObserver(mUserSwitchObserver);
         } catch (RemoteException e) {
@@ -3926,8 +3927,14 @@
             } else if (isSfpsSupported()) {
                 pw.println("        sfpsEnrolled=" + isSfpsEnrolled());
                 pw.println("        shouldListenForSfps=" + shouldListenForFingerprint(false));
-                pw.println("        mSfpsRequireScreenOnToAuthPrefEnabled="
-                        + mSfpsRequireScreenOnToAuthPrefEnabled);
+                if (isSfpsEnrolled()) {
+                    final boolean interactiveToAuthEnabled =
+                                    mFingerprintInteractiveToAuthProvider != null &&
+                                            mFingerprintInteractiveToAuthProvider
+                                            .isEnabled(getCurrentUser());
+                    pw.println("        interactiveToAuthEnabled="
+                            + interactiveToAuthEnabled);
+                }
             }
             new DumpsysTableLogger(
                     "KeyguardFingerprintListen",
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
index bde0692..7e48193 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
@@ -22,6 +22,8 @@
 import android.view.ViewPropertyAnimator;
 
 import com.android.systemui.animation.Interpolators;
+import com.android.systemui.plugins.log.LogBuffer;
+import com.android.systemui.plugins.log.LogLevel;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.AnimatableProperty;
 import com.android.systemui.statusbar.notification.PropertyAnimator;
@@ -31,11 +33,14 @@
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
+import com.google.errorprone.annotations.CompileTimeConstant;
+
 /**
  * Helper class for updating visibility of keyguard views based on keyguard and status bar state.
  * This logic is shared by both the keyguard status view and the keyguard user switcher.
  */
 public class KeyguardVisibilityHelper {
+    private static final String TAG = "KeyguardVisibilityHelper";
 
     private View mView;
     private final KeyguardStateController mKeyguardStateController;
@@ -46,17 +51,26 @@
     private boolean mLastOccludedState = false;
     private boolean mIsUnoccludeTransitionFlagEnabled = false;
     private final AnimationProperties mAnimationProperties = new AnimationProperties();
+    private final LogBuffer mLogBuffer;
 
     public KeyguardVisibilityHelper(View view,
             KeyguardStateController keyguardStateController,
             DozeParameters dozeParameters,
             ScreenOffAnimationController screenOffAnimationController,
-            boolean animateYPos) {
+            boolean animateYPos,
+            LogBuffer logBuffer) {
         mView = view;
         mKeyguardStateController = keyguardStateController;
         mDozeParameters = dozeParameters;
         mScreenOffAnimationController = screenOffAnimationController;
         mAnimateYPos = animateYPos;
+        mLogBuffer = logBuffer;
+    }
+
+    private void log(@CompileTimeConstant String message) {
+        if (mLogBuffer != null) {
+            mLogBuffer.log(TAG, LogLevel.DEBUG, message);
+        }
     }
 
     public boolean isVisibilityAnimating() {
@@ -94,6 +108,9 @@
                         .setStartDelay(mKeyguardStateController.getKeyguardFadingAwayDelay())
                         .setDuration(mKeyguardStateController.getShortenedFadingAwayDuration())
                         .start();
+                log("goingToFullShade && keyguardFadingAway");
+            } else {
+                log("goingToFullShade && !keyguardFadingAway");
             }
         } else if (oldStatusBarState == StatusBarState.SHADE_LOCKED && statusBarState == KEYGUARD) {
             mView.setVisibility(View.VISIBLE);
@@ -105,6 +122,7 @@
                     .setDuration(320)
                     .setInterpolator(Interpolators.ALPHA_IN)
                     .withEndAction(mAnimateKeyguardStatusViewVisibleEndRunnable);
+            log("keyguardFadingAway transition w/ Y Aniamtion");
         } else if (statusBarState == KEYGUARD) {
             if (keyguardFadingAway) {
                 mKeyguardViewVisibilityAnimating = true;
@@ -125,9 +143,13 @@
                             true /* animate */);
                     animator.setDuration(duration)
                             .setStartDelay(delay);
+                    log("keyguardFadingAway transition w/ Y Aniamtion");
+                } else {
+                    log("keyguardFadingAway transition w/o Y Animation");
                 }
                 animator.start();
             } else if (mScreenOffAnimationController.shouldAnimateInKeyguard()) {
+                log("ScreenOff transition");
                 mKeyguardViewVisibilityAnimating = true;
 
                 // Ask the screen off animation controller to animate the keyguard visibility for us
@@ -136,6 +158,7 @@
                         mView, mAnimateKeyguardStatusViewVisibleEndRunnable);
             } else if (!mIsUnoccludeTransitionFlagEnabled && mLastOccludedState && !isOccluded) {
                 // An activity was displayed over the lock screen, and has now gone away
+                log("Unoccluded transition");
                 mView.setVisibility(View.VISIBLE);
                 mView.setAlpha(0f);
 
@@ -146,12 +169,14 @@
                         .withEndAction(mAnimateKeyguardStatusViewVisibleEndRunnable)
                         .start();
             } else {
+                log("Direct set Visibility to VISIBLE");
                 mView.setVisibility(View.VISIBLE);
                 if (!mIsUnoccludeTransitionFlagEnabled) {
                     mView.setAlpha(1f);
                 }
             }
         } else {
+            log("Direct set Visibility to GONE");
             mView.setVisibility(View.GONE);
             mView.setAlpha(1f);
         }
@@ -162,14 +187,18 @@
     private final Runnable mAnimateKeyguardStatusViewInvisibleEndRunnable = () -> {
         mKeyguardViewVisibilityAnimating = false;
         mView.setVisibility(View.INVISIBLE);
+        log("Callback Set Visibility to INVISIBLE");
     };
 
     private final Runnable mAnimateKeyguardStatusViewGoneEndRunnable = () -> {
         mKeyguardViewVisibilityAnimating = false;
         mView.setVisibility(View.GONE);
+        log("CallbackSet Visibility to GONE");
     };
 
     private final Runnable mAnimateKeyguardStatusViewVisibleEndRunnable = () -> {
         mKeyguardViewVisibilityAnimating = false;
+        mView.setVisibility(View.VISIBLE);
+        log("Callback Set Visibility to VISIBLE");
     };
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index dd6a1bd..1322f16 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -501,6 +501,17 @@
                 }
 
                 @Override
+                public void onBiometricsCleared() {
+                    final boolean wasUserUnlockedWithBiometric = mUserUnlockedWithBiometric;
+                    mUserUnlockedWithBiometric =
+                            mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(
+                                    KeyguardUpdateMonitor.getCurrentUser());
+                    if (wasUserUnlockedWithBiometric != mUserUnlockedWithBiometric) {
+                        updateVisibility();
+                    }
+                }
+
+                @Override
                 public void onBiometricRunningStateChanged(boolean running,
                         BiometricSourceType biometricSourceType) {
                     final boolean wasRunningFps = mRunningFPS;
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt
index 886d110..2c7eceb 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt
@@ -18,40 +18,45 @@
 
 import com.android.systemui.log.dagger.KeyguardLog
 import com.android.systemui.plugins.log.LogBuffer
-import com.android.systemui.plugins.log.LogLevel.DEBUG
-import com.android.systemui.plugins.log.LogLevel.ERROR
-import com.android.systemui.plugins.log.LogLevel.INFO
-import com.android.systemui.plugins.log.LogLevel.VERBOSE
-import com.android.systemui.plugins.log.LogLevel.WARNING
+import com.android.systemui.plugins.log.LogLevel
 import com.google.errorprone.annotations.CompileTimeConstant
 import javax.inject.Inject
 
-private const val TAG = "KeyguardLog"
+private const val BIO_TAG = "KeyguardLog"
 
 /**
  * Generic logger for keyguard that's wrapping [LogBuffer]. This class should be used for adding
  * temporary logs or logs for smaller classes when creating whole new [LogBuffer] wrapper might be
  * an overkill.
  */
-class KeyguardLogger @Inject constructor(@KeyguardLog private val buffer: LogBuffer) {
-    fun d(@CompileTimeConstant msg: String) = buffer.log(TAG, DEBUG, msg)
+class KeyguardLogger
+@Inject
+constructor(
+    @KeyguardLog val buffer: LogBuffer,
+) {
+    @JvmOverloads
+    fun log(
+        tag: String,
+        level: LogLevel,
+        @CompileTimeConstant msg: String,
+        ex: Throwable? = null,
+    ) = buffer.log(tag, level, msg, ex)
 
-    fun e(@CompileTimeConstant msg: String) = buffer.log(TAG, ERROR, msg)
-
-    fun v(@CompileTimeConstant msg: String) = buffer.log(TAG, VERBOSE, msg)
-
-    fun w(@CompileTimeConstant msg: String) = buffer.log(TAG, WARNING, msg)
-
-    fun logException(ex: Exception, @CompileTimeConstant logMsg: String) {
-        buffer.log(TAG, ERROR, {}, { logMsg }, exception = ex)
-    }
-
-    fun v(msg: String, arg: Any) {
-        buffer.log(TAG, VERBOSE, { str1 = arg.toString() }, { "$msg: $str1" })
-    }
-
-    fun i(msg: String, arg: Any) {
-        buffer.log(TAG, INFO, { str1 = arg.toString() }, { "$msg: $str1" })
+    fun log(
+        tag: String,
+        level: LogLevel,
+        @CompileTimeConstant msg: String,
+        arg: Any,
+    ) {
+        buffer.log(
+            tag,
+            level,
+            {
+                str1 = msg
+                str2 = arg.toString()
+            },
+            { "$str1: $str2" }
+        )
     }
 
     @JvmOverloads
@@ -61,8 +66,8 @@
         msg: String? = null
     ) {
         buffer.log(
-            TAG,
-            DEBUG,
+            BIO_TAG,
+            LogLevel.DEBUG,
             {
                 str1 = context
                 str2 = "$msgId"
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
index 21d3b24..5b42455 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
@@ -132,6 +132,12 @@
         logBuffer.log(TAG, DEBUG, { int1 = faceRunningState }, { "faceRunningState: $int1" })
     }
 
+    fun logFaceUnlockPossible(isFaceUnlockPossible: Boolean) {
+        logBuffer.log(TAG, DEBUG,
+                { bool1 = isFaceUnlockPossible },
+                {"isUnlockWithFacePossible: $bool1"})
+    }
+
     fun logFingerprintAuthForWrongUser(authUserId: Int) {
         logBuffer.log(TAG, DEBUG,
                 { int1 = authUserId },
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/TrustRepositoryLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/TrustRepositoryLogger.kt
new file mode 100644
index 0000000..249b3fe
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/logging/TrustRepositoryLogger.kt
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.keyguard.logging
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.shared.model.TrustModel
+import com.android.systemui.log.dagger.KeyguardUpdateMonitorLog
+import com.android.systemui.plugins.log.LogBuffer
+import com.android.systemui.plugins.log.LogLevel
+import javax.inject.Inject
+
+/** Logging helper for trust repository. */
+@SysUISingleton
+class TrustRepositoryLogger
+@Inject
+constructor(
+    @KeyguardUpdateMonitorLog private val logBuffer: LogBuffer,
+) {
+    fun onTrustChanged(
+        enabled: Boolean,
+        newlyUnlocked: Boolean,
+        userId: Int,
+        flags: Int,
+        trustGrantedMessages: List<String>?
+    ) {
+        logBuffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                bool1 = enabled
+                bool2 = newlyUnlocked
+                int1 = userId
+                int2 = flags
+                str1 = trustGrantedMessages?.joinToString()
+            },
+            {
+                "onTrustChanged enabled: $bool1, newlyUnlocked: $bool2, " +
+                    "userId: $int1, flags: $int2, grantMessages: $str1"
+            }
+        )
+    }
+
+    fun trustListenerRegistered() {
+        logBuffer.log(TAG, LogLevel.VERBOSE, "TrustRepository#registerTrustListener")
+    }
+
+    fun trustListenerUnregistered() {
+        logBuffer.log(TAG, LogLevel.VERBOSE, "TrustRepository#unregisterTrustListener")
+    }
+
+    fun trustModelEmitted(value: TrustModel) {
+        logBuffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                int1 = value.userId
+                bool1 = value.isTrusted
+            },
+            { "trustModel emitted: userId: $int1 isTrusted: $bool1" }
+        )
+    }
+
+    fun isCurrentUserTrusted(isCurrentUserTrusted: Boolean) {
+        logBuffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            { bool1 = isCurrentUserTrusted },
+            { "isCurrentUserTrusted emitted: $bool1" }
+        )
+    }
+
+    companion object {
+        const val TAG = "TrustRepositoryLog"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/mediator/ScreenOnCoordinator.kt b/packages/SystemUI/src/com/android/keyguard/mediator/ScreenOnCoordinator.kt
index 98ac2c0..0f00a04 100644
--- a/packages/SystemUI/src/com/android/keyguard/mediator/ScreenOnCoordinator.kt
+++ b/packages/SystemUI/src/com/android/keyguard/mediator/ScreenOnCoordinator.kt
@@ -17,8 +17,10 @@
 package com.android.keyguard.mediator
 
 import android.annotation.BinderThread
+import android.os.Handler
 import android.os.Trace
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.unfold.SysUIUnfoldComponent
 import com.android.systemui.util.concurrency.PendingTasksContainer
 import com.android.systemui.util.kotlin.getOrNull
@@ -33,7 +35,8 @@
  */
 @SysUISingleton
 class ScreenOnCoordinator @Inject constructor(
-    unfoldComponent: Optional<SysUIUnfoldComponent>
+    unfoldComponent: Optional<SysUIUnfoldComponent>,
+    @Main private val mainHandler: Handler
 ) {
 
     private val unfoldLightRevealAnimation = unfoldComponent.map(
@@ -55,7 +58,11 @@
         unfoldLightRevealAnimation?.onScreenTurningOn(pendingTasks.registerTask("unfold-reveal"))
         foldAodAnimationController?.onScreenTurningOn(pendingTasks.registerTask("fold-to-aod"))
 
-        pendingTasks.onTasksComplete { onDrawn.run() }
+        pendingTasks.onTasksComplete {
+            mainHandler.post {
+                onDrawn.run()
+            }
+        }
         Trace.endSection()
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java b/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java
index 0fc9ef9..632fcdc 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java
@@ -22,8 +22,6 @@
 import android.os.HandlerThread;
 import android.util.Log;
 
-import androidx.annotation.Nullable;
-
 import com.android.systemui.dagger.GlobalRootComponent;
 import com.android.systemui.dagger.SysUIComponent;
 import com.android.systemui.dagger.WMComponent;
@@ -55,7 +53,6 @@
         mContext = context;
     }
 
-    @Nullable
     protected abstract GlobalRootComponent.Builder getGlobalRootComponentBuilder();
 
     /**
@@ -72,11 +69,6 @@
      * Starts the initialization process. This stands up the Dagger graph.
      */
     public void init(boolean fromTest) throws ExecutionException, InterruptedException {
-        GlobalRootComponent.Builder globalBuilder = getGlobalRootComponentBuilder();
-        if (globalBuilder == null) {
-            return;
-        }
-
         mRootComponent = getGlobalRootComponentBuilder()
                 .context(mContext)
                 .instrumentationTest(fromTest)
@@ -127,7 +119,6 @@
                     .setBackAnimation(Optional.ofNullable(null))
                     .setDesktopMode(Optional.ofNullable(null));
         }
-
         mSysUIComponent = builder.build();
         if (initializeComponents) {
             mSysUIComponent.init();
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt b/packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt
index 55c095b..8aa3040 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt
@@ -16,7 +16,6 @@
 
 package com.android.systemui
 
-import android.app.Application
 import android.content.Context
 import com.android.systemui.dagger.DaggerReferenceGlobalRootComponent
 import com.android.systemui.dagger.GlobalRootComponent
@@ -25,17 +24,7 @@
  * {@link SystemUIInitializer} that stands up AOSP SystemUI.
  */
 class SystemUIInitializerImpl(context: Context) : SystemUIInitializer(context) {
-
-    override fun getGlobalRootComponentBuilder(): GlobalRootComponent.Builder? {
-        return when (Application.getProcessName()) {
-            SCREENSHOT_CROSS_PROFILE_PROCESS -> null
-            else -> DaggerReferenceGlobalRootComponent.builder()
-        }
-    }
-
-    companion object {
-        private const val SYSTEMUI_PROCESS = "com.android.systemui"
-        private const val SCREENSHOT_CROSS_PROFILE_PROCESS =
-                "$SYSTEMUI_PROCESS:screenshot_cross_profile"
+    override fun getGlobalRootComponentBuilder(): GlobalRootComponent.Builder {
+        return DaggerReferenceGlobalRootComponent.builder()
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/AccessibilityButtonModeObserver.java b/packages/SystemUI/src/com/android/systemui/accessibility/AccessibilityButtonModeObserver.java
index fbb909f..2c97d62 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/AccessibilityButtonModeObserver.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/AccessibilityButtonModeObserver.java
@@ -27,6 +27,7 @@
 import android.util.Log;
 
 import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.settings.UserTracker;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -67,8 +68,8 @@
     }
 
     @Inject
-    public AccessibilityButtonModeObserver(Context context) {
-        super(context, Settings.Secure.ACCESSIBILITY_BUTTON_MODE);
+    public AccessibilityButtonModeObserver(Context context, UserTracker userTracker) {
+        super(context, userTracker, Settings.Secure.ACCESSIBILITY_BUTTON_MODE);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/AccessibilityButtonTargetsObserver.java b/packages/SystemUI/src/com/android/systemui/accessibility/AccessibilityButtonTargetsObserver.java
index b32ebcc..53a21b3 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/AccessibilityButtonTargetsObserver.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/AccessibilityButtonTargetsObserver.java
@@ -23,6 +23,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.settings.UserTracker;
 
 import javax.inject.Inject;
 
@@ -48,8 +49,8 @@
     }
 
     @Inject
-    public AccessibilityButtonTargetsObserver(Context context) {
-        super(context, Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS);
+    public AccessibilityButtonTargetsObserver(Context context, UserTracker userTracker) {
+        super(context, userTracker, Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/SecureSettingsContentObserver.java b/packages/SystemUI/src/com/android/systemui/accessibility/SecureSettingsContentObserver.java
index e4e0da6..326773f 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/SecureSettingsContentObserver.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/SecureSettingsContentObserver.java
@@ -27,6 +27,7 @@
 import androidx.annotation.NonNull;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.settings.UserTracker;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -44,6 +45,7 @@
 public abstract class SecureSettingsContentObserver<T> {
 
     private final ContentResolver mContentResolver;
+    private final UserTracker mUserTracker;
     @VisibleForTesting
     final ContentObserver mContentObserver;
 
@@ -52,9 +54,11 @@
     @VisibleForTesting
     final List<T> mListeners = new ArrayList<>();
 
-    protected SecureSettingsContentObserver(Context context, String secureSettingsKey) {
+    protected SecureSettingsContentObserver(Context context, UserTracker userTracker,
+            String secureSettingsKey) {
         mKey = secureSettingsKey;
         mContentResolver = context.getContentResolver();
+        mUserTracker = userTracker;
         mContentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
             @Override
             public void onChange(boolean selfChange) {
@@ -103,7 +107,7 @@
      * See {@link Settings.Secure}.
      */
     public final String getSettingsValue() {
-        return Settings.Secure.getStringForUser(mContentResolver, mKey, UserHandle.USER_CURRENT);
+        return Settings.Secure.getStringForUser(mContentResolver, mKey, mUserTracker.getUserId());
     }
 
     private void updateValueChanged() {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
index dab73e9..4c92598 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
@@ -35,14 +35,12 @@
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.SystemClock;
-import android.os.UserHandle;
 import android.util.Log;
 import android.view.Display;
 import android.view.IWindowManager;
 import android.view.InputDevice;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
-import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 import android.view.accessibility.AccessibilityManager;
 
@@ -52,6 +50,7 @@
 import com.android.systemui.CoreStartable;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.recents.Recents;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shade.ShadeController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
@@ -179,6 +178,7 @@
 
     private final SystemActionsBroadcastReceiver mReceiver;
     private final Context mContext;
+    private final UserTracker mUserTracker;
     private final Optional<Recents> mRecentsOptional;
     private Locale mLocale;
     private final AccessibilityManager mA11yManager;
@@ -190,11 +190,13 @@
 
     @Inject
     public SystemActions(Context context,
+            UserTracker userTracker,
             NotificationShadeWindowController notificationShadeController,
             ShadeController shadeController,
             Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
             Optional<Recents> recentsOptional) {
         mContext = context;
+        mUserTracker = userTracker;
         mShadeController = shadeController;
         mRecentsOptional = recentsOptional;
         mReceiver = new SystemActionsBroadcastReceiver();
@@ -343,6 +345,7 @@
 
     /**
      * Register a system action.
+     *
      * @param actionId the action ID to register.
      */
     public void register(int actionId) {
@@ -440,6 +443,7 @@
 
     /**
      * Unregister a system action.
+     *
      * @param actionId the action ID to unregister.
      */
     public void unregister(int actionId) {
@@ -475,7 +479,8 @@
     }
 
     private void handleNotifications() {
-        mCentralSurfacesOptionalLazy.get().ifPresent(CentralSurfaces::animateExpandNotificationsPanel);
+        mCentralSurfacesOptionalLazy.get().ifPresent(
+                CentralSurfaces::animateExpandNotificationsPanel);
     }
 
     private void handleQuickSettings() {
@@ -507,7 +512,7 @@
 
     private void handleTakeScreenshot() {
         ScreenshotHelper screenshotHelper = new ScreenshotHelper(mContext);
-        screenshotHelper.takeScreenshot(WindowManager.TAKE_SCREENSHOT_FULLSCREEN,
+        screenshotHelper.takeScreenshot(
                 SCREENSHOT_ACCESSIBILITY_ACTIONS, new Handler(Looper.getMainLooper()), null);
     }
 
@@ -525,7 +530,7 @@
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
         final String chooserClassName = AccessibilityButtonChooserActivity.class.getName();
         intent.setClassName(CHOOSER_PACKAGE_NAME, chooserClassName);
-        mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+        mContext.startActivityAsUser(intent, mUserTracker.getUserHandle());
     }
 
     private void handleAccessibilityShortcut() {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenu.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenu.java
index 9af8300..7441e03 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenu.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenu.java
@@ -43,6 +43,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.Prefs;
 import com.android.systemui.shared.system.SysUiStatsLog;
+import com.android.systemui.util.settings.SecureSettings;
 
 import java.util.List;
 
@@ -60,6 +61,7 @@
     private static final float DEFAULT_POSITION_Y_PERCENT = 0.9f;
 
     private final Context mContext;
+    private final SecureSettings mSecureSettings;
     private final AccessibilityFloatingMenuView mMenuView;
     private final MigrationTooltipView mMigrationTooltipView;
     private final DockTooltipView mDockTooltipView;
@@ -77,7 +79,7 @@
             new ContentObserver(mHandler) {
                 @Override
                 public void onChange(boolean selfChange) {
-                    mMenuView.setSizeType(getSizeType(mContext));
+                    mMenuView.setSizeType(getSizeType());
                 }
             };
 
@@ -85,8 +87,8 @@
             new ContentObserver(mHandler) {
                 @Override
                 public void onChange(boolean selfChange) {
-                    mMenuView.updateOpacityWith(isFadeEffectEnabled(mContext),
-                            getOpacityValue(mContext));
+                    mMenuView.updateOpacityWith(isFadeEffectEnabled(),
+                            getOpacityValue());
                 }
             };
 
@@ -98,16 +100,19 @@
                 }
             };
 
-    public AccessibilityFloatingMenu(Context context) {
+    public AccessibilityFloatingMenu(Context context, SecureSettings secureSettings) {
         mContext = context;
+        mSecureSettings = secureSettings;
         mMenuView = new AccessibilityFloatingMenuView(context, getPosition(context));
         mMigrationTooltipView = new MigrationTooltipView(mContext, mMenuView);
         mDockTooltipView = new DockTooltipView(mContext, mMenuView);
     }
 
     @VisibleForTesting
-    AccessibilityFloatingMenu(Context context, AccessibilityFloatingMenuView menuView) {
+    AccessibilityFloatingMenu(Context context, SecureSettings secureSettings,
+            AccessibilityFloatingMenuView menuView) {
         mContext = context;
+        mSecureSettings = secureSettings;
         mMenuView = menuView;
         mMigrationTooltipView = new MigrationTooltipView(mContext, mMenuView);
         mDockTooltipView = new DockTooltipView(mContext, mMenuView);
@@ -130,10 +135,10 @@
 
         mMenuView.show();
         mMenuView.onTargetsChanged(targetList);
-        mMenuView.updateOpacityWith(isFadeEffectEnabled(mContext),
-                getOpacityValue(mContext));
-        mMenuView.setSizeType(getSizeType(mContext));
-        mMenuView.setShapeType(getShapeType(mContext));
+        mMenuView.updateOpacityWith(isFadeEffectEnabled(),
+                getOpacityValue());
+        mMenuView.setSizeType(getSizeType());
+        mMenuView.setShapeType(getShapeType());
         mMenuView.setOnDragEndListener(this::onDragEnd);
 
         showMigrationTooltipIfNecessary();
@@ -170,17 +175,17 @@
     // Migration tooltip was the android S feature. It's just used on the Android version from R
     // to S. In addition, it only shows once.
     private void showMigrationTooltipIfNecessary() {
-        if (isMigrationTooltipPromptEnabled(mContext)) {
+        if (isMigrationTooltipPromptEnabled()) {
             mMigrationTooltipView.show();
 
-            Settings.Secure.putInt(mContext.getContentResolver(),
+            mSecureSettings.putInt(
                     ACCESSIBILITY_FLOATING_MENU_MIGRATION_TOOLTIP_PROMPT, /* disabled */ 0);
         }
     }
 
-    private static boolean isMigrationTooltipPromptEnabled(Context context) {
-        return Settings.Secure.getInt(
-                context.getContentResolver(), ACCESSIBILITY_FLOATING_MENU_MIGRATION_TOOLTIP_PROMPT,
+    private boolean isMigrationTooltipPromptEnabled() {
+        return mSecureSettings.getInt(
+                ACCESSIBILITY_FLOATING_MENU_MIGRATION_TOOLTIP_PROMPT,
                 DEFAULT_MIGRATION_TOOLTIP_PROMPT_IS_DISABLED) == /* enabled */ 1;
     }
 
@@ -212,57 +217,61 @@
         }
     }
 
-    private static boolean isFadeEffectEnabled(Context context) {
-        return Settings.Secure.getInt(
-                context.getContentResolver(), ACCESSIBILITY_FLOATING_MENU_FADE_ENABLED,
+    private boolean isFadeEffectEnabled() {
+        return mSecureSettings.getInt(
+                ACCESSIBILITY_FLOATING_MENU_FADE_ENABLED,
                 DEFAULT_FADE_EFFECT_IS_ENABLED) == /* enabled */ 1;
     }
 
-    private static float getOpacityValue(Context context) {
-        return Settings.Secure.getFloat(
-                context.getContentResolver(), ACCESSIBILITY_FLOATING_MENU_OPACITY,
+    private float getOpacityValue() {
+        return mSecureSettings.getFloat(
+                ACCESSIBILITY_FLOATING_MENU_OPACITY,
                 DEFAULT_OPACITY_VALUE);
     }
 
-    private static int getSizeType(Context context) {
-        return Settings.Secure.getInt(
-                context.getContentResolver(), ACCESSIBILITY_FLOATING_MENU_SIZE, SizeType.SMALL);
+    private int getSizeType() {
+        return mSecureSettings.getInt(
+                ACCESSIBILITY_FLOATING_MENU_SIZE, SizeType.SMALL);
     }
 
-    private static int getShapeType(Context context) {
-        return Settings.Secure.getInt(
-                context.getContentResolver(), ACCESSIBILITY_FLOATING_MENU_ICON_TYPE,
+    private int getShapeType() {
+        return mSecureSettings.getInt(
+                ACCESSIBILITY_FLOATING_MENU_ICON_TYPE,
                 ShapeType.OVAL);
     }
 
     private void registerContentObservers() {
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS),
+        mSecureSettings.registerContentObserverForUser(
+                Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
                 /* notifyForDescendants */ false, mContentObserver,
                 UserHandle.USER_CURRENT);
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE),
+        mSecureSettings.registerContentObserverForUser(
+                Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
+                /* notifyForDescendants */ false, mContentObserver,
+                UserHandle.USER_CURRENT);
+        mSecureSettings.registerContentObserverForUser(
+                Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE,
                 /* notifyForDescendants */ false, mSizeContentObserver,
                 UserHandle.USER_CURRENT);
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_FLOATING_MENU_FADE_ENABLED),
+        mSecureSettings.registerContentObserverForUser(
+                Settings.Secure.ACCESSIBILITY_FLOATING_MENU_FADE_ENABLED,
                 /* notifyForDescendants */ false, mFadeOutContentObserver,
                 UserHandle.USER_CURRENT);
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY),
+        mSecureSettings.registerContentObserverForUser(
+                Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY,
                 /* notifyForDescendants */ false, mFadeOutContentObserver,
                 UserHandle.USER_CURRENT);
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Secure.getUriFor(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES),
+        mSecureSettings.registerContentObserverForUser(
+                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
                 /* notifyForDescendants */ false,
                 mEnabledA11yServicesContentObserver, UserHandle.USER_CURRENT);
     }
 
     private void unregisterContentObservers() {
-        mContext.getContentResolver().unregisterContentObserver(mContentObserver);
-        mContext.getContentResolver().unregisterContentObserver(mSizeContentObserver);
-        mContext.getContentResolver().unregisterContentObserver(mFadeOutContentObserver);
-        mContext.getContentResolver().unregisterContentObserver(
+        mSecureSettings.unregisterContentObserver(mContentObserver);
+        mSecureSettings.unregisterContentObserver(mSizeContentObserver);
+        mSecureSettings.unregisterContentObserver(mFadeOutContentObserver);
+        mSecureSettings.unregisterContentObserver(
                 mEnabledA11yServicesContentObserver);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java
index 403941f..6216b89 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java
@@ -31,6 +31,7 @@
 import com.android.systemui.accessibility.AccessibilityButtonModeObserver.AccessibilityButtonMode;
 import com.android.systemui.accessibility.AccessibilityButtonTargetsObserver;
 import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.util.settings.SecureSettings;
 
 import javax.inject.Inject;
 
@@ -44,6 +45,7 @@
     private final AccessibilityButtonModeObserver mAccessibilityButtonModeObserver;
     private final AccessibilityButtonTargetsObserver mAccessibilityButtonTargetsObserver;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+    private final SecureSettings mSecureSettings;
 
     private Context mContext;
     @VisibleForTesting
@@ -85,11 +87,13 @@
     public AccessibilityFloatingMenuController(Context context,
             AccessibilityButtonTargetsObserver accessibilityButtonTargetsObserver,
             AccessibilityButtonModeObserver accessibilityButtonModeObserver,
-            KeyguardUpdateMonitor keyguardUpdateMonitor) {
+            KeyguardUpdateMonitor keyguardUpdateMonitor,
+            SecureSettings secureSettings) {
         mContext = context;
         mAccessibilityButtonTargetsObserver = accessibilityButtonTargetsObserver;
         mAccessibilityButtonModeObserver = accessibilityButtonModeObserver;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
+        mSecureSettings = secureSettings;
 
         mIsKeyguardVisible = false;
     }
@@ -159,7 +163,7 @@
 
     private void showFloatingMenu() {
         if (mFloatingMenu == null) {
-            mFloatingMenu = new AccessibilityFloatingMenu(mContext);
+            mFloatingMenu = new AccessibilityFloatingMenu(mContext, mSecureSettings);
         }
 
         mFloatingMenu.show();
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index 7c2673c..da2e28c5 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -35,8 +35,10 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.recents.OverviewProxyService;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.util.settings.SecureSettings;
 
 import javax.inject.Inject;
 
@@ -119,6 +121,8 @@
     private final UiController mUiController;
     protected final Lazy<SysUiState> mSysUiState;
     protected final AssistLogger mAssistLogger;
+    private final UserTracker mUserTracker;
+    private final SecureSettings mSecureSettings;
 
     private final DeviceProvisionedController mDeviceProvisionedController;
     private final CommandQueue mCommandQueue;
@@ -135,7 +139,9 @@
             Lazy<SysUiState> sysUiState,
             DefaultUiController defaultUiController,
             AssistLogger assistLogger,
-            @Main Handler uiHandler) {
+            @Main Handler uiHandler,
+            UserTracker userTracker,
+            SecureSettings secureSettings) {
         mContext = context;
         mDeviceProvisionedController = controller;
         mCommandQueue = commandQueue;
@@ -143,6 +149,8 @@
         mAssistDisclosure = new AssistDisclosure(context, uiHandler);
         mPhoneStateMonitor = phoneStateMonitor;
         mAssistLogger = assistLogger;
+        mUserTracker = userTracker;
+        mSecureSettings = secureSettings;
 
         registerVoiceInteractionSessionListener();
 
@@ -273,7 +281,7 @@
                 CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL | CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
                 false /* force */);
 
-        boolean structureEnabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+        boolean structureEnabled = mSecureSettings.getIntForUser(
                 Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1, UserHandle.USER_CURRENT) != 0;
 
         final SearchManager searchManager =
@@ -300,7 +308,7 @@
                 @Override
                 public void run() {
                     mContext.startActivityAsUser(intent, opts.toBundle(),
-                            new UserHandle(UserHandle.USER_CURRENT));
+                            mUserTracker.getUserHandle());
                 }
             });
         } catch (ActivityNotFoundException e) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt
index e4c197f..1404053 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt
@@ -35,13 +35,13 @@
 
     override val actsAsConfirmButton: Boolean = true
 
-    override fun shouldAnimateForTransition(
+    override fun shouldAnimateIconViewForTransition(
             @BiometricState oldState: Int,
             @BiometricState newState: Int
     ): Boolean = when (newState) {
         STATE_PENDING_CONFIRMATION -> true
         STATE_AUTHENTICATED -> false
-        else -> super.shouldAnimateForTransition(oldState, newState)
+        else -> super.shouldAnimateIconViewForTransition(oldState, newState)
     }
 
     @RawRes
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
index b962cc4..436f9df 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
@@ -104,12 +104,14 @@
 
         iconView.frame = 0
         iconViewOverlay.frame = 0
-        if (shouldAnimateForTransition(lastState, newState)) {
-            iconView.playAnimation()
-            iconViewOverlay.playAnimation()
-        } else if (lastState == STATE_IDLE && newState == STATE_AUTHENTICATING_ANIMATING_IN) {
+        if (shouldAnimateIconViewForTransition(lastState, newState)) {
             iconView.playAnimation()
         }
+
+        if (shouldAnimateIconViewOverlayForTransition(lastState, newState)) {
+            iconViewOverlay.playAnimation()
+        }
+
         LottieColorUtils.applyDynamicColors(context, iconView)
         LottieColorUtils.applyDynamicColors(context, iconViewOverlay)
     }
@@ -127,7 +129,7 @@
         }
 
         iconView.frame = 0
-        if (shouldAnimateForTransition(lastState, newState)) {
+        if (shouldAnimateIconViewForTransition(lastState, newState)) {
             iconView.playAnimation()
         }
         LottieColorUtils.applyDynamicColors(context, iconView)
@@ -160,7 +162,20 @@
         return if (id != null) context.getString(id) else null
     }
 
-    protected open fun shouldAnimateForTransition(
+    protected open fun shouldAnimateIconViewForTransition(
+            @BiometricState oldState: Int,
+            @BiometricState newState: Int
+    ) = when (newState) {
+        STATE_HELP,
+        STATE_ERROR -> true
+        STATE_AUTHENTICATING_ANIMATING_IN,
+        STATE_AUTHENTICATING ->
+            oldState == STATE_ERROR || oldState == STATE_HELP || oldState == STATE_IDLE
+        STATE_AUTHENTICATED -> true
+        else -> false
+    }
+
+    protected open fun shouldAnimateIconViewOverlayForTransition(
             @BiometricState oldState: Int,
             @BiometricState newState: Int
     ) = when (newState) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 092339a..2dc0cd3 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -18,6 +18,7 @@
 
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
+import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_REAR;
 
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP;
@@ -76,6 +77,7 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.doze.DozeReceiver;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.keyguard.data.repository.BiometricType;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.VibratorHelper;
@@ -85,8 +87,10 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 
@@ -150,6 +154,7 @@
     @Nullable private List<FingerprintSensorPropertiesInternal> mUdfpsProps;
     @Nullable private List<FingerprintSensorPropertiesInternal> mSidefpsProps;
 
+    @NonNull private final Map<Integer, Boolean> mFpEnrolledForUser = new HashMap<>();
     @NonNull private final SparseBooleanArray mUdfpsEnrolledForUser;
     @NonNull private final SparseBooleanArray mSfpsEnrolledForUser;
     @NonNull private final SensorPrivacyManager mSensorPrivacyManager;
@@ -161,7 +166,6 @@
     private final @Background DelayableExecutor mBackgroundExecutor;
     private final DisplayInfo mCachedDisplayInfo = new DisplayInfo();
 
-
     private final VibratorHelper mVibratorHelper;
 
     private void vibrateSuccess(int modality) {
@@ -331,27 +335,35 @@
         mExecution.assertIsMainThread();
         Log.d(TAG, "handleEnrollmentsChanged, userId: " + userId + ", sensorId: " + sensorId
                 + ", hasEnrollments: " + hasEnrollments);
-        if (mUdfpsProps == null) {
-            Log.d(TAG, "handleEnrollmentsChanged, mUdfpsProps is null");
-        } else {
-            for (FingerprintSensorPropertiesInternal prop : mUdfpsProps) {
+        BiometricType sensorBiometricType = BiometricType.UNKNOWN;
+        if (mFpProps != null) {
+            for (FingerprintSensorPropertiesInternal prop: mFpProps) {
                 if (prop.sensorId == sensorId) {
-                    mUdfpsEnrolledForUser.put(userId, hasEnrollments);
+                    mFpEnrolledForUser.put(userId, hasEnrollments);
+                    if (prop.isAnyUdfpsType()) {
+                        sensorBiometricType = BiometricType.UNDER_DISPLAY_FINGERPRINT;
+                        mUdfpsEnrolledForUser.put(userId, hasEnrollments);
+                    } else if (prop.isAnySidefpsType()) {
+                        sensorBiometricType = BiometricType.SIDE_FINGERPRINT;
+                        mSfpsEnrolledForUser.put(userId, hasEnrollments);
+                    } else if (prop.sensorType == TYPE_REAR) {
+                        sensorBiometricType = BiometricType.REAR_FINGERPRINT;
+                    }
+                    break;
                 }
             }
         }
-
-        if (mSidefpsProps == null) {
-            Log.d(TAG, "handleEnrollmentsChanged, mSidefpsProps is null");
-        } else {
-            for (FingerprintSensorPropertiesInternal prop : mSidefpsProps) {
+        if (mFaceProps != null && sensorBiometricType == BiometricType.UNKNOWN) {
+            for (FaceSensorPropertiesInternal prop : mFaceProps) {
                 if (prop.sensorId == sensorId) {
-                    mSfpsEnrolledForUser.put(userId, hasEnrollments);
+                    sensorBiometricType = BiometricType.FACE;
+                    break;
                 }
             }
         }
         for (Callback cb : mCallbacks) {
             cb.onEnrollmentsChanged();
+            cb.onEnrollmentsChanged(sensorBiometricType, userId, hasEnrollments);
         }
     }
 
@@ -604,6 +616,11 @@
         }
     }
 
+    /** Get FP sensor properties */
+    public @Nullable List<FingerprintSensorPropertiesInternal> getFingerprintProperties() {
+        return mFpProps;
+    }
+
     /**
      * @return where the face sensor exists in pixels in the current device orientation. Returns
      * null if no face sensor exists.
@@ -828,7 +845,7 @@
     }
 
     @Override
-    public void setBiometicContextListener(IBiometricContextListener listener) {
+    public void setBiometricContextListener(IBiometricContextListener listener) {
         mBiometricContextListener = listener;
         notifyDozeChanged(mStatusBarStateController.isDozing(),
                 mWakefulnessLifecycle.getWakefulness());
@@ -1081,6 +1098,13 @@
         return mSfpsEnrolledForUser.get(userId);
     }
 
+    /**
+     * Whether the passed userId has enrolled at least one fingerprint.
+     */
+    public boolean isFingerprintEnrolled(int userId) {
+        return mFpEnrolledForUser.getOrDefault(userId, false);
+    }
+
     private void showDialog(SomeArgs args, boolean skipAnimation, Bundle savedState) {
         mCurrentDialogArgs = args;
 
@@ -1263,6 +1287,16 @@
         default void onEnrollmentsChanged() {}
 
         /**
+         * Called when UDFPS enrollments have changed. This is called after boot and on changes to
+         * enrollment.
+         */
+        default void onEnrollmentsChanged(
+                @NonNull BiometricType biometricType,
+                int userId,
+                boolean hasEnrollments
+        ) {}
+
+        /**
          * Called when the biometric prompt starts showing.
          */
         default void onBiometricPromptShown() {}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintInteractiveToAuthProvider.java b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintInteractiveToAuthProvider.java
new file mode 100644
index 0000000..902bb18
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintInteractiveToAuthProvider.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics;
+
+/** Provides the status of the interactive to auth feature. */
+public interface FingerprintInteractiveToAuthProvider {
+    /**
+     *
+     * @param userId the user Id.
+     * @return true if the InteractiveToAuthFeature is enabled, false if disabled.
+     */
+    boolean isEnabled(int userId);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
index 17ebdad..6f594d5 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
@@ -110,6 +110,9 @@
     private val animationDuration =
         context.resources.getInteger(android.R.integer.config_mediumAnimTime).toLong()
 
+    private val isReverseDefaultRotation =
+        context.resources.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)
+
     private var overlayHideAnimator: ViewPropertyAnimator? = null
 
     private var overlayView: View? = null
@@ -217,8 +220,17 @@
         overlayOffsets = offsets
 
         val lottie = view.findViewById(R.id.sidefps_animation) as LottieAnimationView
-        view.rotation = display.asSideFpsAnimationRotation(offsets.isYAligned())
-        lottie.setAnimation(display.asSideFpsAnimation(offsets.isYAligned()))
+        view.rotation =
+            display.asSideFpsAnimationRotation(
+                offsets.isYAligned(),
+                getRotationFromDefault(display.rotation)
+            )
+        lottie.setAnimation(
+            display.asSideFpsAnimation(
+                offsets.isYAligned(),
+                getRotationFromDefault(display.rotation)
+            )
+        )
         lottie.addLottieOnCompositionLoadedListener {
             // Check that view is not stale, and that overlayView has not been hidden/removed
             if (overlayView != null && overlayView == view) {
@@ -253,11 +265,15 @@
     @VisibleForTesting
     internal fun updateOverlayParams(display: Display, bounds: Rect) {
         val isNaturalOrientation = display.isNaturalOrientation()
+        val isDefaultOrientation =
+            if (isReverseDefaultRotation) !isNaturalOrientation else isNaturalOrientation
         val size = windowManager.maximumWindowMetrics.bounds
-        val displayWidth = if (isNaturalOrientation) size.width() else size.height()
-        val displayHeight = if (isNaturalOrientation) size.height() else size.width()
-        val boundsWidth = if (isNaturalOrientation) bounds.width() else bounds.height()
-        val boundsHeight = if (isNaturalOrientation) bounds.height() else bounds.width()
+
+        val displayWidth = if (isDefaultOrientation) size.width() else size.height()
+        val displayHeight = if (isDefaultOrientation) size.height() else size.width()
+        val boundsWidth = if (isDefaultOrientation) bounds.width() else bounds.height()
+        val boundsHeight = if (isDefaultOrientation) bounds.height() else bounds.width()
+
         val sensorBounds =
             if (overlayOffsets.isYAligned()) {
                 Rect(
@@ -278,11 +294,12 @@
         RotationUtils.rotateBounds(
             sensorBounds,
             Rect(0, 0, displayWidth, displayHeight),
-            display.rotation
+            getRotationFromDefault(display.rotation)
         )
 
         overlayViewParams.x = sensorBounds.left
         overlayViewParams.y = sensorBounds.top
+
         windowManager.updateViewLayout(overlayView, overlayViewParams)
     }
 
@@ -292,7 +309,12 @@
         }
         // hide after a few seconds if the sensor is oriented down and there are
         // large overlapping system bars
-        val rotation = context.display?.rotation
+        var rotation = context.display?.rotation
+
+        if (rotation != null) {
+            rotation = getRotationFromDefault(rotation)
+        }
+
         if (
             windowManager.currentWindowMetrics.windowInsets.hasBigNavigationBar() &&
                 ((rotation == Surface.ROTATION_270 && overlayOffsets.isYAligned()) ||
@@ -319,6 +341,9 @@
             view.visibility = View.VISIBLE
         }
     }
+
+    private fun getRotationFromDefault(rotation: Int): Int =
+        if (isReverseDefaultRotation) (rotation + 1) % 4 else rotation
 }
 
 private val FingerprintManager?.sideFpsSensorProperties: FingerprintSensorPropertiesInternal?
@@ -344,15 +369,15 @@
     getTasks(1).firstOrNull()?.topActivity?.className ?: ""
 
 @RawRes
-private fun Display.asSideFpsAnimation(yAligned: Boolean): Int =
-    when (rotation) {
+private fun Display.asSideFpsAnimation(yAligned: Boolean, rotationFromDefault: Int): Int =
+    when (rotationFromDefault) {
         Surface.ROTATION_0 -> if (yAligned) R.raw.sfps_pulse else R.raw.sfps_pulse_landscape
         Surface.ROTATION_180 -> if (yAligned) R.raw.sfps_pulse else R.raw.sfps_pulse_landscape
         else -> if (yAligned) R.raw.sfps_pulse_landscape else R.raw.sfps_pulse
     }
 
-private fun Display.asSideFpsAnimationRotation(yAligned: Boolean): Float =
-    when (rotation) {
+private fun Display.asSideFpsAnimationRotation(yAligned: Boolean, rotationFromDefault: Int): Float =
+    when (rotationFromDefault) {
         Surface.ROTATION_90 -> if (yAligned) 0f else 180f
         Surface.ROTATION_180 -> 180f
         Surface.ROTATION_270 -> if (yAligned) 180f else 0f
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
index 4130cf5..ef7dcb7 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
@@ -190,11 +190,6 @@
     open fun listenForTouchesOutsideView(): Boolean = false
 
     /**
-     * Called on touches outside of the view if listenForTouchesOutsideView returns true
-     */
-    open fun onTouchOutsideView() {}
-
-    /**
      * Called when a view should announce an accessibility event.
      */
     open fun doAnnounceForAccessibility(str: String) {}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index f3136ba..3fd00ae 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -73,6 +73,7 @@
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
 import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -86,6 +87,7 @@
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.concurrency.DelayableExecutor;
 import com.android.systemui.util.concurrency.Execution;
+import com.android.systemui.util.settings.SecureSettings;
 import com.android.systemui.util.time.SystemClock;
 
 import java.io.PrintWriter;
@@ -149,6 +151,8 @@
     @NonNull private final ActivityLaunchAnimator mActivityLaunchAnimator;
     @NonNull private final PrimaryBouncerInteractor mPrimaryBouncerInteractor;
     @Nullable private final TouchProcessor mTouchProcessor;
+    @NonNull private final AlternateBouncerInteractor mAlternateBouncerInteractor;
+    @NonNull private final SecureSettings mSecureSettings;
 
     // Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple
     // sensors, this, in addition to a lot of the code here, will be updated.
@@ -220,6 +224,10 @@
     @Override
     public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
         pw.println("mSensorProps=(" + mSensorProps + ")");
+        pw.println("Using new touch detection framework: " + mFeatureFlags.isEnabled(
+                Flags.UDFPS_NEW_TOUCH_DETECTION));
+        pw.println("Using ellipse touch detection: " + mFeatureFlags.isEnabled(
+                Flags.UDFPS_ELLIPSE_DETECTION));
     }
 
     public class UdfpsOverlayController extends IUdfpsOverlayController.Stub {
@@ -232,12 +240,12 @@
                             mShadeExpansionStateManager, mKeyguardViewManager,
                             mKeyguardUpdateMonitor, mDialogManager, mDumpManager,
                             mLockscreenShadeTransitionController, mConfigurationController,
-                            mSystemClock, mKeyguardStateController,
+                            mKeyguardStateController,
                             mUnlockedScreenOffAnimationController,
-                            mUdfpsDisplayMode, requestId, reason, callback,
+                            mUdfpsDisplayMode, mSecureSettings, requestId, reason, callback,
                             (view, event, fromUdfpsView) -> onTouch(requestId, event,
                                     fromUdfpsView), mActivityLaunchAnimator, mFeatureFlags,
-                            mPrimaryBouncerInteractor)));
+                            mPrimaryBouncerInteractor, mAlternateBouncerInteractor)));
         }
 
         @Override
@@ -329,13 +337,13 @@
         if (!mOverlayParams.equals(overlayParams)) {
             mOverlayParams = overlayParams;
 
-            final boolean wasShowingAltAuth = mKeyguardViewManager.isShowingAlternateBouncer();
+            final boolean wasShowingAlternateBouncer = mAlternateBouncerInteractor.isVisibleState();
 
             // When the bounds change it's always necessary to re-create the overlay's window with
             // new LayoutParams. If the overlay needs to be shown, this will re-create and show the
             // overlay with the updated LayoutParams. Otherwise, the overlay will remain hidden.
             redrawOverlay();
-            if (wasShowingAltAuth) {
+            if (wasShowingAlternateBouncer) {
                 mKeyguardViewManager.showBouncer(true);
             }
         }
@@ -543,9 +551,6 @@
         final UdfpsView udfpsView = mOverlay.getOverlayView();
         boolean handled = false;
         switch (event.getActionMasked()) {
-            case MotionEvent.ACTION_OUTSIDE:
-                udfpsView.onTouchOutsideView();
-                return true;
             case MotionEvent.ACTION_DOWN:
             case MotionEvent.ACTION_HOVER_ENTER:
                 Trace.beginSection("UdfpsController.onTouch.ACTION_DOWN");
@@ -719,7 +724,9 @@
             @NonNull Optional<Provider<AlternateUdfpsTouchProvider>> alternateTouchProvider,
             @NonNull @BiometricsBackground Executor biometricsExecutor,
             @NonNull PrimaryBouncerInteractor primaryBouncerInteractor,
-            @NonNull SinglePointerTouchProcessor singlePointerTouchProcessor) {
+            @NonNull SinglePointerTouchProcessor singlePointerTouchProcessor,
+            @NonNull AlternateBouncerInteractor alternateBouncerInteractor,
+            @NonNull SecureSettings secureSettings) {
         mContext = context;
         mExecution = execution;
         mVibrator = vibrator;
@@ -759,6 +766,8 @@
 
         mBiometricExecutor = biometricsExecutor;
         mPrimaryBouncerInteractor = primaryBouncerInteractor;
+        mAlternateBouncerInteractor = alternateBouncerInteractor;
+        mSecureSettings = secureSettings;
 
         mTouchProcessor = mFeatureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)
                 ? singlePointerTouchProcessor : null;
@@ -853,9 +862,7 @@
                 onFingerUp(mOverlay.getRequestId(), oldView);
             }
             final boolean removed = mOverlay.hide();
-            if (mKeyguardViewManager.isShowingAlternateBouncer()) {
-                mKeyguardViewManager.hideAlternateBouncer(true);
-            }
+            mKeyguardViewManager.hideAlternateBouncer(true);
             Log.v(TAG, "hideUdfpsOverlay | removing window: " + removed);
         } else {
             Log.v(TAG, "hideUdfpsOverlay | the overlay is already hidden");
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
index 8db4927..b6b5d26 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
@@ -50,6 +50,7 @@
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.shade.ShadeExpansionStateManager
@@ -59,7 +60,7 @@
 import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.policy.KeyguardStateController
-import com.android.systemui.util.time.SystemClock
+import com.android.systemui.util.settings.SecureSettings
 
 private const val TAG = "UdfpsControllerOverlay"
 
@@ -86,10 +87,10 @@
         private val dumpManager: DumpManager,
         private val transitionController: LockscreenShadeTransitionController,
         private val configurationController: ConfigurationController,
-        private val systemClock: SystemClock,
         private val keyguardStateController: KeyguardStateController,
         private val unlockedScreenOffAnimationController: UnlockedScreenOffAnimationController,
         private var udfpsDisplayModeProvider: UdfpsDisplayModeProvider,
+        private val secureSettings: SecureSettings,
         val requestId: Long,
         @ShowReason val requestReason: Int,
         private val controllerCallback: IUdfpsOverlayControllerCallback,
@@ -97,7 +98,8 @@
         private val activityLaunchAnimator: ActivityLaunchAnimator,
         private val featureFlags: FeatureFlags,
         private val primaryBouncerInteractor: PrimaryBouncerInteractor,
-        private val isDebuggable: Boolean = Build.IS_DEBUGGABLE
+        private val alternateBouncerInteractor: AlternateBouncerInteractor,
+        private val isDebuggable: Boolean = Build.IS_DEBUGGABLE,
 ) {
     /** The view, when [isShowing], or null. */
     var overlayView: UdfpsView? = null
@@ -131,7 +133,7 @@
     /** A helper if the [requestReason] was due to enrollment. */
     val enrollHelper: UdfpsEnrollHelper? =
         if (requestReason.isEnrollmentReason() && !shouldRemoveEnrollmentUi()) {
-            UdfpsEnrollHelper(context, fingerprintManager, requestReason)
+            UdfpsEnrollHelper(context, fingerprintManager, secureSettings, requestReason)
         } else {
             null
         }
@@ -255,14 +257,14 @@
                     dumpManager,
                     transitionController,
                     configurationController,
-                    systemClock,
                     keyguardStateController,
                     unlockedScreenOffAnimationController,
                     dialogManager,
                     controller,
                     activityLaunchAnimator,
                     featureFlags,
-                    primaryBouncerInteractor
+                    primaryBouncerInteractor,
+                    alternateBouncerInteractor,
                 )
             }
             REASON_AUTH_BP -> {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java
index d5c763d3..cfa8ec5 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java
@@ -24,11 +24,12 @@
 import android.hardware.fingerprint.FingerprintManager;
 import android.os.Build;
 import android.os.UserHandle;
-import android.provider.Settings;
 import android.util.Log;
 import android.util.TypedValue;
 import android.view.accessibility.AccessibilityManager;
 
+import com.android.systemui.util.settings.SecureSettings;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -51,8 +52,8 @@
         void onLastStepAcquired();
     }
 
-    @NonNull private final Context mContext;
     @NonNull private final FingerprintManager mFingerprintManager;
+    @NonNull private final SecureSettings mSecureSettings;
     // IUdfpsOverlayController reason
     private final int mEnrollReason;
     private final boolean mAccessibilityEnabled;
@@ -70,10 +71,11 @@
     @Nullable Listener mListener;
 
     public UdfpsEnrollHelper(@NonNull Context context,
-            @NonNull FingerprintManager fingerprintManager, int reason) {
+            @NonNull FingerprintManager fingerprintManager, SecureSettings secureSettings,
+            int reason) {
 
-        mContext = context;
         mFingerprintManager = fingerprintManager;
+        mSecureSettings = secureSettings;
         mEnrollReason = reason;
 
         final AccessibilityManager am = context.getSystemService(AccessibilityManager.class);
@@ -84,8 +86,7 @@
         // Number of pixels per mm
         float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_MM, 1,
                 context.getResources().getDisplayMetrics());
-        boolean useNewCoords = Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                NEW_COORDS_OVERRIDE, 0,
+        boolean useNewCoords = mSecureSettings.getIntForUser(NEW_COORDS_OVERRIDE, 0,
                 UserHandle.USER_CURRENT) != 0;
         if (useNewCoords && (Build.IS_ENG || Build.IS_USERDEBUG)) {
             Log.v(TAG, "Using new coordinates");
@@ -210,8 +211,7 @@
 
         float scale = SCALE;
         if (Build.IS_ENG || Build.IS_USERDEBUG) {
-            scale = Settings.Secure.getFloatForUser(mContext.getContentResolver(),
-                    SCALE_OVERRIDE, SCALE,
+            scale = mSecureSettings.getFloatForUser(SCALE_OVERRIDE, SCALE,
                     UserHandle.USER_CURRENT);
         }
         final int index = mLocationsEnrolled - mCenterTouchCount;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.kt
index 63144fc..63a1b76 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.kt
@@ -31,7 +31,10 @@
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor
+import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor
+import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.shade.ShadeExpansionListener
@@ -39,16 +42,14 @@
 import com.android.systemui.statusbar.LockscreenShadeTransitionController
 import com.android.systemui.statusbar.StatusBarState
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator
-import com.android.systemui.statusbar.phone.KeyguardBouncer
-import com.android.systemui.statusbar.phone.KeyguardBouncer.PrimaryBouncerExpansionCallback
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager.AlternateBouncer
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager.KeyguardViewManagerCallback
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager.LegacyAlternateBouncer
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager.OccludingAppBiometricUI
 import com.android.systemui.statusbar.phone.SystemUIDialogManager
 import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.policy.KeyguardStateController
-import com.android.systemui.util.time.SystemClock
 import java.io.PrintWriter
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Job
@@ -65,25 +66,27 @@
     dumpManager: DumpManager,
     private val lockScreenShadeTransitionController: LockscreenShadeTransitionController,
     private val configurationController: ConfigurationController,
-    private val systemClock: SystemClock,
     private val keyguardStateController: KeyguardStateController,
     private val unlockedScreenOffAnimationController: UnlockedScreenOffAnimationController,
     systemUIDialogManager: SystemUIDialogManager,
     private val udfpsController: UdfpsController,
     private val activityLaunchAnimator: ActivityLaunchAnimator,
     featureFlags: FeatureFlags,
-    private val primaryBouncerInteractor: PrimaryBouncerInteractor
+    private val primaryBouncerInteractor: PrimaryBouncerInteractor,
+    private val alternateBouncerInteractor: AlternateBouncerInteractor,
 ) :
     UdfpsAnimationViewController<UdfpsKeyguardView>(
         view,
         statusBarStateController,
         shadeExpansionStateManager,
         systemUIDialogManager,
-        dumpManager
+        dumpManager,
     ) {
     private val useExpandedOverlay: Boolean =
         featureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)
     private val isModernBouncerEnabled: Boolean = featureFlags.isEnabled(Flags.MODERN_BOUNCER)
+    private val isModernAlternateBouncerEnabled: Boolean =
+        featureFlags.isEnabled(Flags.MODERN_ALTERNATE_BOUNCER)
     private var showingUdfpsBouncer = false
     private var udfpsRequested = false
     private var qsExpansion = 0f
@@ -91,7 +94,6 @@
     private var statusBarState = 0
     private var transitionToFullShadeProgress = 0f
     private var lastDozeAmount = 0f
-    private var lastUdfpsBouncerShowTime: Long = -1
     private var panelExpansionFraction = 0f
     private var launchTransitionFadingAway = false
     private var isLaunchingActivity = false
@@ -110,10 +112,10 @@
         }
     /**
      * Hidden amount of input (pin/pattern/password) bouncer. This is used
-     * [KeyguardBouncer.EXPANSION_VISIBLE] (0f) to [KeyguardBouncer.EXPANSION_HIDDEN] (1f). Only
-     * used for the non-modernBouncer.
+     * [KeyguardBouncerConstants.EXPANSION_VISIBLE] (0f) to
+     * [KeyguardBouncerConstants.EXPANSION_HIDDEN] (1f). Only used for the non-modernBouncer.
      */
-    private var inputBouncerHiddenAmount = KeyguardBouncer.EXPANSION_HIDDEN
+    private var inputBouncerHiddenAmount = KeyguardBouncerConstants.EXPANSION_HIDDEN
     private var inputBouncerExpansion = 0f // only used for modernBouncer
 
     private val stateListener: StatusBarStateController.StateListener =
@@ -244,20 +246,8 @@
             }
         }
 
-    private val mAlternateBouncer: AlternateBouncer =
-        object : AlternateBouncer {
-            override fun showAlternateBouncer(): Boolean {
-                return showUdfpsBouncer(true)
-            }
-
-            override fun hideAlternateBouncer(): Boolean {
-                return showUdfpsBouncer(false)
-            }
-
-            override fun isShowingAlternateBouncer(): Boolean {
-                return showingUdfpsBouncer
-            }
-
+    private val occludingAppBiometricUI: OccludingAppBiometricUI =
+        object : OccludingAppBiometricUI {
             override fun requestUdfps(request: Boolean, color: Int) {
                 udfpsRequested = request
                 view.requestUdfps(request, color)
@@ -275,16 +265,19 @@
 
     override fun onInit() {
         super.onInit()
-        keyguardViewManager.setAlternateBouncer(mAlternateBouncer)
+        keyguardViewManager.setOccludingAppBiometricUI(occludingAppBiometricUI)
     }
 
     init {
-        if (isModernBouncerEnabled) {
+        if (isModernBouncerEnabled || isModernAlternateBouncerEnabled) {
             view.repeatWhenAttached {
                 // repeatOnLifecycle CREATED (as opposed to STARTED) because the Bouncer expansion
                 // can make the view not visible; and we still want to listen for events
                 // that may make the view visible again.
-                repeatOnLifecycle(Lifecycle.State.CREATED) { listenForBouncerExpansion(this) }
+                repeatOnLifecycle(Lifecycle.State.CREATED) {
+                    if (isModernBouncerEnabled) listenForBouncerExpansion(this)
+                    if (isModernAlternateBouncerEnabled) listenForAlternateBouncerVisibility(this)
+                }
             }
         }
     }
@@ -300,8 +293,18 @@
         }
     }
 
+    @VisibleForTesting
+    internal suspend fun listenForAlternateBouncerVisibility(scope: CoroutineScope): Job {
+        return scope.launch {
+            alternateBouncerInteractor.isVisible.collect { isVisible: Boolean ->
+                showUdfpsBouncer(isVisible)
+            }
+        }
+    }
+
     public override fun onViewAttached() {
         super.onViewAttached()
+        alternateBouncerInteractor.setAlternateBouncerUIAvailable(true)
         val dozeAmount = statusBarStateController.dozeAmount
         lastDozeAmount = dozeAmount
         stateListener.onDozeAmountChanged(dozeAmount, dozeAmount)
@@ -326,7 +329,8 @@
         view.updatePadding()
         updateAlpha()
         updatePauseAuth()
-        keyguardViewManager.setAlternateBouncer(mAlternateBouncer)
+        keyguardViewManager.setLegacyAlternateBouncer(legacyAlternateBouncer)
+        keyguardViewManager.setOccludingAppBiometricUI(occludingAppBiometricUI)
         lockScreenShadeTransitionController.udfpsKeyguardViewController = this
         activityLaunchAnimator.addListener(activityLaunchAnimatorListener)
         view.mUseExpandedOverlay = useExpandedOverlay
@@ -334,10 +338,12 @@
 
     override fun onViewDetached() {
         super.onViewDetached()
+        alternateBouncerInteractor.setAlternateBouncerUIAvailable(false)
         faceDetectRunning = false
         keyguardStateController.removeCallback(keyguardStateControllerCallback)
         statusBarStateController.removeCallback(stateListener)
-        keyguardViewManager.removeAlternateAuthInterceptor(mAlternateBouncer)
+        keyguardViewManager.removeLegacyAlternateBouncer(legacyAlternateBouncer)
+        keyguardViewManager.removeOccludingAppBiometricUI(occludingAppBiometricUI)
         keyguardUpdateMonitor.requestFaceAuthOnOccludingApp(false)
         configurationController.removeCallback(configurationListener)
         shadeExpansionStateManager.removeExpansionListener(shadeExpansionListener)
@@ -356,7 +362,16 @@
     override fun dump(pw: PrintWriter, args: Array<String>) {
         super.dump(pw, args)
         pw.println("isModernBouncerEnabled=$isModernBouncerEnabled")
+        pw.println("isModernAlternateBouncerEnabled=$isModernAlternateBouncerEnabled")
         pw.println("showingUdfpsAltBouncer=$showingUdfpsBouncer")
+        pw.println(
+            "altBouncerInteractor#isAlternateBouncerVisible=" +
+                "${alternateBouncerInteractor.isVisibleState()}"
+        )
+        pw.println(
+            "altBouncerInteractor#canShowAlternateBouncerForFingerprint=" +
+                "${alternateBouncerInteractor.canShowAlternateBouncerForFingerprint()}"
+        )
         pw.println("faceDetectRunning=$faceDetectRunning")
         pw.println("statusBarState=" + StatusBarState.toString(statusBarState))
         pw.println("transitionToFullShadeProgress=$transitionToFullShadeProgress")
@@ -385,9 +400,6 @@
         val udfpsAffordanceWasNotShowing = shouldPauseAuth()
         showingUdfpsBouncer = show
         if (showingUdfpsBouncer) {
-            lastUdfpsBouncerShowTime = systemClock.uptimeMillis()
-        }
-        if (showingUdfpsBouncer) {
             if (udfpsAffordanceWasNotShowing) {
                 view.animateInUdfpsBouncer(null)
             }
@@ -452,7 +464,7 @@
         return if (isModernBouncerEnabled) {
             inputBouncerExpansion == 1f
         } else {
-            keyguardViewManager.isBouncerShowing && !keyguardViewManager.isShowingAlternateBouncer
+            keyguardViewManager.isBouncerShowing && !alternateBouncerInteractor.isVisibleState()
         }
     }
 
@@ -460,30 +472,6 @@
         return true
     }
 
-    override fun onTouchOutsideView() {
-        maybeShowInputBouncer()
-    }
-
-    /**
-     * If we were previously showing the udfps bouncer, hide it and instead show the regular
-     * (pin/pattern/password) bouncer.
-     *
-     * Does nothing if we weren't previously showing the UDFPS bouncer.
-     */
-    private fun maybeShowInputBouncer() {
-        if (showingUdfpsBouncer && hasUdfpsBouncerShownWithMinTime()) {
-            keyguardViewManager.showPrimaryBouncer(true)
-        }
-    }
-
-    /**
-     * Whether the udfps bouncer has shown for at least 200ms before allowing touches outside of the
-     * udfps icon area to dismiss the udfps bouncer and show the pin/pattern/password bouncer.
-     */
-    private fun hasUdfpsBouncerShownWithMinTime(): Boolean {
-        return systemClock.uptimeMillis() - lastUdfpsBouncerShowTime > 200
-    }
-
     /**
      * Set the progress we're currently transitioning to the full shade. 0.0f means we're not
      * transitioning yet, while 1.0f means we've fully dragged down. For example, start swiping down
@@ -545,7 +533,7 @@
         if (isModernBouncerEnabled) {
             return
         }
-        val altBouncerShowing = keyguardViewManager.isShowingAlternateBouncer
+        val altBouncerShowing = alternateBouncerInteractor.isVisibleState()
         if (altBouncerShowing || !keyguardViewManager.primaryBouncerIsOrWillBeShowing()) {
             inputBouncerHiddenAmount = 1f
         } else if (keyguardViewManager.isBouncerShowing) {
@@ -554,6 +542,21 @@
         }
     }
 
+    private val legacyAlternateBouncer: LegacyAlternateBouncer =
+        object : LegacyAlternateBouncer {
+            override fun showAlternateBouncer(): Boolean {
+                return showUdfpsBouncer(true)
+            }
+
+            override fun hideAlternateBouncer(): Boolean {
+                return showUdfpsBouncer(false)
+            }
+
+            override fun isShowingAlternateBouncer(): Boolean {
+                return showingUdfpsBouncer
+            }
+        }
+
     companion object {
         const val TAG = "UdfpsKeyguardViewController"
     }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
index 4a8877e..e61c614 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
@@ -111,10 +111,6 @@
         }
     }
 
-    fun onTouchOutsideView() {
-        animationViewController?.onTouchOutsideView()
-    }
-
     override fun onAttachedToWindow() {
         super.onAttachedToWindow()
         Log.v(TAG, "onAttachedToWindow")
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetector.kt b/packages/SystemUI/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetector.kt
index 8572242..682d38a 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetector.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetector.kt
@@ -18,6 +18,7 @@
 
 import android.graphics.Point
 import android.graphics.Rect
+import androidx.annotation.VisibleForTesting
 import com.android.systemui.dagger.SysUISingleton
 import kotlin.math.cos
 import kotlin.math.pow
@@ -50,7 +51,8 @@
         return result <= 1
     }
 
-    private fun calculateSensorPoints(sensorBounds: Rect): List<Point> {
+    @VisibleForTesting
+    fun calculateSensorPoints(sensorBounds: Rect): List<Point> {
         val sensorX = sensorBounds.centerX()
         val sensorY = sensorBounds.centerY()
         val cornerOffset: Int = sensorBounds.width() / 4
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/udfps/NormalizedTouchData.kt b/packages/SystemUI/src/com/android/systemui/biometrics/udfps/NormalizedTouchData.kt
index 62bedc6..48d4845 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/udfps/NormalizedTouchData.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/udfps/NormalizedTouchData.kt
@@ -26,28 +26,28 @@
      * Value obtained from [MotionEvent.getPointerId], or [MotionEvent.INVALID_POINTER_ID] if the ID
      * is not available.
      */
-    val pointerId: Int,
+    val pointerId: Int = MotionEvent.INVALID_POINTER_ID,
 
     /** [MotionEvent.getRawX] mapped to natural orientation and native resolution. */
-    val x: Float,
+    val x: Float = 0f,
 
     /** [MotionEvent.getRawY] mapped to natural orientation and native resolution. */
-    val y: Float,
+    val y: Float = 0f,
 
     /** [MotionEvent.getTouchMinor] mapped to natural orientation and native resolution. */
-    val minor: Float,
+    val minor: Float = 0f,
 
     /** [MotionEvent.getTouchMajor] mapped to natural orientation and native resolution. */
-    val major: Float,
+    val major: Float = 0f,
 
     /** [MotionEvent.getOrientation] mapped to natural orientation. */
-    val orientation: Float,
+    val orientation: Float = 0f,
 
     /** [MotionEvent.getEventTime]. */
-    val time: Long,
+    val time: Long = 0,
 
     /** [MotionEvent.getDownTime]. */
-    val gestureStart: Long,
+    val gestureStart: Long = 0,
 ) {
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessor.kt
index 338bf66..3a01cd5 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessor.kt
@@ -27,6 +27,8 @@
 import com.android.systemui.dagger.SysUISingleton
 import javax.inject.Inject
 
+private val SUPPORTED_ROTATIONS = setOf(Surface.ROTATION_90, Surface.ROTATION_270)
+
 /**
  * TODO(b/259140693): Consider using an object pool of TouchProcessorResult to avoid allocations.
  */
@@ -41,74 +43,72 @@
     ): TouchProcessorResult {
 
         fun preprocess(): PreprocessedTouch {
-            // TODO(b/253085297): Add multitouch support. pointerIndex can be > 0 for ACTION_MOVE.
-            val pointerIndex = 0
-            val touchData = event.normalize(pointerIndex, overlayParams)
-            val isGoodOverlap =
-                overlapDetector.isGoodOverlap(touchData, overlayParams.nativeSensorBounds)
-            return PreprocessedTouch(touchData, previousPointerOnSensorId, isGoodOverlap)
+            val touchData = List(event.pointerCount) { event.normalize(it, overlayParams) }
+            val pointersOnSensor =
+                touchData
+                    .filter { overlapDetector.isGoodOverlap(it, overlayParams.nativeSensorBounds) }
+                    .map { it.pointerId }
+            return PreprocessedTouch(touchData, previousPointerOnSensorId, pointersOnSensor)
         }
 
         return when (event.actionMasked) {
-            MotionEvent.ACTION_DOWN -> processActionDown(preprocess())
+            MotionEvent.ACTION_DOWN,
+            MotionEvent.ACTION_POINTER_DOWN,
             MotionEvent.ACTION_MOVE -> processActionMove(preprocess())
-            MotionEvent.ACTION_UP -> processActionUp(preprocess())
-            MotionEvent.ACTION_CANCEL ->
-                processActionCancel(event.normalize(pointerIndex = 0, overlayParams))
+            MotionEvent.ACTION_UP,
+            MotionEvent.ACTION_POINTER_UP ->
+                processActionUp(preprocess(), event.getPointerId(event.actionIndex))
+            MotionEvent.ACTION_CANCEL -> processActionCancel(NormalizedTouchData())
             else ->
                 Failure("Unsupported MotionEvent." + MotionEvent.actionToString(event.actionMasked))
         }
     }
 }
 
+/**
+ * [data] contains a list of NormalizedTouchData for pointers in the motionEvent ordered by
+ * pointerIndex
+ *
+ * [previousPointerOnSensorId] the pointerId of the previous pointer on the sensor,
+ * [MotionEvent.INVALID_POINTER_ID] if none
+ *
+ * [pointersOnSensor] contains a list of ids of pointers on the sensor
+ */
 private data class PreprocessedTouch(
-    val data: NormalizedTouchData,
+    val data: List<NormalizedTouchData>,
     val previousPointerOnSensorId: Int,
-    val isGoodOverlap: Boolean,
+    val pointersOnSensor: List<Int>,
 )
 
-private fun processActionDown(touch: PreprocessedTouch): TouchProcessorResult {
-    return if (touch.isGoodOverlap) {
-        ProcessedTouch(InteractionEvent.DOWN, pointerOnSensorId = touch.data.pointerId, touch.data)
-    } else {
-        val event =
-            if (touch.data.pointerId == touch.previousPointerOnSensorId) {
-                InteractionEvent.UP
-            } else {
-                InteractionEvent.UNCHANGED
-            }
-        ProcessedTouch(event, pointerOnSensorId = INVALID_POINTER_ID, touch.data)
-    }
-}
-
 private fun processActionMove(touch: PreprocessedTouch): TouchProcessorResult {
     val hadPointerOnSensor = touch.previousPointerOnSensorId != INVALID_POINTER_ID
-    val interactionEvent =
-        when {
-            touch.isGoodOverlap && !hadPointerOnSensor -> InteractionEvent.DOWN
-            !touch.isGoodOverlap && hadPointerOnSensor -> InteractionEvent.UP
-            else -> InteractionEvent.UNCHANGED
-        }
-    val pointerOnSensorId =
-        when (interactionEvent) {
-            InteractionEvent.UNCHANGED -> touch.previousPointerOnSensorId
-            InteractionEvent.DOWN -> touch.data.pointerId
-            else -> INVALID_POINTER_ID
-        }
-    return ProcessedTouch(interactionEvent, pointerOnSensorId, touch.data)
+    val hasPointerOnSensor = touch.pointersOnSensor.isNotEmpty()
+    val pointerOnSensorId = touch.pointersOnSensor.firstOrNull() ?: INVALID_POINTER_ID
+
+    return if (!hadPointerOnSensor && hasPointerOnSensor) {
+        val data = touch.data.find { it.pointerId == pointerOnSensorId } ?: NormalizedTouchData()
+        ProcessedTouch(InteractionEvent.DOWN, data.pointerId, data)
+    } else if (hadPointerOnSensor && !hasPointerOnSensor) {
+        ProcessedTouch(InteractionEvent.UP, INVALID_POINTER_ID, NormalizedTouchData())
+    } else {
+        val data = touch.data.find { it.pointerId == pointerOnSensorId } ?: NormalizedTouchData()
+        ProcessedTouch(InteractionEvent.UNCHANGED, pointerOnSensorId, data)
+    }
 }
 
-private fun processActionUp(touch: PreprocessedTouch): TouchProcessorResult {
-    return if (touch.isGoodOverlap) {
-        ProcessedTouch(InteractionEvent.UP, pointerOnSensorId = INVALID_POINTER_ID, touch.data)
+private fun processActionUp(touch: PreprocessedTouch, actionId: Int): TouchProcessorResult {
+    // Finger lifted and it was the only finger on the sensor
+    return if (touch.pointersOnSensor.size == 1 && touch.pointersOnSensor.contains(actionId)) {
+        ProcessedTouch(
+            InteractionEvent.UP,
+            pointerOnSensorId = INVALID_POINTER_ID,
+            NormalizedTouchData()
+        )
     } else {
-        val event =
-            if (touch.previousPointerOnSensorId != INVALID_POINTER_ID) {
-                InteractionEvent.UP
-            } else {
-                InteractionEvent.UNCHANGED
-            }
-        ProcessedTouch(event, pointerOnSensorId = INVALID_POINTER_ID, touch.data)
+        // Pick new pointerOnSensor that's not the finger that was lifted
+        val pointerOnSensorId = touch.pointersOnSensor.find { it != actionId } ?: INVALID_POINTER_ID
+        val data = touch.data.find { it.pointerId == pointerOnSensorId } ?: NormalizedTouchData()
+        ProcessedTouch(InteractionEvent.UNCHANGED, data.pointerId, data)
     }
 }
 
@@ -129,19 +129,27 @@
     val nativeY = naturalTouch.y / overlayParams.scaleFactor
     val nativeMinor: Float = getTouchMinor(pointerIndex) / overlayParams.scaleFactor
     val nativeMajor: Float = getTouchMajor(pointerIndex) / overlayParams.scaleFactor
+    var nativeOrientation: Float = getOrientation(pointerIndex)
+    if (SUPPORTED_ROTATIONS.contains(overlayParams.rotation)) {
+        nativeOrientation = toRadVerticalFromRotated(nativeOrientation.toDouble()).toFloat()
+    }
     return NormalizedTouchData(
         pointerId = getPointerId(pointerIndex),
         x = nativeX,
         y = nativeY,
         minor = nativeMinor,
         major = nativeMajor,
-        // TODO(b/259311354): touch orientation should be reported relative to Surface.ROTATION_O.
-        orientation = getOrientation(pointerIndex),
+        orientation = nativeOrientation,
         time = eventTime,
         gestureStart = downTime,
     )
 }
 
+private fun toRadVerticalFromRotated(rad: Double): Double {
+    val piBound = ((rad % Math.PI) + Math.PI / 2) % Math.PI
+    return if (piBound < Math.PI / 2.0) piBound else piBound - Math.PI
+}
+
 /**
  * Returns the [MotionEvent.getRawX] and [MotionEvent.getRawY] of the given pointer as if the device
  * is in the [Surface.ROTATION_0] orientation.
@@ -152,7 +160,7 @@
 ): PointF {
     val touchPoint = PointF(getRawX(pointerIndex), getRawY(pointerIndex))
     val rot = overlayParams.rotation
-    if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
+    if (SUPPORTED_ROTATIONS.contains(rot)) {
         RotationUtils.rotatePointF(
             touchPoint,
             RotationUtils.deltaRotation(rot, Surface.ROTATION_0),
diff --git a/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt b/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
index 58d40d3..4227a7a 100644
--- a/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
@@ -25,13 +25,13 @@
 import android.content.pm.PackageManager
 import android.content.pm.ResolveInfo
 import android.os.RemoteException
-import android.os.UserHandle
 import android.util.Log
 import android.view.WindowManager
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.ActivityIntentHelper
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.settings.UserTracker
 import com.android.systemui.shared.system.ActivityManagerKt.isInForeground
 import com.android.systemui.statusbar.StatusBarState
 import com.android.systemui.statusbar.phone.CentralSurfaces
@@ -55,6 +55,7 @@
     private val cameraIntents: CameraIntentsWrapper,
     private val contentResolver: ContentResolver,
     @Main private val uiExecutor: Executor,
+    private val userTracker: UserTracker
 ) {
     /**
      * Whether the camera application can be launched for the camera launch gesture.
@@ -111,7 +112,7 @@
                         Intent.FLAG_ACTIVITY_NEW_TASK,
                         null,
                         activityOptions.toBundle(),
-                        UserHandle.CURRENT.identifier,
+                        userTracker.userId,
                     )
                 } catch (e: RemoteException) {
                     Log.w(
diff --git a/packages/SystemUI/src/com/android/systemui/camera/CameraIntents.kt b/packages/SystemUI/src/com/android/systemui/camera/CameraIntents.kt
index 867faf9..cc43e7e 100644
--- a/packages/SystemUI/src/com/android/systemui/camera/CameraIntents.kt
+++ b/packages/SystemUI/src/com/android/systemui/camera/CameraIntents.kt
@@ -20,15 +20,13 @@
 import android.content.Intent
 import android.provider.MediaStore
 import android.text.TextUtils
-
 import com.android.systemui.R
 
 class CameraIntents {
     companion object {
-        val DEFAULT_SECURE_CAMERA_INTENT_ACTION =
-                MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE
-        val DEFAULT_INSECURE_CAMERA_INTENT_ACTION =
-                MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA
+        val DEFAULT_SECURE_CAMERA_INTENT_ACTION = MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE
+        val DEFAULT_INSECURE_CAMERA_INTENT_ACTION = MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA
+        private val VIDEO_CAMERA_INTENT_ACTION = MediaStore.INTENT_ACTION_VIDEO_CAMERA
         const val EXTRA_LAUNCH_SOURCE = "com.android.systemui.camera_launch_source"
 
         @JvmStatic
@@ -44,18 +42,14 @@
         @JvmStatic
         fun getInsecureCameraIntent(context: Context): Intent {
             val intent = Intent(DEFAULT_INSECURE_CAMERA_INTENT_ACTION)
-            getOverrideCameraPackage(context)?.let {
-                intent.setPackage(it)
-            }
+            getOverrideCameraPackage(context)?.let { intent.setPackage(it) }
             return intent
         }
 
         @JvmStatic
         fun getSecureCameraIntent(context: Context): Intent {
             val intent = Intent(DEFAULT_SECURE_CAMERA_INTENT_ACTION)
-            getOverrideCameraPackage(context)?.let {
-                intent.setPackage(it)
-            }
+            getOverrideCameraPackage(context)?.let { intent.setPackage(it) }
             return intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
         }
 
@@ -68,5 +62,11 @@
         fun isInsecureCameraIntent(intent: Intent?): Boolean {
             return intent?.getAction()?.equals(DEFAULT_INSECURE_CAMERA_INTENT_ACTION) ?: false
         }
+
+        /** Returns an [Intent] that can be used to start the camera in video mode. */
+        @JvmStatic
+        fun getVideoCameraIntent(): Intent {
+            return Intent(VIDEO_CAMERA_INTENT_ACTION)
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/camera/CameraIntentsWrapper.kt b/packages/SystemUI/src/com/android/systemui/camera/CameraIntentsWrapper.kt
index cf02f8f..a434617 100644
--- a/packages/SystemUI/src/com/android/systemui/camera/CameraIntentsWrapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/camera/CameraIntentsWrapper.kt
@@ -21,7 +21,9 @@
 import javax.inject.Inject
 
 /** Injectable wrapper around [CameraIntents]. */
-class CameraIntentsWrapper @Inject constructor(
+class CameraIntentsWrapper
+@Inject
+constructor(
     private val context: Context,
 ) {
 
@@ -40,4 +42,9 @@
     fun getInsecureCameraIntent(): Intent {
         return CameraIntents.getInsecureCameraIntent(context)
     }
+
+    /** Returns an [Intent] that can be used to start the camera in video mode. */
+    fun getVideoCameraIntent(): Intent {
+        return CameraIntents.getVideoCameraIntent()
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt b/packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt
index 1454210..fb0c0a6 100644
--- a/packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt
+++ b/packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt
@@ -20,7 +20,7 @@
 import android.content.res.Configuration
 import android.graphics.PixelFormat
 import android.os.SystemProperties
-import android.util.DisplayMetrics
+import android.view.Surface
 import android.view.View
 import android.view.WindowManager
 import com.android.internal.annotations.VisibleForTesting
@@ -36,7 +36,6 @@
 import com.android.systemui.statusbar.commandline.CommandRegistry
 import com.android.systemui.statusbar.policy.BatteryController
 import com.android.systemui.statusbar.policy.ConfigurationController
-import com.android.systemui.util.leak.RotationUtils
 import com.android.systemui.util.time.SystemClock
 import java.io.PrintWriter
 import javax.inject.Inject
@@ -172,30 +171,28 @@
     }
 
     private fun layoutRipple() {
-        val displayMetrics = DisplayMetrics()
-        context.display.getRealMetrics(displayMetrics)
-        val width = displayMetrics.widthPixels
-        val height = displayMetrics.heightPixels
+        val bounds = windowManager.currentWindowMetrics.bounds
+        val width = bounds.width()
+        val height = bounds.height()
         val maxDiameter = Integer.max(width, height) * 2f
         rippleView.setMaxSize(maxDiameter, maxDiameter)
-        when (RotationUtils.getExactRotation(context)) {
-            RotationUtils.ROTATION_LANDSCAPE -> {
+        when (context.display.rotation) {
+            Surface.ROTATION_0 -> {
+                rippleView.setCenter(
+                        width * normalizedPortPosX, height * normalizedPortPosY)
+            }
+            Surface.ROTATION_90 -> {
                 rippleView.setCenter(
                         width * normalizedPortPosY, height * (1 - normalizedPortPosX))
             }
-            RotationUtils.ROTATION_UPSIDE_DOWN -> {
+            Surface.ROTATION_180 -> {
                 rippleView.setCenter(
                         width * (1 - normalizedPortPosX), height * (1 - normalizedPortPosY))
             }
-            RotationUtils.ROTATION_SEASCAPE -> {
+            Surface.ROTATION_270 -> {
                 rippleView.setCenter(
                         width * (1 - normalizedPortPosY), height * normalizedPortPosX)
             }
-            else -> {
-                // ROTATION_NONE
-                rippleView.setCenter(
-                        width * normalizedPortPosX, height * normalizedPortPosY)
-            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
index e8e1f2e..e9ac840 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
@@ -176,7 +176,8 @@
     private @Classifier.InteractionType int mPriorInteractionType = Classifier.GENERIC;
 
     @Inject
-    public BrightLineFalsingManager(FalsingDataProvider falsingDataProvider,
+    public BrightLineFalsingManager(
+            FalsingDataProvider falsingDataProvider,
             MetricsLogger metricsLogger,
             @Named(BRIGHT_LINE_GESTURE_CLASSIFERS) Set<FalsingClassifier> classifiers,
             SingleTapClassifier singleTapClassifier, LongTapClassifier longTapClassifier,
@@ -399,7 +400,9 @@
                 || mDataProvider.isJustUnlockedWithFace()
                 || mDataProvider.isDocked()
                 || mAccessibilityManager.isTouchExplorationEnabled()
-                || mDataProvider.isA11yAction();
+                || mDataProvider.isA11yAction()
+                || (mFeatureFlags.isEnabled(Flags.FALSING_OFF_FOR_UNFOLDED)
+                    && !mDataProvider.isFolded());
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
index 09ebeea..5f347c1 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.classifier;
 
+import android.hardware.devicestate.DeviceStateManager.FoldStateListener;
 import android.util.DisplayMetrics;
 import android.view.MotionEvent;
 import android.view.MotionEvent.PointerCoords;
@@ -42,6 +43,7 @@
     private final int mWidthPixels;
     private final int mHeightPixels;
     private BatteryController mBatteryController;
+    private final FoldStateListener mFoldStateListener;
     private final DockManager mDockManager;
     private final float mXdpi;
     private final float mYdpi;
@@ -65,12 +67,14 @@
     public FalsingDataProvider(
             DisplayMetrics displayMetrics,
             BatteryController batteryController,
+            FoldStateListener foldStateListener,
             DockManager dockManager) {
         mXdpi = displayMetrics.xdpi;
         mYdpi = displayMetrics.ydpi;
         mWidthPixels = displayMetrics.widthPixels;
         mHeightPixels = displayMetrics.heightPixels;
         mBatteryController = batteryController;
+        mFoldStateListener = foldStateListener;
         mDockManager = dockManager;
 
         FalsingClassifier.logInfo("xdpi, ydpi: " + getXdpi() + ", " + getYdpi());
@@ -376,6 +380,10 @@
         return mBatteryController.isWirelessCharging() || mDockManager.isDocked();
     }
 
+    public boolean isFolded() {
+        return Boolean.TRUE.equals(mFoldStateListener.getFolded());
+    }
+
     /** Implement to be alerted abotu the beginning and ending of falsing tracking. */
     public interface SessionListener {
         /** Called when the lock screen is shown and falsing-tracking begins. */
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/TypeClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/TypeClassifier.java
index f576a5a..d8d2c98 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/TypeClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/TypeClassifier.java
@@ -69,6 +69,8 @@
                 // A more sophisticated thing to do here would be to look at the size of the
                 // vertical change relative to the screen size. _Some_ amount of vertical
                 // change should be expected.
+                wrongDirection = vertical;
+                break;
             case NOTIFICATION_DISMISS:
                 wrongDirection = vertical;
                 break;
diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/view/LaunchableImageView.kt b/packages/SystemUI/src/com/android/systemui/common/ui/view/LaunchableImageView.kt
index f95a8ee..7bbfec7 100644
--- a/packages/SystemUI/src/com/android/systemui/common/ui/view/LaunchableImageView.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/ui/view/LaunchableImageView.kt
@@ -28,7 +28,6 @@
         LaunchableViewDelegate(
             this,
             superSetVisibility = { super.setVisibility(it) },
-            superSetTransitionVisibility = { super.setTransitionVisibility(it) },
         )
 
     constructor(context: Context?) : super(context)
@@ -53,8 +52,4 @@
     override fun setVisibility(visibility: Int) {
         delegate.setVisibility(visibility)
     }
-
-    override fun setTransitionVisibility(visibility: Int) {
-        delegate.setTransitionVisibility(visibility)
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/view/LaunchableLinearLayout.kt b/packages/SystemUI/src/com/android/systemui/common/ui/view/LaunchableLinearLayout.kt
index c27b82a..ddde628 100644
--- a/packages/SystemUI/src/com/android/systemui/common/ui/view/LaunchableLinearLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/ui/view/LaunchableLinearLayout.kt
@@ -28,7 +28,6 @@
         LaunchableViewDelegate(
             this,
             superSetVisibility = { super.setVisibility(it) },
-            superSetTransitionVisibility = { super.setTransitionVisibility(it) },
         )
 
     constructor(context: Context?) : super(context)
@@ -53,8 +52,4 @@
     override fun setVisibility(visibility: Int) {
         delegate.setVisibility(visibility)
     }
-
-    override fun setTransitionVisibility(visibility: Int) {
-        delegate.setTransitionVisibility(visibility)
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/compose/BaseComposeFacade.kt b/packages/SystemUI/src/com/android/systemui/compose/BaseComposeFacade.kt
index e5ec727..c0f8549 100644
--- a/packages/SystemUI/src/com/android/systemui/compose/BaseComposeFacade.kt
+++ b/packages/SystemUI/src/com/android/systemui/compose/BaseComposeFacade.kt
@@ -17,8 +17,12 @@
 
 package com.android.systemui.compose
 
+import android.content.Context
+import android.view.View
 import androidx.activity.ComponentActivity
+import androidx.lifecycle.LifecycleOwner
 import com.android.systemui.people.ui.viewmodel.PeopleViewModel
+import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
 
 /**
  * A facade to interact with Compose, when it is available.
@@ -35,10 +39,22 @@
      */
     fun isComposeAvailable(): Boolean
 
+    /**
+     * Return the [ComposeInitializer] to make Compose usable in windows outside normal activities.
+     */
+    fun composeInitializer(): ComposeInitializer
+
     /** Bind the content of [activity] to [viewModel]. */
     fun setPeopleSpaceActivityContent(
         activity: ComponentActivity,
         viewModel: PeopleViewModel,
         onResult: (PeopleViewModel.Result) -> Unit,
     )
+
+    /** Create a [View] to represent [viewModel] on screen. */
+    fun createFooterActionsView(
+        context: Context,
+        viewModel: FooterActionsViewModel,
+        qsVisibilityLifecycleOwner: LifecycleOwner,
+    ): View
 }
diff --git a/packages/SystemUI/src/com/android/systemui/compose/ComposeInitializer.kt b/packages/SystemUI/src/com/android/systemui/compose/ComposeInitializer.kt
new file mode 100644
index 0000000..90dc3a0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/compose/ComposeInitializer.kt
@@ -0,0 +1,48 @@
+/*
+ * 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.compose
+
+import android.view.View
+
+/**
+ * An initializer to use Compose outside of an Activity, e.g. inside a window added directly using
+ * [android.view.WindowManager.addView] (like the shade or status bar) or inside a dialog.
+ *
+ * Example:
+ * ```
+ *    windowManager.addView(MyWindowRootView(context), /* layoutParams */)
+ *
+ *    class MyWindowRootView(context: Context) : FrameLayout(context) {
+ *        override fun onAttachedToWindow() {
+ *            super.onAttachedToWindow()
+ *            ComposeInitializer.onAttachedToWindow(this)
+ *        }
+ *
+ *        override fun onDetachedFromWindow() {
+ *            super.onDetachedFromWindow()
+ *            ComposeInitializer.onDetachedFromWindow(this)
+ *        }
+ *    }
+ * ```
+ */
+interface ComposeInitializer {
+    /** Function to be called on your window root view's [View.onAttachedToWindow] function. */
+    fun onAttachedToWindow(root: View)
+
+    /** Function to be called on your window root view's [View.onDetachedFromWindow] function. */
+    fun onDetachedFromWindow(root: View)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingController.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingController.kt
index eed5531..9b2a224 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingController.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingController.kt
@@ -51,13 +51,22 @@
     fun bindAndLoadSuggested(component: ComponentName, callback: LoadCallback)
 
     /**
-     * Request to bind to the given service.
+     * Request to bind to the given service. This should only be used for services using the full
+     * [ControlsProviderService] API, where SystemUI renders the devices' UI.
      *
      * @param component The [ComponentName] of the service to bind
      */
     fun bindService(component: ComponentName)
 
     /**
+     * Bind to a service that provides a Device Controls panel (embedded activity). This will allow
+     * the app to remain "warm", and reduce latency.
+     *
+     * @param component The [ComponentName] of the [ControlsProviderService] to bind.
+     */
+    fun bindServiceForPanel(component: ComponentName)
+
+    /**
      * Send a subscribe message to retrieve status of a set of controls.
      *
      * @param structureInfo structure containing the controls to update
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt
index 2f0fd99..3d6d335 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt
@@ -170,6 +170,10 @@
         retrieveLifecycleManager(component).bindService()
     }
 
+    override fun bindServiceForPanel(component: ComponentName) {
+        retrieveLifecycleManager(component).bindServiceForPanel()
+    }
+
     override fun changeUser(newUser: UserHandle) {
         if (newUser == currentUser) return
 
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt
index 2f49c3f..f29f6d0 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt
@@ -189,6 +189,14 @@
     fun getPreferredSelection(): SelectedItem
 
     /**
+     * Bind to a service that provides a Device Controls panel (embedded activity). This will allow
+     * the app to remain "warm", and reduce latency.
+     *
+     * @param component The [ComponentName] of the [ControlsProviderService] to bind.
+     */
+    fun bindComponentForPanel(componentName: ComponentName)
+
+    /**
      * Interface for structure to pass data to [ControlsFavoritingActivity].
      */
     interface LoadData {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt
index 80c5f66..111fcbb 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt
@@ -477,6 +477,10 @@
         bindingController.unsubscribe()
     }
 
+    override fun bindComponentForPanel(componentName: ComponentName) {
+        bindingController.bindServiceForPanel(componentName)
+    }
+
     override fun addFavorite(
         componentName: ComponentName,
         structureName: CharSequence,
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
index 5b38e5b..72c3a94 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
@@ -78,6 +78,10 @@
         private const val DEBUG = true
         private val BIND_FLAGS = Context.BIND_AUTO_CREATE or Context.BIND_FOREGROUND_SERVICE or
             Context.BIND_NOT_PERCEPTIBLE
+        // Use BIND_NOT_PERCEPTIBLE so it will be at lower priority from SystemUI.
+        // However, don't use WAIVE_PRIORITY, as by itself, it will kill the app
+        // once the Task is finished in the device controls panel.
+        private val BIND_FLAGS_PANEL = Context.BIND_AUTO_CREATE or Context.BIND_NOT_PERCEPTIBLE
     }
 
     private val intent = Intent().apply {
@@ -87,18 +91,19 @@
         })
     }
 
-    private fun bindService(bind: Boolean) {
+    private fun bindService(bind: Boolean, forPanel: Boolean = false) {
         executor.execute {
             requiresBound = bind
             if (bind) {
-                if (bindTryCount != MAX_BIND_RETRIES) {
+                if (bindTryCount != MAX_BIND_RETRIES && wrapper == null) {
                     if (DEBUG) {
                         Log.d(TAG, "Binding service $intent")
                     }
                     bindTryCount++
                     try {
+                        val flags = if (forPanel) BIND_FLAGS_PANEL else BIND_FLAGS
                         val bound = context
-                            .bindServiceAsUser(intent, serviceConnection, BIND_FLAGS, user)
+                                .bindServiceAsUser(intent, serviceConnection, flags, user)
                         if (!bound) {
                             context.unbindService(serviceConnection)
                         }
@@ -279,6 +284,10 @@
         bindService(true)
     }
 
+    fun bindServiceForPanel() {
+        bindService(bind = true, forPanel = true)
+    }
+
     /**
      * Request unbind from the service.
      */
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 1e3e5cd..6289788 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
@@ -232,6 +232,8 @@
                     ControlKey(selected.structure.componentName, it.ci.controlId)
                 }
                 controlsController.get().subscribeToFavorites(selected.structure)
+            } else {
+                controlsController.get().bindComponentForPanel(selected.componentName)
             }
             listingCallback = createCallback(::showControlsView)
         }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
index 2260e35..4bb5d04 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
@@ -636,6 +636,7 @@
 
     @Provides
     @Singleton
+    @Nullable
     static BluetoothAdapter provideBluetoothAdapter(BluetoothManager bluetoothManager) {
         return bluetoothManager.getAdapter();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java
index b30e0c2..a431a59 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui.dagger;
 
-import com.android.systemui.keyguard.KeyguardQuickAffordanceProvider;
+import com.android.systemui.keyguard.CustomizationProvider;
 import com.android.systemui.statusbar.NotificationInsetsModule;
 import com.android.systemui.statusbar.QsFrameTranslateModule;
 
@@ -49,5 +49,5 @@
     /**
      * Member injection into the supplied argument.
      */
-    void inject(KeyguardQuickAffordanceProvider keyguardQuickAffordanceProvider);
+    void inject(CustomizationProvider customizationProvider);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
index 8012dea..8e9992f 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
@@ -31,6 +31,7 @@
 import com.android.systemui.keyboard.KeyboardUI
 import com.android.systemui.keyguard.KeyguardViewMediator
 import com.android.systemui.log.SessionTracker
+import com.android.systemui.media.dialog.MediaOutputSwitcherDialogUI
 import com.android.systemui.media.RingtonePlayer
 import com.android.systemui.media.taptotransfer.MediaTttCommandLineHelper
 import com.android.systemui.media.taptotransfer.receiver.MediaTttChipControllerReceiver
@@ -217,6 +218,12 @@
     @ClassKey(ToastUI::class)
     abstract fun bindToastUI(service: ToastUI): CoreStartable
 
+    /** Inject into MediaOutputSwitcherDialogUI.  */
+    @Binds
+    @IntoMap
+    @ClassKey(MediaOutputSwitcherDialogUI::class)
+    abstract fun MediaOutputSwitcherDialogUI(sysui: MediaOutputSwitcherDialogUI): CoreStartable
+
     /** Inject into VolumeUI.  */
     @Binds
     @IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index b8e6673..2d0dfa1 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -31,6 +31,7 @@
 import com.android.systemui.appops.dagger.AppOpsModule;
 import com.android.systemui.assist.AssistModule;
 import com.android.systemui.biometrics.AlternateUdfpsTouchProvider;
+import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider;
 import com.android.systemui.biometrics.UdfpsDisplayModeProvider;
 import com.android.systemui.biometrics.dagger.BiometricsModule;
 import com.android.systemui.biometrics.dagger.UdfpsModule;
@@ -53,6 +54,7 @@
 import com.android.systemui.navigationbar.NavigationBarComponent;
 import com.android.systemui.notetask.NoteTaskModule;
 import com.android.systemui.people.PeopleModule;
+import com.android.systemui.plugins.BcSmartspaceConfigPlugin;
 import com.android.systemui.plugins.BcSmartspaceDataPlugin;
 import com.android.systemui.privacy.PrivacyModule;
 import com.android.systemui.qs.FgsManagerController;
@@ -210,6 +212,9 @@
     abstract BcSmartspaceDataPlugin optionalBcSmartspaceDataPlugin();
 
     @BindsOptionalOf
+    abstract BcSmartspaceConfigPlugin optionalBcSmartspaceConfigPlugin();
+
+    @BindsOptionalOf
     abstract Recents optionalRecents();
 
     @BindsOptionalOf
@@ -221,6 +226,9 @@
     @BindsOptionalOf
     abstract AlternateUdfpsTouchProvider optionalUdfpsTouchProvider();
 
+    @BindsOptionalOf
+    abstract FingerprintInteractiveToAuthProvider optionalFingerprintInteractiveToAuthProvider();
+
     @SysUISingleton
     @Binds
     abstract SystemClock bindSystemClock(SystemClockImpl systemClock);
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java b/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java
index 2a3d67f..c331164 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java
@@ -17,12 +17,12 @@
 package com.android.systemui.doze;
 
 import android.hardware.display.AmbientDisplayConfiguration;
-import android.os.UserHandle;
 import android.util.Log;
 
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.doze.DozeMachine.State;
 import com.android.systemui.doze.dagger.DozeScope;
+import com.android.systemui.settings.UserTracker;
 
 import java.io.PrintWriter;
 
@@ -40,14 +40,17 @@
     private final AmbientDisplayConfiguration mConfig;
     private DozeMachine mMachine;
     private final DockManager mDockManager;
+    private final UserTracker mUserTracker;
     private final DockEventListener mDockEventListener;
 
     private int mDockState = DockManager.STATE_NONE;
 
     @Inject
-    DozeDockHandler(AmbientDisplayConfiguration config, DockManager dockManager) {
+    DozeDockHandler(AmbientDisplayConfiguration config, DockManager dockManager,
+            UserTracker userTracker) {
         mConfig = config;
         mDockManager = dockManager;
+        mUserTracker = userTracker;
         mDockEventListener = new DockEventListener();
     }
 
@@ -100,7 +103,7 @@
                     nextState = State.DOZE_AOD_DOCKED;
                     break;
                 case DockManager.STATE_NONE:
-                    nextState = mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT) ? State.DOZE_AOD
+                    nextState = mConfig.alwaysOnEnabled(mUserTracker.getUserId()) ? State.DOZE_AOD
                             : State.DOZE;
                     break;
                 case DockManager.STATE_DOCKED_HIDE:
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
index 96c35d4..fc3263f 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
@@ -23,7 +23,6 @@
 import android.content.res.Configuration;
 import android.hardware.display.AmbientDisplayConfiguration;
 import android.os.Trace;
-import android.os.UserHandle;
 import android.util.Log;
 import android.view.Display;
 
@@ -33,6 +32,7 @@
 import com.android.systemui.doze.dagger.WrappedService;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.keyguard.WakefulnessLifecycle.Wakefulness;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.util.Assert;
 import com.android.systemui.util.wakelock.WakeLock;
@@ -149,6 +149,7 @@
     private final DozeHost mDozeHost;
     private final DockManager mDockManager;
     private final Part[] mParts;
+    private final UserTracker mUserTracker;
 
     private final ArrayList<State> mQueuedRequests = new ArrayList<>();
     private State mState = State.UNINITIALIZED;
@@ -161,7 +162,7 @@
             AmbientDisplayConfiguration ambientDisplayConfig,
             WakeLock wakeLock, WakefulnessLifecycle wakefulnessLifecycle,
             DozeLog dozeLog, DockManager dockManager,
-            DozeHost dozeHost, Part[] parts) {
+            DozeHost dozeHost, Part[] parts, UserTracker userTracker) {
         mDozeService = service;
         mAmbientDisplayConfig = ambientDisplayConfig;
         mWakefulnessLifecycle = wakefulnessLifecycle;
@@ -170,6 +171,7 @@
         mDockManager = dockManager;
         mDozeHost = dozeHost;
         mParts = parts;
+        mUserTracker = userTracker;
         for (Part part : parts) {
             part.setDozeMachine(this);
         }
@@ -429,7 +431,7 @@
                     nextState = State.FINISH;
                 } else if (mDockManager.isDocked()) {
                     nextState = mDockManager.isHidden() ? State.DOZE : State.DOZE_AOD_DOCKED;
-                } else if (mAmbientDisplayConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)) {
+                } else if (mAmbientDisplayConfig.alwaysOnEnabled(mUserTracker.getUserId())) {
                     nextState = State.DOZE_AOD;
                 } else {
                     nextState = State.DOZE;
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
index 937884c..4cade77 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
@@ -43,6 +43,7 @@
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.statusbar.policy.DevicePostureController;
 import com.android.systemui.util.sensors.AsyncSensorManager;
+import com.android.systemui.util.settings.SystemSettings;
 
 import java.io.PrintWriter;
 import java.util.Objects;
@@ -78,6 +79,7 @@
     private final DozeParameters mDozeParameters;
     private final DevicePostureController mDevicePostureController;
     private final DozeLog mDozeLog;
+    private final SystemSettings mSystemSettings;
     private final int[] mSensorToBrightness;
     private final int[] mSensorToScrimOpacity;
     private final int mScreenBrightnessDim;
@@ -110,7 +112,8 @@
             WakefulnessLifecycle wakefulnessLifecycle,
             DozeParameters dozeParameters,
             DevicePostureController devicePostureController,
-            DozeLog dozeLog) {
+            DozeLog dozeLog,
+            SystemSettings systemSettings) {
         mContext = context;
         mDozeService = service;
         mSensorManager = sensorManager;
@@ -122,6 +125,7 @@
         mDozeHost = host;
         mHandler = handler;
         mDozeLog = dozeLog;
+        mSystemSettings = systemSettings;
 
         mScreenBrightnessMinimumDimAmountFloat = context.getResources().getFloat(
                 R.dimen.config_screenBrightnessMinimumDimAmountFloat);
@@ -257,7 +261,7 @@
     }
     //TODO: brightnessfloat change usages to float.
     private int clampToUserSetting(int brightness) {
-        int userSetting = Settings.System.getIntForUser(mContext.getContentResolver(),
+        int userSetting = mSystemSettings.getIntForUser(
                 Settings.System.SCREEN_BRIGHTNESS, Integer.MAX_VALUE,
                 UserHandle.USER_CURRENT);
         return Math.min(brightness, userSetting);
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index 37183e8..e3c568a9 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -116,6 +116,7 @@
     private boolean mListening;
     private boolean mListeningTouchScreenSensors;
     private boolean mListeningProxSensors;
+    private boolean mListeningAodOnlySensors;
     private boolean mUdfpsEnrolled;
 
     @DevicePostureController.DevicePostureInt
@@ -184,7 +185,8 @@
                         dozeParameters.getPulseOnSigMotion(),
                         DozeLog.PULSE_REASON_SENSOR_SIGMOTION,
                         false /* touchCoords */,
-                        false /* touchscreen */),
+                        false /* touchscreen */
+                ),
                 new TriggerSensor(
                         mSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE),
                         Settings.Secure.DOZE_PICK_UP_GESTURE,
@@ -195,14 +197,17 @@
                         false /* touchscreen */,
                         false /* ignoresSetting */,
                         false /* requires prox */,
-                        true /* immediatelyReRegister */),
+                        true /* immediatelyReRegister */,
+                        false /* requiresAod */
+                ),
                 new TriggerSensor(
                         findSensor(config.doubleTapSensorType()),
                         Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
                         true /* configured */,
                         DozeLog.REASON_SENSOR_DOUBLE_TAP,
                         dozeParameters.doubleTapReportsTouchCoordinates(),
-                        true /* touchscreen */),
+                        true /* touchscreen */
+                ),
                 new TriggerSensor(
                         findSensors(config.tapSensorTypeMapping()),
                         Settings.Secure.DOZE_TAP_SCREEN_GESTURE,
@@ -214,7 +219,9 @@
                         false /* ignoresSetting */,
                         dozeParameters.singleTapUsesProx(mDevicePosture) /* requiresProx */,
                         true /* immediatelyReRegister */,
-                        mDevicePosture),
+                        mDevicePosture,
+                        false
+                ),
                 new TriggerSensor(
                         findSensor(config.longPressSensorType()),
                         Settings.Secure.DOZE_PULSE_ON_LONG_PRESS,
@@ -225,7 +232,9 @@
                         true /* touchscreen */,
                         false /* ignoresSetting */,
                         dozeParameters.longPressUsesProx() /* requiresProx */,
-                        true /* immediatelyReRegister */),
+                        true /* immediatelyReRegister */,
+                        false /* requiresAod */
+                ),
                 new TriggerSensor(
                         findSensor(config.udfpsLongPressSensorType()),
                         "doze_pulse_on_auth",
@@ -236,15 +245,18 @@
                         true /* touchscreen */,
                         false /* ignoresSetting */,
                         dozeParameters.longPressUsesProx(),
-                        false /* immediatelyReRegister */),
+                        false /* immediatelyReRegister */,
+                        true /* requiresAod */
+                ),
                 new PluginSensor(
                         new SensorManagerPlugin.Sensor(TYPE_WAKE_DISPLAY),
                         Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE,
                         mConfig.wakeScreenGestureAvailable()
-                          && mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT),
+                          && mConfig.alwaysOnEnabled(mUserTracker.getUserId()),
                         DozeLog.REASON_SENSOR_WAKE_UP_PRESENCE,
                         false /* reports touch coordinates */,
-                        false /* touchscreen */),
+                        false /* touchscreen */
+                ),
                 new PluginSensor(
                         new SensorManagerPlugin.Sensor(TYPE_WAKE_LOCK_SCREEN),
                         Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE,
@@ -252,7 +264,8 @@
                         DozeLog.PULSE_REASON_SENSOR_WAKE_REACH,
                         false /* reports touch coordinates */,
                         false /* touchscreen */,
-                        mConfig.getWakeLockScreenDebounce()),
+                        mConfig.getWakeLockScreenDebounce()
+                ),
                 new TriggerSensor(
                         findSensor(config.quickPickupSensorType()),
                         Settings.Secure.DOZE_QUICK_PICKUP_GESTURE,
@@ -263,7 +276,9 @@
                         false /* requiresTouchscreen */,
                         false /* ignoresSetting */,
                         false /* requiresProx */,
-                        true /* immediatelyReRegister */),
+                        true /* immediatelyReRegister */,
+                        false /* requiresAod */
+                ),
         };
         setProxListening(false);  // Don't immediately start listening when we register.
         mProximitySensor.register(
@@ -278,7 +293,7 @@
 
     private boolean udfpsLongPressConfigured() {
         return mUdfpsEnrolled
-                && (mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT) || mScreenOffUdfpsEnabled);
+                && (mConfig.alwaysOnEnabled(mUserTracker.getUserId()) || mScreenOffUdfpsEnabled);
     }
 
     private boolean quickPickUpConfigured() {
@@ -357,29 +372,36 @@
     /**
      * If sensors should be registered and sending signals.
      */
-    public void setListening(boolean listen, boolean includeTouchScreenSensors) {
-        if (mListening == listen && mListeningTouchScreenSensors == includeTouchScreenSensors) {
+    public void setListening(boolean listen, boolean includeTouchScreenSensors,
+            boolean includeAodOnlySensors) {
+        if (mListening == listen && mListeningTouchScreenSensors == includeTouchScreenSensors
+                && mListeningAodOnlySensors == includeAodOnlySensors) {
             return;
         }
         mListening = listen;
         mListeningTouchScreenSensors = includeTouchScreenSensors;
+        mListeningAodOnlySensors = includeAodOnlySensors;
         updateListening();
     }
 
     /**
      * If sensors should be registered and sending signals.
      */
-    public void setListening(boolean listen, boolean includeTouchScreenSensors,
-            boolean lowPowerStateOrOff) {
+    public void setListeningWithPowerState(boolean listen, boolean includeTouchScreenSensors,
+            boolean includeAodRequiringSensors, boolean lowPowerStateOrOff) {
         final boolean shouldRegisterProxSensors =
                 !mSelectivelyRegisterProxSensors || lowPowerStateOrOff;
-        if (mListening == listen && mListeningTouchScreenSensors == includeTouchScreenSensors
-                && mListeningProxSensors == shouldRegisterProxSensors) {
+        if (mListening == listen
+                && mListeningTouchScreenSensors == includeTouchScreenSensors
+                && mListeningProxSensors == shouldRegisterProxSensors
+                && mListeningAodOnlySensors == includeAodRequiringSensors
+        ) {
             return;
         }
         mListening = listen;
         mListeningTouchScreenSensors = includeTouchScreenSensors;
         mListeningProxSensors = shouldRegisterProxSensors;
+        mListeningAodOnlySensors = includeAodRequiringSensors;
         updateListening();
     }
 
@@ -391,7 +413,8 @@
         for (TriggerSensor s : mTriggerSensors) {
             boolean listen = mListening
                     && (!s.mRequiresTouchscreen || mListeningTouchScreenSensors)
-                    && (!s.mRequiresProx || mListeningProxSensors);
+                    && (!s.mRequiresProx || mListeningProxSensors)
+                    && (!s.mRequiresAod || mListeningAodOnlySensors);
             s.setListening(listen);
             if (listen) {
                 anyListening = true;
@@ -499,6 +522,9 @@
         private final boolean mRequiresTouchscreen;
         private final boolean mRequiresProx;
 
+        // Whether the sensor should only register if the device is in AOD
+        private final boolean mRequiresAod;
+
         // Whether to immediately re-register this sensor after the sensor is triggered.
         // If false, the sensor registration will be updated on the next AOD state transition.
         private final boolean mImmediatelyReRegister;
@@ -527,7 +553,8 @@
                     requiresTouchscreen,
                     false /* ignoresSetting */,
                     false /* requiresProx */,
-                    true /* immediatelyReRegister */
+                    true /* immediatelyReRegister */,
+                    false
             );
         }
 
@@ -541,7 +568,8 @@
                 boolean requiresTouchscreen,
                 boolean ignoresSetting,
                 boolean requiresProx,
-                boolean immediatelyReRegister
+                boolean immediatelyReRegister,
+                boolean requiresAod
         ) {
             this(
                     new Sensor[]{ sensor },
@@ -554,7 +582,8 @@
                     ignoresSetting,
                     requiresProx,
                     immediatelyReRegister,
-                    DevicePostureController.DEVICE_POSTURE_UNKNOWN
+                    DevicePostureController.DEVICE_POSTURE_UNKNOWN,
+                    requiresAod
             );
         }
 
@@ -569,7 +598,8 @@
                 boolean ignoresSetting,
                 boolean requiresProx,
                 boolean immediatelyReRegister,
-                @DevicePostureController.DevicePostureInt int posture
+                @DevicePostureController.DevicePostureInt int posture,
+                boolean requiresAod
         ) {
             mSensors = sensors;
             mSetting = setting;
@@ -580,6 +610,7 @@
             mRequiresTouchscreen = requiresTouchscreen;
             mIgnoresSetting = ignoresSetting;
             mRequiresProx = requiresProx;
+            mRequiresAod = requiresAod;
             mPosture = posture;
             mImmediatelyReRegister = immediatelyReRegister;
         }
@@ -663,13 +694,13 @@
         }
 
         protected boolean enabledBySetting() {
-            if (!mConfig.enabled(UserHandle.USER_CURRENT)) {
+            if (!mConfig.enabled(mUserTracker.getUserId())) {
                 return false;
             } else if (TextUtils.isEmpty(mSetting)) {
                 return true;
             }
             return mSecureSettings.getIntForUser(mSetting, mSettingDefault ? 1 : 0,
-                    UserHandle.USER_CURRENT) != 0;
+                    mUserTracker.getUserId()) != 0;
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSuppressor.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSuppressor.java
index e6d9865..de0bdd3 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSuppressor.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSuppressor.java
@@ -20,10 +20,10 @@
 
 import android.hardware.display.AmbientDisplayConfiguration;
 import android.os.PowerManager;
-import android.os.UserHandle;
 import android.text.TextUtils;
 
 import com.android.systemui.doze.dagger.DozeScope;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.phone.BiometricUnlockController;
 
 import java.io.PrintWriter;
@@ -57,6 +57,7 @@
     private final AmbientDisplayConfiguration mConfig;
     private final DozeLog mDozeLog;
     private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
+    private final UserTracker mUserTracker;
 
     private boolean mIsCarModeEnabled = false;
 
@@ -65,11 +66,13 @@
             DozeHost dozeHost,
             AmbientDisplayConfiguration config,
             DozeLog dozeLog,
-            Lazy<BiometricUnlockController> biometricUnlockControllerLazy) {
+            Lazy<BiometricUnlockController> biometricUnlockControllerLazy,
+            UserTracker userTracker) {
         mDozeHost = dozeHost;
         mConfig = config;
         mDozeLog = dozeLog;
         mBiometricUnlockControllerLazy = biometricUnlockControllerLazy;
+        mUserTracker = userTracker;
     }
 
     @Override
@@ -148,7 +151,7 @@
 
     private void handleCarModeExited() {
         mDozeLog.traceCarModeEnded();
-        mMachine.requestState(mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)
+        mMachine.requestState(mConfig.alwaysOnEnabled(mUserTracker.getUserId())
                 ? DozeMachine.State.DOZE_AOD : DozeMachine.State.DOZE);
     }
 
@@ -166,7 +169,7 @@
             if (mDozeHost.isPowerSaveActive()) {
                 nextState = DozeMachine.State.DOZE;
             } else if (mMachine.getState() == DozeMachine.State.DOZE
-                    && mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)) {
+                    && mConfig.alwaysOnEnabled(mUserTracker.getUserId())) {
                 nextState = DozeMachine.State.DOZE_AOD;
             }
 
@@ -181,7 +184,7 @@
             // handles suppression changes, while DozeMachine#transitionPolicy handles gating
             // transitions to DOZE_AOD
             final DozeMachine.State nextState;
-            if (mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT) && !suppressed) {
+            if (mConfig.alwaysOnEnabled(mUserTracker.getUserId()) && !suppressed) {
                 nextState = DozeMachine.State.DOZE_AOD;
             } else {
                 nextState = DozeMachine.State.DOZE;
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index b95c3f3..b709608 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -111,6 +111,7 @@
     private boolean mWantProxSensor;
     private boolean mWantTouchScreenSensors;
     private boolean mWantSensors;
+    private boolean mInAod;
 
     private final UserTracker.Callback mUserChangedCallback =
             new UserTracker.Callback() {
@@ -460,12 +461,19 @@
                 mDozeSensors.requestTemporaryDisable();
                 break;
             case DOZE:
-            case DOZE_AOD:
                 mAodInterruptRunnable = null;
-                mWantProxSensor = newState != DozeMachine.State.DOZE;
+                mWantProxSensor = false;
                 mWantSensors = true;
                 mWantTouchScreenSensors = true;
-                if (newState == DozeMachine.State.DOZE_AOD && !sWakeDisplaySensorState) {
+                mInAod = false;
+                break;
+            case DOZE_AOD:
+                mAodInterruptRunnable = null;
+                mWantProxSensor = true;
+                mWantSensors = true;
+                mWantTouchScreenSensors = true;
+                mInAod = true;
+                if (!sWakeDisplaySensorState) {
                     onWakeScreen(false, newState, DozeLog.REASON_SENSOR_WAKE_UP_PRESENCE);
                 }
                 break;
@@ -491,7 +499,7 @@
                 break;
             default:
         }
-        mDozeSensors.setListening(mWantSensors, mWantTouchScreenSensors);
+        mDozeSensors.setListening(mWantSensors, mWantTouchScreenSensors, mInAod);
     }
 
     private void registerCallbacks() {
@@ -510,11 +518,12 @@
 
     private void stopListeningToAllTriggers() {
         unregisterCallbacks();
-        mDozeSensors.setListening(false, false);
+        mDozeSensors.setListening(false, false, false);
         mDozeSensors.setProxListening(false);
         mWantSensors = false;
         mWantProxSensor = false;
         mWantTouchScreenSensors = false;
+        mInAod = false;
     }
 
     @Override
@@ -523,7 +532,8 @@
         final boolean lowPowerStateOrOff = state == Display.STATE_DOZE
                 || state == Display.STATE_DOZE_SUSPEND || state == Display.STATE_OFF;
         mDozeSensors.setProxListening(mWantProxSensor && lowPowerStateOrOff);
-        mDozeSensors.setListening(mWantSensors, mWantTouchScreenSensors, lowPowerStateOrOff);
+        mDozeSensors.setListeningWithPowerState(mWantSensors, mWantTouchScreenSensors,
+                mInAod, lowPowerStateOrOff);
 
         if (mAodInterruptRunnable != null && state == Display.STATE_ON) {
             mAodInterruptRunnable.run();
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
index 3106173..33c8379 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
@@ -38,6 +38,7 @@
 import com.android.systemui.dreams.dagger.DreamOverlayComponent;
 import com.android.systemui.dreams.dagger.DreamOverlayModule;
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor;
+import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback;
 import com.android.systemui.statusbar.BlurUtils;
 import com.android.systemui.statusbar.phone.KeyguardBouncer;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -85,8 +86,9 @@
 
     private boolean mBouncerAnimating;
 
-    private final KeyguardBouncer.PrimaryBouncerExpansionCallback mBouncerExpansionCallback =
-            new KeyguardBouncer.PrimaryBouncerExpansionCallback() {
+    private final PrimaryBouncerExpansionCallback
+            mBouncerExpansionCallback =
+            new PrimaryBouncerExpansionCallback() {
 
                 @Override
                 public void onStartingToShow() {
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
index a9a9cae..dd01be0 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
@@ -208,6 +208,13 @@
         });
     }
 
+    @Override
+    public void onEndDream() {
+        mExecutor.execute(() -> {
+            resetCurrentDreamOverlayLocked();
+        });
+    }
+
     private Lifecycle.State getCurrentStateLocked() {
         return mLifecycleRegistry.getCurrentState();
     }
@@ -291,6 +298,7 @@
         mDreamOverlayContainerViewController = null;
         mDreamOverlayTouchMonitor = null;
 
+        mWindow = null;
         mStarted = false;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java
index f244cb0..96bce4c 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
@@ -26,6 +27,9 @@
 import androidx.constraintlayout.widget.ConstraintLayout;
 
 import com.android.systemui.R;
+import com.android.systemui.shared.shadow.DoubleShadowIconDrawable;
+import com.android.systemui.shared.shadow.DoubleShadowTextHelper.ShadowInfo;
+import com.android.systemui.statusbar.AlphaOptimizedImageView;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -60,8 +64,15 @@
     public static final int STATUS_ICON_PRIORITY_MODE_ON = 6;
 
     private final Map<Integer, View> mStatusIcons = new HashMap<>();
+    private Context mContext;
     private ViewGroup mSystemStatusViewGroup;
     private ViewGroup mExtraSystemStatusViewGroup;
+    private ShadowInfo mKeyShadowInfo;
+    private ShadowInfo mAmbientShadowInfo;
+    private int mDrawableSize;
+    private int mDrawableInsetSize;
+    private static final float KEY_SHADOW_ALPHA = 0.35f;
+    private static final float AMBIENT_SHADOW_ALPHA = 0.4f;
 
     public DreamOverlayStatusBarView(Context context) {
         this(context, null);
@@ -73,6 +84,7 @@
 
     public DreamOverlayStatusBarView(Context context, AttributeSet attrs, int defStyleAttr) {
         this(context, attrs, defStyleAttr, 0);
+        mContext = context;
     }
 
     public DreamOverlayStatusBarView(
@@ -80,14 +92,36 @@
         super(context, attrs, defStyleAttr, defStyleRes);
     }
 
+
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
 
+        mKeyShadowInfo = createShadowInfo(
+            R.dimen.dream_overlay_status_bar_key_text_shadow_radius,
+            R.dimen.dream_overlay_status_bar_key_text_shadow_dx,
+            R.dimen.dream_overlay_status_bar_key_text_shadow_dy,
+            KEY_SHADOW_ALPHA
+        );
+
+        mAmbientShadowInfo = createShadowInfo(
+            R.dimen.dream_overlay_status_bar_ambient_text_shadow_radius,
+            R.dimen.dream_overlay_status_bar_ambient_text_shadow_dx,
+            R.dimen.dream_overlay_status_bar_ambient_text_shadow_dy,
+            AMBIENT_SHADOW_ALPHA
+        );
+
+        mDrawableSize = mContext
+                        .getResources()
+                        .getDimensionPixelSize(R.dimen.dream_overlay_status_bar_icon_size);
+        mDrawableInsetSize = mContext
+                             .getResources()
+                             .getDimensionPixelSize(R.dimen.dream_overlay_icon_inset_dimen);
+
         mStatusIcons.put(STATUS_ICON_WIFI_UNAVAILABLE,
-                fetchStatusIconForResId(R.id.dream_overlay_wifi_status));
+                addDoubleShadow(fetchStatusIconForResId(R.id.dream_overlay_wifi_status)));
         mStatusIcons.put(STATUS_ICON_ALARM_SET,
-                fetchStatusIconForResId(R.id.dream_overlay_alarm_set));
+                addDoubleShadow(fetchStatusIconForResId(R.id.dream_overlay_alarm_set)));
         mStatusIcons.put(STATUS_ICON_CAMERA_DISABLED,
                 fetchStatusIconForResId(R.id.dream_overlay_camera_off));
         mStatusIcons.put(STATUS_ICON_MIC_DISABLED,
@@ -97,7 +131,7 @@
         mStatusIcons.put(STATUS_ICON_NOTIFICATIONS,
                 fetchStatusIconForResId(R.id.dream_overlay_notification_indicator));
         mStatusIcons.put(STATUS_ICON_PRIORITY_MODE_ON,
-                fetchStatusIconForResId(R.id.dream_overlay_priority_mode));
+                addDoubleShadow(fetchStatusIconForResId(R.id.dream_overlay_priority_mode)));
 
         mSystemStatusViewGroup = findViewById(R.id.dream_overlay_system_status);
         mExtraSystemStatusViewGroup = findViewById(R.id.dream_overlay_extra_items);
@@ -137,4 +171,34 @@
         }
         return false;
     }
+
+    private View addDoubleShadow(View icon) {
+        if (icon instanceof AlphaOptimizedImageView) {
+            AlphaOptimizedImageView i = (AlphaOptimizedImageView) icon;
+            Drawable drawableIcon = i.getDrawable();
+            i.setImageDrawable(new DoubleShadowIconDrawable(
+                    mKeyShadowInfo,
+                    mAmbientShadowInfo,
+                    drawableIcon,
+                    mDrawableSize,
+                    mDrawableInsetSize
+            ));
+        }
+        return icon;
+    }
+
+    private ShadowInfo createShadowInfo(int blurId, int offsetXId, int offsetYId, float alpha) {
+        return new ShadowInfo(
+            fetchDimensionForResId(blurId),
+            fetchDimensionForResId(offsetXId),
+            fetchDimensionForResId(offsetYId),
+            alpha
+        );
+    }
+
+    private Float fetchDimensionForResId(int resId) {
+        return mContext
+               .getResources()
+               .getDimension(resId);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
index f1bb156..90c440c 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
@@ -25,7 +25,6 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
-import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.format.DateFormat;
 import android.util.PluralsMessageFormatter;
@@ -37,6 +36,7 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dreams.DreamOverlayStatusBarItemsProvider.StatusBarItem;
 import com.android.systemui.dreams.dagger.DreamOverlayComponent;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.CrossFadeHelper;
 import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController;
 import com.android.systemui.statusbar.policy.NextAlarmController;
@@ -72,6 +72,7 @@
             mDreamOverlayNotificationCountProvider;
     private final ZenModeController mZenModeController;
     private final DreamOverlayStateController mDreamOverlayStateController;
+    private final UserTracker mUserTracker;
     private final StatusBarWindowStateController mStatusBarWindowStateController;
     private final DreamOverlayStatusBarItemsProvider mStatusBarItemsProvider;
     private final Executor mMainExecutor;
@@ -154,7 +155,8 @@
             ZenModeController zenModeController,
             StatusBarWindowStateController statusBarWindowStateController,
             DreamOverlayStatusBarItemsProvider statusBarItemsProvider,
-            DreamOverlayStateController dreamOverlayStateController) {
+            DreamOverlayStateController dreamOverlayStateController,
+            UserTracker userTracker) {
         super(view);
         mResources = resources;
         mMainExecutor = mainExecutor;
@@ -169,6 +171,7 @@
         mStatusBarItemsProvider = statusBarItemsProvider;
         mZenModeController = zenModeController;
         mDreamOverlayStateController = dreamOverlayStateController;
+        mUserTracker = userTracker;
 
         // Register to receive show/hide updates for the system status bar. Our custom status bar
         // needs to hide when the system status bar is showing to ovoid overlapping status bars.
@@ -259,7 +262,7 @@
 
     private void updateAlarmStatusIcon() {
         final AlarmManager.AlarmClockInfo alarm =
-                mAlarmManager.getNextAlarmClock(UserHandle.USER_CURRENT);
+                mAlarmManager.getNextAlarmClock(mUserTracker.getUserId());
         final boolean hasAlarm = alarm != null && alarm.getTriggerTime() > 0;
         showIcon(
                 DreamOverlayStatusBarView.STATUS_ICON_ALARM_SET,
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
index 92cdcf9..44207f4 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
@@ -36,10 +36,10 @@
 
 import com.android.internal.logging.UiEvent;
 import com.android.internal.logging.UiEventLogger;
+import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants;
 import com.android.systemui.shade.ShadeExpansionChangeEvent;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
-import com.android.systemui.statusbar.phone.KeyguardBouncer;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.wm.shell.animation.FlingAnimationUtils;
 
@@ -274,16 +274,18 @@
                         (float) Math.hypot(horizontalVelocity, verticalVelocity);
 
                 final float expansion = flingRevealsOverlay(verticalVelocity, velocityVector)
-                        ? KeyguardBouncer.EXPANSION_HIDDEN : KeyguardBouncer.EXPANSION_VISIBLE;
+                        ? KeyguardBouncerConstants.EXPANSION_HIDDEN
+                        : KeyguardBouncerConstants.EXPANSION_VISIBLE;
 
                 // Log the swiping up to show Bouncer event.
-                if (!mBouncerInitiallyShowing && expansion == KeyguardBouncer.EXPANSION_VISIBLE) {
+                if (!mBouncerInitiallyShowing
+                        && expansion == KeyguardBouncerConstants.EXPANSION_VISIBLE) {
                     mUiEventLogger.log(DreamEvent.DREAM_SWIPED);
                 }
 
                 flingToExpansion(verticalVelocity, expansion);
 
-                if (expansion == KeyguardBouncer.EXPANSION_HIDDEN) {
+                if (expansion == KeyguardBouncerConstants.EXPANSION_HIDDEN) {
                     mStatusBarKeyguardViewManager.reset(false);
                 }
                 break;
@@ -302,7 +304,8 @@
                     float dragDownAmount = expansionFraction * expansionHeight;
                     setPanelExpansion(expansionFraction, dragDownAmount);
                 });
-        if (!mBouncerInitiallyShowing && targetExpansion == KeyguardBouncer.EXPANSION_VISIBLE) {
+        if (!mBouncerInitiallyShowing
+                && targetExpansion == KeyguardBouncerConstants.EXPANSION_VISIBLE) {
             animator.addListener(
                     new AnimatorListenerAdapter() {
                         @Override
@@ -335,7 +338,7 @@
         final float targetHeight = viewHeight * expansion;
         final float expansionHeight = targetHeight - currentHeight;
         final ValueAnimator animator = createExpansionAnimator(expansion, expansionHeight);
-        if (expansion == KeyguardBouncer.EXPANSION_HIDDEN) {
+        if (expansion == KeyguardBouncerConstants.EXPANSION_HIDDEN) {
             // Hides the bouncer, i.e., fully expands the space above the bouncer.
             mFlingAnimationUtilsClosing.apply(animator, currentHeight, targetHeight, velocity,
                     viewHeight);
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index dbeef8d..ede4223 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -64,6 +64,10 @@
     // TODO(b/259130119): Tracking Bug
     val FSI_ON_DND_UPDATE = unreleasedFlag(259130119, "fsi_on_dnd_update", teamfood = true)
 
+    // TODO(b/265804648): Tracking Bug
+    @JvmField
+    val DISABLE_FSI = unreleasedFlag(265804648, "disable_fsi")
+
     // TODO(b/254512538): Tracking Bug
     val INSTANT_VOICE_REPLY = unreleasedFlag(111, "instant_voice_reply", teamfood = true)
 
@@ -75,18 +79,9 @@
         unreleasedFlag(119, "notification_memory_logging_enabled", teamfood = true)
 
     // TODO(b/254512731): Tracking Bug
-    @JvmField
-    val NOTIFICATION_DISMISSAL_FADE =
-        unreleasedFlag(113, "notification_dismissal_fade", teamfood = true)
+    @JvmField val NOTIFICATION_DISMISSAL_FADE = releasedFlag(113, "notification_dismissal_fade")
 
-    // TODO(b/259558771): Tracking Bug
-    val STABILITY_INDEX_FIX = releasedFlag(114, "stability_index_fix")
-
-    // TODO(b/259559750): Tracking Bug
-    val SEMI_STABLE_SORT = releasedFlag(115, "semi_stable_sort")
-
-    @JvmField
-    val USE_ROUNDNESS_SOURCETYPES = unreleasedFlag(116, "use_roundness_sourcetype", teamfood = true)
+    @JvmField val USE_ROUNDNESS_SOURCETYPES = releasedFlag(116, "use_roundness_sourcetype")
 
     // TODO(b/259217907)
     @JvmField
@@ -109,14 +104,16 @@
         unreleasedFlag(174148361, "notification_inline_reply_animation", teamfood = true)
 
     val FILTER_UNSEEN_NOTIFS_ON_KEYGUARD =
-        unreleasedFlag(254647461, "filter_unseen_notifs_on_keyguard", teamfood = true)
+        releasedFlag(254647461, "filter_unseen_notifs_on_keyguard", teamfood = true)
+
+    // TODO(b/263414400): Tracking Bug
+    @JvmField
+    val NOTIFICATION_ANIMATE_BIG_PICTURE = unreleasedFlag(120, "notification_animate_big_picture")
 
     // 200 - keyguard/lockscreen
     // ** Flag retired **
     // public static final BooleanFlag KEYGUARD_LAYOUT =
     //         new BooleanFlag(200, true);
-    // TODO(b/254512713): Tracking Bug
-    @JvmField val LOCKSCREEN_ANIMATIONS = releasedFlag(201, "lockscreen_animations")
 
     // TODO(b/254512750): Tracking Bug
     val NEW_UNLOCK_SWIPE_ANIMATION = releasedFlag(202, "new_unlock_swipe_animation")
@@ -166,7 +163,7 @@
     // TODO(b/255618149): Tracking Bug
     @JvmField
     val CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES =
-        unreleasedFlag(216, "customizable_lock_screen_quick_affordances", teamfood = false)
+        unreleasedFlag(216, "customizable_lock_screen_quick_affordances", teamfood = true)
 
     /** Shows chipbar UI whenever the device is unlocked by ActiveUnlock (watch). */
     // TODO(b/256513609): Tracking Bug
@@ -181,6 +178,13 @@
     @JvmField
     val LIGHT_REVEAL_MIGRATION = unreleasedFlag(218, "light_reveal_migration", teamfood = false)
 
+    /**
+     * Whether to use the new alternate bouncer architecture, a refactor of and eventual replacement
+     * of the Alternate/Authentication Bouncer. No visual UI changes.
+     */
+    // TODO(b/260619425): Tracking Bug
+    @JvmField val MODERN_ALTERNATE_BOUNCER = releasedFlag(219, "modern_alternate_bouncer")
+
     /** Flag to control the migration of face auth to modern architecture. */
     // TODO(b/262838215): Tracking bug
     @JvmField val FACE_AUTH_REFACTOR = unreleasedFlag(220, "face_auth_refactor")
@@ -196,7 +200,26 @@
     /** A different path for unocclusion transitions back to keyguard */
     // TODO(b/262859270): Tracking Bug
     @JvmField
-    val UNOCCLUSION_TRANSITION = unreleasedFlag(223, "unocclusion_transition", teamfood = false)
+    val UNOCCLUSION_TRANSITION = unreleasedFlag(223, "unocclusion_transition", teamfood = true)
+
+    // flag for controlling auto pin confirmation and material u shapes in bouncer
+    @JvmField
+    val AUTO_PIN_CONFIRMATION =
+        unreleasedFlag(224, "auto_pin_confirmation", "auto_pin_confirmation")
+
+    // TODO(b/262859270): Tracking Bug
+    @JvmField val FALSING_OFF_FOR_UNFOLDED = releasedFlag(225, "falsing_off_for_unfolded")
+
+    /** Enables code to show contextual loyalty cards in wallet entrypoints */
+    // TODO(b/247587924): Tracking Bug
+    @JvmField
+    val ENABLE_WALLET_CONTEXTUAL_LOYALTY_CARDS =
+        unreleasedFlag(226, "enable_wallet_contextual_loyalty_cards", teamfood = false)
+
+    // TODO(b/242908637): Tracking Bug
+    @JvmField
+    val WALLPAPER_FULLSCREEN_PREVIEW =
+        unreleasedFlag(227, "wallpaper_fullscreen_preview", teamfood = true)
 
     // 300 - power menu
     // TODO(b/254512600): Tracking Bug
@@ -209,6 +232,11 @@
         releasedFlag(401, "smartspace_shared_element_transition_enabled")
     val SMARTSPACE = resourceBooleanFlag(402, R.bool.flag_smartspace, "smartspace")
 
+    // TODO(b/258517050): Clean up after the feature is launched.
+    @JvmField
+    val SMARTSPACE_DATE_WEATHER_DECOUPLED =
+        sysPropBooleanFlag(403, "persist.sysui.ss.dw_decoupled", default = false)
+
     // 500 - quick settings
 
     // TODO(b/254512321): Tracking Bug
@@ -247,10 +275,11 @@
 
     // TODO(b/256614751): Tracking Bug
     val NEW_STATUS_BAR_MOBILE_ICONS_BACKEND =
-        unreleasedFlag(608, "new_status_bar_mobile_icons_backend")
+        unreleasedFlag(608, "new_status_bar_mobile_icons_backend", teamfood = true)
 
     // TODO(b/256613548): Tracking Bug
-    val NEW_STATUS_BAR_WIFI_ICON_BACKEND = unreleasedFlag(609, "new_status_bar_wifi_icon_backend")
+    val NEW_STATUS_BAR_WIFI_ICON_BACKEND =
+        unreleasedFlag(609, "new_status_bar_wifi_icon_backend", teamfood = true)
 
     // TODO(b/256623670): Tracking Bug
     @JvmField
@@ -276,7 +305,7 @@
 
     // 801 - region sampling
     // TODO(b/254512848): Tracking Bug
-    val REGION_SAMPLING = unreleasedFlag(801, "region_sampling", teamfood = true)
+    val REGION_SAMPLING = unreleasedFlag(801, "region_sampling")
 
     // 803 - screen contents translation
     // TODO(b/254513187): Tracking Bug
@@ -289,7 +318,7 @@
 
     // 900 - media
     // TODO(b/254512697): Tracking Bug
-    val MEDIA_TAP_TO_TRANSFER = unreleasedFlag(900, "media_tap_to_transfer", teamfood = true)
+    val MEDIA_TAP_TO_TRANSFER = releasedFlag(900, "media_tap_to_transfer")
 
     // TODO(b/254512502): Tracking Bug
     val MEDIA_SESSION_ACTIONS = unreleasedFlag(901, "media_session_actions")
@@ -319,13 +348,21 @@
     val MEDIA_TTT_RECEIVER_SUCCESS_RIPPLE =
         unreleasedFlag(910, "media_ttt_receiver_success_ripple", teamfood = true)
 
+    // TODO(b/263512203): Tracking Bug
+    val MEDIA_EXPLICIT_INDICATOR = unreleasedFlag(911, "media_explicit_indicator", teamfood = true)
+
+    // TODO(b/265813373): Tracking Bug
+    val MEDIA_TAP_TO_TRANSFER_DISMISS_GESTURE =
+        unreleasedFlag(912, "media_ttt_dismiss_gesture", teamfood = true)
+
     // 1000 - dock
     val SIMULATE_DOCK_THROUGH_CHARGING = releasedFlag(1000, "simulate_dock_through_charging")
 
     // TODO(b/254512758): Tracking Bug
     @JvmField val ROUNDED_BOX_RIPPLE = releasedFlag(1002, "rounded_box_ripple")
 
-    val SHOW_LOWLIGHT_ON_DIRECT_BOOT = unreleasedFlag(1003, "show_lowlight_on_direct_boot")
+    // TODO(b/265045965): Tracking Bug
+    val SHOW_LOWLIGHT_ON_DIRECT_BOOT = releasedFlag(1003, "show_lowlight_on_direct_boot")
 
     // 1100 - windowing
     @Keep
@@ -388,6 +425,17 @@
     val WM_DESKTOP_WINDOWING_2 =
         sysPropBooleanFlag(1112, "persist.wm.debug.desktop_mode_2", default = false)
 
+    // TODO(b/254513207): Tracking Bug to delete
+    @Keep
+    @JvmField
+    val WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES =
+        unreleasedFlag(
+            1113,
+            name = "screen_record_enterprise_policies",
+            namespace = DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+            teamfood = false
+        )
+
     // 1200 - predictive back
     @Keep
     @JvmField
@@ -413,10 +461,26 @@
     val WM_ENABLE_PREDICTIVE_BACK_SYSUI =
         unreleasedFlag(1204, "persist.wm.debug.predictive_back_sysui_enable", teamfood = true)
 
-    // 1300 - screenshots
-    // TODO(b/254512719): Tracking Bug
-    @JvmField val SCREENSHOT_REQUEST_PROCESSOR = releasedFlag(1300, "screenshot_request_processor")
+    // TODO(b/255697805): Tracking Bug
+    @JvmField
+    val TRACKPAD_GESTURE_BACK = unreleasedFlag(1205, "trackpad_gesture_back", teamfood = false)
 
+    // TODO(b/263826204): Tracking Bug
+    @JvmField
+    val WM_ENABLE_PREDICTIVE_BACK_BOUNCER_ANIM =
+        unreleasedFlag(1206, "persist.wm.debug.predictive_back_bouncer_anim", teamfood = true)
+
+    // TODO(b/238475428): Tracking Bug
+    @JvmField
+    val WM_SHADE_ALLOW_BACK_GESTURE =
+        unreleasedFlag(1207, "persist.wm.debug.shade_allow_back_gesture", teamfood = false)
+
+    // TODO(b/238475428): Tracking Bug
+    @JvmField
+    val WM_SHADE_ANIMATE_BACK_GESTURE =
+        unreleasedFlag(1208, "persist.wm.debug.shade_animate_back_gesture", teamfood = true)
+
+    // 1300 - screenshots
     // TODO(b/254513155): Tracking Bug
     @JvmField
     val SCREENSHOT_WORK_PROFILE_POLICY =
@@ -445,8 +509,7 @@
 
     // 1800 - shade container
     @JvmField
-    val LEAVE_SHADE_OPEN_FOR_BUGREPORT =
-        unreleasedFlag(1800, "leave_shade_open_for_bugreport", teamfood = true)
+    val LEAVE_SHADE_OPEN_FOR_BUGREPORT = releasedFlag(1800, "leave_shade_open_for_bugreport")
 
     // 1900
     @JvmField val NOTE_TASKS = unreleasedFlag(1900, "keycode_flag")
@@ -472,6 +535,7 @@
     @JvmField val ENABLE_STYLUS_CHARGING_UI = unreleasedFlag(2301, "enable_stylus_charging_ui")
     @JvmField
     val ENABLE_USI_BATTERY_NOTIFICATIONS = unreleasedFlag(2302, "enable_usi_battery_notifications")
+    @JvmField val ENABLE_STYLUS_EDUCATION = unreleasedFlag(2303, "enable_stylus_education")
 
     // 2400 - performance tools and debugging info
     // TODO(b/238923086): Tracking Bug
@@ -489,6 +553,23 @@
     @JvmField
     val OUTPUT_SWITCHER_DEVICE_STATUS = unreleasedFlag(2502, "output_switcher_device_status")
 
+    // TODO(b/20911786): Tracking Bug
+    @JvmField
+    val OUTPUT_SWITCHER_SHOW_API_ENABLED =
+        unreleasedFlag(2503, "output_switcher_show_api_enabled", teamfood = true)
+
+    // 2700 - unfold transitions
+    // TODO(b/265764985): Tracking Bug
+    @Keep
+    @JvmField
+    val ENABLE_DARK_VIGNETTE_WHEN_FOLDING =
+        unreleasedFlag(2700, "enable_dark_vignette_when_folding")
+
     // TODO(b259590361): Tracking bug
     val EXPERIMENTAL_FLAG = unreleasedFlag(2, "exp_flag_release")
+
+    // 2600 - keyboard shortcut
+    // TODO(b/259352579): Tracking Bug
+    @JvmField
+    val SHORTCUT_LIST_SEARCH_LAYOUT = unreleasedFlag(2600, "shortcut_list_search_layout")
 }
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
index db2cd91..e80e71c 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
@@ -21,7 +21,6 @@
 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_GLOBAL_ACTIONS;
-import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
 
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
@@ -901,7 +900,7 @@
                         | Intent.FLAG_ACTIVITY_CLEAR_TOP);
                 intent.putExtra(EmergencyDialerConstants.EXTRA_ENTRY_TYPE,
                         EmergencyDialerConstants.ENTRY_TYPE_POWER_MENU);
-                mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+                mContext.startActivityAsUser(intent, mUserTracker.getUserHandle());
             }
         }
     }
@@ -959,8 +958,7 @@
             mHandler.postDelayed(new Runnable() {
                 @Override
                 public void run() {
-                    mScreenshotHelper.takeScreenshot(TAKE_SCREENSHOT_FULLSCREEN,
-                            SCREENSHOT_GLOBAL_ACTIONS, mHandler, null);
+                    mScreenshotHelper.takeScreenshot(SCREENSHOT_GLOBAL_ACTIONS, mHandler, null);
                     mMetricsLogger.action(MetricsEvent.ACTION_SCREENSHOT_POWER_MENU);
                     mUiEventLogger.log(GlobalActionsEvent.GA_SCREENSHOT_PRESS);
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
index 4f1a2b3..ad7973e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
@@ -24,7 +24,6 @@
 import android.bluetooth.le.ScanRecord;
 import android.bluetooth.le.ScanResult;
 import android.bluetooth.le.ScanSettings;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.hardware.input.InputManager;
@@ -53,6 +52,7 @@
 import com.android.systemui.CoreStartable;
 import com.android.systemui.R;
 import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.util.settings.SecureSettings;
 
 import java.io.PrintWriter;
 import java.util.Arrays;
@@ -108,6 +108,7 @@
     protected volatile Context mContext;
 
     private final Provider<LocalBluetoothManager> mBluetoothManagerProvider;
+    private final SecureSettings mSecureSettings;
 
     private boolean mEnabled;
     private String mKeyboardName;
@@ -125,9 +126,11 @@
     private int mState;
 
     @Inject
-    public KeyboardUI(Context context, Provider<LocalBluetoothManager> bluetoothManagerProvider) {
+    public KeyboardUI(Context context, Provider<LocalBluetoothManager> bluetoothManagerProvider,
+            SecureSettings secureSettings) {
         mContext = context;
         this.mBluetoothManagerProvider = bluetoothManagerProvider;
+        mSecureSettings = secureSettings;
     }
 
     @Override
@@ -298,9 +301,8 @@
     }
 
     private boolean isUserSetupComplete() {
-        ContentResolver resolver = mContext.getContentResolver();
-        return Secure.getIntForUser(
-                resolver, Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
+        return mSecureSettings.getIntForUser(
+                Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
     }
 
     private CachedBluetoothDevice getPairedKeyboard() {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProvider.kt b/packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt
similarity index 73%
rename from packages/SystemUI/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProvider.kt
rename to packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt
index cbcede0..482138e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt
@@ -33,11 +33,11 @@
 import com.android.systemui.SystemUIAppComponentFactoryBase.ContextAvailableCallback
 import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
 import com.android.systemui.keyguard.ui.preview.KeyguardRemotePreviewManager
-import com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderContract as Contract
+import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
 import javax.inject.Inject
 import kotlinx.coroutines.runBlocking
 
-class KeyguardQuickAffordanceProvider :
+class CustomizationProvider :
     ContentProvider(), SystemUIAppComponentFactoryBase.ContextInitializer {
 
     @Inject lateinit var interactor: KeyguardQuickAffordanceInteractor
@@ -49,17 +49,23 @@
         UriMatcher(UriMatcher.NO_MATCH).apply {
             addURI(
                 Contract.AUTHORITY,
-                Contract.SlotTable.TABLE_NAME,
+                Contract.LockScreenQuickAffordances.qualifiedTablePath(
+                    Contract.LockScreenQuickAffordances.SlotTable.TABLE_NAME,
+                ),
                 MATCH_CODE_ALL_SLOTS,
             )
             addURI(
                 Contract.AUTHORITY,
-                Contract.AffordanceTable.TABLE_NAME,
+                Contract.LockScreenQuickAffordances.qualifiedTablePath(
+                    Contract.LockScreenQuickAffordances.AffordanceTable.TABLE_NAME,
+                ),
                 MATCH_CODE_ALL_AFFORDANCES,
             )
             addURI(
                 Contract.AUTHORITY,
-                Contract.SelectionTable.TABLE_NAME,
+                Contract.LockScreenQuickAffordances.qualifiedTablePath(
+                    Contract.LockScreenQuickAffordances.SelectionTable.TABLE_NAME,
+                ),
                 MATCH_CODE_ALL_SELECTIONS,
             )
             addURI(
@@ -94,9 +100,18 @@
 
         val tableName =
             when (uriMatcher.match(uri)) {
-                MATCH_CODE_ALL_SLOTS -> Contract.SlotTable.TABLE_NAME
-                MATCH_CODE_ALL_AFFORDANCES -> Contract.AffordanceTable.TABLE_NAME
-                MATCH_CODE_ALL_SELECTIONS -> Contract.SelectionTable.TABLE_NAME
+                MATCH_CODE_ALL_SLOTS ->
+                    Contract.LockScreenQuickAffordances.qualifiedTablePath(
+                        Contract.LockScreenQuickAffordances.SlotTable.TABLE_NAME,
+                    )
+                MATCH_CODE_ALL_AFFORDANCES ->
+                    Contract.LockScreenQuickAffordances.qualifiedTablePath(
+                        Contract.LockScreenQuickAffordances.AffordanceTable.TABLE_NAME,
+                    )
+                MATCH_CODE_ALL_SELECTIONS ->
+                    Contract.LockScreenQuickAffordances.qualifiedTablePath(
+                        Contract.LockScreenQuickAffordances.SelectionTable.TABLE_NAME,
+                    )
                 MATCH_CODE_ALL_FLAGS -> Contract.FlagsTable.TABLE_NAME
                 else -> null
             }
@@ -174,22 +189,34 @@
             throw IllegalArgumentException("Cannot insert selection, no values passed in!")
         }
 
-        if (!values.containsKey(Contract.SelectionTable.Columns.SLOT_ID)) {
+        if (
+            !values.containsKey(Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID)
+        ) {
             throw IllegalArgumentException(
                 "Cannot insert selection, " +
-                    "\"${Contract.SelectionTable.Columns.SLOT_ID}\" not specified!"
+                    "\"${Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID}\"" +
+                    " not specified!"
             )
         }
 
-        if (!values.containsKey(Contract.SelectionTable.Columns.AFFORDANCE_ID)) {
+        if (
+            !values.containsKey(
+                Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_ID
+            )
+        ) {
             throw IllegalArgumentException(
                 "Cannot insert selection, " +
-                    "\"${Contract.SelectionTable.Columns.AFFORDANCE_ID}\" not specified!"
+                    "\"${Contract.LockScreenQuickAffordances
+                        .SelectionTable.Columns.AFFORDANCE_ID}\" not specified!"
             )
         }
 
-        val slotId = values.getAsString(Contract.SelectionTable.Columns.SLOT_ID)
-        val affordanceId = values.getAsString(Contract.SelectionTable.Columns.AFFORDANCE_ID)
+        val slotId =
+            values.getAsString(Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID)
+        val affordanceId =
+            values.getAsString(
+                Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_ID
+            )
 
         if (slotId.isNullOrEmpty()) {
             throw IllegalArgumentException("Cannot insert selection, slot ID was empty!")
@@ -207,8 +234,10 @@
 
         return if (success) {
             Log.d(TAG, "Successfully selected $affordanceId for slot $slotId")
-            context?.contentResolver?.notifyChange(Contract.SelectionTable.URI, null)
-            Contract.SelectionTable.URI
+            context
+                ?.contentResolver
+                ?.notifyChange(Contract.LockScreenQuickAffordances.SelectionTable.URI, null)
+            Contract.LockScreenQuickAffordances.SelectionTable.URI
         } else {
             Log.d(TAG, "Failed to select $affordanceId for slot $slotId")
             null
@@ -218,9 +247,9 @@
     private suspend fun querySelections(): Cursor {
         return MatrixCursor(
                 arrayOf(
-                    Contract.SelectionTable.Columns.SLOT_ID,
-                    Contract.SelectionTable.Columns.AFFORDANCE_ID,
-                    Contract.SelectionTable.Columns.AFFORDANCE_NAME,
+                    Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID,
+                    Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_ID,
+                    Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_NAME,
                 )
             )
             .apply {
@@ -243,13 +272,17 @@
     private suspend fun queryAffordances(): Cursor {
         return MatrixCursor(
                 arrayOf(
-                    Contract.AffordanceTable.Columns.ID,
-                    Contract.AffordanceTable.Columns.NAME,
-                    Contract.AffordanceTable.Columns.ICON,
-                    Contract.AffordanceTable.Columns.IS_ENABLED,
-                    Contract.AffordanceTable.Columns.ENABLEMENT_INSTRUCTIONS,
-                    Contract.AffordanceTable.Columns.ENABLEMENT_ACTION_TEXT,
-                    Contract.AffordanceTable.Columns.ENABLEMENT_COMPONENT_NAME,
+                    Contract.LockScreenQuickAffordances.AffordanceTable.Columns.ID,
+                    Contract.LockScreenQuickAffordances.AffordanceTable.Columns.NAME,
+                    Contract.LockScreenQuickAffordances.AffordanceTable.Columns.ICON,
+                    Contract.LockScreenQuickAffordances.AffordanceTable.Columns.IS_ENABLED,
+                    Contract.LockScreenQuickAffordances.AffordanceTable.Columns
+                        .ENABLEMENT_INSTRUCTIONS,
+                    Contract.LockScreenQuickAffordances.AffordanceTable.Columns
+                        .ENABLEMENT_ACTION_TEXT,
+                    Contract.LockScreenQuickAffordances.AffordanceTable.Columns
+                        .ENABLEMENT_COMPONENT_NAME,
+                    Contract.LockScreenQuickAffordances.AffordanceTable.Columns.CONFIGURE_INTENT,
                 )
             )
             .apply {
@@ -261,10 +294,12 @@
                             representation.iconResourceId,
                             if (representation.isEnabled) 1 else 0,
                             representation.instructions?.joinToString(
-                                Contract.AffordanceTable.ENABLEMENT_INSTRUCTIONS_DELIMITER
+                                Contract.LockScreenQuickAffordances.AffordanceTable
+                                    .ENABLEMENT_INSTRUCTIONS_DELIMITER
                             ),
                             representation.actionText,
                             representation.actionComponentName,
+                            representation.configureIntent?.toUri(0),
                         )
                     )
                 }
@@ -274,8 +309,8 @@
     private fun querySlots(): Cursor {
         return MatrixCursor(
                 arrayOf(
-                    Contract.SlotTable.Columns.ID,
-                    Contract.SlotTable.Columns.CAPACITY,
+                    Contract.LockScreenQuickAffordances.SlotTable.Columns.ID,
+                    Contract.LockScreenQuickAffordances.SlotTable.Columns.CAPACITY,
                 )
             )
             .apply {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
index 53070a0..228320b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
@@ -23,6 +23,7 @@
 import android.graphics.Matrix
 import android.graphics.Rect
 import android.os.Handler
+import android.os.PowerManager
 import android.os.RemoteException
 import android.util.Log
 import android.view.RemoteAnimationTarget
@@ -145,7 +146,8 @@
     private val featureFlags: FeatureFlags,
     private val biometricUnlockControllerLazy: Lazy<BiometricUnlockController>,
     private val statusBarStateController: SysuiStatusBarStateController,
-    private val notificationShadeWindowController: NotificationShadeWindowController
+    private val notificationShadeWindowController: NotificationShadeWindowController,
+    private val powerManager: PowerManager
 ) : KeyguardStateController.Callback, ISysuiUnlockAnimationController.Stub() {
 
     interface KeyguardUnlockAnimationListener {
@@ -344,7 +346,7 @@
                 override fun onAnimationEnd(animation: Animator) {
                     Log.d(TAG, "surfaceBehindEntryAnimator#onAnimationEnd")
                     playingCannedUnlockAnimation = false
-                    keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished(
+                    keyguardViewMediator.get().exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
                         false /* cancelled */
                     )
                 }
@@ -579,7 +581,7 @@
             biometricUnlockControllerLazy.get().isWakeAndUnlock -> {
                 Log.d(TAG, "playCannedUnlockAnimation, isWakeAndUnlock")
                 setSurfaceBehindAppearAmount(1f)
-                keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished(
+                keyguardViewMediator.get().exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
                     false /* cancelled */)
             }
 
@@ -627,7 +629,7 @@
                 return@postDelayed
             }
 
-            keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished(
+            keyguardViewMediator.get().exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
                 false /* cancelled */)
         }, CANNED_UNLOCK_START_DELAY)
     }
@@ -745,7 +747,8 @@
                         !keyguardStateController.isFlingingToDismissKeyguardDuringSwipeGesture &&
                         dismissAmount >= DISMISS_AMOUNT_EXIT_KEYGUARD_THRESHOLD)) {
             setSurfaceBehindAppearAmount(1f)
-            keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished(false /* cancelled */)
+            keyguardViewMediator.get().exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
+                    false /* cancelled */)
         }
     }
 
@@ -783,10 +786,15 @@
                     surfaceHeight * SURFACE_BEHIND_SCALE_PIVOT_Y
             )
 
-            // If we're snapping the keyguard back, immediately begin fading it out.
-            val animationAlpha =
-                    if (keyguardStateController.isSnappingKeyguardBackAfterSwipe) amount
-                    else surfaceBehindAlpha
+
+            val animationAlpha = when {
+                // If we're snapping the keyguard back, immediately begin fading it out.
+                keyguardStateController.isSnappingKeyguardBackAfterSwipe -> amount
+                // If the screen has turned back off, the unlock animation is going to be cancelled,
+                // so set the surface alpha to 0f so it's no longer visible.
+                !powerManager.isInteractive -> 0f
+                else -> surfaceBehindAlpha
+            }
 
             // SyncRtSurfaceTransactionApplier cannot apply transaction when the target view is
             // unable to draw
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 8aada1f..95bba13 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -34,6 +34,7 @@
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE;
 import static com.android.systemui.DejankUtils.whitelistIpcs;
 import static com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel.LOCKSCREEN_ANIMATION_DURATION_MS;
+import static com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel.DREAMING_ANIMATION_DURATION_MS;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -122,6 +123,8 @@
 import com.android.systemui.dagger.qualifiers.UiBackground;
 import com.android.systemui.dreams.DreamOverlayStateController;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.keyguard.dagger.KeyguardModule;
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -144,12 +147,12 @@
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 import com.android.systemui.util.DeviceConfigProxy;
 
-import dagger.Lazy;
-
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.concurrent.Executor;
 
+import dagger.Lazy;
+
 /**
  * Mediates requests related to the keyguard.  This includes queries about the
  * state of the keyguard, power management events that effect whether the keyguard
@@ -507,6 +510,8 @@
 
     private CentralSurfaces mCentralSurfaces;
 
+    private boolean mUnocclusionTransitionFlagEnabled = false;
+
     private final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener =
             new DeviceConfig.OnPropertiesChangedListener() {
             @Override
@@ -958,8 +963,9 @@
                 public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
                         RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
                         IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException {
-                    setOccluded(true /* isOccluded */, true /* animate */);
-
+                    if (!mUnocclusionTransitionFlagEnabled) {
+                        setOccluded(true /* isOccluded */, true /* animate */);
+                    }
                     if (apps == null || apps.length == 0 || apps[0] == null) {
                         if (DEBUG) {
                             Log.d(TAG, "No apps provided to the OccludeByDream runner; "
@@ -1001,9 +1007,20 @@
                                     applier.scheduleApply(paramsBuilder.build());
                                 });
                         mOccludeByDreamAnimator.addListener(new AnimatorListenerAdapter() {
+                            private boolean mIsCancelled = false;
+                            @Override
+                            public void onAnimationCancel(Animator animation) {
+                                mIsCancelled = true;
+                            }
+
                             @Override
                             public void onAnimationEnd(Animator animation) {
                                 try {
+                                    if (!mIsCancelled && mUnocclusionTransitionFlagEnabled) {
+                                        // We're already on the main thread, don't queue this call
+                                        handleSetOccluded(true /* isOccluded */,
+                                                false /* animate */);
+                                    }
                                     finishedCallback.onAnimationFinished();
                                     mOccludeByDreamAnimator = null;
                                 } catch (RemoteException e) {
@@ -1176,6 +1193,7 @@
             ScreenOnCoordinator screenOnCoordinator,
             InteractionJankMonitor interactionJankMonitor,
             DreamOverlayStateController dreamOverlayStateController,
+            FeatureFlags featureFlags,
             Lazy<ShadeController> shadeControllerLazy,
             Lazy<NotificationShadeWindowController> notificationShadeWindowControllerLazy,
             Lazy<ActivityLaunchAnimator> activityLaunchAnimator,
@@ -1230,9 +1248,9 @@
                 R.dimen.physical_power_button_center_screen_location_y);
         mWindowCornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context);
 
-        mDreamOpenAnimationDuration = context.getResources().getInteger(
-                com.android.internal.R.integer.config_dreamOpenAnimationDuration);
+        mDreamOpenAnimationDuration = (int) DREAMING_ANIMATION_DURATION_MS;
         mDreamCloseAnimationDuration = (int) LOCKSCREEN_ANIMATION_DURATION_MS;
+        mUnocclusionTransitionFlagEnabled = featureFlags.isEnabled(Flags.UNOCCLUSION_TRANSITION);
     }
 
     public void userActivity() {
@@ -1316,7 +1334,7 @@
         mHideAnimation = AnimationUtils.loadAnimation(mContext,
                 com.android.internal.R.anim.lock_screen_behind_enter);
 
-        mWorkLockController = new WorkLockActivityController(mContext);
+        mWorkLockController = new WorkLockActivityController(mContext, mUserTracker);
     }
 
     @Override
@@ -1458,16 +1476,16 @@
     public void maybeHandlePendingLock() {
         if (mPendingLock) {
 
-            // The screen off animation is playing, so if we lock now, the foreground app will
-            // vanish and the keyguard will jump-cut in. Delay it, until either:
+            // The screen off animation is playing or is about to be, so if we lock now, the
+            // foreground app will vanish and the keyguard will jump-cut in. Delay it, until either:
             //   - The screen off animation ends. We will call maybeHandlePendingLock from
             //     the end action in UnlockedScreenOffAnimationController#animateInKeyguard.
             //   - The screen off animation is cancelled by the device waking back up. We will call
             //     maybeHandlePendingLock from KeyguardViewMediator#onStartedWakingUp.
-            if (mScreenOffAnimationController.isKeyguardShowDelayed()) {
+            if (mScreenOffAnimationController.shouldDelayKeyguardShow()) {
                 if (DEBUG) {
                     Log.d(TAG, "#maybeHandlePendingLock: not handling because the screen off "
-                            + "animation's isKeyguardShowDelayed() returned true. This should be "
+                            + "animation's shouldDelayKeyguardShow() returned true. This should be "
                             + "handled soon by #onStartedWakingUp, or by the end actions of the "
                             + "screen off animation.");
                 }
@@ -1792,7 +1810,6 @@
 
         Trace.beginSection("KeyguardViewMediator#setOccluded");
         if (DEBUG) Log.d(TAG, "setOccluded " + isOccluded);
-        mInteractionJankMonitor.cancel(CUJ_LOCKSCREEN_TRANSITION_FROM_AOD);
         mHandler.removeMessages(SET_OCCLUDED);
         Message msg = mHandler.obtainMessage(SET_OCCLUDED, isOccluded ? 1 : 0, animate ? 1 : 0);
         mHandler.sendMessage(msg);
@@ -1825,6 +1842,8 @@
     private void handleSetOccluded(boolean isOccluded, boolean animate) {
         Trace.beginSection("KeyguardViewMediator#handleSetOccluded");
         Log.d(TAG, "handleSetOccluded(" + isOccluded + ")");
+        mInteractionJankMonitor.cancel(CUJ_LOCKSCREEN_TRANSITION_FROM_AOD);
+
         synchronized (KeyguardViewMediator.this) {
             if (mHiding && isOccluded) {
                 // We're in the process of going away but WindowManager wants to show a
@@ -1893,12 +1912,6 @@
      * Enable the keyguard if the settings are appropriate.
      */
     private void doKeyguardLocked(Bundle options) {
-        if (KeyguardUpdateMonitor.CORE_APPS_ONLY) {
-            // Don't show keyguard during half-booted cryptkeeper stage.
-            if (DEBUG) Log.d(TAG, "doKeyguard: not showing because booting to cryptkeeper");
-            return;
-        }
-
         // if another app is disabling us, don't show
         if (!mExternallyEnabled) {
             if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled");
@@ -1907,13 +1920,23 @@
             return;
         }
 
-        // if the keyguard is already showing, don't bother. check flags in both files
-        // to account for the hiding animation which results in a delay and discrepancy
-        // between flags
+        // If the keyguard is already showing, see if we don't need to bother re-showing it. Check
+        // flags in both files to account for the hiding animation which results in a delay and
+        // discrepancy between flags.
         if (mShowing && mKeyguardStateController.isShowing()) {
-            if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
-            resetStateLocked();
-            return;
+            if (mPM.isInteractive()) {
+                // It's already showing, and we're not trying to show it while the screen is off.
+                // We can simply reset all of the views.
+                if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
+                resetStateLocked();
+                return;
+            } else {
+                // We are trying to show the keyguard while the screen is off - this results from
+                // race conditions involving locking while unlocking. Don't short-circuit here and
+                // ensure the keyguard is fully re-shown.
+                Log.e(TAG,
+                        "doKeyguard: already showing, but re-showing since we're not interactive");
+            }
         }
 
         // In split system user mode, we never unlock system user.
@@ -2258,6 +2281,10 @@
         }
         if (!mKeyguardDonePending && mHideAnimationRun && !mHideAnimationRunning) {
             handleKeyguardDone();
+        } else if (mSurfaceBehindRemoteAnimationRunning) {
+            // We're already running the keyguard exit animation, likely due to an in-progress swipe
+            // to unlock.
+           exitKeyguardAndFinishSurfaceBehindRemoteAnimation(false /* cancelled */);
         } else if (!mHideAnimationRun) {
             if (DEBUG) Log.d(TAG, "tryKeyguardDone: starting pre-hide animation");
             mHideAnimationRun = true;
@@ -2725,27 +2752,42 @@
     }
 
     /**
-     * Called if the keyguard exit animation has been cancelled, and we should dismiss to the
-     * keyguard.
+     * Called if the keyguard exit animation has been cancelled.
      *
      * This can happen due to the system cancelling the RemoteAnimation (due to a timeout, a new
-     * app transition before finishing the current RemoteAnimation).
+     * app transition before finishing the current RemoteAnimation, or the keyguard being re-shown).
      */
     private void handleCancelKeyguardExitAnimation() {
-        showSurfaceBehindKeyguard();
-        onKeyguardExitRemoteAnimationFinished(true /* cancelled */);
+        if (mPendingLock) {
+            Log.d(TAG, "#handleCancelKeyguardExitAnimation: keyguard exit animation cancelled. "
+                    + "There's a pending lock, so we were cancelled because the device was locked "
+                    + "again during the unlock sequence. We should end up locked.");
+
+            // A lock is pending, meaning the keyguard exit animation was cancelled because we're
+            // re-locking. We should just end the surface-behind animation without exiting the
+            // keyguard. The pending lock will be handled by onFinishedGoingToSleep().
+            finishSurfaceBehindRemoteAnimation(true);
+        } else {
+            Log.d(TAG, "#handleCancelKeyguardExitAnimation: keyguard exit animation cancelled. "
+                    + "No pending lock, we should end up unlocked with the app/launcher visible.");
+
+            // No lock is pending, so the animation was cancelled during the unlock sequence, but
+            // we should end up unlocked. Show the surface and exit the keyguard.
+            showSurfaceBehindKeyguard();
+            exitKeyguardAndFinishSurfaceBehindRemoteAnimation(true /* cancelled */);
+        }
     }
 
     /**
-     * Called when we're done running the keyguard exit animation.
+     * Called when we're done running the keyguard exit animation, we should now end up unlocked.
      *
-     * This will call {@link #mSurfaceBehindRemoteAnimationFinishedCallback} to let WM know that
-     * we're done with the RemoteAnimation, actually hide the keyguard, and clean up state related
-     * to the keyguard exit animation.
+     * This will call {@link #handleCancelKeyguardExitAnimation()} to let WM know that we're done
+     * with the RemoteAnimation, actually hide the keyguard, and clean up state related to the
+     * keyguard exit animation.
      *
      * @param cancelled {@code true} if the animation was cancelled before it finishes.
      */
-    public void onKeyguardExitRemoteAnimationFinished(boolean cancelled) {
+    public void exitKeyguardAndFinishSurfaceBehindRemoteAnimation(boolean cancelled) {
         Log.d(TAG, "onKeyguardExitRemoteAnimationFinished");
         if (!mSurfaceBehindRemoteAnimationRunning && !mSurfaceBehindRemoteAnimationRequested) {
             Log.d(TAG, "skip onKeyguardExitRemoteAnimationFinished cancelled=" + cancelled
@@ -2774,10 +2816,6 @@
             }
 
             finishSurfaceBehindRemoteAnimation(cancelled);
-            mSurfaceBehindRemoteAnimationRequested = false;
-
-            // The remote animation is over, so we're not going away anymore.
-            mKeyguardStateController.notifyKeyguardGoingAway(false);
 
             // Dispatch the callback on animation finishes.
             mUpdateMonitor.dispatchKeyguardDismissAnimationFinished();
@@ -2836,13 +2874,17 @@
         return mSurfaceBehindRemoteAnimationRunning;
     }
 
-    /** If it's running, finishes the RemoteAnimation on the surface behind the keyguard. */
+    /**
+     * If it's running, finishes the RemoteAnimation on the surface behind the keyguard and resets
+     * related state.
+     *
+     * This does not set keyguard state to either locked or unlocked, it simply ends the remote
+     * animation on the surface behind the keyguard. This can be called by
+     */
     void finishSurfaceBehindRemoteAnimation(boolean cancelled) {
-        if (!mSurfaceBehindRemoteAnimationRunning) {
-            return;
-        }
-
+        mSurfaceBehindRemoteAnimationRequested = false;
         mSurfaceBehindRemoteAnimationRunning = false;
+        mKeyguardStateController.notifyKeyguardGoingAway(false);
 
         if (mSurfaceBehindRemoteAnimationFinishedCallback != null) {
             try {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java
index 017b65a..ffd8a02 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java
@@ -33,6 +33,7 @@
 import com.android.systemui.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.util.time.SystemClock;
 
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
@@ -63,6 +64,7 @@
 
     private final Context mContext;
     private final DisplayMetrics mDisplayMetrics;
+    private final SystemClock mSystemClock;
 
     @Nullable
     private final IWallpaperManager mWallpaperManagerService;
@@ -71,6 +73,9 @@
 
     private @PowerManager.WakeReason int mLastWakeReason = PowerManager.WAKE_REASON_UNKNOWN;
 
+    public static final long UNKNOWN_LAST_WAKE_TIME = -1;
+    private long mLastWakeTime = UNKNOWN_LAST_WAKE_TIME;
+
     @Nullable
     private Point mLastWakeOriginLocation = null;
 
@@ -84,10 +89,12 @@
     public WakefulnessLifecycle(
             Context context,
             @Nullable IWallpaperManager wallpaperManagerService,
+            SystemClock systemClock,
             DumpManager dumpManager) {
         mContext = context;
         mDisplayMetrics = context.getResources().getDisplayMetrics();
         mWallpaperManagerService = wallpaperManagerService;
+        mSystemClock = systemClock;
 
         dumpManager.registerDumpable(getClass().getSimpleName(), this);
     }
@@ -104,6 +111,14 @@
     }
 
     /**
+     * Returns the most recent time (in device uptimeMillis) the display woke up.
+     * Returns {@link UNKNOWN_LAST_WAKE_TIME} if there hasn't been a wakeup yet.
+     */
+    public long getLastWakeTime() {
+        return mLastWakeTime;
+    }
+
+    /**
      * Returns the most recent reason the device went to sleep up. This is one of
      * PowerManager.GO_TO_SLEEP_REASON_*.
      */
@@ -117,6 +132,7 @@
         }
         setWakefulness(WAKEFULNESS_WAKING);
         mLastWakeReason = pmWakeReason;
+        mLastWakeTime = mSystemClock.uptimeMillis();
         updateLastWakeOriginLocation();
 
         if (mWallpaperManagerService != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java
index 16817ed..b92499e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java
@@ -26,10 +26,10 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.RemoteException;
-import android.os.UserHandle;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.shared.system.TaskStackChangeListeners;
 
@@ -37,16 +37,20 @@
     private static final String TAG = WorkLockActivityController.class.getSimpleName();
 
     private final Context mContext;
+    private final UserTracker mUserTracker;
     private final IActivityTaskManager mIatm;
 
-    public WorkLockActivityController(Context context) {
-        this(context, TaskStackChangeListeners.getInstance(), ActivityTaskManager.getService());
+    public WorkLockActivityController(Context context, UserTracker userTracker) {
+        this(context, userTracker, TaskStackChangeListeners.getInstance(),
+                ActivityTaskManager.getService());
     }
 
     @VisibleForTesting
     WorkLockActivityController(
-            Context context, TaskStackChangeListeners tscl, IActivityTaskManager iAtm) {
+            Context context, UserTracker userTracker, TaskStackChangeListeners tscl,
+            IActivityTaskManager iAtm) {
         mContext = context;
+        mUserTracker = userTracker;
         mIatm = iAtm;
 
         tscl.registerTaskStackListener(mLockListener);
@@ -65,7 +69,8 @@
         options.setLaunchTaskId(info.taskId);
         options.setTaskOverlay(true, false /* canResume */);
 
-        final int result = startActivityAsUser(intent, options.toBundle(), UserHandle.USER_CURRENT);
+        final int result = startActivityAsUser(intent, options.toBundle(),
+                mUserTracker.getUserId());
         if (ActivityManager.isStartResultSuccessful(result)) {
             // OK
         } else {
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 47ef0fa..98d3570 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
@@ -39,6 +39,7 @@
 import com.android.systemui.dagger.qualifiers.UiBackground;
 import com.android.systemui.dreams.DreamOverlayStateController;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
 import com.android.systemui.keyguard.KeyguardViewMediator;
@@ -112,6 +113,7 @@
             ScreenOnCoordinator screenOnCoordinator,
             InteractionJankMonitor interactionJankMonitor,
             DreamOverlayStateController dreamOverlayStateController,
+            FeatureFlags featureFlags,
             Lazy<ShadeController> shadeController,
             Lazy<NotificationShadeWindowController> notificationShadeWindowController,
             Lazy<ActivityLaunchAnimator> activityLaunchAnimator,
@@ -142,6 +144,7 @@
                 screenOnCoordinator,
                 interactionJankMonitor,
                 dreamOverlayStateController,
+                featureFlags,
                 shadeController,
                 notificationShadeWindowController,
                 activityLaunchAnimator,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/BouncerView.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/BouncerView.kt
index 80c6130..faeb485 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/BouncerView.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/BouncerView.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.keyguard.data
 
 import android.view.KeyEvent
+import android.window.OnBackAnimationCallback
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.plugins.ActivityStarter
 import java.lang.ref.WeakReference
@@ -51,4 +52,6 @@
         cancelAction: Runnable?,
     )
     fun willDismissWithActions(): Boolean
+    /** @return the {@link OnBackAnimationCallback} to animate Bouncer during a back gesture. */
+    fun getBackCallback(): OnBackAnimationCallback
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt
index ea5b4f4..76c2430 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt
@@ -25,10 +25,12 @@
 object BuiltInKeyguardQuickAffordanceKeys {
     // Please keep alphabetical order of const names to simplify future maintenance.
     const val CAMERA = "camera"
+    const val CREATE_NOTE = "create_note"
     const val DO_NOT_DISTURB = "do_not_disturb"
     const val FLASHLIGHT = "flashlight"
     const val HOME_CONTROLS = "home"
     const val QR_CODE_SCANNER = "qr_code_scanner"
     const val QUICK_ACCESS_WALLET = "wallet"
+    const val VIDEO_CAMERA = "video_camera"
     // Please keep alphabetical order of const names to simplify future maintenance.
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt
index dbc376e..f6e6d6b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt
@@ -26,6 +26,7 @@
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.statusbar.StatusBarState
 import dagger.Lazy
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
@@ -46,7 +47,7 @@
         get() = context.getString(R.string.accessibility_camera_button)
 
     override val pickerIconResourceId: Int
-        get() = com.android.internal.R.drawable.perm_group_camera
+        get() = R.drawable.ic_camera
 
     override val lockScreenState: Flow<KeyguardQuickAffordanceConfig.LockScreenState>
         get() =
@@ -54,12 +55,20 @@
                 KeyguardQuickAffordanceConfig.LockScreenState.Visible(
                     icon =
                         Icon.Resource(
-                            com.android.internal.R.drawable.perm_group_camera,
+                            R.drawable.ic_camera,
                             ContentDescription.Resource(R.string.accessibility_camera_button)
                         )
                 )
             )
 
+    override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState {
+        return if (isLaunchable()) {
+            super.getPickerScreenState()
+        } else {
+            KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice
+        }
+    }
+
     override fun onTriggered(
         expandable: Expandable?
     ): KeyguardQuickAffordanceConfig.OnTriggeredResult {
@@ -68,4 +77,8 @@
             .launchCamera(StatusBarManager.CAMERA_LAUNCH_SOURCE_QUICK_AFFORDANCE)
         return KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled
     }
+
+    private fun isLaunchable(): Boolean {
+        return cameraGestureHelper.get().canCameraGestureBeLaunched(StatusBarState.KEYGUARD)
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
index 8efb366..be73f85 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.keyguard.data.quickaffordance
 
 import android.content.Context
+import android.content.Intent
 import android.net.Uri
 import android.provider.Settings
 import android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS
@@ -39,6 +40,7 @@
 import com.android.systemui.statusbar.policy.ZenModeController
 import com.android.systemui.util.settings.SecureSettings
 import com.android.systemui.util.settings.SettingsProxyExt.observerFlow
+import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.flow.Flow
@@ -48,10 +50,10 @@
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.onStart
-import javax.inject.Inject
 
 @SysUISingleton
-class DoNotDisturbQuickAffordanceConfig constructor(
+class DoNotDisturbQuickAffordanceConfig
+constructor(
     private val context: Context,
     private val controller: ZenModeController,
     private val secureSettings: SecureSettings,
@@ -59,7 +61,7 @@
     @Background private val backgroundDispatcher: CoroutineDispatcher,
     private val testConditionId: Uri?,
     testDialog: EnableZenModeDialog?,
-): KeyguardQuickAffordanceConfig {
+) : KeyguardQuickAffordanceConfig {
 
     @Inject
     constructor(
@@ -76,20 +78,23 @@
 
     private val conditionUri: Uri
         get() =
-            testConditionId ?: ZenModeConfig.toTimeCondition(
-                context,
-                settingsValue,
-                userTracker.userId,
-                true, /* shortVersion */
-            ).id
+            testConditionId
+                ?: ZenModeConfig.toTimeCondition(
+                        context,
+                        settingsValue,
+                        userTracker.userId,
+                        true, /* shortVersion */
+                    )
+                    .id
 
     private val dialog: EnableZenModeDialog by lazy {
-        testDialog ?: EnableZenModeDialog(
-            context,
-            R.style.Theme_SystemUI_Dialog,
-            true, /* cancelIsNeutral */
-            ZenModeDialogMetricsLogger(context),
-        )
+        testDialog
+            ?: EnableZenModeDialog(
+                context,
+                R.style.Theme_SystemUI_Dialog,
+                true, /* cancelIsNeutral */
+                ZenModeDialogMetricsLogger(context),
+            )
     }
 
     override val key: String = BuiltInKeyguardQuickAffordanceKeys.DO_NOT_DISTURB
@@ -98,58 +103,62 @@
 
     override val pickerIconResourceId: Int = R.drawable.ic_do_not_disturb
 
-    override val lockScreenState: Flow<KeyguardQuickAffordanceConfig.LockScreenState> = combine(
-        conflatedCallbackFlow {
-            val callback = object: ZenModeController.Callback {
-                override fun onZenChanged(zen: Int) {
-                    dndMode = zen
-                    trySendWithFailureLogging(updateState(), TAG)
-                }
+    override val lockScreenState: Flow<KeyguardQuickAffordanceConfig.LockScreenState> =
+        combine(
+            conflatedCallbackFlow {
+                val callback =
+                    object : ZenModeController.Callback {
+                        override fun onZenChanged(zen: Int) {
+                            dndMode = zen
+                            trySendWithFailureLogging(updateState(), TAG)
+                        }
 
-                override fun onZenAvailableChanged(available: Boolean) {
-                    isAvailable = available
-                    trySendWithFailureLogging(updateState(), TAG)
-                }
-            }
+                        override fun onZenAvailableChanged(available: Boolean) {
+                            isAvailable = available
+                            trySendWithFailureLogging(updateState(), TAG)
+                        }
+                    }
 
-            dndMode = controller.zen
-            isAvailable = controller.isZenAvailable
-            trySendWithFailureLogging(updateState(), TAG)
+                dndMode = controller.zen
+                isAvailable = controller.isZenAvailable
+                trySendWithFailureLogging(updateState(), TAG)
 
-            controller.addCallback(callback)
+                controller.addCallback(callback)
 
-            awaitClose { controller.removeCallback(callback) }
-        },
-        secureSettings
-            .observerFlow(Settings.Secure.ZEN_DURATION)
-            .onStart { emit(Unit) }
-            .map { secureSettings.getInt(Settings.Secure.ZEN_DURATION, ZEN_MODE_OFF) }
-            .flowOn(backgroundDispatcher)
-            .distinctUntilChanged()
-            .onEach { settingsValue = it }
-    ) { callbackFlowValue, _ -> callbackFlowValue }
+                awaitClose { controller.removeCallback(callback) }
+            },
+            secureSettings
+                .observerFlow(userTracker.userId, Settings.Secure.ZEN_DURATION)
+                .onStart { emit(Unit) }
+                .map { secureSettings.getInt(Settings.Secure.ZEN_DURATION, ZEN_MODE_OFF) }
+                .flowOn(backgroundDispatcher)
+                .distinctUntilChanged()
+                .onEach { settingsValue = it }
+        ) { callbackFlowValue, _ -> callbackFlowValue }
 
     override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState {
         return if (controller.isZenAvailable) {
-            KeyguardQuickAffordanceConfig.PickerScreenState.Default
+            KeyguardQuickAffordanceConfig.PickerScreenState.Default(
+                configureIntent = Intent(Settings.ACTION_ZEN_MODE_SETTINGS)
+            )
         } else {
             KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice
         }
     }
 
-    override fun onTriggered(expandable: Expandable?):
-            KeyguardQuickAffordanceConfig.OnTriggeredResult {
+    override fun onTriggered(
+        expandable: Expandable?
+    ): KeyguardQuickAffordanceConfig.OnTriggeredResult {
         return when {
-            !isAvailable ->
-                KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled
+            !isAvailable -> KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled
             dndMode != ZEN_MODE_OFF -> {
                 controller.setZen(ZEN_MODE_OFF, null, TAG)
                 KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled
             }
             settingsValue == ZEN_DURATION_PROMPT ->
                 KeyguardQuickAffordanceConfig.OnTriggeredResult.ShowDialog(
-                        dialog.createDialog(),
-                        expandable
+                    dialog.createDialog(),
+                    expandable
                 )
             settingsValue == ZEN_DURATION_FOREVER -> {
                 controller.setZen(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, TAG)
@@ -187,4 +196,4 @@
     companion object {
         const val TAG = "DoNotDisturbQuickAffordanceConfig"
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt
index 62fe80a..3412f35 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt
@@ -135,7 +135,7 @@
 
     override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState =
         if (flashlightController.isAvailable) {
-            KeyguardQuickAffordanceConfig.PickerScreenState.Default
+            KeyguardQuickAffordanceConfig.PickerScreenState.Default()
         } else {
             KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice
         }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt
index 394426d..a1e9137d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt
@@ -81,10 +81,6 @@
                 instructions =
                     listOf(
                         context.getString(
-                            R.string.keyguard_affordance_enablement_dialog_message,
-                            pickerName,
-                        ),
-                        context.getString(
                             R.string.keyguard_affordance_enablement_dialog_home_instruction_1
                         ),
                         context.getString(
@@ -94,7 +90,7 @@
             )
         }
 
-        return KeyguardQuickAffordanceConfig.PickerScreenState.Default
+        return KeyguardQuickAffordanceConfig.PickerScreenState.Default()
     }
 
     override fun onTriggered(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt
index 71d01eb..a1cce5c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt
@@ -39,6 +39,7 @@
             quickAccessWallet: QuickAccessWalletKeyguardQuickAffordanceConfig,
             qrCodeScanner: QrCodeScannerKeyguardQuickAffordanceConfig,
             camera: CameraQuickAffordanceConfig,
+            videoCamera: VideoCameraQuickAffordanceConfig,
         ): Set<KeyguardQuickAffordanceConfig> {
             return setOf(
                 camera,
@@ -47,6 +48,7 @@
                 home,
                 quickAccessWallet,
                 qrCodeScanner,
+                videoCamera,
             )
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt
index 02ebcd3..e32edcb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt
@@ -22,7 +22,7 @@
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
-import com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderContract as Contract
+import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
 import kotlinx.coroutines.flow.Flow
 
 /** Defines interface that can act as data source for a single quick affordance model. */
@@ -46,7 +46,7 @@
      * Returns the [PickerScreenState] representing the affordance in the settings or selector
      * experience.
      */
-    suspend fun getPickerScreenState(): PickerScreenState = PickerScreenState.Default
+    suspend fun getPickerScreenState(): PickerScreenState = PickerScreenState.Default()
 
     /**
      * Notifies that the affordance was clicked by the user.
@@ -63,7 +63,10 @@
     sealed class PickerScreenState {
 
         /** The picker shows the item for selecting this affordance as it normally would. */
-        object Default : PickerScreenState()
+        data class Default(
+            /** Optional [Intent] to use to start an activity to configure this affordance. */
+            val configureIntent: Intent? = null,
+        ) : PickerScreenState()
 
         /**
          * The picker does not show an item for selecting this affordance as it is not supported on
@@ -90,8 +93,9 @@
              * the user to be able to set up the quick affordance and make it enabled.
              *
              * This is either just an action for the `Intent` or a package name and action,
-             * separated by [Contract.AffordanceTable.COMPONENT_NAME_SEPARATOR] for convenience, you
-             * can use the [componentName] function.
+             * separated by
+             * [Contract.LockScreenQuickAffordances.AffordanceTable.COMPONENT_NAME_SEPARATOR] for
+             * convenience, you can use the [componentName] function.
              */
             val actionComponentName: String? = null,
         ) : PickerScreenState() {
@@ -145,8 +149,8 @@
 
         /**
          * Returning this as a result from the [onTriggered] method means that the implementation
-         * has _not_ taken care of the action and the system should show a Dialog using the
-         * given [AlertDialog] and [Expandable].
+         * has _not_ taken care of the action and the system should show a Dialog using the given
+         * [AlertDialog] and [Expandable].
          */
         data class ShowDialog(
             val dialog: AlertDialog,
@@ -162,7 +166,8 @@
             return when {
                 action.isNullOrEmpty() -> null
                 !packageName.isNullOrEmpty() ->
-                    "$packageName${Contract.AffordanceTable.COMPONENT_NAME_SEPARATOR}$action"
+                    "$packageName${Contract.LockScreenQuickAffordances.AffordanceTable
+                        .COMPONENT_NAME_SEPARATOR}$action"
                 else -> action
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceProviderClientFactory.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceProviderClientFactory.kt
index 727a813..60ef116 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceProviderClientFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceProviderClientFactory.kt
@@ -19,13 +19,13 @@
 
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.settings.UserTracker
-import com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderClient
-import com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderClientImpl
+import com.android.systemui.shared.customization.data.content.CustomizationProviderClient
+import com.android.systemui.shared.customization.data.content.CustomizationProviderClientImpl
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
 
 interface KeyguardQuickAffordanceProviderClientFactory {
-    fun create(): KeyguardQuickAffordanceProviderClient
+    fun create(): CustomizationProviderClient
 }
 
 class KeyguardQuickAffordanceProviderClientFactoryImpl
@@ -34,8 +34,8 @@
     private val userTracker: UserTracker,
     @Background private val backgroundDispatcher: CoroutineDispatcher,
 ) : KeyguardQuickAffordanceProviderClientFactory {
-    override fun create(): KeyguardQuickAffordanceProviderClient {
-        return KeyguardQuickAffordanceProviderClientImpl(
+    override fun create(): CustomizationProviderClient {
+        return CustomizationProviderClientImpl(
             context = userTracker.userContext,
             backgroundDispatcher = backgroundDispatcher,
         )
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManager.kt
index 8ffef25..e9bd889 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManager.kt
@@ -24,7 +24,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.settings.UserTracker
-import com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderClient
+import com.android.systemui.shared.customization.data.content.CustomizationProviderClient
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -69,7 +69,7 @@
         awaitClose { userTracker.removeCallback(callback) }
     }
 
-    private val clientOrNull: StateFlow<KeyguardQuickAffordanceProviderClient?> =
+    private val clientOrNull: StateFlow<CustomizationProviderClient?> =
         userId
             .distinctUntilChanged()
             .map { selectedUserId ->
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt
index a96ce77..ea6c107 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt
@@ -84,16 +84,12 @@
                     instructions =
                         listOf(
                             context.getString(
-                                R.string.keyguard_affordance_enablement_dialog_message,
-                                pickerName,
-                            ),
-                            context.getString(
                                 R.string
                                     .keyguard_affordance_enablement_dialog_qr_scanner_instruction
                             ),
                         ),
                 )
-            else -> KeyguardQuickAffordanceConfig.PickerScreenState.Default
+            else -> KeyguardQuickAffordanceConfig.PickerScreenState.Default()
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
index beb20ce..4ba2eb9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
@@ -100,9 +100,9 @@
 
     override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState {
         return when {
-            !walletController.isWalletEnabled ->
+            !walletController.walletClient.isWalletServiceAvailable ->
                 KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice
-            walletController.walletClient.tileIcon == null || queryCards().isEmpty() -> {
+            !walletController.isWalletEnabled || queryCards().isEmpty() -> {
                 val componentName =
                     walletController.walletClient.createWalletSettingsIntent().toComponentName()
                 val actionText =
@@ -118,10 +118,6 @@
                     instructions =
                         listOf(
                             context.getString(
-                                R.string.keyguard_affordance_enablement_dialog_message,
-                                pickerName,
-                            ),
-                            context.getString(
                                 R.string.keyguard_affordance_enablement_dialog_wallet_instruction_1
                             ),
                             context.getString(
@@ -132,7 +128,7 @@
                     actionComponentName = componentName,
                 )
             }
-            else -> KeyguardQuickAffordanceConfig.PickerScreenState.Default
+            else -> KeyguardQuickAffordanceConfig.PickerScreenState.Default()
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt
new file mode 100644
index 0000000..d9ec3b1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt
@@ -0,0 +1,105 @@
+/*
+ *  Copyright (C) 2023 The Android Open Source Project
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package com.android.systemui.keyguard.data.quickaffordance
+
+import android.app.StatusBarManager
+import android.content.Context
+import android.content.Intent
+import com.android.systemui.ActivityIntentHelper
+import com.android.systemui.R
+import com.android.systemui.animation.Expandable
+import com.android.systemui.camera.CameraIntents
+import com.android.systemui.camera.CameraIntentsWrapper
+import com.android.systemui.common.shared.model.ContentDescription
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.settings.UserTracker
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flowOf
+
+@SysUISingleton
+class VideoCameraQuickAffordanceConfig
+@Inject
+constructor(
+    @Application private val context: Context,
+    private val cameraIntents: CameraIntentsWrapper,
+    private val activityIntentHelper: ActivityIntentHelper,
+    private val userTracker: UserTracker,
+) : KeyguardQuickAffordanceConfig {
+
+    private val intent: Intent by lazy {
+        cameraIntents.getVideoCameraIntent().apply {
+            putExtra(
+                CameraIntents.EXTRA_LAUNCH_SOURCE,
+                StatusBarManager.CAMERA_LAUNCH_SOURCE_QUICK_AFFORDANCE,
+            )
+        }
+    }
+
+    override val key: String
+        get() = BuiltInKeyguardQuickAffordanceKeys.VIDEO_CAMERA
+
+    override val pickerName: String
+        get() = context.getString(R.string.video_camera)
+
+    override val pickerIconResourceId: Int
+        get() = R.drawable.ic_videocam
+
+    override val lockScreenState: Flow<KeyguardQuickAffordanceConfig.LockScreenState>
+        get() =
+            flowOf(
+                if (isLaunchable()) {
+                    KeyguardQuickAffordanceConfig.LockScreenState.Visible(
+                        icon =
+                            Icon.Resource(
+                                R.drawable.ic_videocam,
+                                ContentDescription.Resource(R.string.video_camera)
+                            )
+                    )
+                } else {
+                    KeyguardQuickAffordanceConfig.LockScreenState.Hidden
+                }
+            )
+
+    override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState {
+        return if (isLaunchable()) {
+            super.getPickerScreenState()
+        } else {
+            KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice
+        }
+    }
+
+    override fun onTriggered(
+        expandable: Expandable?
+    ): KeyguardQuickAffordanceConfig.OnTriggeredResult {
+        return KeyguardQuickAffordanceConfig.OnTriggeredResult.StartActivity(
+            intent = intent,
+            canShowWhileLocked = false,
+        )
+    }
+
+    private fun isLaunchable(): Boolean {
+        return activityIntentHelper.getTargetActivityInfo(
+            intent,
+            userTracker.userId,
+            true,
+        ) != null
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricRepository.kt
new file mode 100644
index 0000000..25d8f40
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricRepository.kt
@@ -0,0 +1,184 @@
+/*
+ * 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.data.repository
+
+import android.app.admin.DevicePolicyManager
+import android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
+import android.content.Context
+import android.content.IntentFilter
+import android.os.Looper
+import android.os.UserHandle
+import com.android.internal.widget.LockPatternUtils
+import com.android.systemui.biometrics.AuthController
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
+import com.android.systemui.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.user.data.repository.UserRepository
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.flow.transformLatest
+
+/**
+ * Acts as source of truth for biometric features.
+ *
+ * Abstracts-away data sources and their schemas so the rest of the app doesn't need to worry about
+ * upstream changes.
+ */
+interface BiometricRepository {
+    /** Whether any fingerprints are enrolled for the current user. */
+    val isFingerprintEnrolled: StateFlow<Boolean>
+
+    /**
+     * Whether the current user is allowed to use a strong biometric for device entry based on
+     * Android Security policies. If false, the user may be able to use primary authentication for
+     * device entry.
+     */
+    val isStrongBiometricAllowed: StateFlow<Boolean>
+
+    /** Whether fingerprint feature is enabled for the current user by the DevicePolicy */
+    val isFingerprintEnabledByDevicePolicy: StateFlow<Boolean>
+}
+
+@SysUISingleton
+class BiometricRepositoryImpl
+@Inject
+constructor(
+    context: Context,
+    lockPatternUtils: LockPatternUtils,
+    broadcastDispatcher: BroadcastDispatcher,
+    authController: AuthController,
+    userRepository: UserRepository,
+    devicePolicyManager: DevicePolicyManager,
+    @Application scope: CoroutineScope,
+    @Background backgroundDispatcher: CoroutineDispatcher,
+    @Main looper: Looper,
+) : BiometricRepository {
+
+    /** UserId of the current selected user. */
+    private val selectedUserId: Flow<Int> =
+        userRepository.selectedUserInfo.map { it.id }.distinctUntilChanged()
+
+    override val isFingerprintEnrolled: StateFlow<Boolean> =
+        selectedUserId
+            .flatMapLatest { userId ->
+                conflatedCallbackFlow {
+                    val callback =
+                        object : AuthController.Callback {
+                            override fun onEnrollmentsChanged(
+                                sensorBiometricType: BiometricType,
+                                userId: Int,
+                                hasEnrollments: Boolean
+                            ) {
+                                if (sensorBiometricType.isFingerprint) {
+                                    trySendWithFailureLogging(
+                                        hasEnrollments,
+                                        TAG,
+                                        "update fpEnrollment"
+                                    )
+                                }
+                            }
+                        }
+                    authController.addCallback(callback)
+                    awaitClose { authController.removeCallback(callback) }
+                }
+            }
+            .stateIn(
+                scope,
+                started = SharingStarted.Eagerly,
+                initialValue =
+                    authController.isFingerprintEnrolled(userRepository.getSelectedUserInfo().id)
+            )
+
+    override val isStrongBiometricAllowed: StateFlow<Boolean> =
+        selectedUserId
+            .flatMapLatest { currUserId ->
+                conflatedCallbackFlow {
+                    val callback =
+                        object : LockPatternUtils.StrongAuthTracker(context, looper) {
+                            override fun onStrongAuthRequiredChanged(userId: Int) {
+                                if (currUserId != userId) {
+                                    return
+                                }
+
+                                trySendWithFailureLogging(
+                                    isBiometricAllowedForUser(true, currUserId),
+                                    TAG
+                                )
+                            }
+
+                            override fun onIsNonStrongBiometricAllowedChanged(userId: Int) {
+                                // no-op
+                            }
+                        }
+                    lockPatternUtils.registerStrongAuthTracker(callback)
+                    awaitClose { lockPatternUtils.unregisterStrongAuthTracker(callback) }
+                }
+            }
+            .stateIn(
+                scope,
+                started = SharingStarted.Eagerly,
+                initialValue =
+                    lockPatternUtils.isBiometricAllowedForUser(
+                        userRepository.getSelectedUserInfo().id
+                    )
+            )
+
+    override val isFingerprintEnabledByDevicePolicy: StateFlow<Boolean> =
+        selectedUserId
+            .flatMapLatest { userId ->
+                broadcastDispatcher
+                    .broadcastFlow(
+                        filter = IntentFilter(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
+                        user = UserHandle.ALL
+                    )
+                    .transformLatest {
+                        emit(
+                            (devicePolicyManager.getKeyguardDisabledFeatures(null, userId) and
+                                DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) == 0
+                        )
+                    }
+                    .flowOn(backgroundDispatcher)
+                    .distinctUntilChanged()
+            }
+            .stateIn(
+                scope,
+                started = SharingStarted.Eagerly,
+                initialValue =
+                    devicePolicyManager.getKeyguardDisabledFeatures(
+                        null,
+                        userRepository.getSelectedUserInfo().id
+                    ) and DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT == 0
+            )
+
+    companion object {
+        private const val TAG = "BiometricsRepositoryImpl"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricType.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricType.kt
new file mode 100644
index 0000000..93c9781
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricType.kt
@@ -0,0 +1,33 @@
+/*
+ * 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.data.repository
+
+enum class BiometricType(val isFingerprint: Boolean) {
+    // An unsupported biometric type
+    UNKNOWN(false),
+
+    // Fingerprint sensor that is located on the back (opposite side of the display) of the device
+    REAR_FINGERPRINT(true),
+
+    // Fingerprint sensor that is located under the display
+    UNDER_DISPLAY_FINGERPRINT(true),
+
+    // Fingerprint sensor that is located on the side of the device, typically on the power button
+    SIDE_FINGERPRINT(true),
+    FACE(false),
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepository.kt
new file mode 100644
index 0000000..08edbc6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepository.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.systemui.keyguard.data.repository
+
+import android.hardware.biometrics.BiometricSourceType
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+
+/** Encapsulates state about device entry fingerprint auth mechanism. */
+interface DeviceEntryFingerprintAuthRepository {
+    /** Whether the device entry fingerprint auth is locked out. */
+    val isLockedOut: Flow<Boolean>
+}
+
+/**
+ * Implementation of [DeviceEntryFingerprintAuthRepository] that uses [KeyguardUpdateMonitor] as the
+ * source of truth.
+ *
+ * Dependency on [KeyguardUpdateMonitor] will be removed once fingerprint auth state is moved out of
+ * [KeyguardUpdateMonitor]
+ */
+@SysUISingleton
+class DeviceEntryFingerprintAuthRepositoryImpl
+@Inject
+constructor(
+    val keyguardUpdateMonitor: KeyguardUpdateMonitor,
+) : DeviceEntryFingerprintAuthRepository {
+
+    override val isLockedOut: Flow<Boolean> = conflatedCallbackFlow {
+        val sendLockoutUpdate =
+            fun() {
+                trySendWithFailureLogging(
+                    keyguardUpdateMonitor.isFingerprintLockedOut,
+                    TAG,
+                    "onLockedOutStateChanged"
+                )
+            }
+        val callback =
+            object : KeyguardUpdateMonitorCallback() {
+                override fun onLockedOutStateChanged(biometricSourceType: BiometricSourceType?) {
+                    if (biometricSourceType == BiometricSourceType.FINGERPRINT) {
+                        sendLockoutUpdate()
+                    }
+                }
+            }
+        keyguardUpdateMonitor.registerCallback(callback)
+        sendLockoutUpdate()
+        awaitClose { keyguardUpdateMonitor.removeCallback(callback) }
+    }
+
+    companion object {
+        const val TAG = "DeviceEntryFingerprintAuthRepositoryImpl"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepository.kt
index 90f3c7d..41574d1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepository.kt
@@ -20,15 +20,18 @@
 import com.android.keyguard.ViewMediatorCallback
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_HIDDEN
 import com.android.systemui.keyguard.shared.model.BouncerShowMessageModel
 import com.android.systemui.keyguard.shared.model.KeyguardBouncerModel
 import com.android.systemui.log.dagger.BouncerLog
 import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.log.table.logDiffsForTable
 import com.android.systemui.statusbar.phone.KeyguardBouncer
+import com.android.systemui.util.time.SystemClock
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.asStateFlow
 import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.flow.launchIn
@@ -44,6 +47,7 @@
 @Inject
 constructor(
     private val viewMediatorCallback: ViewMediatorCallback,
+    private val clock: SystemClock,
     @Application private val applicationScope: CoroutineScope,
     @BouncerLog private val buffer: TableLogBuffer,
 ) {
@@ -70,7 +74,7 @@
      *      1f = panel fully showing = bouncer fully hidden
      * ```
      */
-    private val _panelExpansionAmount = MutableStateFlow(KeyguardBouncer.EXPANSION_HIDDEN)
+    private val _panelExpansionAmount = MutableStateFlow(EXPANSION_HIDDEN)
     val panelExpansionAmount = _panelExpansionAmount.asStateFlow()
     private val _keyguardPosition = MutableStateFlow(0f)
     val keyguardPosition = _keyguardPosition.asStateFlow()
@@ -94,6 +98,14 @@
         setUpLogging()
     }
 
+    /** Values associated with the AlternateBouncer */
+    private val _isAlternateBouncerVisible = MutableStateFlow(false)
+    val isAlternateBouncerVisible = _isAlternateBouncerVisible.asStateFlow()
+    var lastAlternateBouncerVisibleTime: Long = NOT_VISIBLE
+    private val _isAlternateBouncerUIAvailable = MutableStateFlow<Boolean>(false)
+    val isAlternateBouncerUIAvailable: StateFlow<Boolean> =
+        _isAlternateBouncerUIAvailable.asStateFlow()
+
     fun setPrimaryScrimmed(isScrimmed: Boolean) {
         _primaryBouncerScrimmed.value = isScrimmed
     }
@@ -102,6 +114,19 @@
         _primaryBouncerVisible.value = isVisible
     }
 
+    fun setAlternateVisible(isVisible: Boolean) {
+        if (isVisible && !_isAlternateBouncerVisible.value) {
+            lastAlternateBouncerVisibleTime = clock.uptimeMillis()
+        } else if (!isVisible) {
+            lastAlternateBouncerVisibleTime = NOT_VISIBLE
+        }
+        _isAlternateBouncerVisible.value = isVisible
+    }
+
+    fun setAlternateBouncerUIAvailable(isAvailable: Boolean) {
+        _isAlternateBouncerUIAvailable.value = isAvailable
+    }
+
     fun setPrimaryShow(keyguardBouncerModel: KeyguardBouncerModel?) {
         _primaryBouncerShow.value = keyguardBouncerModel
     }
@@ -202,4 +227,8 @@
             .logDiffsForTable(buffer, "", "ResourceUpdateRequests", false)
             .launchIn(applicationScope)
     }
+
+    companion object {
+        private const val NOT_VISIBLE = -1L
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
index e3f5e90..2b2b9d0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
@@ -187,6 +187,8 @@
                 pickerState is KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice
             }
             .map { (config, pickerState) ->
+                val defaultPickerState =
+                    pickerState as? KeyguardQuickAffordanceConfig.PickerScreenState.Default
                 val disabledPickerState =
                     pickerState as? KeyguardQuickAffordanceConfig.PickerScreenState.Disabled
                 KeyguardQuickAffordancePickerRepresentation(
@@ -198,6 +200,7 @@
                     instructions = disabledPickerState?.instructions,
                     actionText = disabledPickerState?.actionText,
                     actionComponentName = disabledPickerState?.actionComponentName,
+                    configureIntent = defaultPickerState?.configureIntent,
                 )
             }
     }
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 a4fd087..d99af90 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
@@ -40,6 +40,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.statusbar.phone.BiometricUnlockController
 import com.android.systemui.statusbar.phone.BiometricUnlockController.WakeAndUnlockMode
+import com.android.systemui.statusbar.phone.DozeParameters
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import javax.inject.Inject
 import kotlinx.coroutines.channels.awaitClose
@@ -88,6 +89,9 @@
     /** Observable for whether the bouncer is showing. */
     val isBouncerShowing: Flow<Boolean>
 
+    /** Is the always-on display available to be used? */
+    val isAodAvailable: Flow<Boolean>
+
     /**
      * Observable for whether we are in doze state.
      *
@@ -182,6 +186,7 @@
     private val keyguardStateController: KeyguardStateController,
     private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
     private val dozeTransitionListener: DozeTransitionListener,
+    private val dozeParameters: DozeParameters,
     private val authController: AuthController,
     private val dreamOverlayCallbackController: DreamOverlayCallbackController,
 ) : KeyguardRepository {
@@ -220,6 +225,31 @@
             }
             .distinctUntilChanged()
 
+    override val isAodAvailable: Flow<Boolean> =
+        conflatedCallbackFlow {
+                val callback =
+                    object : DozeParameters.Callback {
+                        override fun onAlwaysOnChange() {
+                            trySendWithFailureLogging(
+                                dozeParameters.getAlwaysOn(),
+                                TAG,
+                                "updated isAodAvailable"
+                            )
+                        }
+                    }
+
+                dozeParameters.addCallback(callback)
+                // Adding the callback does not send an initial update.
+                trySendWithFailureLogging(
+                    dozeParameters.getAlwaysOn(),
+                    TAG,
+                    "initial isAodAvailable"
+                )
+
+                awaitClose { dozeParameters.removeCallback(callback) }
+            }
+            .distinctUntilChanged()
+
     override val isKeyguardOccluded: Flow<Boolean> =
         conflatedCallbackFlow {
                 val callback =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryModule.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryModule.kt
index 26f853f..4639597 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryModule.kt
@@ -30,4 +30,6 @@
 
     @Binds
     fun lightRevealScrimRepository(impl: LightRevealScrimRepositoryImpl): LightRevealScrimRepository
+
+    @Binds fun biometricRepository(impl: BiometricRepositoryImpl): BiometricRepository
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt
index 343c2dc..0c4bca6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt
@@ -135,11 +135,14 @@
             Log.i(TAG, "Duplicate call to start the transition, rejecting: $info")
             return null
         }
-        if (lastStep.transitionState != TransitionState.FINISHED) {
-            Log.i(TAG, "Transition still active: $lastStep, canceling")
-        }
+        val startingValue =
+            if (lastStep.transitionState != TransitionState.FINISHED) {
+                Log.i(TAG, "Transition still active: $lastStep, canceling")
+                lastStep.value
+            } else {
+                0f
+            }
 
-        val startingValue = 1f - lastStep.value
         lastAnimator?.cancel()
         lastAnimator = info.animator
 
@@ -206,7 +209,7 @@
             return
         }
 
-        if (state == TransitionState.FINISHED) {
+        if (state == TransitionState.FINISHED || state == TransitionState.CANCELED) {
             updateTransitionId = null
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt
new file mode 100644
index 0000000..d90f328
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.data.repository
+
+import android.app.trust.TrustManager
+import com.android.keyguard.logging.TrustRepositoryLogger
+import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.keyguard.shared.model.TrustModel
+import com.android.systemui.user.data.repository.UserRepository
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.onStart
+import kotlinx.coroutines.flow.shareIn
+
+/** Encapsulates any state relevant to trust agents and trust grants. */
+interface TrustRepository {
+    /** Flow representing whether the current user is trusted. */
+    val isCurrentUserTrusted: Flow<Boolean>
+}
+
+@SysUISingleton
+class TrustRepositoryImpl
+@Inject
+constructor(
+    @Application private val applicationScope: CoroutineScope,
+    private val userRepository: UserRepository,
+    private val trustManager: TrustManager,
+    private val logger: TrustRepositoryLogger,
+) : TrustRepository {
+    private val latestTrustModelForUser = mutableMapOf<Int, TrustModel>()
+
+    private val trust =
+        conflatedCallbackFlow {
+                val callback =
+                    object : TrustManager.TrustListener {
+                        override fun onTrustChanged(
+                            enabled: Boolean,
+                            newlyUnlocked: Boolean,
+                            userId: Int,
+                            flags: Int,
+                            grantMsgs: List<String>?
+                        ) {
+                            logger.onTrustChanged(enabled, newlyUnlocked, userId, flags, grantMsgs)
+                            trySendWithFailureLogging(
+                                TrustModel(enabled, userId),
+                                TrustRepositoryLogger.TAG,
+                                "onTrustChanged"
+                            )
+                        }
+
+                        override fun onTrustError(message: CharSequence?) = Unit
+
+                        override fun onTrustManagedChanged(enabled: Boolean, userId: Int) = Unit
+                    }
+                trustManager.registerTrustListener(callback)
+                logger.trustListenerRegistered()
+                awaitClose {
+                    logger.trustListenerUnregistered()
+                    trustManager.unregisterTrustListener(callback)
+                }
+            }
+            .onEach {
+                latestTrustModelForUser[it.userId] = it
+                logger.trustModelEmitted(it)
+            }
+            .shareIn(applicationScope, started = SharingStarted.Eagerly, replay = 1)
+
+    override val isCurrentUserTrusted: Flow<Boolean>
+        get() =
+            combine(trust, userRepository.selectedUserInfo, ::Pair)
+                .map { latestTrustModelForUser[it.second.id]?.isTrusted ?: false }
+                .distinctUntilChanged()
+                .onEach { logger.isCurrentUserTrusted(it) }
+                .onStart { emit(false) }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt
new file mode 100644
index 0000000..28c0b28
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt
@@ -0,0 +1,126 @@
+/*
+ * 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.interactor
+
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.data.repository.BiometricRepository
+import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepository
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager.LegacyAlternateBouncer
+import com.android.systemui.util.time.SystemClock
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+
+/** Encapsulates business logic for interacting with the lock-screen alternate bouncer. */
+@SysUISingleton
+class AlternateBouncerInteractor
+@Inject
+constructor(
+    private val bouncerRepository: KeyguardBouncerRepository,
+    private val biometricRepository: BiometricRepository,
+    private val systemClock: SystemClock,
+    private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
+    featureFlags: FeatureFlags,
+) {
+    val isModernAlternateBouncerEnabled = featureFlags.isEnabled(Flags.MODERN_ALTERNATE_BOUNCER)
+    var legacyAlternateBouncer: LegacyAlternateBouncer? = null
+    var legacyAlternateBouncerVisibleTime: Long = NOT_VISIBLE
+
+    val isVisible: Flow<Boolean> = bouncerRepository.isAlternateBouncerVisible
+
+    /**
+     * Sets the correct bouncer states to show the alternate bouncer if it can show.
+     * @return whether alternateBouncer is visible
+     */
+    fun show(): Boolean {
+        return when {
+            isModernAlternateBouncerEnabled -> {
+                bouncerRepository.setAlternateVisible(canShowAlternateBouncerForFingerprint())
+                isVisibleState()
+            }
+            canShowAlternateBouncerForFingerprint() -> {
+                if (legacyAlternateBouncer?.showAlternateBouncer() == true) {
+                    legacyAlternateBouncerVisibleTime = systemClock.uptimeMillis()
+                    true
+                } else {
+                    false
+                }
+            }
+            else -> false
+        }
+    }
+
+    /**
+     * Sets the correct bouncer states to hide the bouncer. Should only be called through
+     * StatusBarKeyguardViewManager until ScrimController is refactored to use
+     * alternateBouncerInteractor.
+     * @return true if the alternate bouncer was newly hidden, else false.
+     */
+    fun hide(): Boolean {
+        return if (isModernAlternateBouncerEnabled) {
+            val wasAlternateBouncerVisible = isVisibleState()
+            bouncerRepository.setAlternateVisible(false)
+            wasAlternateBouncerVisible && !isVisibleState()
+        } else {
+            legacyAlternateBouncer?.hideAlternateBouncer() ?: false
+        }
+    }
+
+    fun isVisibleState(): Boolean {
+        return if (isModernAlternateBouncerEnabled) {
+            bouncerRepository.isAlternateBouncerVisible.value
+        } else {
+            legacyAlternateBouncer?.isShowingAlternateBouncer ?: false
+        }
+    }
+
+    fun setAlternateBouncerUIAvailable(isAvailable: Boolean) {
+        bouncerRepository.setAlternateBouncerUIAvailable(isAvailable)
+    }
+
+    fun canShowAlternateBouncerForFingerprint(): Boolean {
+        return if (isModernAlternateBouncerEnabled) {
+            bouncerRepository.isAlternateBouncerUIAvailable.value &&
+                biometricRepository.isFingerprintEnrolled.value &&
+                biometricRepository.isStrongBiometricAllowed.value &&
+                biometricRepository.isFingerprintEnabledByDevicePolicy.value
+        } else {
+            legacyAlternateBouncer != null &&
+                keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(true)
+        }
+    }
+
+    /**
+     * Whether the alt bouncer has shown for a minimum time before allowing touches to dismiss the
+     * alternate bouncer and show the primary bouncer.
+     */
+    fun hasAlternateBouncerShownWithMinTime(): Boolean {
+        return if (isModernAlternateBouncerEnabled) {
+            (systemClock.uptimeMillis() - bouncerRepository.lastAlternateBouncerVisibleTime) >
+                MIN_VISIBILITY_DURATION_UNTIL_TOUCHES_DISMISS_ALTERNATE_BOUNCER_MS
+        } else {
+            systemClock.uptimeMillis() - legacyAlternateBouncerVisibleTime > 200
+        }
+    }
+
+    companion object {
+        private const val MIN_VISIBILITY_DURATION_UNTIL_TOUCHES_DISMISS_ALTERNATE_BOUNCER_MS = 200L
+        private const val NOT_VISIBLE = -1L
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
index fd2d271..ce61f2f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
@@ -21,9 +21,9 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
-import com.android.systemui.keyguard.shared.model.DozeStateModel.Companion.isDozeOff
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionInfo
+import com.android.systemui.keyguard.shared.model.WakefulnessModel.Companion.isWakingOrStartingToWake
 import com.android.systemui.util.kotlin.sample
 import javax.inject.Inject
 import kotlin.time.Duration
@@ -48,12 +48,11 @@
 
     private fun listenForDozingToLockscreen() {
         scope.launch {
-            keyguardInteractor.dozeTransitionModel
+            keyguardInteractor.wakefulnessModel
                 .sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair)
-                .collect { pair ->
-                    val (dozeTransitionModel, lastStartedTransition) = pair
+                .collect { (wakefulnessModel, lastStartedTransition) ->
                     if (
-                        isDozeOff(dozeTransitionModel.to) &&
+                        isWakingOrStartingToWake(wakefulnessModel) &&
                             lastStartedTransition.to == KeyguardState.DOZING
                     ) {
                         keyguardTransitionRepository.startTransition(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
index 3b09ae7..81a5828 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
@@ -21,7 +21,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
-import com.android.systemui.keyguard.shared.model.BiometricUnlockModel.Companion.isWakeAndUnlock
+import com.android.systemui.keyguard.shared.model.BiometricUnlockModel
 import com.android.systemui.keyguard.shared.model.DozeStateModel
 import com.android.systemui.keyguard.shared.model.DozeStateModel.Companion.isDozeOff
 import com.android.systemui.keyguard.shared.model.KeyguardState
@@ -31,8 +31,10 @@
 import kotlin.time.Duration
 import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.launch
 
 @SysUISingleton
@@ -56,7 +58,7 @@
         scope.launch {
             // Using isDreamingWithOverlay provides an optimized path to LOCKSCREEN state, which
             // otherwise would have gone through OCCLUDED first
-            keyguardInteractor.isDreamingWithOverlay
+            keyguardInteractor.isAbleToDream
                 .sample(
                     combine(
                         keyguardInteractor.dozeTransitionModel,
@@ -65,8 +67,7 @@
                     ),
                     ::toTriple
                 )
-                .collect { triple ->
-                    val (isDreaming, dozeTransitionModel, lastStartedTransition) = triple
+                .collect { (isDreaming, dozeTransitionModel, lastStartedTransition) ->
                     if (
                         !isDreaming &&
                             isDozeOff(dozeTransitionModel.to) &&
@@ -88,6 +89,9 @@
     private fun listenForDreamingToOccluded() {
         scope.launch {
             keyguardInteractor.isDreaming
+                // Add a slight delay, as dreaming and occluded events will arrive with a small gap
+                // in time. This prevents a transition to OCCLUSION happening prematurely.
+                .onEach { delay(50) }
                 .sample(
                     combine(
                         keyguardInteractor.isKeyguardOccluded,
@@ -96,8 +100,7 @@
                     ),
                     ::toTriple
                 )
-                .collect { triple ->
-                    val (isDreaming, isOccluded, lastStartedTransition) = triple
+                .collect { (isDreaming, isOccluded, lastStartedTransition) ->
                     if (
                         isOccluded &&
                             !isDreaming &&
@@ -123,24 +126,18 @@
 
     private fun listenForDreamingToGone() {
         scope.launch {
-            keyguardInteractor.biometricUnlockState
-                .sample(keyguardTransitionInteractor.finishedKeyguardState, ::Pair)
-                .collect { pair ->
-                    val (biometricUnlockState, keyguardState) = pair
-                    if (
-                        keyguardState == KeyguardState.DREAMING &&
-                            isWakeAndUnlock(biometricUnlockState)
-                    ) {
-                        keyguardTransitionRepository.startTransition(
-                            TransitionInfo(
-                                name,
-                                KeyguardState.DREAMING,
-                                KeyguardState.GONE,
-                                getAnimator(),
-                            )
+            keyguardInteractor.biometricUnlockState.collect { biometricUnlockState ->
+                if (biometricUnlockState == BiometricUnlockModel.WAKE_AND_UNLOCK_FROM_DREAM) {
+                    keyguardTransitionRepository.startTransition(
+                        TransitionInfo(
+                            name,
+                            KeyguardState.DREAMING,
+                            KeyguardState.GONE,
+                            getAnimator(),
                         )
-                    }
+                    )
                 }
+            }
         }
     }
 
@@ -151,8 +148,7 @@
                     keyguardTransitionInteractor.finishedKeyguardState,
                     ::Pair
                 )
-                .collect { pair ->
-                    val (dozeTransitionModel, keyguardState) = pair
+                .collect { (dozeTransitionModel, keyguardState) ->
                     if (
                         dozeTransitionModel.to == DozeStateModel.DOZE &&
                             keyguardState == KeyguardState.DREAMING
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
index 553fafe..14f918d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
@@ -26,7 +26,10 @@
 import com.android.systemui.keyguard.shared.model.WakefulnessState
 import com.android.systemui.util.kotlin.sample
 import javax.inject.Inject
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.launch
 
 @SysUISingleton
@@ -40,23 +43,22 @@
 ) : TransitionInteractor(FromGoneTransitionInteractor::class.simpleName!!) {
 
     override fun start() {
-        listenForGoneToAod()
+        listenForGoneToAodOrDozing()
         listenForGoneToDreaming()
     }
 
     private fun listenForGoneToDreaming() {
         scope.launch {
             keyguardInteractor.isAbleToDream
-                .sample(keyguardTransitionInteractor.finishedKeyguardState, ::Pair)
-                .collect { pair ->
-                    val (isAbleToDream, keyguardState) = pair
-                    if (isAbleToDream && keyguardState == KeyguardState.GONE) {
+                .sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair)
+                .collect { (isAbleToDream, lastStartedStep) ->
+                    if (isAbleToDream && lastStartedStep.to == KeyguardState.GONE) {
                         keyguardTransitionRepository.startTransition(
                             TransitionInfo(
                                 name,
                                 KeyguardState.GONE,
                                 KeyguardState.DREAMING,
-                                getAnimator(),
+                                getAnimator(TO_DREAMING_DURATION),
                             )
                         )
                     }
@@ -64,21 +66,31 @@
         }
     }
 
-    private fun listenForGoneToAod() {
+    private fun listenForGoneToAodOrDozing() {
         scope.launch {
             keyguardInteractor.wakefulnessModel
-                .sample(keyguardTransitionInteractor.finishedKeyguardState, ::Pair)
-                .collect { pair ->
-                    val (wakefulnessState, keyguardState) = pair
+                .sample(
+                    combine(
+                        keyguardTransitionInteractor.startedKeyguardTransitionStep,
+                        keyguardInteractor.isAodAvailable,
+                        ::Pair
+                    ),
+                    ::toTriple
+                )
+                .collect { (wakefulnessState, lastStartedStep, isAodAvailable) ->
                     if (
-                        keyguardState == KeyguardState.GONE &&
+                        lastStartedStep.to == KeyguardState.GONE &&
                             wakefulnessState.state == WakefulnessState.STARTING_TO_SLEEP
                     ) {
                         keyguardTransitionRepository.startTransition(
                             TransitionInfo(
                                 name,
                                 KeyguardState.GONE,
-                                KeyguardState.AOD,
+                                if (isAodAvailable) {
+                                    KeyguardState.AOD
+                                } else {
+                                    KeyguardState.DOZING
+                                },
                                 getAnimator(),
                             )
                         )
@@ -87,14 +99,15 @@
         }
     }
 
-    private fun getAnimator(): ValueAnimator {
+    private fun getAnimator(duration: Duration = DEFAULT_DURATION): ValueAnimator {
         return ValueAnimator().apply {
             setInterpolator(Interpolators.LINEAR)
-            setDuration(TRANSITION_DURATION_MS)
+            setDuration(duration.inWholeMilliseconds)
         }
     }
 
     companion object {
-        private const val TRANSITION_DURATION_MS = 500L
+        private val DEFAULT_DURATION = 500.milliseconds
+        val TO_DREAMING_DURATION = 933.milliseconds
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
index 326acc9..5674e2a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
@@ -21,15 +21,17 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
-import com.android.systemui.keyguard.shared.model.DozeStateModel
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.StatusBarState.KEYGUARD
 import com.android.systemui.keyguard.shared.model.TransitionInfo
 import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.keyguard.shared.model.WakefulnessState
 import com.android.systemui.shade.data.repository.ShadeRepository
 import com.android.systemui.util.kotlin.sample
 import java.util.UUID
 import javax.inject.Inject
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.flow.combine
@@ -46,12 +48,11 @@
     private val keyguardTransitionRepository: KeyguardTransitionRepository,
 ) : TransitionInteractor(FromLockscreenTransitionInteractor::class.simpleName!!) {
 
-    private var transitionId: UUID? = null
-
     override fun start() {
         listenForLockscreenToGone()
         listenForLockscreenToOccluded()
-        listenForLockscreenToAod()
+        listenForLockscreenToCamera()
+        listenForLockscreenToAodOrDozing()
         listenForLockscreenToBouncer()
         listenForLockscreenToDreaming()
         listenForLockscreenToBouncerDragging()
@@ -69,7 +70,7 @@
                                 name,
                                 KeyguardState.LOCKSCREEN,
                                 KeyguardState.DREAMING,
-                                getAnimator(),
+                                getAnimator(TO_DREAMING_DURATION),
                             )
                         )
                     }
@@ -101,6 +102,7 @@
 
     /* Starts transitions when manually dragging up the bouncer from the lockscreen. */
     private fun listenForLockscreenToBouncerDragging() {
+        var transitionId: UUID? = null
         scope.launch {
             shadeRepository.shadeModel
                 .sample(
@@ -111,25 +113,43 @@
                     ),
                     ::toTriple
                 )
-                .collect { triple ->
-                    val (shadeModel, keyguardState, statusBarState) = triple
-
+                .collect { (shadeModel, keyguardState, statusBarState) ->
                     val id = transitionId
                     if (id != null) {
                         // An existing `id` means a transition is started, and calls to
-                        // `updateTransition` will control it until FINISHED
-                        keyguardTransitionRepository.updateTransition(
-                            id,
-                            1f - shadeModel.expansionAmount,
-                            if (
-                                shadeModel.expansionAmount == 0f || shadeModel.expansionAmount == 1f
-                            ) {
-                                transitionId = null
+                        // `updateTransition` will control it until FINISHED or CANCELED
+                        var nextState =
+                            if (shadeModel.expansionAmount == 0f) {
                                 TransitionState.FINISHED
+                            } else if (shadeModel.expansionAmount == 1f) {
+                                TransitionState.CANCELED
                             } else {
                                 TransitionState.RUNNING
                             }
+                        keyguardTransitionRepository.updateTransition(
+                            id,
+                            1f - shadeModel.expansionAmount,
+                            nextState,
                         )
+
+                        if (
+                            nextState == TransitionState.CANCELED ||
+                                nextState == TransitionState.FINISHED
+                        ) {
+                            transitionId = null
+                        }
+
+                        // If canceled, just put the state back
+                        if (nextState == TransitionState.CANCELED) {
+                            keyguardTransitionRepository.startTransition(
+                                TransitionInfo(
+                                    ownerName = name,
+                                    from = KeyguardState.BOUNCER,
+                                    to = KeyguardState.LOCKSCREEN,
+                                    animator = getAnimator(0.milliseconds)
+                                )
+                            )
+                        }
                     } else {
                         // TODO (b/251849525): Remove statusbarstate check when that state is
                         // integrated into KeyguardTransitionRepository
@@ -184,17 +204,14 @@
                     ),
                     ::toTriple
                 )
-                .collect { triple ->
-                    val (isOccluded, keyguardState, isDreaming) = triple
-                    // Occlusion signals come from the framework, and should interrupt any
-                    // existing transition
-                    if (isOccluded && !isDreaming) {
+                .collect { (isOccluded, keyguardState, isDreaming) ->
+                    if (isOccluded && !isDreaming && keyguardState == KeyguardState.LOCKSCREEN) {
                         keyguardTransitionRepository.startTransition(
                             TransitionInfo(
                                 name,
                                 keyguardState,
                                 KeyguardState.OCCLUDED,
-                                getAnimator(),
+                                getAnimator(TO_OCCLUDED_DURATION),
                             )
                         )
                     }
@@ -202,19 +219,59 @@
         }
     }
 
-    private fun listenForLockscreenToAod() {
+    /** This signal may come in before the occlusion signal, and can provide a custom transition */
+    private fun listenForLockscreenToCamera() {
         scope.launch {
-            keyguardInteractor
-                .dozeTransitionTo(DozeStateModel.DOZE_AOD)
+            keyguardInteractor.onCameraLaunchDetected
                 .sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair)
-                .collect { pair ->
-                    val (dozeToAod, lastStartedStep) = pair
-                    if (lastStartedStep.to == KeyguardState.LOCKSCREEN) {
+                .collect { (_, lastStartedStep) ->
+                    // DREAMING/AOD/OFF may trigger on the first power button push, so include this
+                    // state in order to cancel and correct the transition
+                    if (
+                        lastStartedStep.to == KeyguardState.LOCKSCREEN ||
+                            lastStartedStep.to == KeyguardState.DREAMING ||
+                            lastStartedStep.to == KeyguardState.DOZING ||
+                            lastStartedStep.to == KeyguardState.AOD ||
+                            lastStartedStep.to == KeyguardState.OFF
+                    ) {
                         keyguardTransitionRepository.startTransition(
                             TransitionInfo(
                                 name,
                                 KeyguardState.LOCKSCREEN,
-                                KeyguardState.AOD,
+                                KeyguardState.OCCLUDED,
+                                getAnimator(TO_OCCLUDED_DURATION),
+                            )
+                        )
+                    }
+                }
+        }
+    }
+
+    private fun listenForLockscreenToAodOrDozing() {
+        scope.launch {
+            keyguardInteractor.wakefulnessModel
+                .sample(
+                    combine(
+                        keyguardTransitionInteractor.startedKeyguardTransitionStep,
+                        keyguardInteractor.isAodAvailable,
+                        ::Pair
+                    ),
+                    ::toTriple
+                )
+                .collect { (wakefulnessState, lastStartedStep, isAodAvailable) ->
+                    if (
+                        lastStartedStep.to == KeyguardState.LOCKSCREEN &&
+                            wakefulnessState.state == WakefulnessState.STARTING_TO_SLEEP
+                    ) {
+                        keyguardTransitionRepository.startTransition(
+                            TransitionInfo(
+                                name,
+                                KeyguardState.LOCKSCREEN,
+                                if (isAodAvailable) {
+                                    KeyguardState.AOD
+                                } else {
+                                    KeyguardState.DOZING
+                                },
                                 getAnimator(),
                             )
                         )
@@ -223,14 +280,16 @@
         }
     }
 
-    private fun getAnimator(): ValueAnimator {
+    private fun getAnimator(duration: Duration = DEFAULT_DURATION): ValueAnimator {
         return ValueAnimator().apply {
             setInterpolator(Interpolators.LINEAR)
-            setDuration(TRANSITION_DURATION_MS)
+            setDuration(duration.inWholeMilliseconds)
         }
     }
 
     companion object {
-        private const val TRANSITION_DURATION_MS = 500L
+        private val DEFAULT_DURATION = 500.milliseconds
+        val TO_DREAMING_DURATION = 933.milliseconds
+        val TO_OCCLUDED_DURATION = 450.milliseconds
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
index 8878901..2dc8fee 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
@@ -23,12 +23,14 @@
 import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionInfo
+import com.android.systemui.keyguard.shared.model.WakefulnessState
 import com.android.systemui.util.kotlin.sample
 import javax.inject.Inject
 import kotlin.time.Duration
 import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.launch
 
 @SysUISingleton
@@ -44,6 +46,7 @@
     override fun start() {
         listenForOccludedToLockscreen()
         listenForOccludedToDreaming()
+        listenForOccludedToAodOrDozing()
     }
 
     private fun listenForOccludedToDreaming() {
@@ -70,8 +73,7 @@
         scope.launch {
             keyguardInteractor.isKeyguardOccluded
                 .sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair)
-                .collect { pair ->
-                    val (isOccluded, lastStartedKeyguardState) = pair
+                .collect { (isOccluded, lastStartedKeyguardState) ->
                     // Occlusion signals come from the framework, and should interrupt any
                     // existing transition
                     if (!isOccluded && lastStartedKeyguardState.to == KeyguardState.OCCLUDED) {
@@ -88,6 +90,39 @@
         }
     }
 
+    private fun listenForOccludedToAodOrDozing() {
+        scope.launch {
+            keyguardInteractor.wakefulnessModel
+                .sample(
+                    combine(
+                        keyguardTransitionInteractor.startedKeyguardTransitionStep,
+                        keyguardInteractor.isAodAvailable,
+                        ::Pair
+                    ),
+                    ::toTriple
+                )
+                .collect { (wakefulnessState, lastStartedStep, isAodAvailable) ->
+                    if (
+                        lastStartedStep.to == KeyguardState.OCCLUDED &&
+                            wakefulnessState.state == WakefulnessState.STARTING_TO_SLEEP
+                    ) {
+                        keyguardTransitionRepository.startTransition(
+                            TransitionInfo(
+                                name,
+                                KeyguardState.OCCLUDED,
+                                if (isAodAvailable) {
+                                    KeyguardState.AOD
+                                } else {
+                                    KeyguardState.DOZING
+                                },
+                                getAnimator(),
+                            )
+                        )
+                    }
+                }
+        }
+    }
+
     private fun getAnimator(duration: Duration = DEFAULT_DURATION): ValueAnimator {
         return ValueAnimator().apply {
             setInterpolator(Interpolators.LINEAR)
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 402c179..4cf56fe 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
@@ -17,20 +17,30 @@
 
 package com.android.systemui.keyguard.domain.interactor
 
+import android.app.StatusBarManager
 import android.graphics.Point
+import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.keyguard.data.repository.KeyguardRepository
 import com.android.systemui.keyguard.shared.model.BiometricUnlockModel
+import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel
 import com.android.systemui.keyguard.shared.model.DozeStateModel
 import com.android.systemui.keyguard.shared.model.DozeStateModel.Companion.isDozeOff
 import com.android.systemui.keyguard.shared.model.DozeTransitionModel
 import com.android.systemui.keyguard.shared.model.StatusBarState
 import com.android.systemui.keyguard.shared.model.WakefulnessModel
-import com.android.systemui.util.kotlin.sample
+import com.android.systemui.statusbar.CommandQueue
+import com.android.systemui.statusbar.CommandQueue.Callbacks
 import javax.inject.Inject
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flow
 import kotlinx.coroutines.flow.merge
 
 /**
@@ -41,6 +51,7 @@
 @Inject
 constructor(
     private val repository: KeyguardRepository,
+    private val commandQueue: CommandQueue,
 ) {
     /**
      * The amount of doze the system is in, where `1.0` is fully dozing and `0.0` is not dozing at
@@ -49,6 +60,8 @@
     val dozeAmount: Flow<Float> = repository.linearDozeAmount
     /** Whether the system is in doze mode. */
     val isDozing: Flow<Boolean> = repository.isDozing
+    /** Whether Always-on Display mode is available. */
+    val isAodAvailable: Flow<Boolean> = repository.isAodAvailable
     /** Doze transition information. */
     val dozeTransitionModel: Flow<DozeTransitionModel> = repository.dozeTransitionModel
     /**
@@ -58,19 +71,44 @@
     val isDreaming: Flow<Boolean> = repository.isDreaming
     /** Whether the system is dreaming with an overlay active */
     val isDreamingWithOverlay: Flow<Boolean> = repository.isDreamingWithOverlay
+    /** Event for when the camera gesture is detected */
+    val onCameraLaunchDetected: Flow<CameraLaunchSourceModel> = conflatedCallbackFlow {
+        val callback =
+            object : CommandQueue.Callbacks {
+                override fun onCameraLaunchGestureDetected(source: Int) {
+                    trySendWithFailureLogging(
+                        cameraLaunchSourceIntToModel(source),
+                        TAG,
+                        "updated onCameraLaunchGestureDetected"
+                    )
+                }
+            }
+
+        commandQueue.addCallback(callback)
+
+        awaitClose { commandQueue.removeCallback(callback) }
+    }
 
     /**
      * Dozing and dreaming have overlapping events. If the doze state remains in FINISH, it means
      * that doze mode is not running and DREAMING is ok to commence.
+     *
+     * Allow a brief moment to prevent rapidly oscillating between true/false signals.
      */
     val isAbleToDream: Flow<Boolean> =
         merge(isDreaming, isDreamingWithOverlay)
-            .sample(
+            .combine(
                 dozeTransitionModel,
                 { isDreaming, dozeTransitionModel ->
                     isDreaming && isDozeOff(dozeTransitionModel.to)
                 }
             )
+            .flatMapLatest { isAbleToDream ->
+                flow {
+                    delay(50)
+                    emit(isAbleToDream)
+                }
+            }
             .distinctUntilChanged()
 
     /** Whether the keyguard is showing or not. */
@@ -103,4 +141,21 @@
     fun isKeyguardShowing(): Boolean {
         return repository.isKeyguardShowing()
     }
+
+    private fun cameraLaunchSourceIntToModel(value: Int): CameraLaunchSourceModel {
+        return when (value) {
+            StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE -> CameraLaunchSourceModel.WIGGLE
+            StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP ->
+                CameraLaunchSourceModel.POWER_DOUBLE_TAP
+            StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER ->
+                CameraLaunchSourceModel.LIFT_TRIGGER
+            StatusBarManager.CAMERA_LAUNCH_SOURCE_QUICK_AFFORDANCE ->
+                CameraLaunchSourceModel.QUICK_AFFORDANCE
+            else -> throw IllegalArgumentException("Invalid CameraLaunchSourceModel value: $value")
+        }
+    }
+
+    companion object {
+        private const val TAG = "KeyguardInteractor"
+    }
 }
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 9772cb9..9ddc575 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
@@ -36,7 +36,7 @@
 import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.settings.UserTracker
-import com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderContract as Contract
+import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
 import com.android.systemui.statusbar.phone.SystemUIDialog
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import dagger.Lazy
@@ -363,6 +363,10 @@
                 name = Contract.FlagsTable.FLAG_NAME_CUSTOM_CLOCKS_ENABLED,
                 value = featureFlags.isEnabled(Flags.LOCKSCREEN_CUSTOM_CLOCKS),
             ),
+            KeyguardPickerFlag(
+                name = Contract.FlagsTable.FLAG_NAME_WALLPAPER_FULLSCREEN_PREVIEW,
+                value = featureFlags.isEnabled(Flags.WALLPAPER_FULLSCREEN_PREVIEW),
+            ),
         )
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt
index a2661d7..d4e23499 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt
@@ -19,11 +19,14 @@
 import com.android.keyguard.logging.KeyguardLogger
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.plugins.log.LogLevel.VERBOSE
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.launch
 
+private val TAG = KeyguardTransitionAuditLogger::class.simpleName!!
+
 /** Collect flows of interest for auditing keyguard transitions. */
 @SysUISingleton
 class KeyguardTransitionAuditLogger
@@ -37,35 +40,47 @@
 
     fun start() {
         scope.launch {
-            keyguardInteractor.wakefulnessModel.collect { logger.v("WakefulnessModel", it) }
+            keyguardInteractor.wakefulnessModel.collect {
+                logger.log(TAG, VERBOSE, "WakefulnessModel", it)
+            }
         }
 
         scope.launch {
-            keyguardInteractor.isBouncerShowing.collect { logger.v("Bouncer showing", it) }
+            keyguardInteractor.isBouncerShowing.collect {
+                logger.log(TAG, VERBOSE, "Bouncer showing", it)
+            }
         }
 
-        scope.launch { keyguardInteractor.isDozing.collect { logger.v("isDozing", it) } }
+        scope.launch {
+            keyguardInteractor.isDozing.collect { logger.log(TAG, VERBOSE, "isDozing", it) }
+        }
 
-        scope.launch { keyguardInteractor.isDreaming.collect { logger.v("isDreaming", it) } }
+        scope.launch {
+            keyguardInteractor.isDreaming.collect { logger.log(TAG, VERBOSE, "isDreaming", it) }
+        }
 
         scope.launch {
             interactor.finishedKeyguardTransitionStep.collect {
-                logger.i("Finished transition", it)
+                logger.log(TAG, VERBOSE, "Finished transition", it)
             }
         }
 
         scope.launch {
             interactor.canceledKeyguardTransitionStep.collect {
-                logger.i("Canceled transition", it)
+                logger.log(TAG, VERBOSE, "Canceled transition", it)
             }
         }
 
         scope.launch {
-            interactor.startedKeyguardTransitionStep.collect { logger.i("Started transition", it) }
+            interactor.startedKeyguardTransitionStep.collect {
+                logger.log(TAG, VERBOSE, "Started transition", it)
+            }
         }
 
         scope.launch {
-            keyguardInteractor.dozeTransitionModel.collect { logger.i("Doze transition", it) }
+            keyguardInteractor.dozeTransitionModel.collect {
+                logger.log(TAG, VERBOSE, "Doze transition", it)
+            }
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
index 04024be..ad6dbea 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
@@ -22,13 +22,17 @@
 import com.android.systemui.keyguard.shared.model.AnimationParams
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
+import com.android.systemui.keyguard.shared.model.KeyguardState.BOUNCER
 import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING
+import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
 import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
 import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionState.STARTED
 import com.android.systemui.keyguard.shared.model.TransitionStep
 import javax.inject.Inject
+import kotlin.math.max
+import kotlin.math.min
 import kotlin.time.Duration
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.filter
@@ -42,24 +46,39 @@
 constructor(
     repository: KeyguardTransitionRepository,
 ) {
+    /** (any)->AOD transition information */
+    val anyStateToAodTransition: Flow<TransitionStep> =
+        repository.transitions.filter { step -> step.to == KeyguardState.AOD }
+
     /** AOD->LOCKSCREEN transition information. */
     val aodToLockscreenTransition: Flow<TransitionStep> = repository.transition(AOD, LOCKSCREEN)
 
-    /** LOCKSCREEN->AOD transition information. */
-    val lockscreenToAodTransition: Flow<TransitionStep> = repository.transition(LOCKSCREEN, AOD)
-
     /** DREAMING->LOCKSCREEN transition information. */
     val dreamingToLockscreenTransition: Flow<TransitionStep> =
         repository.transition(DREAMING, LOCKSCREEN)
 
+    /** GONE->DREAMING transition information. */
+    val goneToDreamingTransition: Flow<TransitionStep> = repository.transition(GONE, DREAMING)
+
+    /** LOCKSCREEN->AOD transition information. */
+    val lockscreenToAodTransition: Flow<TransitionStep> = repository.transition(LOCKSCREEN, AOD)
+
+    /** LOCKSCREEN->BOUNCER transition information. */
+    val lockscreenToBouncerTransition: Flow<TransitionStep> =
+        repository.transition(LOCKSCREEN, BOUNCER)
+
+    /** LOCKSCREEN->DREAMING transition information. */
+    val lockscreenToDreamingTransition: Flow<TransitionStep> =
+        repository.transition(LOCKSCREEN, DREAMING)
+
+    /** LOCKSCREEN->OCCLUDED transition information. */
+    val lockscreenToOccludedTransition: Flow<TransitionStep> =
+        repository.transition(LOCKSCREEN, OCCLUDED)
+
     /** OCCLUDED->LOCKSCREEN transition information. */
     val occludedToLockscreenTransition: Flow<TransitionStep> =
         repository.transition(OCCLUDED, LOCKSCREEN)
 
-    /** (any)->AOD transition information */
-    val anyStateToAodTransition: Flow<TransitionStep> =
-        repository.transitions.filter { step -> step.to == KeyguardState.AOD }
-
     /**
      * AOD<->LOCKSCREEN transition information, mapped to dozeAmount range of AOD (1f) <->
      * Lockscreen (0f).
@@ -98,13 +117,23 @@
     ): Flow<Float> {
         val start = (params.startTime / totalDuration).toFloat()
         val chunks = (totalDuration / params.duration).toFloat()
+        var isRunning = false
         return flow
-            // When starting, emit a value of 0f to give animations a chance to set initial state
             .map { step ->
+                val value = (step.value - start) * chunks
                 if (step.transitionState == STARTED) {
-                    0f
+                    // When starting, make sure to always emit. If a transition is started from the
+                    // middle, it is possible this animation is being skipped but we need to inform
+                    // the ViewModels of the last update
+                    isRunning = true
+                    max(0f, min(1f, value))
+                } else if (isRunning && value >= 1f) {
+                    // Always send a final value of 1. Because of rounding, [value] may never be
+                    // exactly 1.
+                    isRunning = false
+                    1f
                 } else {
-                    (step.value - start) * chunks
+                    value
                 }
             }
             .filter { value -> value >= 0f && value <= 1f }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerCallbackInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerCallbackInteractor.kt
index c5e49c6..3099a49 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerCallbackInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerCallbackInteractor.kt
@@ -18,27 +18,29 @@
 
 import android.view.View
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.statusbar.phone.KeyguardBouncer
+import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_HIDDEN
+import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_VISIBLE
 import com.android.systemui.util.ListenerSet
 import javax.inject.Inject
 
 /** Interactor to add and remove callbacks for the bouncer. */
 @SysUISingleton
 class PrimaryBouncerCallbackInteractor @Inject constructor() {
-    private var resetCallbacks = ListenerSet<KeyguardBouncer.KeyguardResetCallback>()
-    private var expansionCallbacks = ArrayList<KeyguardBouncer.PrimaryBouncerExpansionCallback>()
+    private var resetCallbacks = ListenerSet<KeyguardResetCallback>()
+    private var expansionCallbacks = ArrayList<PrimaryBouncerExpansionCallback>()
+
     /** Add a KeyguardResetCallback. */
-    fun addKeyguardResetCallback(callback: KeyguardBouncer.KeyguardResetCallback) {
+    fun addKeyguardResetCallback(callback: KeyguardResetCallback) {
         resetCallbacks.addIfAbsent(callback)
     }
 
     /** Remove a KeyguardResetCallback. */
-    fun removeKeyguardResetCallback(callback: KeyguardBouncer.KeyguardResetCallback) {
+    fun removeKeyguardResetCallback(callback: KeyguardResetCallback) {
         resetCallbacks.remove(callback)
     }
 
     /** Adds a callback to listen to bouncer expansion updates. */
-    fun addBouncerExpansionCallback(callback: KeyguardBouncer.PrimaryBouncerExpansionCallback) {
+    fun addBouncerExpansionCallback(callback: PrimaryBouncerExpansionCallback) {
         if (!expansionCallbacks.contains(callback)) {
             expansionCallbacks.add(callback)
         }
@@ -48,7 +50,7 @@
      * Removes a previously added callback. If the callback was never added, this method does
      * nothing.
      */
-    fun removeBouncerExpansionCallback(callback: KeyguardBouncer.PrimaryBouncerExpansionCallback) {
+    fun removeBouncerExpansionCallback(callback: PrimaryBouncerExpansionCallback) {
         expansionCallbacks.remove(callback)
     }
 
@@ -99,4 +101,40 @@
             callback.onKeyguardReset()
         }
     }
+
+    /** Callback updated when the primary bouncer's show and hide states change. */
+    interface PrimaryBouncerExpansionCallback {
+        /**
+         * Invoked when the bouncer expansion reaches [EXPANSION_VISIBLE]. This is NOT called each
+         * time the bouncer is shown, but rather only when the fully shown amount has changed based
+         * on the panel expansion. The bouncer's visibility can still change when the expansion
+         * amount hasn't changed. See [PrimaryBouncerInteractor.isFullyShowing] for the checks for
+         * the bouncer showing state.
+         */
+        fun onFullyShown() {}
+
+        /** Invoked when the bouncer is starting to transition to a hidden state. */
+        fun onStartingToHide() {}
+
+        /** Invoked when the bouncer is starting to transition to a visible state. */
+        fun onStartingToShow() {}
+
+        /** Invoked when the bouncer expansion reaches [EXPANSION_HIDDEN]. */
+        fun onFullyHidden() {}
+
+        /**
+         * From 0f [EXPANSION_VISIBLE] when fully visible to 1f [EXPANSION_HIDDEN] when fully hidden
+         */
+        fun onExpansionChanged(bouncerHideAmount: Float) {}
+
+        /**
+         * Invoked when visibility of KeyguardBouncer has changed. Note the bouncer expansion can be
+         * [EXPANSION_VISIBLE], but the view's visibility can be [View.INVISIBLE].
+         */
+        fun onVisibilityChanged(isVisible: Boolean) {}
+    }
+
+    interface KeyguardResetCallback {
+        fun onKeyguardReset()
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
index 2a3a33e..a92540d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
@@ -32,11 +32,11 @@
 import com.android.systemui.keyguard.DismissCallbackRegistry
 import com.android.systemui.keyguard.data.BouncerView
 import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepository
+import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants
 import com.android.systemui.keyguard.shared.model.BouncerShowMessageModel
 import com.android.systemui.keyguard.shared.model.KeyguardBouncerModel
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.shared.system.SysUiStatsLog
-import com.android.systemui.statusbar.phone.KeyguardBouncer
 import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import javax.inject.Inject
@@ -77,6 +77,7 @@
 
     /** Runnable to show the primary bouncer. */
     val showRunnable = Runnable {
+        repository.setPrimaryVisible(true)
         repository.setPrimaryShow(
             KeyguardBouncerModel(
                 promptReason = repository.bouncerPromptReason ?: 0,
@@ -85,7 +86,6 @@
             )
         )
         repository.setPrimaryShowingSoon(false)
-        repository.setPrimaryVisible(true)
         primaryBouncerCallbackInteractor.dispatchVisibilityChanged(View.VISIBLE)
     }
 
@@ -143,7 +143,7 @@
         Trace.beginSection("KeyguardBouncer#show")
         repository.setPrimaryScrimmed(isScrimmed)
         if (isScrimmed) {
-            setPanelExpansion(KeyguardBouncer.EXPANSION_VISIBLE)
+            setPanelExpansion(KeyguardBouncerConstants.EXPANSION_VISIBLE)
         }
 
         if (resumeBouncer) {
@@ -204,14 +204,14 @@
         }
 
         if (
-            expansion == KeyguardBouncer.EXPANSION_VISIBLE &&
-                oldExpansion != KeyguardBouncer.EXPANSION_VISIBLE
+            expansion == KeyguardBouncerConstants.EXPANSION_VISIBLE &&
+                oldExpansion != KeyguardBouncerConstants.EXPANSION_VISIBLE
         ) {
             falsingCollector.onBouncerShown()
             primaryBouncerCallbackInteractor.dispatchFullyShown()
         } else if (
-            expansion == KeyguardBouncer.EXPANSION_HIDDEN &&
-                oldExpansion != KeyguardBouncer.EXPANSION_HIDDEN
+            expansion == KeyguardBouncerConstants.EXPANSION_HIDDEN &&
+                oldExpansion != KeyguardBouncerConstants.EXPANSION_HIDDEN
         ) {
             /*
              * There are cases where #hide() was not invoked, such as when
@@ -222,8 +222,8 @@
             DejankUtils.postAfterTraversal { primaryBouncerCallbackInteractor.dispatchReset() }
             primaryBouncerCallbackInteractor.dispatchFullyHidden()
         } else if (
-            expansion != KeyguardBouncer.EXPANSION_VISIBLE &&
-                oldExpansion == KeyguardBouncer.EXPANSION_VISIBLE
+            expansion != KeyguardBouncerConstants.EXPANSION_VISIBLE &&
+                oldExpansion == KeyguardBouncerConstants.EXPANSION_VISIBLE
         ) {
             primaryBouncerCallbackInteractor.dispatchStartingToHide()
             repository.setPrimaryStartingToHide(true)
@@ -303,7 +303,7 @@
     fun isFullyShowing(): Boolean {
         return (repository.primaryBouncerShowingSoon.value ||
             repository.primaryBouncerVisible.value) &&
-            repository.panelExpansionAmount.value == KeyguardBouncer.EXPANSION_VISIBLE &&
+            repository.panelExpansionAmount.value == KeyguardBouncerConstants.EXPANSION_VISIBLE &&
             repository.primaryBouncerStartingDisappearAnimation.value == null
     }
 
@@ -315,8 +315,8 @@
     /** If bouncer expansion is between 0f and 1f non-inclusive. */
     fun isInTransit(): Boolean {
         return repository.primaryBouncerShowingSoon.value ||
-            repository.panelExpansionAmount.value != KeyguardBouncer.EXPANSION_HIDDEN &&
-                repository.panelExpansionAmount.value != KeyguardBouncer.EXPANSION_VISIBLE
+            repository.panelExpansionAmount.value != KeyguardBouncerConstants.EXPANSION_HIDDEN &&
+                repository.panelExpansionAmount.value != KeyguardBouncerConstants.EXPANSION_VISIBLE
     }
 
     /** Return whether bouncer is animating away. */
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/constants/KeyguardBouncerConstants.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/constants/KeyguardBouncerConstants.kt
new file mode 100644
index 0000000..bb5ac84
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/constants/KeyguardBouncerConstants.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.keyguard.shared.constants
+
+object KeyguardBouncerConstants {
+    /**
+     * Values for the bouncer expansion represented as the panel expansion. Panel expansion 1f =
+     * panel fully showing = bouncer fully hidden Panel expansion 0f = panel fully hiding = bouncer
+     * fully showing
+     */
+    const val EXPANSION_HIDDEN = 1f
+    const val EXPANSION_VISIBLE = 0f
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/CameraLaunchSourceModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/CameraLaunchSourceModel.kt
new file mode 100644
index 0000000..19baf77
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/CameraLaunchSourceModel.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.keyguard.shared.model
+
+/** Camera launch sources */
+enum class CameraLaunchSourceModel {
+    /** Device is wiggled */
+    WIGGLE,
+    /** Power button has been double tapped */
+    POWER_DOUBLE_TAP,
+    /** Device has been lifted */
+    LIFT_TRIGGER,
+    /** Quick affordance button has been pressed */
+    QUICK_AFFORDANCE,
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardQuickAffordancePickerRepresentation.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardQuickAffordancePickerRepresentation.kt
index 7d13359..e7e9159 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardQuickAffordancePickerRepresentation.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardQuickAffordancePickerRepresentation.kt
@@ -17,6 +17,7 @@
 
 package com.android.systemui.keyguard.shared.model
 
+import android.content.Intent
 import androidx.annotation.DrawableRes
 
 /**
@@ -45,4 +46,7 @@
      * user to a destination where they can re-enable it.
      */
     val actionComponentName: String? = null,
+
+    /** Optional [Intent] to use to start an activity to configure this affordance. */
+    val configureIntent: Intent? = null,
 )
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/TrustModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/TrustModel.kt
new file mode 100644
index 0000000..4fd14b1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/TrustModel.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.shared.model
+
+/** Represents the trust state */
+data class TrustModel(
+    /** If true, the system believes the environment to be trusted. */
+    val isTrusted: Boolean,
+    /** The user, for which the trust changed. */
+    val userId: Int,
+)
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 b19795c..d020529 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
@@ -45,7 +45,6 @@
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.statusbar.VibratorHelper
-import com.android.systemui.util.kotlin.pairwise
 import kotlin.math.pow
 import kotlin.math.sqrt
 import kotlin.time.Duration.Companion.milliseconds
@@ -129,18 +128,6 @@
                 }
 
                 launch {
-                    viewModel.startButton
-                        .map { it.isActivated }
-                        .pairwise()
-                        .collect { (prev, next) ->
-                            when {
-                                !prev && next -> vibratorHelper?.vibrate(Vibrations.Activated)
-                                prev && !next -> vibratorHelper?.vibrate(Vibrations.Deactivated)
-                            }
-                        }
-                }
-
-                launch {
                     viewModel.endButton.collect { buttonModel ->
                         updateButton(
                             view = endButton,
@@ -153,18 +140,6 @@
                 }
 
                 launch {
-                    viewModel.endButton
-                        .map { it.isActivated }
-                        .pairwise()
-                        .collect { (prev, next) ->
-                            when {
-                                !prev && next -> vibratorHelper?.vibrate(Vibrations.Activated)
-                                prev && !next -> vibratorHelper?.vibrate(Vibrations.Deactivated)
-                            }
-                        }
-                }
-
-                launch {
                     viewModel.isOverlayContainerVisible.collect { isVisible ->
                         overlayContainer.visibility =
                             if (isVisible) {
@@ -367,14 +342,12 @@
 
         private val longPressDurationMs = ViewConfiguration.getLongPressTimeout().toLong()
         private var longPressAnimator: ViewPropertyAnimator? = null
-        private var downTimestamp = 0L
 
         @SuppressLint("ClickableViewAccessibility")
         override fun onTouch(v: View?, event: MotionEvent?): Boolean {
             return when (event?.actionMasked) {
                 MotionEvent.ACTION_DOWN ->
                     if (viewModel.configKey != null) {
-                        downTimestamp = System.currentTimeMillis()
                         longPressAnimator =
                             view
                                 .animate()
@@ -383,6 +356,13 @@
                                 .setDuration(longPressDurationMs)
                                 .withEndAction {
                                     view.setOnClickListener {
+                                        vibratorHelper?.vibrate(
+                                            if (viewModel.isActivated) {
+                                                Vibrations.Activated
+                                            } else {
+                                                Vibrations.Deactivated
+                                            }
+                                        )
                                         viewModel.onClicked(
                                             KeyguardQuickAffordanceViewModel.OnClickedParameters(
                                                 configKey = viewModel.configKey,
@@ -392,6 +372,7 @@
                                     }
                                     view.performClick()
                                     view.setOnClickListener(null)
+                                    cancel()
                                 }
                         true
                     } else {
@@ -413,7 +394,7 @@
                 MotionEvent.ACTION_UP -> {
                     cancel(
                         onAnimationEnd =
-                            if (System.currentTimeMillis() - downTimestamp < longPressDurationMs) {
+                            if (event.eventTime - event.downTime < longPressDurationMs) {
                                 Runnable {
                                     messageDisplayer.invoke(
                                         R.string.keyguard_affordance_press_too_short
@@ -454,7 +435,6 @@
         }
 
         private fun cancel(onAnimationEnd: Runnable? = null) {
-            downTimestamp = 0L
             longPressAnimator?.cancel()
             longPressAnimator = null
             view.animate().scaleX(1f).scaleY(1f).withEndAction(onAnimationEnd)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt
index f772b17..5e46c5d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt
@@ -19,6 +19,7 @@
 import android.view.KeyEvent
 import android.view.View
 import android.view.ViewGroup
+import android.window.OnBackAnimationCallback
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.internal.policy.SystemBarUtils
@@ -27,10 +28,10 @@
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.dagger.KeyguardBouncerComponent
 import com.android.systemui.keyguard.data.BouncerViewDelegate
+import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_VISIBLE
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.plugins.ActivityStarter
-import com.android.systemui.statusbar.phone.KeyguardBouncer.EXPANSION_VISIBLE
 import kotlinx.coroutines.awaitCancellation
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.launch
@@ -55,6 +56,10 @@
                         mode == KeyguardSecurityModel.SecurityMode.SimPuk
                 }
 
+                override fun getBackCallback(): OnBackAnimationCallback {
+                    return hostViewController.backCallback
+                }
+
                 override fun shouldDismissOnMenuPressed(): Boolean {
                     return hostViewController.shouldEnableMenuKey()
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt
index e164f5d..6627865 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt
@@ -22,10 +22,14 @@
 import com.android.systemui.keyguard.domain.interactor.FromDreamingTransitionInteractor.Companion.TO_LOCKSCREEN_DURATION
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.AnimationParams
+import com.android.systemui.keyguard.shared.model.TransitionState.CANCELED
+import com.android.systemui.keyguard.shared.model.TransitionState.FINISHED
 import javax.inject.Inject
 import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
 
 /**
  * Breaks down DREAMING->LOCKSCREEN transition into discrete steps for corresponding views to
@@ -49,9 +53,15 @@
 
     /** Lockscreen views y-translation */
     fun lockscreenTranslationY(translatePx: Int): Flow<Float> {
-        return flowForAnimation(LOCKSCREEN_TRANSLATION_Y).map { value ->
-            -translatePx + (EMPHASIZED_DECELERATE.getInterpolation(value) * translatePx)
-        }
+        return merge(
+            flowForAnimation(LOCKSCREEN_TRANSLATION_Y).map { value ->
+                -translatePx + (EMPHASIZED_DECELERATE.getInterpolation(value) * translatePx)
+            },
+            // On end, reset the translation to 0
+            interactor.dreamingToLockscreenTransition
+                .filter { it.transitionState == FINISHED || it.transitionState == CANCELED }
+                .map { 0f }
+        )
     }
 
     /** Lockscreen views alpha */
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModel.kt
new file mode 100644
index 0000000..5a47960
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModel.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.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.FromGoneTransitionInteractor.Companion.TO_DREAMING_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.AnimationParams
+import com.android.systemui.keyguard.shared.model.TransitionState.CANCELED
+import com.android.systemui.keyguard.shared.model.TransitionState.FINISHED
+import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
+
+/** Breaks down GONE->DREAMING transition into discrete steps for corresponding views to consume. */
+@SysUISingleton
+class GoneToDreamingTransitionViewModel
+@Inject
+constructor(
+    private val interactor: KeyguardTransitionInteractor,
+) {
+
+    /** Lockscreen views y-translation */
+    fun lockscreenTranslationY(translatePx: Int): Flow<Float> {
+        return merge(
+            flowForAnimation(LOCKSCREEN_TRANSLATION_Y).map { value ->
+                (EMPHASIZED_ACCELERATE.getInterpolation(value) * translatePx)
+            },
+            // On end, reset the translation to 0
+            interactor.goneToDreamingTransition
+                .filter { it.transitionState == FINISHED || it.transitionState == CANCELED }
+                .map { 0f }
+        )
+    }
+
+    /** Lockscreen views alpha */
+    val lockscreenAlpha: Flow<Float> = flowForAnimation(LOCKSCREEN_ALPHA).map { 1f - it }
+
+    private fun flowForAnimation(params: AnimationParams): Flow<Float> {
+        return interactor.transitionStepAnimation(
+            interactor.goneToDreamingTransition,
+            params,
+            totalDuration = TO_DREAMING_DURATION
+        )
+    }
+
+    companion object {
+        val LOCKSCREEN_TRANSLATION_Y = AnimationParams(duration = 500.milliseconds)
+        val LOCKSCREEN_ALPHA = AnimationParams(duration = 250.milliseconds)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModel.kt
index e5d4e49..c6002d6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModel.kt
@@ -20,9 +20,9 @@
 import com.android.systemui.keyguard.data.BouncerView
 import com.android.systemui.keyguard.data.BouncerViewDelegate
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor
+import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_VISIBLE
 import com.android.systemui.keyguard.shared.model.BouncerShowMessageModel
 import com.android.systemui.keyguard.shared.model.KeyguardBouncerModel
-import com.android.systemui.statusbar.phone.KeyguardBouncer.EXPANSION_VISIBLE
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.filter
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModel.kt
new file mode 100644
index 0000000..e05adbd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModel.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.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor.Companion.TO_DREAMING_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.AnimationParams
+import com.android.systemui.keyguard.shared.model.TransitionState.CANCELED
+import com.android.systemui.keyguard.shared.model.TransitionState.FINISHED
+import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
+
+/**
+ * Breaks down LOCKSCREEN->DREAMING transition into discrete steps for corresponding views to
+ * consume.
+ */
+@SysUISingleton
+class LockscreenToDreamingTransitionViewModel
+@Inject
+constructor(
+    private val interactor: KeyguardTransitionInteractor,
+) {
+
+    /** Lockscreen views y-translation */
+    fun lockscreenTranslationY(translatePx: Int): Flow<Float> {
+        return merge(
+            flowForAnimation(LOCKSCREEN_TRANSLATION_Y).map { value ->
+                (EMPHASIZED_ACCELERATE.getInterpolation(value) * translatePx)
+            },
+            // On end, reset the translation to 0
+            interactor.lockscreenToDreamingTransition
+                .filter { it.transitionState == FINISHED || it.transitionState == CANCELED }
+                .map { 0f }
+        )
+    }
+
+    /** Lockscreen views alpha */
+    val lockscreenAlpha: Flow<Float> = flowForAnimation(LOCKSCREEN_ALPHA).map { 1f - it }
+
+    private fun flowForAnimation(params: AnimationParams): Flow<Float> {
+        return interactor.transitionStepAnimation(
+            interactor.lockscreenToDreamingTransition,
+            params,
+            totalDuration = TO_DREAMING_DURATION
+        )
+    }
+
+    companion object {
+        @JvmField val DREAMING_ANIMATION_DURATION_MS = TO_DREAMING_DURATION.inWholeMilliseconds
+
+        val LOCKSCREEN_TRANSLATION_Y = AnimationParams(duration = 500.milliseconds)
+        val LOCKSCREEN_ALPHA = AnimationParams(duration = 250.milliseconds)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt
new file mode 100644
index 0000000..22d292e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor.Companion.TO_OCCLUDED_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.AnimationParams
+import com.android.systemui.keyguard.shared.model.TransitionState
+import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
+
+/**
+ * Breaks down LOCKSCREEN->OCCLUDED transition into discrete steps for corresponding views to
+ * consume.
+ */
+@SysUISingleton
+class LockscreenToOccludedTransitionViewModel
+@Inject
+constructor(
+    private val interactor: KeyguardTransitionInteractor,
+) {
+
+    /** Lockscreen views y-translation */
+    fun lockscreenTranslationY(translatePx: Int): Flow<Float> {
+        return merge(
+            flowForAnimation(LOCKSCREEN_TRANSLATION_Y).map { value ->
+                (EMPHASIZED_ACCELERATE.getInterpolation(value) * translatePx)
+            },
+            // On end, reset the translation to 0
+            interactor.lockscreenToOccludedTransition
+                .filter { step -> step.transitionState == TransitionState.FINISHED }
+                .map { 0f }
+        )
+    }
+
+    /** Lockscreen views alpha */
+    val lockscreenAlpha: Flow<Float> = flowForAnimation(LOCKSCREEN_ALPHA).map { 1f - it }
+
+    private fun flowForAnimation(params: AnimationParams): Flow<Float> {
+        return interactor.transitionStepAnimation(
+            interactor.lockscreenToOccludedTransition,
+            params,
+            totalDuration = TO_OCCLUDED_DURATION
+        )
+    }
+
+    companion object {
+        val LOCKSCREEN_TRANSLATION_Y = AnimationParams(duration = TO_OCCLUDED_DURATION)
+        val LOCKSCREEN_ALPHA = AnimationParams(duration = 250.milliseconds)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/lifecycle/RepeatWhenAttached.kt b/packages/SystemUI/src/com/android/systemui/lifecycle/RepeatWhenAttached.kt
index e364918..d69ac7f 100644
--- a/packages/SystemUI/src/com/android/systemui/lifecycle/RepeatWhenAttached.kt
+++ b/packages/SystemUI/src/com/android/systemui/lifecycle/RepeatWhenAttached.kt
@@ -145,7 +145,7 @@
  * └───────────────┴───────────────────┴──────────────┴─────────────────┘
  * ```
  */
-private class ViewLifecycleOwner(
+class ViewLifecycleOwner(
     private val view: View,
 ) : LifecycleOwner {
 
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/KeyguardClockLog.kt b/packages/SystemUI/src/com/android/systemui/log/dagger/KeyguardClockLog.kt
index 0645236..9f563fe4 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/KeyguardClockLog.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/KeyguardClockLog.kt
@@ -23,3 +23,15 @@
 @MustBeDocumented
 @Retention(AnnotationRetention.RUNTIME)
 annotation class KeyguardClockLog
+
+/** A [com.android.systemui.plugins.log.LogBuffer] for small keyguard clock logs. */
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class KeyguardSmallClockLog
+
+/** A [com.android.systemui.plugins.log.LogBuffer] for large keyguard clock logs. */
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class KeyguardLargeClockLog
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index e3730af..15306f9 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -94,6 +94,14 @@
         return factory.create("LSShadeTransitionLog", 50);
     }
 
+    /** Provides a logging buffer for shade window messages. */
+    @Provides
+    @SysUISingleton
+    @ShadeWindowLog
+    public static LogBuffer provideShadeWindowLogBuffer(LogBufferFactory factory) {
+        return factory.create("ShadeWindowLog", 600, false);
+    }
+
     /** Provides a logging buffer for Shade messages. */
     @Provides
     @SysUISingleton
@@ -183,15 +191,12 @@
                 false /* systrace */);
     }
 
-    /**
-     * Provides a logging buffer for logs related to swiping away the status bar while in immersive
-     * mode. See {@link com.android.systemui.statusbar.gesture.SwipeStatusBarAwayGestureLogger}.
-     */
+    /** Provides a logging buffer for logs related to swipe up gestures. */
     @Provides
     @SysUISingleton
-    @SwipeStatusBarAwayLog
-    public static LogBuffer provideSwipeAwayGestureLogBuffer(LogBufferFactory factory) {
-        return factory.create("SwipeStatusBarAwayLog", 30);
+    @SwipeUpLog
+    public static LogBuffer provideSwipeUpLogBuffer(LogBufferFactory factory) {
+        return factory.create("SwipeUpLog", 30);
     }
 
     /**
@@ -327,13 +332,33 @@
     }
 
     /**
-     * Provides a {@link LogBuffer} for keyguard clock logs.
+     * Provides a {@link LogBuffer} for general keyguard clock logs.
      */
     @Provides
     @SysUISingleton
     @KeyguardClockLog
     public static LogBuffer provideKeyguardClockLog(LogBufferFactory factory) {
-        return factory.create("KeyguardClockLog", 500);
+        return factory.create("KeyguardClockLog", 100);
+    }
+
+    /**
+     * Provides a {@link LogBuffer} for keyguard small clock logs.
+     */
+    @Provides
+    @SysUISingleton
+    @KeyguardSmallClockLog
+    public static LogBuffer provideKeyguardSmallClockLog(LogBufferFactory factory) {
+        return factory.create("KeyguardSmallClockLog", 100);
+    }
+
+    /**
+     * Provides a {@link LogBuffer} for keyguard large clock logs.
+     */
+    @Provides
+    @SysUISingleton
+    @KeyguardLargeClockLog
+    public static LogBuffer provideKeyguardLargeClockLog(LogBufferFactory factory) {
+        return factory.create("KeyguardLargeClockLog", 100);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/SwipeStatusBarAwayLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/ShadeWindowLog.java
similarity index 80%
copy from packages/SystemUI/src/com/android/systemui/log/dagger/SwipeStatusBarAwayLog.java
copy to packages/SystemUI/src/com/android/systemui/log/dagger/ShadeWindowLog.java
index 4c276e2..1d2b68c 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/SwipeStatusBarAwayLog.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/ShadeWindowLog.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -25,12 +25,9 @@
 
 import javax.inject.Qualifier;
 
-/**
- * A {@link LogBuffer} for
- * {@link com.android.systemui.statusbar.gesture.SwipeStatusBarAwayGestureLogger}.
- */
+/** A {@link LogBuffer} for shade window modification messages. */
 @Qualifier
 @Documented
 @Retention(RUNTIME)
-public @interface SwipeStatusBarAwayLog {
+public @interface ShadeWindowLog {
 }
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/SwipeStatusBarAwayLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/SwipeUpLog.java
similarity index 88%
rename from packages/SystemUI/src/com/android/systemui/log/dagger/SwipeStatusBarAwayLog.java
rename to packages/SystemUI/src/com/android/systemui/log/dagger/SwipeUpLog.java
index 4c276e2..d58b538 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/SwipeStatusBarAwayLog.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/SwipeUpLog.java
@@ -27,10 +27,10 @@
 
 /**
  * A {@link LogBuffer} for
- * {@link com.android.systemui.statusbar.gesture.SwipeStatusBarAwayGestureLogger}.
+ * {@link com.android.systemui.statusbar.gesture.SwipeUpGestureLogger}.
  */
 @Qualifier
 @Documented
 @Retention(RUNTIME)
-public @interface SwipeStatusBarAwayLog {
+public @interface SwipeUpLog {
 }
diff --git a/packages/SystemUI/src/com/android/systemui/log/table/TableLogBufferFactory.kt b/packages/SystemUI/src/com/android/systemui/log/table/TableLogBufferFactory.kt
index 7a90a74..7ccc43c 100644
--- a/packages/SystemUI/src/com/android/systemui/log/table/TableLogBufferFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/table/TableLogBufferFactory.kt
@@ -29,6 +29,18 @@
     private val dumpManager: DumpManager,
     private val systemClock: SystemClock,
 ) {
+    private val existingBuffers = mutableMapOf<String, TableLogBuffer>()
+
+    /**
+     * Creates a new [TableLogBuffer]. This method should only be called from static contexts, where
+     * it is guaranteed only to be created one time. See [getOrCreate] for a cache-aware method of
+     * obtaining a buffer.
+     *
+     * @param name a unique table name
+     * @param maxSize the buffer max size. See [adjustMaxSize]
+     *
+     * @return a new [TableLogBuffer] registered with [DumpManager]
+     */
     fun create(
         name: String,
         maxSize: Int,
@@ -37,4 +49,23 @@
         dumpManager.registerNormalDumpable(name, tableBuffer)
         return tableBuffer
     }
+
+    /**
+     * Log buffers are retained indefinitely by [DumpManager], so that they can be represented in
+     * bugreports. Because of this, many of them are created statically in the Dagger graph.
+     *
+     * In the case where you have to create a logbuffer with a name only known at runtime, this
+     * method can be used to lazily create a table log buffer which is then cached for reuse.
+     *
+     * @return a [TableLogBuffer] suitable for reuse
+     */
+    fun getOrCreate(
+        name: String,
+        maxSize: Int,
+    ): TableLogBuffer =
+        existingBuffers.getOrElse(name) {
+            val buffer = create(name, maxSize)
+            existingBuffers[name] = buffer
+            buffer
+        }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
index ceb4845..a692ad7 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
@@ -18,6 +18,7 @@
 import android.app.ActivityOptions
 import android.content.Intent
 import android.content.res.Configuration
+import android.content.res.Resources
 import android.media.projection.IMediaProjection
 import android.media.projection.MediaProjectionManager.EXTRA_MEDIA_PROJECTION
 import android.os.Binder
@@ -27,6 +28,7 @@
 import android.os.UserHandle
 import android.view.ViewGroup
 import com.android.internal.annotations.VisibleForTesting
+import com.android.internal.app.AbstractMultiProfilePagerAdapter.MyUserIdProvider
 import com.android.internal.app.ChooserActivity
 import com.android.internal.app.ResolverListController
 import com.android.internal.app.chooser.NotSelectableTargetInfo
@@ -59,16 +61,12 @@
     private lateinit var configurationController: ConfigurationController
     private lateinit var controller: MediaProjectionAppSelectorController
     private lateinit var recentsViewController: MediaProjectionRecentsViewController
+    private lateinit var component: MediaProjectionAppSelectorComponent
 
     override fun getLayoutResource() = R.layout.media_projection_app_selector
 
     public override fun onCreate(bundle: Bundle?) {
-        val component =
-            componentFactory.create(
-                activity = this,
-                view = this,
-                resultHandler = this
-            )
+        component = componentFactory.create(activity = this, view = this, resultHandler = this)
 
         // Create a separate configuration controller for this activity as the configuration
         // might be different from the global one
@@ -76,11 +74,12 @@
         controller = component.controller
         recentsViewController = component.recentsViewController
 
-        val queryIntent = Intent(Intent.ACTION_MAIN).apply { addCategory(Intent.CATEGORY_LAUNCHER) }
-        intent.putExtra(Intent.EXTRA_INTENT, queryIntent)
+        intent.configureChooserIntent(
+            resources,
+            component.hostUserHandle,
+            component.personalProfileUserHandle
+        )
 
-        val title = getString(R.string.media_projection_permission_app_selector_title)
-        intent.putExtra(Intent.EXTRA_TITLE, title)
         super.onCreate(bundle)
         controller.init()
     }
@@ -183,6 +182,13 @@
 
     override fun shouldShowContentPreview() = true
 
+    override fun shouldShowContentPreviewWhenEmpty(): Boolean = true
+
+    override fun createMyUserIdProvider(): MyUserIdProvider =
+        object : MyUserIdProvider() {
+            override fun getMyUserId(): Int = component.hostUserHandle.identifier
+        }
+
     override fun createContentPreviewView(parent: ViewGroup): ViewGroup =
         recentsViewController.createView(parent)
 
@@ -193,6 +199,34 @@
          * instance through activity result.
          */
         const val EXTRA_CAPTURE_REGION_RESULT_RECEIVER = "capture_region_result_receiver"
+
+        /** UID of the app that originally launched the media projection flow (host app user) */
+        const val EXTRA_HOST_APP_USER_HANDLE = "launched_from_user_handle"
         const val KEY_CAPTURE_TARGET = "capture_region"
+
+        /** Set up intent for the [ChooserActivity] */
+        private fun Intent.configureChooserIntent(
+            resources: Resources,
+            hostUserHandle: UserHandle,
+            personalProfileUserHandle: UserHandle
+        ) {
+            // Specify the query intent to show icons for all apps on the chooser screen
+            val queryIntent =
+                Intent(Intent.ACTION_MAIN).apply { addCategory(Intent.CATEGORY_LAUNCHER) }
+            putExtra(Intent.EXTRA_INTENT, queryIntent)
+
+            // Update the title of the chooser
+            val title = resources.getString(R.string.media_projection_permission_app_selector_title)
+            putExtra(Intent.EXTRA_TITLE, title)
+
+            // Select host app's profile tab by default
+            val selectedProfile =
+                if (hostUserHandle == personalProfileUserHandle) {
+                    PROFILE_PERSONAL
+                } else {
+                    PROFILE_WORK
+                }
+            putExtra(EXTRA_SELECTED_PROFILE, selectedProfile)
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
index bfa67a8..d830fc4 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
@@ -22,6 +22,7 @@
 import static com.android.systemui.screenrecord.ScreenShareOptionKt.SINGLE_APP;
 
 import android.app.Activity;
+import android.app.ActivityManager;
 import android.app.AlertDialog;
 import android.content.DialogInterface;
 import android.content.Intent;
@@ -35,6 +36,7 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.UserHandle;
 import android.text.BidiFormatter;
 import android.text.SpannableString;
 import android.text.TextPaint;
@@ -208,8 +210,14 @@
                 final Intent intent = new Intent(this, MediaProjectionAppSelectorActivity.class);
                 intent.putExtra(MediaProjectionManager.EXTRA_MEDIA_PROJECTION,
                         projection.asBinder());
+                intent.putExtra(MediaProjectionAppSelectorActivity.EXTRA_HOST_APP_USER_HANDLE,
+                        UserHandle.getUserHandleForUid(getLaunchedFromUid()));
                 intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
-                startActivity(intent);
+
+                // Start activity from the current foreground user to avoid creating a separate
+                // SystemUI process without access to recent tasks because it won't have
+                // WM Shell running inside.
+                startActivityAsUser(intent, UserHandle.of(ActivityManager.getCurrentUser()));
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error granting projection permission", e);
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaData.kt b/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaData.kt
index f006442..be18cbe 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaData.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaData.kt
@@ -88,7 +88,10 @@
     val instanceId: InstanceId,
 
     /** The UID of the app, used for logging */
-    val appUid: Int
+    val appUid: Int,
+
+    /** Whether explicit indicator exists */
+    val isExplicit: Boolean = false,
 ) {
     companion object {
         /** Media is playing on the local device */
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaViewHolder.kt
index a8f39fa9a..1c8bfd1 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaViewHolder.kt
@@ -24,6 +24,7 @@
 import android.widget.SeekBar
 import android.widget.TextView
 import androidx.constraintlayout.widget.Barrier
+import com.android.internal.widget.CachingIconView
 import com.android.systemui.R
 import com.android.systemui.media.controls.models.GutsViewHolder
 import com.android.systemui.surfaceeffects.ripple.MultiRippleView
@@ -44,6 +45,7 @@
     val appIcon = itemView.requireViewById<ImageView>(R.id.icon)
     val titleText = itemView.requireViewById<TextView>(R.id.header_title)
     val artistText = itemView.requireViewById<TextView>(R.id.header_artist)
+    val explicitIndicator = itemView.requireViewById<CachingIconView>(R.id.media_explicit_indicator)
 
     // Output switcher
     val seamless = itemView.requireViewById<ViewGroup>(R.id.media_seamless)
@@ -123,6 +125,7 @@
                 R.id.app_name,
                 R.id.header_title,
                 R.id.header_artist,
+                R.id.media_explicit_indicator,
                 R.id.media_seamless,
                 R.id.media_progress_bar,
                 R.id.actionPlayPause,
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 2dd339d..a132797 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
@@ -45,6 +45,7 @@
 import android.os.UserHandle
 import android.provider.Settings
 import android.service.notification.StatusBarNotification
+import android.support.v4.media.MediaMetadataCompat
 import android.text.TextUtils
 import android.util.Log
 import androidx.media.utils.MediaConstants
@@ -660,6 +661,10 @@
         val currentEntry = mediaEntries.get(packageName)
         val instanceId = currentEntry?.instanceId ?: logger.getNewInstanceId()
         val appUid = currentEntry?.appUid ?: Process.INVALID_UID
+        val isExplicit =
+            desc.extras?.getLong(MediaConstants.METADATA_KEY_IS_EXPLICIT) ==
+                MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT &&
+                mediaFlags.isExplicitIndicatorEnabled()
 
         val mediaAction = getResumeMediaAction(resumeAction)
         val lastActive = systemClock.elapsedRealtime()
@@ -689,7 +694,8 @@
                     hasCheckedForResume = true,
                     lastActive = lastActive,
                     instanceId = instanceId,
-                    appUid = appUid
+                    appUid = appUid,
+                    isExplicit = isExplicit,
                 )
             )
         }
@@ -750,6 +756,15 @@
             song = HybridGroupManager.resolveTitle(notif)
         }
 
+        // 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
+        }
+
         // Artist name
         var artist: CharSequence? = metadata?.getString(MediaMetadata.METADATA_KEY_ARTIST)
         if (artist == null) {
@@ -848,10 +863,11 @@
                     notificationKey = key,
                     hasCheckedForResume = hasCheckedForResume,
                     isPlaying = isPlaying,
-                    isClearable = sbn.isClearable(),
+                    isClearable = !sbn.isOngoing,
                     lastActive = lastActive,
                     instanceId = instanceId,
-                    appUid = appUid
+                    appUid = appUid,
+                    isExplicit = isExplicit,
                 )
             )
         }
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/ColorSchemeTransition.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/ColorSchemeTransition.kt
index 93be6a7..4827a16 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/ColorSchemeTransition.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/ColorSchemeTransition.kt
@@ -162,8 +162,8 @@
                     context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK ==
                         UI_MODE_NIGHT_YES
                 )
-                    colorScheme.accent1[2]
-                else colorScheme.accent1[3]
+                    colorScheme.accent1.s100
+                else colorScheme.accent1.s200
             },
             { seamlessColor: Int ->
                 val accentColorList = ColorStateList.valueOf(seamlessColor)
@@ -230,7 +230,14 @@
 
     fun updateColorScheme(colorScheme: ColorScheme?): Boolean {
         var anyChanged = false
-        colorTransitions.forEach { anyChanged = it.updateColorScheme(colorScheme) || anyChanged }
+        colorTransitions.forEach {
+            val isChanged = it.updateColorScheme(colorScheme)
+
+            // Ignore changes to colorSeamless, since that is expected when toggling dark mode
+            if (it == colorSeamless) return@forEach
+
+            anyChanged = isChanged || anyChanged
+        }
         colorScheme?.let { mediaViewHolder.gutsViewHolder.colorScheme = colorScheme }
         return anyChanged
     }
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/KeyguardMediaController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/KeyguardMediaController.kt
index 899148b..8f1c904 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/KeyguardMediaController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/KeyguardMediaController.kt
@@ -130,7 +130,12 @@
     private var splitShadeContainer: ViewGroup? = null
 
     /** Track the media player setting status on lock screen. */
-    private var allowMediaPlayerOnLockScreen: Boolean = true
+    private var allowMediaPlayerOnLockScreen: Boolean =
+        secureSettings.getBoolForUser(
+            Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN,
+            true,
+            UserHandle.USER_CURRENT
+        )
     private val lockScreenMediaPlayerUri =
         secureSettings.getUriFor(Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN)
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
index 1fdbc99..e7f7647 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
@@ -94,7 +94,7 @@
     private var currentCarouselWidth: Int = 0
 
     /** The current height of the carousel */
-    private var currentCarouselHeight: Int = 0
+    @VisibleForTesting var currentCarouselHeight: Int = 0
 
     /** Are we currently showing only active players */
     private var currentlyShowingOnlyActive: Boolean = false
@@ -128,14 +128,14 @@
     /** The measured height of the carousel */
     private var carouselMeasureHeight: Int = 0
     private var desiredHostState: MediaHostState? = null
-    private val mediaCarousel: MediaScrollView
+    @VisibleForTesting var mediaCarousel: MediaScrollView
     val mediaCarouselScrollHandler: MediaCarouselScrollHandler
     val mediaFrame: ViewGroup
     @VisibleForTesting
     lateinit var settingsButton: View
         private set
     private val mediaContent: ViewGroup
-    @VisibleForTesting val pageIndicator: PageIndicator
+    @VisibleForTesting var pageIndicator: PageIndicator
     private val visualStabilityCallback: OnReorderingAllowedListener
     private var needsReordering: Boolean = false
     private var keysNeedRemoval = mutableSetOf<String>()
@@ -160,30 +160,26 @@
         }
 
     companion object {
-        const val ANIMATION_BASE_DURATION = 2200f
-        const val DURATION = 167f
-        const val DETAILS_DELAY = 1067f
-        const val CONTROLS_DELAY = 1400f
-        const val PAGINATION_DELAY = 1900f
-        const val MEDIATITLES_DELAY = 1000f
-        const val MEDIACONTAINERS_DELAY = 967f
         val TRANSFORM_BEZIER = PathInterpolator(0.68F, 0F, 0F, 1F)
-        val REVERSE_BEZIER = PathInterpolator(0F, 0.68F, 1F, 0F)
 
-        fun calculateAlpha(squishinessFraction: Float, delay: Float, duration: Float): Float {
-            val transformStartFraction = delay / ANIMATION_BASE_DURATION
-            val transformDurationFraction = duration / ANIMATION_BASE_DURATION
-            val squishinessToTime = REVERSE_BEZIER.getInterpolation(squishinessFraction)
-            return MathUtils.constrain(
-                (squishinessToTime - transformStartFraction) / transformDurationFraction,
-                0F,
-                1F
-            )
+        fun calculateAlpha(
+            squishinessFraction: Float,
+            startPosition: Float,
+            endPosition: Float
+        ): Float {
+            val transformFraction =
+                MathUtils.constrain(
+                    (squishinessFraction - startPosition) / (endPosition - startPosition),
+                    0F,
+                    1F
+                )
+            return TRANSFORM_BEZIER.getInterpolation(transformFraction)
         }
     }
 
     private val configListener =
         object : ConfigurationController.ConfigurationListener {
+            var lastOrientation = -1
 
             override fun onDensityOrFontScaleChanged() {
                 // System font changes should only happen when UMO is offscreen or a flicker may
@@ -200,7 +196,13 @@
             override fun onConfigChanged(newConfig: Configuration?) {
                 if (newConfig == null) return
                 isRtl = newConfig.layoutDirection == View.LAYOUT_DIRECTION_RTL
-                updatePlayers(recreateMedia = true)
+                val newOrientation = newConfig.orientation
+                if (lastOrientation != newOrientation) {
+                    // The players actually depend on the orientation possibly, so we have to
+                    // recreate them (at least on large screen devices)
+                    lastOrientation = newOrientation
+                    updatePlayers(recreateMedia = true)
+                }
             }
 
             override fun onUiModeChanged() {
@@ -717,6 +719,9 @@
     private fun updatePlayers(recreateMedia: Boolean) {
         pageIndicator.tintList =
             ColorStateList.valueOf(context.getColor(R.color.media_paging_indicator))
+        val previousVisibleKey =
+            MediaPlayerData.visiblePlayerKeys()
+                .elementAtOrNull(mediaCarouselScrollHandler.visibleMediaIndex)
 
         MediaPlayerData.mediaData().forEach { (key, data, isSsMediaRec) ->
             if (isSsMediaRec) {
@@ -741,6 +746,9 @@
                     isSsReactivated = isSsReactivated
                 )
             }
+            if (recreateMedia) {
+                reorderAllPlayers(previousVisibleKey)
+            }
         }
     }
 
@@ -800,7 +808,12 @@
         val squishFraction = hostStates[currentEndLocation]?.squishFraction ?: 1.0F
         val endAlpha =
             (if (endIsVisible) 1.0f else 0.0f) *
-                calculateAlpha(squishFraction, PAGINATION_DELAY, DURATION)
+                calculateAlpha(
+                    squishFraction,
+                    (pageIndicator.translationY + pageIndicator.height) /
+                        mediaCarousel.measuredHeight,
+                    1F
+                )
         var alpha = 1.0f
         if (!endIsVisible || !startIsVisible) {
             var progress = currentTransitionProgress
@@ -826,7 +839,8 @@
         pageIndicator.translationX = translationX + mediaCarouselScrollHandler.contentTranslation
         val layoutParams = pageIndicator.layoutParams as ViewGroup.MarginLayoutParams
         pageIndicator.translationY =
-            (currentCarouselHeight - pageIndicator.height - layoutParams.bottomMargin).toFloat()
+            (mediaCarousel.measuredHeight - pageIndicator.height - layoutParams.bottomMargin)
+                .toFloat()
     }
 
     /** Update the dimension of this carousel. */
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaColorSchemes.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaColorSchemes.kt
index 82abf9b..2a8362b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaColorSchemes.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaColorSchemes.kt
@@ -19,28 +19,28 @@
 import com.android.systemui.monet.ColorScheme
 
 /** Returns the surface color for media controls based on the scheme. */
-internal fun surfaceFromScheme(scheme: ColorScheme) = scheme.accent2[9] // A2-800
+internal fun surfaceFromScheme(scheme: ColorScheme) = scheme.accent2.s800 // A2-800
 
 /** Returns the primary accent color for media controls based on the scheme. */
-internal fun accentPrimaryFromScheme(scheme: ColorScheme) = scheme.accent1[2] // A1-100
+internal fun accentPrimaryFromScheme(scheme: ColorScheme) = scheme.accent1.s100 // A1-100
 
 /** Returns the secondary accent color for media controls based on the scheme. */
-internal fun accentSecondaryFromScheme(scheme: ColorScheme) = scheme.accent1[3] // A1-200
+internal fun accentSecondaryFromScheme(scheme: ColorScheme) = scheme.accent1.s200 // A1-200
 
 /** Returns the primary text color for media controls based on the scheme. */
-internal fun textPrimaryFromScheme(scheme: ColorScheme) = scheme.neutral1[1] // N1-50
+internal fun textPrimaryFromScheme(scheme: ColorScheme) = scheme.neutral1.s50 // N1-50
 
 /** Returns the inverse of the primary text color for media controls based on the scheme. */
-internal fun textPrimaryInverseFromScheme(scheme: ColorScheme) = scheme.neutral1[10] // N1-900
+internal fun textPrimaryInverseFromScheme(scheme: ColorScheme) = scheme.neutral1.s900 // N1-900
 
 /** Returns the secondary text color for media controls based on the scheme. */
-internal fun textSecondaryFromScheme(scheme: ColorScheme) = scheme.neutral2[3] // N2-200
+internal fun textSecondaryFromScheme(scheme: ColorScheme) = scheme.neutral2.s200 // N2-200
 
 /** Returns the tertiary text color for media controls based on the scheme. */
-internal fun textTertiaryFromScheme(scheme: ColorScheme) = scheme.neutral2[5] // N2-400
+internal fun textTertiaryFromScheme(scheme: ColorScheme) = scheme.neutral2.s400 // N2-400
 
 /** Returns the color for the start of the background gradient based on the scheme. */
-internal fun backgroundStartFromScheme(scheme: ColorScheme) = scheme.accent2[8] // A2-700
+internal fun backgroundStartFromScheme(scheme: ColorScheme) = scheme.accent2.s700 // A2-700
 
 /** Returns the color for the end of the background gradient based on the scheme. */
-internal fun backgroundEndFromScheme(scheme: ColorScheme) = scheme.accent1[8] // A1-700
+internal fun backgroundEndFromScheme(scheme: ColorScheme) = scheme.accent1.s700 // A1-700
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 db7a145..45d50f0 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
@@ -50,7 +50,6 @@
 import android.os.Trace;
 import android.text.TextUtils;
 import android.util.Log;
-import android.util.Pair;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
@@ -68,6 +67,7 @@
 import com.android.internal.graphics.ColorUtils;
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.logging.InstanceId;
+import com.android.internal.widget.CachingIconView;
 import com.android.settingslib.widget.AdaptiveIcon;
 import com.android.systemui.ActivityIntentHelper;
 import com.android.systemui.R;
@@ -111,8 +111,11 @@
 import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseController;
 import com.android.systemui.util.ColorUtilKt;
 import com.android.systemui.util.animation.TransitionLayout;
+import com.android.systemui.util.concurrency.DelayableExecutor;
 import com.android.systemui.util.time.SystemClock;
 
+import dagger.Lazy;
+
 import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.List;
@@ -120,7 +123,7 @@
 
 import javax.inject.Inject;
 
-import dagger.Lazy;
+import kotlin.Triple;
 import kotlin.Unit;
 
 /**
@@ -166,10 +169,13 @@
             R.id.action1
     );
 
+    // Time in millis for playing turbulence noise that is played after a touch ripple.
+    @VisibleForTesting static final long TURBULENCE_NOISE_PLAY_DURATION = 7500L;
+
     private final SeekBarViewModel mSeekBarViewModel;
     private SeekBarObserver mSeekBarObserver;
     protected final Executor mBackgroundExecutor;
-    private final Executor mMainExecutor;
+    private final DelayableExecutor mMainExecutor;
     private final ActivityStarter mActivityStarter;
     private final BroadcastSender mBroadcastSender;
 
@@ -222,10 +228,10 @@
     private String mSwitchBroadcastApp;
     private MultiRippleController mMultiRippleController;
     private TurbulenceNoiseController mTurbulenceNoiseController;
-    private FeatureFlags mFeatureFlags;
-    private TurbulenceNoiseAnimationConfig mTurbulenceNoiseAnimationConfig = null;
+    private final FeatureFlags mFeatureFlags;
+    private TurbulenceNoiseAnimationConfig mTurbulenceNoiseAnimationConfig;
     @VisibleForTesting
-    MultiRippleController.Companion.RipplesFinishedListener mRipplesFinishedListener = null;
+    MultiRippleController.Companion.RipplesFinishedListener mRipplesFinishedListener;
 
     /**
      * Initialize a new control panel
@@ -239,7 +245,7 @@
     public MediaControlPanel(
             Context context,
             @Background Executor backgroundExecutor,
-            @Main Executor mainExecutor,
+            @Main DelayableExecutor mainExecutor,
             ActivityStarter activityStarter,
             BroadcastSender broadcastSender,
             MediaViewController mediaViewController,
@@ -398,10 +404,11 @@
 
         TextView titleText = mMediaViewHolder.getTitleText();
         TextView artistText = mMediaViewHolder.getArtistText();
+        CachingIconView explicitIndicator = mMediaViewHolder.getExplicitIndicator();
         AnimatorSet enter = loadAnimator(R.anim.media_metadata_enter,
-                Interpolators.EMPHASIZED_DECELERATE, titleText, artistText);
+                Interpolators.EMPHASIZED_DECELERATE, titleText, artistText, explicitIndicator);
         AnimatorSet exit = loadAnimator(R.anim.media_metadata_exit,
-                Interpolators.EMPHASIZED_ACCELERATE, titleText, artistText);
+                Interpolators.EMPHASIZED_ACCELERATE, titleText, artistText, explicitIndicator);
 
         MultiRippleView multiRippleView = vh.getMultiRippleView();
         mMultiRippleController = new MultiRippleController(multiRippleView);
@@ -409,10 +416,12 @@
         if (mFeatureFlags.isEnabled(Flags.UMO_TURBULENCE_NOISE)) {
             mRipplesFinishedListener = () -> {
                 if (mTurbulenceNoiseAnimationConfig == null) {
-                    mTurbulenceNoiseAnimationConfig = createLingeringNoiseAnimation();
+                    mTurbulenceNoiseAnimationConfig = createTurbulenceNoiseAnimation();
                 }
                 // Color will be correctly updated in ColorSchemeTransition.
                 mTurbulenceNoiseController.play(mTurbulenceNoiseAnimationConfig);
+                mMainExecutor.executeDelayed(
+                        mTurbulenceNoiseController::finish, TURBULENCE_NOISE_PLAY_DURATION);
             };
             mMultiRippleController.addRipplesFinishedListener(mRipplesFinishedListener);
         }
@@ -664,11 +673,15 @@
     private boolean bindSongMetadata(MediaData data) {
         TextView titleText = mMediaViewHolder.getTitleText();
         TextView artistText = mMediaViewHolder.getArtistText();
+        ConstraintSet expandedSet = mMediaViewController.getExpandedLayout();
+        ConstraintSet collapsedSet = mMediaViewController.getCollapsedLayout();
         return mMetadataAnimationHandler.setNext(
-            Pair.create(data.getSong(), data.getArtist()),
+            new Triple(data.getSong(), data.getArtist(), data.isExplicit()),
             () -> {
                 titleText.setText(data.getSong());
                 artistText.setText(data.getArtist());
+                setVisibleAndAlpha(expandedSet, R.id.media_explicit_indicator, data.isExplicit());
+                setVisibleAndAlpha(collapsedSet, R.id.media_explicit_indicator, data.isExplicit());
 
                 // refreshState is required here to resize the text views (and prevent ellipsis)
                 mMediaViewController.refreshState();
@@ -1056,7 +1069,7 @@
         );
     }
 
-    private TurbulenceNoiseAnimationConfig createLingeringNoiseAnimation() {
+    private TurbulenceNoiseAnimationConfig createTurbulenceNoiseAnimation() {
         return new TurbulenceNoiseAnimationConfig(
                 TurbulenceNoiseAnimationConfig.DEFAULT_NOISE_GRID_COUNT,
                 TurbulenceNoiseAnimationConfig.DEFAULT_LUMINOSITY_MULTIPLIER,
@@ -1070,7 +1083,11 @@
                 TurbulenceNoiseAnimationConfig.DEFAULT_OPACITY,
                 /* width= */ mMediaViewHolder.getMultiRippleView().getWidth(),
                 /* height= */ mMediaViewHolder.getMultiRippleView().getHeight(),
-                TurbulenceNoiseAnimationConfig.DEFAULT_NOISE_DURATION_IN_MILLIS,
+                TurbulenceNoiseAnimationConfig.DEFAULT_MAX_DURATION_IN_MILLIS,
+                /* easeInDuration= */
+                TurbulenceNoiseAnimationConfig.DEFAULT_EASING_DURATION_IN_MILLIS,
+                /* easeOutDuration= */
+                TurbulenceNoiseAnimationConfig.DEFAULT_EASING_DURATION_IN_MILLIS,
                 this.getContext().getResources().getDisplayMetrics().density,
                 BlendMode.PLUS,
                 /* onAnimationEnd= */ null
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt
index f7a9bc7..66f12d6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt
@@ -41,6 +41,7 @@
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.dreams.DreamOverlayStateController
 import com.android.systemui.keyguard.WakefulnessLifecycle
+import com.android.systemui.media.controls.pipeline.MediaDataManager
 import com.android.systemui.media.dream.MediaDreamComplication
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.shade.ShadeStateEvents
@@ -93,6 +94,7 @@
     private val keyguardStateController: KeyguardStateController,
     private val bypassController: KeyguardBypassController,
     private val mediaCarouselController: MediaCarouselController,
+    private val mediaManager: MediaDataManager,
     private val keyguardViewController: KeyguardViewController,
     private val dreamOverlayStateController: DreamOverlayStateController,
     configurationController: ConfigurationController,
@@ -224,9 +226,9 @@
 
     private var inSplitShade = false
 
-    /** Is there any active media in the carousel? */
-    private var hasActiveMedia: Boolean = false
-        get() = mediaHosts.get(LOCATION_QQS)?.visible == true
+    /** Is there any active media or recommendation in the carousel? */
+    private var hasActiveMediaOrRecommendation: Boolean = false
+        get() = mediaManager.hasActiveMediaOrRecommendation()
 
     /** Are we currently waiting on an animation to start? */
     private var animationPending: Boolean = false
@@ -582,12 +584,8 @@
         val viewHost = createUniqueObjectHost()
         mediaObject.hostView = viewHost
         mediaObject.addVisibilityChangeListener {
-            // If QQS changes visibility, we need to force an update to ensure the transition
-            // goes into the correct state
-            val stateUpdate = mediaObject.location == LOCATION_QQS
-
             // Never animate because of a visibility change, only state changes should do that
-            updateDesiredLocation(forceNoAnimation = true, forceStateUpdate = stateUpdate)
+            updateDesiredLocation(forceNoAnimation = true)
         }
         mediaHosts[mediaObject.location] = mediaObject
         if (mediaObject.location == desiredLocation) {
@@ -908,7 +906,7 @@
     fun isCurrentlyInGuidedTransformation(): Boolean {
         return hasValidStartAndEndLocations() &&
             getTransformationProgress() >= 0 &&
-            areGuidedTransitionHostsVisible()
+            (areGuidedTransitionHostsVisible() || !hasActiveMediaOrRecommendation)
     }
 
     private fun hasValidStartAndEndLocations(): Boolean {
@@ -965,7 +963,7 @@
     private fun getQSTransformationProgress(): Float {
         val currentHost = getHost(desiredLocation)
         val previousHost = getHost(previousLocation)
-        if (hasActiveMedia && (currentHost?.location == LOCATION_QS && !inSplitShade)) {
+        if (currentHost?.location == LOCATION_QS && !inSplitShade) {
             if (previousHost?.location == LOCATION_QQS) {
                 if (previousHost.visible || statusbarState != StatusBarState.KEYGUARD) {
                     return qsExpansion
@@ -1028,7 +1026,8 @@
     private fun updateHostAttachment() =
         traceSection("MediaHierarchyManager#updateHostAttachment") {
             var newLocation = resolveLocationForFading()
-            var canUseOverlay = !isCurrentlyFading()
+            // Don't use the overlay when fading or when we don't have active media
+            var canUseOverlay = !isCurrentlyFading() && hasActiveMediaOrRecommendation
             if (isCrossFadeAnimatorRunning) {
                 if (
                     getHost(newLocation)?.visible == true &&
@@ -1122,7 +1121,6 @@
                 dreamOverlayActive && dreamMediaComplicationActive -> LOCATION_DREAM_OVERLAY
                 (qsExpansion > 0.0f || inSplitShade) && !onLockscreen -> LOCATION_QS
                 qsExpansion > 0.4f && onLockscreen -> LOCATION_QS
-                !hasActiveMedia -> LOCATION_QS
                 onLockscreen && isSplitShadeExpanding() -> LOCATION_QS
                 onLockscreen && isTransformingToFullShadeAndInQQS() -> LOCATION_QQS
                 onLockscreen && allowMediaPlayerOnLockScreen -> LOCATION_LOCKSCREEN
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
index 4feb984..2ec7be6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
@@ -24,11 +24,6 @@
 import com.android.systemui.media.controls.models.GutsViewHolder
 import com.android.systemui.media.controls.models.player.MediaViewHolder
 import com.android.systemui.media.controls.models.recommendation.RecommendationViewHolder
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.CONTROLS_DELAY
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.DETAILS_DELAY
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.DURATION
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.MEDIACONTAINERS_DELAY
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.MEDIATITLES_DELAY
 import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.calculateAlpha
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.util.animation.MeasurementOutput
@@ -36,6 +31,8 @@
 import com.android.systemui.util.animation.TransitionLayoutController
 import com.android.systemui.util.animation.TransitionViewState
 import com.android.systemui.util.traceSection
+import java.lang.Float.max
+import java.lang.Float.min
 import javax.inject.Inject
 
 /**
@@ -80,8 +77,16 @@
             setOf(
                 R.id.header_title,
                 R.id.header_artist,
+                R.id.media_explicit_indicator,
                 R.id.actionPlayPause,
             )
+
+        val backgroundIds =
+            setOf(
+                R.id.album_art,
+                R.id.turbulence_noise_view,
+                R.id.touch_ripple_view,
+            )
     }
 
     /** A listener when the current dimensions of the player change */
@@ -295,35 +300,111 @@
         squishFraction: Float
     ): TransitionViewState {
         val squishedViewState = viewState.copy()
-        squishedViewState.height = (squishedViewState.height * squishFraction).toInt()
-        controlIds.forEach { id ->
-            squishedViewState.widgetStates.get(id)?.let { state ->
-                state.alpha = calculateAlpha(squishFraction, CONTROLS_DELAY, DURATION)
-            }
+        val squishedHeight = (squishedViewState.measureHeight * squishFraction).toInt()
+        squishedViewState.height = squishedHeight
+        // We are not overriding the squishedViewStates height but only the children to avoid
+        // them remeasuring the whole view. Instead it just remains as the original size
+        backgroundIds.forEach { id ->
+            squishedViewState.widgetStates.get(id)?.let { state -> state.height = squishedHeight }
         }
 
-        detailIds.forEach { id ->
-            squishedViewState.widgetStates.get(id)?.let { state ->
-                state.alpha = calculateAlpha(squishFraction, DETAILS_DELAY, DURATION)
-            }
-        }
-
-        RecommendationViewHolder.mediaContainersIds.forEach { id ->
-            squishedViewState.widgetStates.get(id)?.let { state ->
-                state.alpha = calculateAlpha(squishFraction, MEDIACONTAINERS_DELAY, DURATION)
-            }
-        }
-
-        RecommendationViewHolder.mediaTitlesAndSubtitlesIds.forEach { id ->
-            squishedViewState.widgetStates.get(id)?.let { state ->
-                state.alpha = calculateAlpha(squishFraction, MEDIATITLES_DELAY, DURATION)
-            }
-        }
-
+        // media player
+        val controlsTop =
+            calculateWidgetGroupAlphaForSquishiness(
+                controlIds,
+                squishedViewState.measureHeight.toFloat(),
+                squishedViewState,
+                squishFraction
+            )
+        calculateWidgetGroupAlphaForSquishiness(
+            detailIds,
+            controlsTop,
+            squishedViewState,
+            squishFraction
+        )
+        // recommendation card
+        val titlesTop =
+            calculateWidgetGroupAlphaForSquishiness(
+                RecommendationViewHolder.mediaTitlesAndSubtitlesIds,
+                squishedViewState.measureHeight.toFloat(),
+                squishedViewState,
+                squishFraction
+            )
+        calculateWidgetGroupAlphaForSquishiness(
+            RecommendationViewHolder.mediaContainersIds,
+            titlesTop,
+            squishedViewState,
+            squishFraction
+        )
         return squishedViewState
     }
 
     /**
+     * This function is to make each widget in UMO disappear before being clipped by squished UMO
+     *
+     * The general rule is that widgets in UMO has been divided into several groups, and widgets in
+     * one group have the same alpha during squishing It will change from alpha 0.0 when the visible
+     * bottom of UMO reach the bottom of this group It will change to alpha 1.0 when the visible
+     * bottom of UMO reach the top of the group below e.g.Album title, artist title and play-pause
+     * button will change alpha together.
+     * ```
+     *     And their alpha becomes 1.0 when the visible bottom of UMO reach the top of controls,
+     *     including progress bar, next button, previous button
+     * ```
+     * widgetGroupIds: a group of widgets have same state during UMO is squished,
+     * ```
+     *     e.g. Album title, artist title and play-pause button
+     * ```
+     * groupEndPosition: the height of UMO, when the height reaches this value,
+     * ```
+     *     widgets in this group should have 1.0 as alpha
+     *     e.g., the group of album title, artist title and play-pause button will become fully
+     *         visible when the height of UMO reaches the top of controls group
+     *         (progress bar, previous button and next button)
+     * ```
+     * squishedViewState: hold the widgetState of each widget, which will be modified
+     * squishFraction: the squishFraction of UMO
+     */
+    private fun calculateWidgetGroupAlphaForSquishiness(
+        widgetGroupIds: Set<Int>,
+        groupEndPosition: Float,
+        squishedViewState: TransitionViewState,
+        squishFraction: Float
+    ): Float {
+        val nonsquishedHeight = squishedViewState.measureHeight
+        var groupTop = squishedViewState.measureHeight.toFloat()
+        var groupBottom = 0F
+        widgetGroupIds.forEach { id ->
+            squishedViewState.widgetStates.get(id)?.let { state ->
+                groupTop = min(groupTop, state.y)
+                groupBottom = max(groupBottom, state.y + state.height)
+            }
+        }
+        // startPosition means to the height of squished UMO where the widget alpha should start
+        // changing from 0.0
+        // generally, it equals to the bottom of widgets, so that we can meet the requirement that
+        // widget should not go beyond the bounds of background
+        // endPosition means to the height of squished UMO where the widget alpha should finish
+        // changing alpha to 1.0
+        var startPosition = groupBottom
+        val endPosition = groupEndPosition
+        if (startPosition == endPosition) {
+            startPosition = (endPosition - 0.2 * (groupBottom - groupTop)).toFloat()
+        }
+        widgetGroupIds.forEach { id ->
+            squishedViewState.widgetStates.get(id)?.let { state ->
+                state.alpha =
+                    calculateAlpha(
+                        squishFraction,
+                        startPosition / nonsquishedHeight,
+                        endPosition / nonsquishedHeight
+                    )
+            }
+        }
+        return groupTop // used for the widget group above this group
+    }
+
+    /**
      * Obtain a new viewState for a given media state. This usually returns a cached state, but if
      * it's not available, it will recreate one by measuring, which may be expensive.
      */
@@ -421,10 +502,9 @@
     fun getMeasurementsForState(hostState: MediaHostState): MeasurementOutput? =
         traceSection("MediaViewController#getMeasurementsForState") {
             // measurements should never factor in the squish fraction
-            val viewState =
-                obtainViewState(hostState.copy().also { it.squishFraction = 1.0f }) ?: return null
-            measurement.measuredWidth = viewState.width
-            measurement.measuredHeight = viewState.height
+            val viewState = obtainViewState(hostState) ?: return null
+            measurement.measuredWidth = viewState.measureWidth
+            measurement.measuredHeight = viewState.measureHeight
             return measurement
         }
 
@@ -453,7 +533,7 @@
             // The view might not be bound yet or has never been measured and in that case will be
             // reset once the state is fully available
             var endViewState = obtainViewState(endHostState) ?: return
-            endViewState = updateViewStateToCarouselSize(endViewState, endLocation, tmpState2)!!
+            endViewState = updateViewStateSize(endViewState, endLocation, tmpState2)!!
             layoutController.setMeasureState(endViewState)
 
             // If the view isn't bound, we can drop the animation, otherwise we'll execute it
@@ -464,7 +544,7 @@
 
             val result: TransitionViewState
             var startViewState = obtainViewState(startHostState)
-            startViewState = updateViewStateToCarouselSize(startViewState, startLocation, tmpState3)
+            startViewState = updateViewStateSize(startViewState, startLocation, tmpState3)
 
             if (!endHostState.visible) {
                 // Let's handle the case where the end is gone first. In this case we take the
@@ -517,18 +597,40 @@
             )
         }
 
-    private fun updateViewStateToCarouselSize(
+    private fun updateViewStateSize(
         viewState: TransitionViewState?,
         location: Int,
         outState: TransitionViewState
     ): TransitionViewState? {
-        val result = viewState?.copy(outState) ?: return null
+        var result = viewState?.copy(outState) ?: return null
+        val state = mediaHostStatesManager.mediaHostStates[location]
         val overrideSize = mediaHostStatesManager.carouselSizes[location]
+        var overridden = false
         overrideSize?.let {
             // To be safe we're using a maximum here. The override size should always be set
             // properly though.
-            result.height = Math.max(it.measuredHeight, result.height)
-            result.width = Math.max(it.measuredWidth, result.width)
+            if (
+                result.measureHeight != it.measuredHeight || result.measureWidth != it.measuredWidth
+            ) {
+                result.measureHeight = Math.max(it.measuredHeight, result.measureHeight)
+                result.measureWidth = Math.max(it.measuredWidth, result.measureWidth)
+                // The measureHeight and the shown height should both be set to the overridden
+                // height
+                result.height = result.measureHeight
+                result.width = result.measureWidth
+                // Make sure all background views are also resized such that their size is correct
+                backgroundIds.forEach { id ->
+                    result.widgetStates.get(id)?.let { state ->
+                        state.height = result.height
+                        state.width = result.width
+                    }
+                }
+                overridden = true
+            }
+        }
+        if (overridden && state != null && state.squishFraction <= 1f) {
+            // Let's squish the media player if our size was overridden
+            result = squishViewState(result, state.squishFraction)
         }
         logger.logMediaSize("update to carousel", result.width, result.height)
         return result
@@ -562,7 +664,13 @@
      */
     private fun obtainViewStateForLocation(@MediaLocation location: Int): TransitionViewState? {
         val mediaHostState = mediaHostStatesManager.mediaHostStates[location] ?: return null
-        return obtainViewState(mediaHostState)
+        val viewState = obtainViewState(mediaHostState)
+        if (viewState != null) {
+            // update the size of the viewstate for the location with the override
+            updateViewStateSize(viewState, location, tmpState)
+            return tmpState
+        }
+        return viewState
     }
 
     /**
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 8d4931a..5bc35ca 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
@@ -42,4 +42,7 @@
      * [android.app.StatusBarManager.registerNearbyMediaDevicesProvider] for more information.
      */
     fun areNearbyMediaDevicesEnabled() = featureFlags.isEnabled(Flags.MEDIA_NEARBY_DEVICES)
+
+    /** Check whether we show explicit indicator on UMO */
+    fun isExplicitIndicatorEnabled() = featureFlags.isEnabled(Flags.MEDIA_EXPLICIT_INDICATOR)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
index a9e1a4d..4803371 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -95,6 +95,7 @@
     private RecyclerView mDevicesRecyclerView;
     private LinearLayout mDeviceListLayout;
     private LinearLayout mCastAppLayout;
+    private LinearLayout mMediaMetadataSectionLayout;
     private Button mDoneButton;
     private Button mStopButton;
     private Button mAppButton;
@@ -240,6 +241,7 @@
         mHeaderSubtitle = mDialogView.requireViewById(R.id.header_subtitle);
         mHeaderIcon = mDialogView.requireViewById(R.id.header_icon);
         mDevicesRecyclerView = mDialogView.requireViewById(R.id.list_result);
+        mMediaMetadataSectionLayout = mDialogView.requireViewById(R.id.media_metadata_section);
         mDeviceListLayout = mDialogView.requireViewById(R.id.device_list);
         mDoneButton = mDialogView.requireViewById(R.id.done);
         mStopButton = mDialogView.requireViewById(R.id.stop);
@@ -255,21 +257,17 @@
         mDevicesRecyclerView.setLayoutManager(mLayoutManager);
         mDevicesRecyclerView.setAdapter(mAdapter);
         mDevicesRecyclerView.setHasFixedSize(false);
-        // Init header icon
-        mHeaderIcon.setOnClickListener(v -> onHeaderIconClick());
         // Init bottom buttons
         mDoneButton.setOnClickListener(v -> dismiss());
         mStopButton.setOnClickListener(v -> {
             mMediaOutputController.releaseSession();
             dismiss();
         });
-        mAppButton.setOnClickListener(v -> {
-            mBroadcastSender.closeSystemDialogs();
-            if (mMediaOutputController.getAppLaunchIntent() != null) {
-                mContext.startActivity(mMediaOutputController.getAppLaunchIntent());
-            }
-            dismiss();
-        });
+        mAppButton.setOnClickListener(v -> mMediaOutputController.tryToLaunchMediaApplication());
+        if (mMediaOutputController.isAdvancedLayoutSupported()) {
+            mMediaMetadataSectionLayout.setOnClickListener(
+                    v -> mMediaOutputController.tryToLaunchMediaApplication());
+        }
     }
 
     @Override
@@ -560,7 +558,7 @@
 
     @Override
     public void dismissDialog() {
-        dismiss();
+        mBroadcastSender.closeSystemDialogs();
     }
 
     void onHeaderIconClick() {
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index 8eb25c4..f95da27 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -382,6 +382,15 @@
         return mContext.getPackageManager().getLaunchIntentForPackage(mPackageName);
     }
 
+    void tryToLaunchMediaApplication() {
+        Intent launchIntent = getAppLaunchIntent();
+        if (launchIntent != null) {
+            launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            mCallback.dismissDialog();
+            mContext.startActivity(launchIntent);
+        }
+    }
+
     CharSequence getHeaderTitle() {
         if (mMediaController != null) {
             final MediaMetadata metadata = mMediaController.getMetadata();
@@ -493,20 +502,20 @@
         ColorScheme mCurrentColorScheme = new ColorScheme(wallpaperColors,
                 isDarkTheme);
         if (isDarkTheme) {
-            mColorItemContent = mCurrentColorScheme.getAccent1().get(2); // A1-100
-            mColorSeekbarProgress = mCurrentColorScheme.getAccent2().get(7); // A2-600
-            mColorButtonBackground = mCurrentColorScheme.getAccent1().get(4); // A1-300
-            mColorItemBackground = mCurrentColorScheme.getNeutral2().get(9); // N2-800
-            mColorConnectedItemBackground = mCurrentColorScheme.getAccent2().get(9); // A2-800
-            mColorPositiveButtonText = mCurrentColorScheme.getAccent2().get(9); // A2-800
-            mColorDialogBackground = mCurrentColorScheme.getNeutral1().get(10); // N1-900
+            mColorItemContent = mCurrentColorScheme.getAccent1().getS100(); // A1-100
+            mColorSeekbarProgress = mCurrentColorScheme.getAccent2().getS600(); // A2-600
+            mColorButtonBackground = mCurrentColorScheme.getAccent1().getS300(); // A1-300
+            mColorItemBackground = mCurrentColorScheme.getNeutral2().getS800(); // N2-800
+            mColorConnectedItemBackground = mCurrentColorScheme.getAccent2().getS800(); // A2-800
+            mColorPositiveButtonText = mCurrentColorScheme.getAccent2().getS800(); // A2-800
+            mColorDialogBackground = mCurrentColorScheme.getNeutral1().getS900(); // N1-900
         } else {
-            mColorItemContent = mCurrentColorScheme.getAccent1().get(9); // A1-800
-            mColorSeekbarProgress = mCurrentColorScheme.getAccent1().get(4); // A1-300
-            mColorButtonBackground = mCurrentColorScheme.getAccent1().get(7); // A1-600
-            mColorItemBackground = mCurrentColorScheme.getAccent2().get(1); // A2-50
-            mColorConnectedItemBackground = mCurrentColorScheme.getAccent1().get(2); // A1-100
-            mColorPositiveButtonText = mCurrentColorScheme.getNeutral1().get(1); // N1-50
+            mColorItemContent = mCurrentColorScheme.getAccent1().getS800(); // A1-800
+            mColorSeekbarProgress = mCurrentColorScheme.getAccent1().getS300(); // A1-300
+            mColorButtonBackground = mCurrentColorScheme.getAccent1().getS600(); // A1-600
+            mColorItemBackground = mCurrentColorScheme.getAccent2().getS50(); // A2-50
+            mColorConnectedItemBackground = mCurrentColorScheme.getAccent1().getS100(); // A1-100
+            mColorPositiveButtonText = mCurrentColorScheme.getNeutral1().getS50(); // N1-50
             mColorDialogBackground = mCurrentColorScheme.getBackgroundColor();
         }
     }
@@ -630,50 +639,28 @@
 
     private void buildMediaItems(List<MediaDevice> devices) {
         synchronized (mMediaDevicesLock) {
-            //TODO(b/257851968): do the organization only when there's no suggested sorted order
-            // we get from application
-            attachRangeInfo(devices);
-            Collections.sort(devices, Comparator.naturalOrder());
+            if (!isRouteProcessSupported() || (isRouteProcessSupported()
+                    && !mLocalMediaManager.isPreferenceRouteListingExist())) {
+                attachRangeInfo(devices);
+                Collections.sort(devices, Comparator.naturalOrder());
+            }
             // For the first time building list, to make sure the top device is the connected
             // device.
+            boolean needToHandleMutingExpectedDevice =
+                    hasMutingExpectedDevice() && !isCurrentConnectedDeviceRemote();
+            final MediaDevice connectedMediaDevice =
+                    needToHandleMutingExpectedDevice ? null
+                            : getCurrentConnectedMediaDevice();
             if (mMediaItemList.isEmpty()) {
-                boolean needToHandleMutingExpectedDevice =
-                        hasMutingExpectedDevice() && !isCurrentConnectedDeviceRemote();
-                final MediaDevice connectedMediaDevice =
-                        needToHandleMutingExpectedDevice ? null
-                                : getCurrentConnectedMediaDevice();
                 if (connectedMediaDevice == null) {
                     if (DEBUG) {
                         Log.d(TAG, "No connected media device or muting expected device exist.");
                     }
-                    if (needToHandleMutingExpectedDevice) {
-                        for (MediaDevice device : devices) {
-                            if (device.isMutingExpectedDevice()) {
-                                mMediaItemList.add(0, new MediaItem(device));
-                                mMediaItemList.add(1, new MediaItem(mContext.getString(
-                                        R.string.media_output_group_title_speakers_and_displays),
-                                        MediaItem.MediaItemType.TYPE_GROUP_DIVIDER));
-                            } else {
-                                mMediaItemList.add(new MediaItem(device));
-                            }
-                        }
-                        mMediaItemList.add(new MediaItem());
-                    } else {
-                        mMediaItemList.addAll(
-                                devices.stream().map(MediaItem::new).collect(Collectors.toList()));
-                        categorizeMediaItems(null);
-                    }
+                    categorizeMediaItems(null, devices, needToHandleMutingExpectedDevice);
                     return;
                 }
                 // selected device exist
-                for (MediaDevice device : devices) {
-                    if (TextUtils.equals(device.getId(), connectedMediaDevice.getId())) {
-                        mMediaItemList.add(0, new MediaItem(device));
-                    } else {
-                        mMediaItemList.add(new MediaItem(device));
-                    }
-                }
-                categorizeMediaItems(connectedMediaDevice);
+                categorizeMediaItems(connectedMediaDevice, devices, false);
                 return;
             }
             // To keep the same list order
@@ -707,31 +694,46 @@
         }
     }
 
-    private void categorizeMediaItems(MediaDevice connectedMediaDevice) {
+    private void categorizeMediaItems(MediaDevice connectedMediaDevice, List<MediaDevice> devices,
+            boolean needToHandleMutingExpectedDevice) {
         synchronized (mMediaDevicesLock) {
             Set<String> selectedDevicesIds = getSelectedMediaDevice().stream().map(
                     MediaDevice::getId).collect(Collectors.toSet());
             if (connectedMediaDevice != null) {
                 selectedDevicesIds.add(connectedMediaDevice.getId());
             }
-            int latestSelected = 1;
-            for (MediaItem item : mMediaItemList) {
-                if (item.getMediaDevice().isPresent()) {
-                    MediaDevice device = item.getMediaDevice().get();
-                    if (selectedDevicesIds.contains(device.getId())) {
-                        latestSelected = mMediaItemList.indexOf(item) + 1;
-                    } else {
-                        mMediaItemList.add(latestSelected, new MediaItem(mContext.getString(
-                                R.string.media_output_group_title_speakers_and_displays),
-                                MediaItem.MediaItemType.TYPE_GROUP_DIVIDER));
-                        break;
+            boolean suggestedDeviceAdded = false;
+            boolean displayGroupAdded = false;
+            for (MediaDevice device : devices) {
+                if (needToHandleMutingExpectedDevice && device.isMutingExpectedDevice()) {
+                    mMediaItemList.add(0, new MediaItem(device));
+                } else if (!needToHandleMutingExpectedDevice && selectedDevicesIds.contains(
+                        device.getId())) {
+                    mMediaItemList.add(0, new MediaItem(device));
+                } else {
+                    if (device.isSuggestedDevice() && !suggestedDeviceAdded) {
+                        attachGroupDivider(mContext.getString(
+                                R.string.media_output_group_title_suggested_device));
+                        suggestedDeviceAdded = true;
+                    } else if (!device.isSuggestedDevice() && !displayGroupAdded) {
+                        attachGroupDivider(mContext.getString(
+                                R.string.media_output_group_title_speakers_and_displays));
+                        displayGroupAdded = true;
                     }
+                    mMediaItemList.add(new MediaItem(device));
                 }
             }
             mMediaItemList.add(new MediaItem());
         }
     }
 
+    private void attachGroupDivider(String title) {
+        synchronized (mMediaDevicesLock) {
+            mMediaItemList.add(
+                    new MediaItem(title, MediaItem.MediaItemType.TYPE_GROUP_DIVIDER));
+        }
+    }
+
     private void attachRangeInfo(List<MediaDevice> devices) {
         for (MediaDevice mediaDevice : devices) {
             if (mNearbyDeviceInfoMap.containsKey(mediaDevice.getId())) {
@@ -751,6 +753,10 @@
         return mFeatureFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT);
     }
 
+    public boolean isRouteProcessSupported() {
+        return mFeatureFlags.isEnabled(Flags.OUTPUT_SWITCHER_ROUTES_PROCESSING);
+    }
+
     List<MediaDevice> getGroupMediaDevices() {
         final List<MediaDevice> selectedDevices = getSelectedMediaDevice();
         final List<MediaDevice> selectableDevices = getSelectableMediaDevice();
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSwitcherDialogUI.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSwitcherDialogUI.java
new file mode 100644
index 0000000..e35575b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSwitcherDialogUI.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.dialog;
+
+import android.annotation.MainThread;
+import android.content.Context;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.systemui.CoreStartable;
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
+import com.android.systemui.statusbar.CommandQueue;
+
+import javax.inject.Inject;
+
+/** Controls display of media output switcher. */
+@SysUISingleton
+public class MediaOutputSwitcherDialogUI implements CoreStartable, CommandQueue.Callbacks {
+
+    private static final String TAG = "MediaOutputSwitcherDialogUI";
+
+    private final CommandQueue mCommandQueue;
+    private final MediaOutputDialogFactory mMediaOutputDialogFactory;
+    private final FeatureFlags mFeatureFlags;
+
+    @Inject
+    public MediaOutputSwitcherDialogUI(
+            Context context,
+            CommandQueue commandQueue,
+            MediaOutputDialogFactory mediaOutputDialogFactory,
+            FeatureFlags featureFlags) {
+        mCommandQueue = commandQueue;
+        mMediaOutputDialogFactory = mediaOutputDialogFactory;
+        mFeatureFlags = featureFlags;
+    }
+
+    @Override
+    public void start() {
+        if (mFeatureFlags.isEnabled(Flags.OUTPUT_SWITCHER_SHOW_API_ENABLED)) {
+            mCommandQueue.addCallback(this);
+        } else {
+            Log.w(TAG, "Show media output switcher is not enabled.");
+        }
+    }
+
+    @Override
+    @MainThread
+    public void showMediaOutputSwitcher(String packageName) {
+        if (!TextUtils.isEmpty(packageName)) {
+            mMediaOutputDialogFactory.create(packageName, false, null);
+        } else {
+            Log.e(TAG, "Unable to launch media output dialog. Package name is empty.");
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttFlags.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttFlags.kt
index 8a565fa..60504e4 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttFlags.kt
@@ -30,4 +30,8 @@
     /** Check whether the flag for the receiver success state is enabled. */
     fun isMediaTttReceiverSuccessRippleEnabled(): Boolean =
         featureFlags.isEnabled(Flags.MEDIA_TTT_RECEIVER_SUCCESS_RIPPLE)
+
+    /** True if the media transfer chip can be dismissed via a gesture. */
+    fun isMediaTttDismissGestureEnabled(): Boolean =
+        featureFlags.isEnabled(Flags.MEDIA_TAP_TO_TRANSFER_DISMISS_GESTURE)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
index 889147b..60dd5da 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
@@ -30,8 +30,8 @@
 import android.view.ViewGroup
 import android.view.WindowManager
 import android.view.accessibility.AccessibilityManager
+import android.view.View.ACCESSIBILITY_LIVE_REGION_ASSERTIVE
 import com.android.internal.widget.CachingIconView
-import com.android.settingslib.Utils
 import com.android.systemui.R
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.ui.binder.TintedIconViewBinder
@@ -78,6 +78,7 @@
         private val viewUtil: ViewUtil,
         wakeLockBuilder: WakeLock.Builder,
         systemClock: SystemClock,
+        private val rippleController: MediaTttReceiverRippleController,
 ) : TemporaryViewDisplayController<ChipReceiverInfo, MediaTttLogger<ChipReceiverInfo>>(
         context,
         logger,
@@ -114,9 +115,6 @@
         }
     }
 
-    private var maxRippleWidth: Float = 0f
-    private var maxRippleHeight: Float = 0f
-
     private fun updateMediaTapToTransferReceiverDisplay(
         @StatusBarManager.MediaTransferReceiverState displayState: Int,
         routeInfo: MediaRoute2Info,
@@ -201,41 +199,44 @@
 
         val iconView = currentView.getAppIconView()
         iconView.setPadding(iconPadding, iconPadding, iconPadding, iconPadding)
+        iconView.accessibilityLiveRegion = ACCESSIBILITY_LIVE_REGION_ASSERTIVE
         TintedIconViewBinder.bind(iconInfo.toTintedIcon(), iconView)
     }
 
     override fun animateViewIn(view: ViewGroup) {
         val appIconView = view.getAppIconView()
-        appIconView.animate()
-                .translationYBy(-1 * getTranslationAmount().toFloat())
-                .setDuration(ICON_TRANSLATION_ANIM_DURATION)
-                .start()
-        appIconView.animate()
-                .alpha(1f)
-                .setDuration(ICON_ALPHA_ANIM_DURATION)
-                .start()
-        // Using withEndAction{} doesn't apply a11y focus when screen is unlocked.
-        appIconView.postOnAnimation { view.requestAccessibilityFocus() }
-        expandRipple(view.requireViewById(R.id.ripple))
+        val iconRippleView: ReceiverChipRippleView = view.requireViewById(R.id.icon_glow_ripple)
+        val rippleView: ReceiverChipRippleView = view.requireViewById(R.id.ripple)
+        animateViewTranslationAndFade(appIconView, -1 * getTranslationAmount(), 1f)
+        animateViewTranslationAndFade(iconRippleView, -1 * getTranslationAmount(), 1f)
+        rippleController.expandToInProgressState(rippleView, iconRippleView)
     }
 
     override fun animateViewOut(view: ViewGroup, removalReason: String?, onAnimationEnd: Runnable) {
         val appIconView = view.getAppIconView()
-        appIconView.animate()
-                .translationYBy(getTranslationAmount().toFloat())
-                .setDuration(ICON_TRANSLATION_ANIM_DURATION)
-                .start()
-        appIconView.animate()
-                .alpha(0f)
-                .setDuration(ICON_ALPHA_ANIM_DURATION)
-                .start()
-
+        val iconRippleView: ReceiverChipRippleView = view.requireViewById(R.id.icon_glow_ripple)
         val rippleView: ReceiverChipRippleView = view.requireViewById(R.id.ripple)
         if (removalReason == ChipStateReceiver.TRANSFER_TO_RECEIVER_SUCCEEDED.name &&
                 mediaTttFlags.isMediaTttReceiverSuccessRippleEnabled()) {
-            expandRippleToFull(rippleView, onAnimationEnd)
+            rippleController.expandToSuccessState(rippleView, onAnimationEnd)
+            animateViewTranslationAndFade(
+                iconRippleView,
+                -1 * getTranslationAmount(),
+                0f,
+                translationDuration = ICON_TRANSLATION_SUCCEEDED_DURATION,
+                alphaDuration = ICON_TRANSLATION_SUCCEEDED_DURATION,
+            )
+            animateViewTranslationAndFade(
+                appIconView,
+                -1 * getTranslationAmount(),
+                0f,
+                translationDuration = ICON_TRANSLATION_SUCCEEDED_DURATION,
+                alphaDuration = ICON_TRANSLATION_SUCCEEDED_DURATION,
+            )
         } else {
-            rippleView.collapseRipple(onAnimationEnd)
+            rippleController.collapseRipple(rippleView, onAnimationEnd)
+            animateViewTranslationAndFade(iconRippleView, getTranslationAmount(), 0f)
+            animateViewTranslationAndFade(appIconView, getTranslationAmount(), 0f)
         }
     }
 
@@ -245,74 +246,41 @@
         viewUtil.setRectToViewWindowLocation(view.getAppIconView(), outRect)
     }
 
+    /** Animation of view translation and fading. */
+    private fun animateViewTranslationAndFade(
+        view: View,
+        translationYBy: Float,
+        alphaEndValue: Float,
+        translationDuration: Long = ICON_TRANSLATION_ANIM_DURATION,
+        alphaDuration: Long = ICON_ALPHA_ANIM_DURATION,
+    ) {
+        view.animate()
+            .translationYBy(translationYBy)
+            .setDuration(translationDuration)
+            .start()
+        view.animate()
+            .alpha(alphaEndValue)
+            .setDuration(alphaDuration)
+            .start()
+    }
+
     /** Returns the amount that the chip will be translated by in its intro animation. */
-    private fun getTranslationAmount(): Int {
-        return context.resources.getDimensionPixelSize(R.dimen.media_ttt_receiver_vert_translation)
-    }
-
-    private fun expandRipple(rippleView: ReceiverChipRippleView) {
-        if (rippleView.rippleInProgress()) {
-            // Skip if ripple is still playing
-            return
-        }
-
-        // In case the device orientation changes, we need to reset the layout.
-        rippleView.addOnLayoutChangeListener (
-            View.OnLayoutChangeListener { v, _, _, _, _, _, _, _, _ ->
-                if (v == null) return@OnLayoutChangeListener
-
-                val layoutChangedRippleView = v as ReceiverChipRippleView
-                layoutRipple(layoutChangedRippleView)
-                layoutChangedRippleView.invalidate()
-            }
-        )
-        rippleView.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
-            override fun onViewDetachedFromWindow(view: View?) {}
-
-            override fun onViewAttachedToWindow(view: View?) {
-                if (view == null) {
-                    return
-                }
-                val attachedRippleView = view as ReceiverChipRippleView
-                layoutRipple(attachedRippleView)
-                attachedRippleView.expandRipple()
-                attachedRippleView.removeOnAttachStateChangeListener(this)
-            }
-        })
-    }
-
-    private fun layoutRipple(rippleView: ReceiverChipRippleView, isFullScreen: Boolean = false) {
-        val windowBounds = windowManager.currentWindowMetrics.bounds
-        val height = windowBounds.height().toFloat()
-        val width = windowBounds.width().toFloat()
-
-        if (isFullScreen) {
-            maxRippleHeight = height * 2f
-            maxRippleWidth = width * 2f
-        } else {
-            maxRippleHeight = height / 2f
-            maxRippleWidth = width / 2f
-        }
-        rippleView.setMaxSize(maxRippleWidth, maxRippleHeight)
-        // Center the ripple on the bottom of the screen in the middle.
-        rippleView.setCenter(width * 0.5f, height)
-        val color = Utils.getColorAttrDefaultColor(context, R.attr.wallpaperTextColorAccent)
-        rippleView.setColor(color, 70)
+    private fun getTranslationAmount(): Float {
+        return rippleController.getRippleSize() * 0.5f -
+            rippleController.getReceiverIconSize()
     }
 
     private fun View.getAppIconView(): CachingIconView {
         return this.requireViewById(R.id.app_icon)
     }
 
-    private fun expandRippleToFull(rippleView: ReceiverChipRippleView, onAnimationEnd: Runnable?) {
-        layoutRipple(rippleView, true)
-        rippleView.expandToFull(maxRippleHeight, onAnimationEnd)
+    companion object {
+        private const val ICON_TRANSLATION_ANIM_DURATION = 500L
+        private const val ICON_TRANSLATION_SUCCEEDED_DURATION = 167L
+        private val ICON_ALPHA_ANIM_DURATION = 5.frames
     }
 }
 
-val ICON_TRANSLATION_ANIM_DURATION = 30.frames
-val ICON_ALPHA_ANIM_DURATION = 5.frames
-
 data class ChipReceiverInfo(
     val routeInfo: MediaRoute2Info,
     val appIconDrawableOverride: Drawable?,
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverRippleController.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverRippleController.kt
new file mode 100644
index 0000000..5013802
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverRippleController.kt
@@ -0,0 +1,163 @@
+/*
+ * 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.media.taptotransfer.receiver
+
+import android.content.Context
+import android.content.res.ColorStateList
+import android.view.View
+import android.view.WindowManager
+import com.android.settingslib.Utils
+import com.android.systemui.R
+import javax.inject.Inject
+
+/**
+ * A controller responsible for the animation of the ripples shown in media tap-to-transfer on the
+ * receiving device.
+ */
+class MediaTttReceiverRippleController
+@Inject
+constructor(
+    private val context: Context,
+    private val windowManager: WindowManager,
+) {
+
+    private var maxRippleWidth: Float = 0f
+    private var maxRippleHeight: Float = 0f
+
+    /** Expands the icon and main ripple to in-progress state */
+    fun expandToInProgressState(
+        mainRippleView: ReceiverChipRippleView,
+        iconRippleView: ReceiverChipRippleView,
+    ) {
+        expandRipple(mainRippleView, isIconRipple = false)
+        expandRipple(iconRippleView, isIconRipple = true)
+    }
+
+    private fun expandRipple(rippleView: ReceiverChipRippleView, isIconRipple: Boolean) {
+        if (rippleView.rippleInProgress()) {
+            // Skip if ripple is still playing
+            return
+        }
+
+        // In case the device orientation changes, we need to reset the layout.
+        rippleView.addOnLayoutChangeListener(
+            View.OnLayoutChangeListener { v, _, _, _, _, _, _, _, _ ->
+                if (v == null) return@OnLayoutChangeListener
+
+                val layoutChangedRippleView = v as ReceiverChipRippleView
+                if (isIconRipple) {
+                    layoutIconRipple(layoutChangedRippleView)
+                } else {
+                    layoutRipple(layoutChangedRippleView)
+                }
+                layoutChangedRippleView.invalidate()
+            }
+        )
+        rippleView.addOnAttachStateChangeListener(
+            object : View.OnAttachStateChangeListener {
+                override fun onViewDetachedFromWindow(view: View?) {}
+
+                override fun onViewAttachedToWindow(view: View?) {
+                    if (view == null) {
+                        return
+                    }
+                    val attachedRippleView = view as ReceiverChipRippleView
+                    if (isIconRipple) {
+                        layoutIconRipple(attachedRippleView)
+                    } else {
+                        layoutRipple(attachedRippleView)
+                    }
+                    attachedRippleView.expandRipple()
+                    attachedRippleView.removeOnAttachStateChangeListener(this)
+                }
+            }
+        )
+    }
+
+    /** Expands the ripple to cover the screen. */
+    fun expandToSuccessState(rippleView: ReceiverChipRippleView, onAnimationEnd: Runnable?) {
+        layoutRipple(rippleView, isFullScreen = true)
+        rippleView.expandToFull(maxRippleHeight, onAnimationEnd)
+    }
+
+    /** Collapses the ripple. */
+    fun collapseRipple(rippleView: ReceiverChipRippleView, onAnimationEnd: Runnable? = null) {
+        rippleView.collapseRipple(onAnimationEnd)
+    }
+
+    private fun layoutRipple(rippleView: ReceiverChipRippleView, isFullScreen: Boolean = false) {
+        val windowBounds = windowManager.currentWindowMetrics.bounds
+        val height = windowBounds.height().toFloat()
+        val width = windowBounds.width().toFloat()
+
+        if (isFullScreen) {
+            maxRippleHeight = height * 2f
+            maxRippleWidth = width * 2f
+        } else {
+            maxRippleHeight = getRippleSize()
+            maxRippleWidth = getRippleSize()
+        }
+        rippleView.setMaxSize(maxRippleWidth, maxRippleHeight)
+        // Center the ripple on the bottom of the screen in the middle.
+        rippleView.setCenter(width * 0.5f, height)
+        rippleView.setColor(getRippleColor(), RIPPLE_OPACITY)
+    }
+
+    private fun layoutIconRipple(iconRippleView: ReceiverChipRippleView) {
+        val windowBounds = windowManager.currentWindowMetrics.bounds
+        val height = windowBounds.height().toFloat()
+        val width = windowBounds.width().toFloat()
+        val radius = getReceiverIconSize().toFloat()
+
+        iconRippleView.setMaxSize(radius * 0.8f, radius * 0.8f)
+        iconRippleView.setCenter(
+            width * 0.5f,
+            height - getReceiverIconSize() * 0.5f - getReceiverIconBottomMargin()
+        )
+        iconRippleView.setColor(getRippleColor(), RIPPLE_OPACITY)
+    }
+
+    private fun getRippleColor(): Int {
+        var colorStateList =
+            ColorStateList.valueOf(
+                Utils.getColorAttrDefaultColor(context, R.attr.wallpaperTextColorAccent)
+            )
+        return colorStateList.withLStar(TONE_PERCENT).defaultColor
+    }
+
+    /** Returns the size of the ripple. */
+    internal fun getRippleSize(): Float {
+        return getReceiverIconSize() * 4f
+    }
+
+    /** Returns the size of the icon of the receiver. */
+    internal fun getReceiverIconSize(): Int {
+        return context.resources.getDimensionPixelSize(R.dimen.media_ttt_icon_size_receiver)
+    }
+
+    /** Return the bottom margin of the icon of the receiver. */
+    internal fun getReceiverIconBottomMargin(): Int {
+        // Adding a margin to make sure ripple behind the icon is not cut by the screen bounds.
+        return context.resources.getDimensionPixelSize(
+            R.dimen.media_ttt_receiver_icon_bottom_margin
+        )
+    }
+
+    companion object {
+        const val RIPPLE_OPACITY = 70
+        const val TONE_PERCENT = 95f
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt
index 87b2528..f8785fc 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt
@@ -33,14 +33,14 @@
     private var isStarted: Boolean
 
     init {
-        setupShader(RippleShader.RippleShape.ELLIPSE)
+        setupShader(RippleShader.RippleShape.CIRCLE)
         setRippleFill(true)
         setSparkleStrength(0f)
-        duration = 3000L
         isStarted = false
     }
 
     fun expandRipple(onAnimationEnd: Runnable? = null) {
+        duration = DEFAULT_DURATION
         isStarted = true
         super.startRipple(onAnimationEnd)
     }
@@ -50,6 +50,7 @@
         if (!isStarted) {
             return // Ignore if ripple is not started yet.
         }
+        duration = DEFAULT_DURATION
         // Reset all listeners to animator.
         animator.removeAllListeners()
         animator.addListener(object : AnimatorListenerAdapter() {
@@ -74,6 +75,7 @@
         setRippleFill(false)
 
         val startingPercentage = calculateStartingPercentage(newHeight)
+        animator.duration = EXPAND_TO_FULL_DURATION
         animator.addUpdateListener { updateListener ->
             val now = updateListener.currentPlayTime
             val progress = updateListener.animatedValue as Float
@@ -100,4 +102,9 @@
         val remainingPercentage = (1 - ratio).toDouble().pow(1 / 3.toDouble()).toFloat()
         return 1 - remainingPercentage
     }
+
+    companion object {
+        const val DEFAULT_DURATION = 333L
+        const val EXPAND_TO_FULL_DURATION = 1000L
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
index 9f44d98..902a10a0 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
@@ -30,6 +30,7 @@
 import com.android.systemui.media.taptotransfer.common.MediaTttLogger
 import com.android.systemui.media.taptotransfer.common.MediaTttUtils
 import com.android.systemui.statusbar.CommandQueue
+import com.android.systemui.temporarydisplay.TemporaryViewDisplayController
 import com.android.systemui.temporarydisplay.ViewPriority
 import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator
 import com.android.systemui.temporarydisplay.chipbar.ChipbarEndItem
@@ -54,6 +55,7 @@
 
     private var displayedState: ChipStateSender? = null
     // A map to store current chip state per id.
+    // TODO(b/265455911): Log whenever we add or remove from the store.
     private var stateMap: MutableMap<String, ChipStateSender> = mutableMapOf()
 
     private val commandQueueCallbacks =
@@ -102,10 +104,9 @@
         }
         uiEventLogger.logSenderStateChange(chipState)
 
-        stateMap.put(routeInfo.id, chipState)
         if (chipState == ChipStateSender.FAR_FROM_RECEIVER) {
             // No need to store the state since it is the default state
-            stateMap.remove(routeInfo.id)
+            removeIdFromStore(routeInfo.id)
             // Return early if we're not displaying a chip anyway
             val currentDisplayedState = displayedState ?: return
 
@@ -126,7 +127,9 @@
             displayedState = null
             chipbarCoordinator.removeView(routeInfo.id, removalReason)
         } else {
+            stateMap[routeInfo.id] = chipState
             displayedState = chipState
+            chipbarCoordinator.registerListener(displayListener)
             chipbarCoordinator.displayView(
                 createChipbarInfo(
                     chipState,
@@ -135,7 +138,7 @@
                     context,
                     logger,
                 )
-            ) { stateMap.remove(routeInfo.id) }
+            )
         }
     }
 
@@ -150,7 +153,12 @@
         logger: MediaTttLogger<ChipbarInfo>,
     ): ChipbarInfo {
         val packageName = routeInfo.clientPackageName
-        val otherDeviceName = routeInfo.name.toString()
+        val otherDeviceName =
+            if (routeInfo.name.isBlank()) {
+                context.getString(R.string.media_ttt_default_device_type)
+            } else {
+                routeInfo.name.toString()
+            }
 
         return ChipbarInfo(
             // Display the app's icon as the start icon
@@ -177,6 +185,7 @@
                     }
                 },
             vibrationEffect = chipStateSender.transferStatus.vibrationEffect,
+            allowSwipeToDismiss = true,
             windowTitle = MediaTttUtils.WINDOW_TITLE_SENDER,
             wakeReason = MediaTttUtils.WAKE_REASON_SENDER,
             timeoutMs = chipStateSender.timeout,
@@ -220,4 +229,14 @@
             onClickListener,
         )
     }
+
+    private val displayListener =
+        TemporaryViewDisplayController.Listener { id -> removeIdFromStore(id) }
+
+    private fun removeIdFromStore(id: String) {
+        stateMap.remove(id)
+        if (stateMap.isEmpty()) {
+            chipbarCoordinator.unregisterListener(displayListener)
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt
index 6c41caa..1d86343 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt
@@ -19,9 +19,11 @@
 import android.app.Activity
 import android.content.ComponentName
 import android.content.Context
+import android.os.UserHandle
 import com.android.launcher3.icons.IconFactory
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.media.MediaProjectionAppSelectorActivity
+import com.android.systemui.media.MediaProjectionAppSelectorActivity.Companion.EXTRA_HOST_APP_USER_HANDLE
 import com.android.systemui.mediaprojection.appselector.data.ActivityTaskManagerThumbnailLoader
 import com.android.systemui.mediaprojection.appselector.data.AppIconLoader
 import com.android.systemui.mediaprojection.appselector.data.IconLoaderLibAppIconLoader
@@ -30,6 +32,8 @@
 import com.android.systemui.mediaprojection.appselector.data.ShellRecentTaskListProvider
 import com.android.systemui.mediaprojection.appselector.view.MediaProjectionRecentsViewController
 import com.android.systemui.mediaprojection.appselector.view.TaskPreviewSizeProvider
+import com.android.systemui.settings.UserTracker
+import com.android.systemui.shared.system.ActivityManagerWrapper
 import com.android.systemui.statusbar.phone.ConfigurationControllerImpl
 import com.android.systemui.statusbar.policy.ConfigurationController
 import dagger.Binds
@@ -39,6 +43,7 @@
 import dagger.Subcomponent
 import dagger.multibindings.ClassKey
 import dagger.multibindings.IntoMap
+import java.lang.IllegalArgumentException
 import javax.inject.Qualifier
 import javax.inject.Scope
 import kotlinx.coroutines.CoroutineScope
@@ -46,6 +51,12 @@
 
 @Qualifier @Retention(AnnotationRetention.BINARY) annotation class MediaProjectionAppSelector
 
+@Qualifier @Retention(AnnotationRetention.BINARY) annotation class HostUserHandle
+
+@Qualifier @Retention(AnnotationRetention.BINARY) annotation class PersonalProfile
+
+@Qualifier @Retention(AnnotationRetention.BINARY) annotation class WorkProfile
+
 @Retention(AnnotationRetention.RUNTIME) @Scope annotation class MediaProjectionAppSelectorScope
 
 @Module(subcomponents = [MediaProjectionAppSelectorComponent::class])
@@ -83,7 +94,7 @@
         @MediaProjectionAppSelector
         @MediaProjectionAppSelectorScope
         fun provideAppSelectorComponentName(context: Context): ComponentName =
-                ComponentName(context, MediaProjectionAppSelectorActivity::class.java)
+            ComponentName(context, MediaProjectionAppSelectorActivity::class.java)
 
         @Provides
         @MediaProjectionAppSelector
@@ -93,9 +104,32 @@
         ): ConfigurationController = ConfigurationControllerImpl(activity)
 
         @Provides
-        fun bindIconFactory(
-            context: Context
-        ): IconFactory = IconFactory.obtain(context)
+        @PersonalProfile
+        @MediaProjectionAppSelectorScope
+        fun personalUserHandle(activityManagerWrapper: ActivityManagerWrapper): UserHandle {
+            // Current foreground user is the 'personal' profile
+            return UserHandle.of(activityManagerWrapper.currentUserId)
+        }
+
+        @Provides
+        @WorkProfile
+        @MediaProjectionAppSelectorScope
+        fun workProfileUserHandle(userTracker: UserTracker): UserHandle? =
+            userTracker.userProfiles.find { it.isManagedProfile }?.userHandle
+
+        @Provides
+        @HostUserHandle
+        @MediaProjectionAppSelectorScope
+        fun hostUserHandle(activity: MediaProjectionAppSelectorActivity): UserHandle {
+            val extras =
+                activity.intent.extras
+                    ?: error("MediaProjectionAppSelectorActivity should be launched with extras")
+            return extras.getParcelable(EXTRA_HOST_APP_USER_HANDLE)
+                ?: error("MediaProjectionAppSelectorActivity should be provided with " +
+                        "$EXTRA_HOST_APP_USER_HANDLE extra")
+        }
+
+        @Provides fun bindIconFactory(context: Context): IconFactory = IconFactory.obtain(context)
 
         @Provides
         @MediaProjectionAppSelector
@@ -124,6 +158,8 @@
 
     val controller: MediaProjectionAppSelectorController
     val recentsViewController: MediaProjectionRecentsViewController
+    @get:HostUserHandle val hostUserHandle: UserHandle
+    @get:PersonalProfile val personalProfileUserHandle: UserHandle
 
     @MediaProjectionAppSelector val configurationController: ConfigurationController
 }
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorController.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorController.kt
index d744a40b..52c7ca3 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorController.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorController.kt
@@ -17,24 +17,36 @@
 package com.android.systemui.mediaprojection.appselector
 
 import android.content.ComponentName
+import android.os.UserHandle
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
 import com.android.systemui.mediaprojection.appselector.data.RecentTask
 import com.android.systemui.mediaprojection.appselector.data.RecentTaskListProvider
+import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.cancel
 import kotlinx.coroutines.launch
-import javax.inject.Inject
 
 @MediaProjectionAppSelectorScope
-class MediaProjectionAppSelectorController @Inject constructor(
+class MediaProjectionAppSelectorController
+@Inject
+constructor(
     private val recentTaskListProvider: RecentTaskListProvider,
     private val view: MediaProjectionAppSelectorView,
+    private val flags: FeatureFlags,
+    @HostUserHandle private val hostUserHandle: UserHandle,
     @MediaProjectionAppSelector private val scope: CoroutineScope,
     @MediaProjectionAppSelector private val appSelectorComponentName: ComponentName
 ) {
 
     fun init() {
         scope.launch {
-            val tasks = recentTaskListProvider.loadRecentTasks().sortTasks()
+            val recentTasks = recentTaskListProvider.loadRecentTasks()
+
+            val tasks = recentTasks
+                .filterDevicePolicyRestrictedTasks()
+                .sortedTasks()
+
             view.bind(tasks)
         }
     }
@@ -43,9 +55,20 @@
         scope.cancel()
     }
 
-    private fun List<RecentTask>.sortTasks(): List<RecentTask> =
-        sortedBy {
-            // Show normal tasks first and only then tasks with opened app selector
-            it.topActivityComponent == appSelectorComponentName
+    /**
+     * Removes all recent tasks that are different from the profile of the host app to avoid any
+     * cross-profile sharing
+     */
+    private fun List<RecentTask>.filterDevicePolicyRestrictedTasks(): List<RecentTask> =
+        if (flags.isEnabled(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES)) {
+            // TODO(b/263950746): filter tasks based on the enterprise policies
+            this
+        } else {
+            filter { UserHandle.of(it.userId) == hostUserHandle }
         }
+
+    private fun List<RecentTask>.sortedTasks(): List<RecentTask> = sortedBy {
+        // Show normal tasks first and only then tasks with opened app selector
+        it.topActivityComponent == appSelectorComponentName
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTask.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTask.kt
index cd994b8..41e2286 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTask.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTask.kt
@@ -17,11 +17,12 @@
 package com.android.systemui.mediaprojection.appselector.data
 
 import android.annotation.ColorInt
+import android.annotation.UserIdInt
 import android.content.ComponentName
 
 data class RecentTask(
     val taskId: Int,
-    val userId: Int,
+    @UserIdInt val userId: Int,
     val topActivityComponent: ComponentName?,
     val baseIntentComponent: ComponentName?,
     @ColorInt val colorBackground: Int?
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
index 2c0745b..1121e160 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
@@ -185,7 +185,7 @@
     public void registerNavTaskStateUpdater(NavbarTaskbarStateUpdater listener) {
         mA11yEventListeners.add(listener);
         listener.updateAccessibilityServicesState();
-        listener.updateAssistantAvailable(mAssistantAvailable);
+        listener.updateAssistantAvailable(mAssistantAvailable, mLongPressHomeEnabled);
     }
 
     public void removeNavTaskStateUpdater(NavbarTaskbarStateUpdater listener) {
@@ -198,9 +198,10 @@
         }
     }
 
-    private void dispatchAssistantEventUpdate(boolean assistantAvailable) {
+    private void dispatchAssistantEventUpdate(boolean assistantAvailable,
+            boolean longPressHomeEnabled) {
         for (NavbarTaskbarStateUpdater listener : mA11yEventListeners) {
-            listener.updateAssistantAvailable(assistantAvailable);
+            listener.updateAssistantAvailable(assistantAvailable, longPressHomeEnabled);
         }
     }
 
@@ -296,7 +297,7 @@
 
     private void updateAssistantAvailability() {
         boolean assistantAvailableForUser = mAssistManagerLazy.get()
-                .getAssistInfoForUser(UserHandle.USER_CURRENT) != null;
+                .getAssistInfoForUser(mUserTracker.getUserId()) != null;
         boolean longPressDefault = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_assistLongPressHomeEnabledDefault);
         mLongPressHomeEnabled = Settings.Secure.getIntForUser(mContentResolver,
@@ -311,7 +312,7 @@
         mAssistantAvailable = assistantAvailableForUser
                 && mAssistantTouchGestureEnabled
                 && QuickStepContract.isGesturalMode(mNavBarMode);
-        dispatchAssistantEventUpdate(mAssistantAvailable);
+        dispatchAssistantEventUpdate(mAssistantAvailable, mLongPressHomeEnabled);
     }
 
     public boolean getLongPressHomeEnabled() {
@@ -366,7 +367,7 @@
      */
     public interface NavbarTaskbarStateUpdater {
         void updateAccessibilityServicesState();
-        void updateAssistantAvailable(boolean available);
+        void updateAssistantAvailable(boolean available, boolean longPressHomeEnabled);
     }
 
     /** Data class to help Taskbar/Navbar initiate state correctly when switching between the two.*/
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index bdb67ad..5993e2e 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.navigationbar;
 
+import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
 import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
 import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN;
 import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
@@ -44,6 +45,7 @@
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SWITCHER_SHOWING;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
 import static com.android.systemui.shared.system.QuickStepContract.isGesturalMode;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
 import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
@@ -70,7 +72,6 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.os.UserHandle;
 import android.provider.DeviceConfig;
 import android.telecom.TelecomManager;
 import android.text.TextUtils;
@@ -136,9 +137,10 @@
 import com.android.systemui.shared.recents.utilities.Utilities;
 import com.android.systemui.shared.rotation.RotationButton;
 import com.android.systemui.shared.rotation.RotationButtonController;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.shared.system.SysUiStatsLog;
+import com.android.systemui.shared.system.TaskStackChangeListener;
+import com.android.systemui.shared.system.TaskStackChangeListeners;
 import com.android.systemui.statusbar.AutoHideUiElement;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.CommandQueue.Callbacks;
@@ -252,6 +254,7 @@
     private final AutoHideController.Factory mAutoHideControllerFactory;
     private final Optional<TelecomManager> mTelecomManagerOptional;
     private final InputMethodManager mInputMethodManager;
+    private final TaskStackChangeListeners mTaskStackChangeListeners;
 
     @VisibleForTesting
     public int mDisplayId;
@@ -335,15 +338,16 @@
                 }
 
                 @Override
-                public void updateAssistantAvailable(boolean available) {
+                public void updateAssistantAvailable(boolean available,
+                        boolean longPressHomeEnabled) {
                     // TODO(b/198002034): Content observers currently can still be called back after
                     //  being unregistered, and in this case we can ignore the change if the nav bar
                     //  has been destroyed already
                     if (mView == null) {
                         return;
                     }
-                    mLongPressHomeEnabled = mNavBarHelper.getLongPressHomeEnabled();
-                    updateAssistantEntrypoints(available);
+                    mLongPressHomeEnabled = longPressHomeEnabled;
+                    updateAssistantEntrypoints(available, longPressHomeEnabled);
                 }
             };
 
@@ -487,6 +491,18 @@
             }
     };
 
+    private boolean mScreenPinningActive = false;
+    private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
+        @Override
+        public void onLockTaskModeChanged(int mode) {
+            mScreenPinningActive = (mode == LOCK_TASK_MODE_PINNED);
+            mSysUiFlagsContainer.setFlag(SYSUI_STATE_SCREEN_PINNING, mScreenPinningActive)
+                    .commitUpdate(mDisplayId);
+            mView.setInScreenPinning(mScreenPinningActive);
+            updateScreenPinningGestures();
+        }
+    };
+
     @Inject
     NavigationBar(
             NavigationBarView navigationBarView,
@@ -528,7 +544,8 @@
             EdgeBackGestureHandler edgeBackGestureHandler,
             Optional<BackAnimation> backAnimation,
             UserContextProvider userContextProvider,
-            WakefulnessLifecycle wakefulnessLifecycle) {
+            WakefulnessLifecycle wakefulnessLifecycle,
+            TaskStackChangeListeners taskStackChangeListeners) {
         super(navigationBarView);
         mFrame = navigationBarFrame;
         mContext = context;
@@ -567,6 +584,7 @@
         mInputMethodManager = inputMethodManager;
         mUserContextProvider = userContextProvider;
         mWakefulnessLifecycle = wakefulnessLifecycle;
+        mTaskStackChangeListeners = taskStackChangeListeners;
 
         mNavColorSampleMargin = getResources()
                 .getDimensionPixelSize(R.dimen.navigation_handle_sample_horizontal_margin);
@@ -675,6 +693,7 @@
         mCommandQueue.recomputeDisableFlags(mDisplayId, false);
 
         mNotificationShadeDepthController.addListener(mDepthListener);
+        mTaskStackChangeListeners.registerTaskStackListener(mTaskStackListener);
     }
 
     public void destroyView() {
@@ -688,6 +707,7 @@
         mNotificationShadeDepthController.removeListener(mDepthListener);
 
         mDeviceConfigProxy.removeOnPropertiesChangedListener(mOnPropertiesChangedListener);
+        mTaskStackChangeListeners.unregisterTaskStackListener(mTaskStackListener);
     }
 
     @Override
@@ -989,11 +1009,15 @@
         pw.println("  mTransientShown=" + mTransientShown);
         pw.println("  mTransientShownFromGestureOnSystemBar="
                 + mTransientShownFromGestureOnSystemBar);
+        pw.println("  mScreenPinningActive=" + mScreenPinningActive);
         dumpBarTransitions(pw, "mNavigationBarView", getBarTransitions());
 
         pw.println("  mOrientedHandleSamplingRegion: " + mOrientedHandleSamplingRegion);
         mView.dump(pw);
         mRegionSamplingHelper.dump(pw);
+        if (mAutoHideController != null) {
+            mAutoHideController.dump(pw);
+        }
     }
 
     // ----- CommandQueue Callbacks -----
@@ -1212,10 +1236,9 @@
 
     private void updateScreenPinningGestures() {
         // Change the cancel pin gesture to home and back if recents button is invisible
-        boolean pinningActive = ActivityManagerWrapper.getInstance().isScreenPinningActive();
         ButtonDispatcher backButton = mView.getBackButton();
         ButtonDispatcher recentsButton = mView.getRecentsButton();
-        if (pinningActive) {
+        if (mScreenPinningActive) {
             boolean recentsVisible = mView.isRecentsButtonVisible();
             backButton.setOnLongClickListener(recentsVisible
                     ? this::onLongPressBackRecents
@@ -1226,8 +1249,8 @@
             recentsButton.setOnLongClickListener(null);
         }
         // Note, this needs to be set after even if we're setting the listener to null
-        backButton.setLongClickable(pinningActive);
-        recentsButton.setLongClickable(pinningActive);
+        backButton.setLongClickable(mScreenPinningActive);
+        recentsButton.setLongClickable(mScreenPinningActive);
     }
 
     private void notifyNavigationBarScreenOn() {
@@ -1310,8 +1333,7 @@
 
     @VisibleForTesting
     boolean onHomeLongClick(View v) {
-        if (!mView.isRecentsButtonVisible()
-                && ActivityManagerWrapper.getInstance().isScreenPinningActive()) {
+        if (!mView.isRecentsButtonVisible() && mScreenPinningActive) {
             return onLongPressBackHome(v);
         }
         if (shouldDisableNavbarGestures()) {
@@ -1454,7 +1476,7 @@
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
         final String chooserClassName = AccessibilityButtonChooserActivity.class.getName();
         intent.setClassName(CHOOSER_PACKAGE_NAME, chooserClassName);
-        mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+        mContext.startActivityAsUser(intent, mUserTracker.getUserHandle());
         return true;
     }
 
@@ -1485,10 +1507,12 @@
                 .commitUpdate(mDisplayId);
     }
 
-    private void updateAssistantEntrypoints(boolean assistantAvailable) {
+    private void updateAssistantEntrypoints(boolean assistantAvailable,
+            boolean longPressHomeEnabled) {
         if (mOverviewProxyService.getProxy() != null) {
             try {
-                mOverviewProxyService.getProxy().onAssistantAvailable(assistantAvailable);
+                mOverviewProxyService.getProxy().onAssistantAvailable(assistantAvailable,
+                        longPressHomeEnabled);
             } catch (RemoteException e) {
                 Log.w(TAG, "Unable to send assistant availability data to launcher");
             }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
index 8914552..dce69bb 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
@@ -24,7 +24,6 @@
 import static com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler.DEBUG_MISSING_GESTURE_TAG;
 import static com.android.systemui.shared.recents.utilities.Utilities.isTablet;
 
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
@@ -57,13 +56,14 @@
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.shared.system.QuickStepContract;
+import com.android.systemui.shared.system.TaskStackChangeListeners;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.CommandQueue.Callbacks;
 import com.android.systemui.statusbar.phone.AutoHideController;
 import com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
 import com.android.systemui.statusbar.phone.LightBarController;
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.util.settings.SecureSettings;
 import com.android.wm.shell.back.BackAnimation;
 import com.android.wm.shell.pip.Pip;
 
@@ -86,9 +86,9 @@
     private final Handler mHandler;
     private final NavigationBarComponent.Factory mNavigationBarComponentFactory;
     private FeatureFlags mFeatureFlags;
+    private final SecureSettings mSecureSettings;
     private final DisplayManager mDisplayManager;
     private final TaskbarDelegate mTaskbarDelegate;
-    private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     private int mNavMode;
     @VisibleForTesting boolean mIsTablet;
 
@@ -112,28 +112,29 @@
             NavBarHelper navBarHelper,
             TaskbarDelegate taskbarDelegate,
             NavigationBarComponent.Factory navigationBarComponentFactory,
-            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
             DumpManager dumpManager,
             AutoHideController autoHideController,
             LightBarController lightBarController,
+            TaskStackChangeListeners taskStackChangeListeners,
             Optional<Pip> pipOptional,
             Optional<BackAnimation> backAnimation,
-            FeatureFlags featureFlags) {
+            FeatureFlags featureFlags,
+            SecureSettings secureSettings) {
         mContext = context;
         mHandler = mainHandler;
         mNavigationBarComponentFactory = navigationBarComponentFactory;
         mFeatureFlags = featureFlags;
+        mSecureSettings = secureSettings;
         mDisplayManager = mContext.getSystemService(DisplayManager.class);
         commandQueue.addCallback(this);
         configurationController.addCallback(this);
         mConfigChanges.applyNewConfig(mContext.getResources());
         mNavMode = navigationModeController.addListener(this);
         mTaskbarDelegate = taskbarDelegate;
-        mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
         mTaskbarDelegate.setDependencies(commandQueue, overviewProxyService,
                 navBarHelper, navigationModeController, sysUiFlagsContainer,
                 dumpManager, autoHideController, lightBarController, pipOptional,
-                backAnimation.orElse(null));
+                backAnimation.orElse(null), taskStackChangeListeners);
         mIsTablet = isTablet(mContext);
         dumpManager.registerDumpable(this);
     }
@@ -193,8 +194,7 @@
     }
 
     private void updateAccessibilityButtonModeIfNeeded() {
-        ContentResolver contentResolver = mContext.getContentResolver();
-        final int mode = Settings.Secure.getIntForUser(contentResolver,
+        final int mode = mSecureSettings.getIntForUser(
                 Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
                 ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR, UserHandle.USER_CURRENT);
 
@@ -208,14 +208,14 @@
         // force update to ACCESSIBILITY_BUTTON_MODE_GESTURE.
         if (QuickStepContract.isGesturalMode(mNavMode)
                 && mode == ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR) {
-            Settings.Secure.putIntForUser(contentResolver,
+            mSecureSettings.putIntForUser(
                     Settings.Secure.ACCESSIBILITY_BUTTON_MODE, ACCESSIBILITY_BUTTON_MODE_GESTURE,
                     UserHandle.USER_CURRENT);
             // ACCESSIBILITY_BUTTON_MODE_GESTURE is incompatible under non gestural mode. Need to
             // force update to ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR.
         } else if (!QuickStepContract.isGesturalMode(mNavMode)
                 && mode == ACCESSIBILITY_BUTTON_MODE_GESTURE) {
-            Settings.Secure.putIntForUser(contentResolver,
+            mSecureSettings.putIntForUser(
                     Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
                     ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR, UserHandle.USER_CURRENT);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
index 403d276..88c4fd5 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.navigationbar;
 
+import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
 import static android.inputmethodservice.InputMethodService.canImeRenderGesturalNavButtons;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
 
@@ -80,6 +81,7 @@
 import com.android.systemui.shared.rotation.RotationButtonController;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.QuickStepContract;
+import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.statusbar.phone.AutoHideController;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.LightBarTransitionsController;
@@ -160,6 +162,7 @@
      * fully locked mode we only show that unlocking is blocked.
      */
     private ScreenPinningNotify mScreenPinningNotify;
+    private boolean mScreenPinningActive = false;
 
     /**
      * {@code true} if the IME can render the back button and the IME switcher button.
@@ -636,14 +639,13 @@
         // When screen pinning, don't hide back and home when connected service or back and
         // recents buttons when disconnected from launcher service in screen pinning mode,
         // as they are used for exiting.
-        final boolean pinningActive = ActivityManagerWrapper.getInstance().isScreenPinningActive();
         if (mOverviewProxyEnabled) {
             // Force disable recents when not in legacy mode
             disableRecent |= !QuickStepContract.isLegacyMode(mNavBarMode);
-            if (pinningActive && !QuickStepContract.isGesturalMode(mNavBarMode)) {
+            if (mScreenPinningActive && !QuickStepContract.isGesturalMode(mNavBarMode)) {
                 disableBack = disableHome = false;
             }
-        } else if (pinningActive) {
+        } else if (mScreenPinningActive) {
             disableBack = disableRecent = false;
         }
 
@@ -738,9 +740,7 @@
     public void updateDisabledSystemUiStateFlags(SysUiState sysUiState) {
         int displayId = mContext.getDisplayId();
 
-        sysUiState.setFlag(SYSUI_STATE_SCREEN_PINNING,
-                        ActivityManagerWrapper.getInstance().isScreenPinningActive())
-                .setFlag(SYSUI_STATE_OVERVIEW_DISABLED,
+        sysUiState.setFlag(SYSUI_STATE_OVERVIEW_DISABLED,
                         (mDisabledFlags & View.STATUS_BAR_DISABLE_RECENT) != 0)
                 .setFlag(SYSUI_STATE_HOME_DISABLED,
                         (mDisabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0)
@@ -749,6 +749,10 @@
                 .commitUpdate(displayId);
     }
 
+    public void setInScreenPinning(boolean active) {
+        mScreenPinningActive = active;
+    }
+
     private void updatePanelSystemUiStateFlags() {
         if (SysUiState.DEBUG) {
             Log.d(TAG, "Updating panel sysui state flags: panelView=" + mPanelView);
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
index 3dec513..6ee86aa 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.navigationbar;
 
+import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
 import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
 import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN;
 import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
@@ -40,6 +41,7 @@
 
 import android.app.StatusBarManager;
 import android.app.StatusBarManager.WindowVisibleState;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.Rect;
@@ -68,6 +70,8 @@
 import com.android.systemui.shared.recents.utilities.Utilities;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.QuickStepContract;
+import com.android.systemui.shared.system.TaskStackChangeListener;
+import com.android.systemui.shared.system.TaskStackChangeListeners;
 import com.android.systemui.statusbar.AutoHideUiElement;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.AutoHideController;
@@ -101,6 +105,7 @@
     private AutoHideController mAutoHideController;
     private LightBarController mLightBarController;
     private LightBarTransitionsController mLightBarTransitionsController;
+    private TaskStackChangeListeners mTaskStackChangeListeners;
     private Optional<Pip> mPipOptional;
     private int mDisplayId;
     private int mNavigationIconHints;
@@ -112,8 +117,9 @@
                 }
 
                 @Override
-                public void updateAssistantAvailable(boolean available) {
-                    updateAssistantAvailability(available);
+                public void updateAssistantAvailable(boolean available,
+                        boolean longPressHomeEnabled) {
+                    updateAssistantAvailability(available, longPressHomeEnabled);
                 }
             };
     private int mDisabledFlags;
@@ -126,6 +132,14 @@
     private final DisplayManager mDisplayManager;
     private Context mWindowContext;
     private ScreenPinningNotify mScreenPinningNotify;
+    private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
+        @Override
+        public void onLockTaskModeChanged(int mode) {
+            mSysUiState.setFlag(SYSUI_STATE_SCREEN_PINNING, mode == LOCK_TASK_MODE_PINNED)
+                    .commitUpdate(mDisplayId);
+        }
+    };
+
     private int mNavigationMode = -1;
     private final Consumer<Rect> mPipListener;
 
@@ -175,7 +189,8 @@
             AutoHideController autoHideController,
             LightBarController lightBarController,
             Optional<Pip> pipOptional,
-            BackAnimation backAnimation) {
+            BackAnimation backAnimation,
+            TaskStackChangeListeners taskStackChangeListeners) {
         // TODO: adding this in the ctor results in a dagger dependency cycle :(
         mCommandQueue = commandQueue;
         mOverviewProxyService = overviewProxyService;
@@ -188,6 +203,7 @@
         mPipOptional = pipOptional;
         mBackAnimation = backAnimation;
         mLightBarTransitionsController = createLightBarTransitionsController();
+        mTaskStackChangeListeners = taskStackChangeListeners;
     }
 
     // Separated into a method to keep setDependencies() clean/readable.
@@ -233,6 +249,7 @@
         mPipOptional.ifPresent(this::addPipExclusionBoundsChangeListener);
         mEdgeBackGestureHandler.setBackAnimation(mBackAnimation);
         mEdgeBackGestureHandler.onConfigurationChanged(mContext.getResources().getConfiguration());
+        mTaskStackChangeListeners.registerTaskStackListener(mTaskStackListener);
         mInitialized = true;
     }
 
@@ -252,6 +269,7 @@
         mLightBarTransitionsController.destroy();
         mLightBarController.setNavigationBar(null);
         mPipOptional.ifPresent(this::removePipExclusionBoundsChangeListener);
+        mTaskStackChangeListeners.unregisterTaskStackListener(mTaskStackListener);
         mInitialized = false;
     }
 
@@ -299,8 +317,6 @@
                 .setFlag(SYSUI_STATE_NAV_BAR_HIDDEN, !isWindowVisible())
                 .setFlag(SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY,
                         allowSystemGestureIgnoringBarVisibility())
-                .setFlag(SYSUI_STATE_SCREEN_PINNING,
-                        ActivityManagerWrapper.getInstance().isScreenPinningActive())
                 .setFlag(SYSUI_STATE_IMMERSIVE_MODE, isImmersiveMode())
                 .commitUpdate(mDisplayId);
     }
@@ -309,13 +325,15 @@
         return (mSysUiState.getFlags() & View.STATUS_BAR_DISABLE_RECENT) == 0;
     }
 
-    private void updateAssistantAvailability(boolean assistantAvailable) {
+    private void updateAssistantAvailability(boolean assistantAvailable,
+            boolean longPressHomeEnabled) {
         if (mOverviewProxyService.getProxy() == null) {
             return;
         }
 
         try {
-            mOverviewProxyService.getProxy().onAssistantAvailable(assistantAvailable);
+            mOverviewProxyService.getProxy().onAssistantAvailable(assistantAvailable,
+                    longPressHomeEnabled);
         } catch (RemoteException e) {
             Log.e(TAG, "onAssistantAvailable() failed, available: " + assistantAvailable, e);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index 13c5b48..eea0e4c 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -273,7 +273,6 @@
                 @Override
                 public void triggerBack() {
                     // Notify FalsingManager that an intentional gesture has occurred.
-                    // TODO(b/186519446): use a different method than isFalseTouch
                     mFalsingManager.isFalseTouch(BACK_GESTURE);
                     // Only inject back keycodes when ahead-of-time back dispatching is disabled.
                     if (mBackAnimation == null) {
@@ -502,6 +501,15 @@
     }
 
     private void updateIsEnabled() {
+        try {
+            Trace.beginSection("EdgeBackGestureHandler#updateIsEnabled");
+            updateIsEnabledTraced();
+        } finally {
+            Trace.endSection();
+        }
+    }
+
+    private void updateIsEnabledTraced() {
         boolean isEnabled = mIsAttached && mIsGesturalModeEnabled;
         if (isEnabled == mIsEnabled) {
             return;
@@ -587,13 +595,18 @@
     }
 
     private void setEdgeBackPlugin(NavigationEdgeBackPlugin edgeBackPlugin) {
-        if (mEdgeBackPlugin != null) {
-            mEdgeBackPlugin.onDestroy();
+        try {
+            Trace.beginSection("setEdgeBackPlugin");
+            if (mEdgeBackPlugin != null) {
+                mEdgeBackPlugin.onDestroy();
+            }
+            mEdgeBackPlugin = edgeBackPlugin;
+            mEdgeBackPlugin.setBackCallback(mBackCallback);
+            mEdgeBackPlugin.setLayoutParams(createLayoutParams());
+            updateDisplaySize();
+        } finally {
+            Trace.endSection();
         }
-        mEdgeBackPlugin = edgeBackPlugin;
-        mEdgeBackPlugin.setBackCallback(mBackCallback);
-        mEdgeBackPlugin.setLayoutParams(createLayoutParams());
-        updateDisplaySize();
     }
 
     public boolean isHandlingGestures() {
@@ -919,6 +932,10 @@
                             mThresholdCrossed = true;
                             // Capture inputs
                             mInputMonitor.pilferPointers();
+                            if (mBackAnimation != null) {
+                                // Notify FalsingManager that an intentional gesture has occurred.
+                                mFalsingManager.isFalseTouch(BACK_GESTURE);
+                            }
                             mInputEventReceiver.setBatchingEnabled(true);
                         } else {
                             logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_FAR_FROM_EDGE);
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
index 6dd60d0..08d1857 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
@@ -57,7 +57,9 @@
      * If the keyguard is locked, notes will open as a full screen experience. A locked device has
      * no contextual information which let us use the whole screen space available.
      *
-     * If no in multi-window or the keyguard is unlocked, notes will open as a floating experience.
+     * If no in multi-window or the keyguard is unlocked, notes will open as a bubble OR it will be
+     * collapsed if the notes bubble is already opened.
+     *
      * That will let users open other apps in full screen, and take contextual notes.
      */
     fun showNoteTask(isInMultiWindowMode: Boolean = false) {
@@ -75,7 +77,7 @@
             context.startActivity(intent)
         } else {
             // TODO(b/254606432): Should include Intent.EXTRA_FLOATING_WINDOW_MODE parameter.
-            bubbles.showAppBubble(intent)
+            bubbles.showOrHideAppBubble(intent)
         }
     }
 
@@ -102,4 +104,9 @@
             PackageManager.DONT_KILL_APP,
         )
     }
+
+    companion object {
+        // TODO(b/254604589): Use final KeyEvent.KEYCODE_* instead.
+        const val NOTE_TASK_KEY_EVENT = 311
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt
index d14b7a7..d5f4a5a 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt
@@ -16,7 +16,6 @@
 
 package com.android.systemui.notetask
 
-import android.view.KeyEvent
 import androidx.annotation.VisibleForTesting
 import com.android.systemui.statusbar.CommandQueue
 import com.android.wm.shell.bubbles.Bubbles
@@ -37,7 +36,7 @@
     val callbacks =
         object : CommandQueue.Callbacks {
             override fun handleSystemKey(keyCode: Int) {
-                if (keyCode == KeyEvent.KEYCODE_VIDEO_APP_1) {
+                if (keyCode == NoteTaskController.NOTE_TASK_KEY_EVENT) {
                     noteTaskController.showNoteTask()
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskIntentResolver.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskIntentResolver.kt
index 98d6991..4b10d69 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskIntentResolver.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskIntentResolver.kt
@@ -21,12 +21,12 @@
 import android.content.pm.ActivityInfo
 import android.content.pm.PackageManager
 import android.content.pm.PackageManager.ResolveInfoFlags
-import com.android.systemui.notetask.NoteTaskIntentResolver.Companion.NOTES_ACTION
+import com.android.systemui.notetask.NoteTaskIntentResolver.Companion.ACTION_CREATE_NOTE
 import javax.inject.Inject
 
 /**
- * Class responsible to query all apps and find one that can handle the [NOTES_ACTION]. If found, an
- * [Intent] ready for be launched will be returned. Otherwise, returns null.
+ * Class responsible to query all apps and find one that can handle the [ACTION_CREATE_NOTE]. If
+ * found, an [Intent] ready for be launched will be returned. Otherwise, returns null.
  *
  * TODO(b/248274123): should be revisited once the notes role is implemented.
  */
@@ -37,15 +37,16 @@
 ) {
 
     fun resolveIntent(): Intent? {
-        val intent = Intent(NOTES_ACTION)
+        val intent = Intent(ACTION_CREATE_NOTE)
         val flags = ResolveInfoFlags.of(PackageManager.MATCH_DEFAULT_ONLY.toLong())
         val infoList = packageManager.queryIntentActivities(intent, flags)
 
         for (info in infoList) {
-            val packageName = info.serviceInfo.applicationInfo.packageName ?: continue
+            val packageName = info.activityInfo.applicationInfo.packageName ?: continue
             val activityName = resolveActivityNameForNotesAction(packageName) ?: continue
 
-            return Intent(NOTES_ACTION)
+            return Intent(ACTION_CREATE_NOTE)
+                .setPackage(packageName)
                 .setComponent(ComponentName(packageName, activityName))
                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
         }
@@ -54,7 +55,7 @@
     }
 
     private fun resolveActivityNameForNotesAction(packageName: String): String? {
-        val intent = Intent(NOTES_ACTION).setPackage(packageName)
+        val intent = Intent(ACTION_CREATE_NOTE).setPackage(packageName)
         val flags = ResolveInfoFlags.of(PackageManager.MATCH_DEFAULT_ONLY.toLong())
         val resolveInfo = packageManager.resolveActivity(intent, flags)
 
@@ -69,8 +70,11 @@
     }
 
     companion object {
-        // TODO(b/254606432): Use Intent.ACTION_NOTES and Intent.ACTION_NOTES_LOCKED instead.
-        const val NOTES_ACTION = "android.intent.action.NOTES"
+        // TODO(b/254606432): Use Intent.ACTION_CREATE_NOTE instead.
+        const val ACTION_CREATE_NOTE = "android.intent.action.CREATE_NOTE"
+
+        // TODO(b/265912743): Use RoleManager.NOTES_ROLE instead.
+        const val NOTE_ROLE = "android.app.role.NOTES"
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt
index 8bdf319..22ce121 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt
@@ -18,11 +18,13 @@
 
 import android.app.Activity
 import android.app.KeyguardManager
+import android.app.role.RoleManager
 import android.content.Context
 import android.os.UserManager
 import androidx.core.content.getSystemService
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
+import com.android.systemui.notetask.quickaffordance.NoteTaskQuickAffordanceModule
 import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity
 import com.android.systemui.notetask.shortcut.LaunchNoteTaskActivity
 import dagger.Binds
@@ -33,20 +35,25 @@
 import java.util.Optional
 
 /** Compose all dependencies required by Note Task feature. */
-@Module
+@Module(includes = [NoteTaskQuickAffordanceModule::class])
 internal interface NoteTaskModule {
 
     @[Binds IntoMap ClassKey(LaunchNoteTaskActivity::class)]
-    fun bindNoteTaskLauncherActivity(activity: LaunchNoteTaskActivity): Activity?
+    fun LaunchNoteTaskActivity.bindNoteTaskLauncherActivity(): Activity
 
     @[Binds IntoMap ClassKey(CreateNoteTaskShortcutActivity::class)]
-    fun bindNoteTaskShortcutActivity(activity: CreateNoteTaskShortcutActivity): Activity?
+    fun CreateNoteTaskShortcutActivity.bindNoteTaskShortcutActivity(): Activity
 
     companion object {
 
         @[Provides NoteTaskEnabledKey]
-        fun provideIsNoteTaskEnabled(featureFlags: FeatureFlags): Boolean {
-            return featureFlags.isEnabled(Flags.NOTE_TASKS)
+        fun provideIsNoteTaskEnabled(
+            featureFlags: FeatureFlags,
+            roleManager: RoleManager,
+        ): Boolean {
+            val isRoleAvailable = roleManager.isRoleAvailable(NoteTaskIntentResolver.NOTE_ROLE)
+            val isFeatureEnabled = featureFlags.isEnabled(Flags.NOTE_TASKS)
+            return isRoleAvailable && isFeatureEnabled
         }
 
         @Provides
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
new file mode 100644
index 0000000..cfbaa48
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
@@ -0,0 +1,70 @@
+/*
+ * 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.notetask.quickaffordance
+
+import android.content.Context
+import com.android.systemui.R
+import com.android.systemui.animation.Expandable
+import com.android.systemui.common.shared.model.ContentDescription
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.keyguard.data.quickaffordance.BuiltInKeyguardQuickAffordanceKeys
+import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
+import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.LockScreenState
+import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.OnTriggeredResult
+import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.PickerScreenState
+import com.android.systemui.notetask.NoteTaskController
+import com.android.systemui.notetask.NoteTaskEnabledKey
+import javax.inject.Inject
+import kotlinx.coroutines.flow.flowOf
+
+internal class NoteTaskQuickAffordanceConfig
+@Inject
+constructor(
+    context: Context,
+    private val noteTaskController: NoteTaskController,
+    @NoteTaskEnabledKey private val isEnabled: Boolean,
+) : KeyguardQuickAffordanceConfig {
+
+    override val key = BuiltInKeyguardQuickAffordanceKeys.CREATE_NOTE
+
+    override val pickerName: String = context.getString(R.string.note_task_button_label)
+
+    override val pickerIconResourceId = R.drawable.ic_note_task_shortcut_keyguard
+
+    override val lockScreenState = flowOf(getLockScreenState())
+
+    // TODO(b/265949213)
+    private fun getLockScreenState() =
+        if (isEnabled) {
+            val icon = Icon.Resource(pickerIconResourceId, ContentDescription.Loaded(pickerName))
+            LockScreenState.Visible(icon)
+        } else {
+            LockScreenState.Hidden
+        }
+
+    override suspend fun getPickerScreenState() =
+        if (isEnabled) {
+            PickerScreenState.Default()
+        } else {
+            PickerScreenState.UnavailableOnDevice
+        }
+
+    override fun onTriggered(expandable: Expandable?): OnTriggeredResult {
+        noteTaskController.showNoteTask()
+        return OnTriggeredResult.Handled
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceModule.kt b/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceModule.kt
new file mode 100644
index 0000000..7cb932a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceModule.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.notetask.quickaffordance
+
+import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
+import dagger.Binds
+import dagger.Module
+import dagger.multibindings.IntoSet
+
+@Module
+internal interface NoteTaskQuickAffordanceModule {
+
+    @[Binds IntoSet]
+    fun NoteTaskQuickAffordanceConfig.bindNoteTaskQuickAffordance(): KeyguardQuickAffordanceConfig
+}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/shortcut/CreateNoteTaskShortcutActivity.kt b/packages/SystemUI/src/com/android/systemui/notetask/shortcut/CreateNoteTaskShortcutActivity.kt
index f6a623e..6ab0da6 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/shortcut/CreateNoteTaskShortcutActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/shortcut/CreateNoteTaskShortcutActivity.kt
@@ -46,7 +46,7 @@
                 id = SHORTCUT_ID,
                 shortLabel = getString(R.string.note_task_button_label),
                 intent = LaunchNoteTaskActivity.newIntent(context = this),
-                iconResource = R.drawable.ic_note_task_button,
+                iconResource = R.drawable.ic_note_task_shortcut_widget,
             )
         setResult(Activity.RESULT_OK, intent)
 
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivity.kt b/packages/SystemUI/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivity.kt
index 47fe676..f203e7a 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivity.kt
@@ -45,8 +45,8 @@
         fun newIntent(context: Context): Intent {
             return Intent(context, LaunchNoteTaskActivity::class.java).apply {
                 // Intent's action must be set in shortcuts, or an exception will be thrown.
-                // TODO(b/254606432): Use Intent.ACTION_NOTES instead.
-                action = NoteTaskIntentResolver.NOTES_ACTION
+                // TODO(b/254606432): Use Intent.ACTION_CREATE_NOTE instead.
+                action = NoteTaskIntentResolver.ACTION_CREATE_NOTE
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
index fba5f63..7f0f894 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
@@ -68,8 +68,10 @@
         };
 
         if (ComposeFacade.INSTANCE.isComposeAvailable()) {
+            Log.d(TAG, "Using the Compose implementation of the PeopleSpaceActivity");
             ComposeFacade.INSTANCE.setPeopleSpaceActivityContent(this, viewModel, onResult);
         } else {
+            Log.d(TAG, "Using the View implementation of the PeopleSpaceActivity");
             ViewGroup view = PeopleViewBinder.create(this);
             PeopleViewBinder.bind(view, viewModel, /* lifecycleOwner= */ this, onResult);
             setContentView(view);
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index 90fc1d7..595b882 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -68,6 +68,7 @@
 import com.android.systemui.broadcast.BroadcastSender;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.util.NotificationChannels;
@@ -175,7 +176,7 @@
     private ActivityStarter mActivityStarter;
     private final BroadcastSender mBroadcastSender;
     private final UiEventLogger mUiEventLogger;
-
+    private final UserTracker mUserTracker;
     private final Lazy<BatteryController> mBatteryControllerLazy;
     private final DialogLaunchAnimator mDialogLaunchAnimator;
 
@@ -184,7 +185,8 @@
     @Inject
     public PowerNotificationWarnings(Context context, ActivityStarter activityStarter,
             BroadcastSender broadcastSender, Lazy<BatteryController> batteryControllerLazy,
-            DialogLaunchAnimator dialogLaunchAnimator, UiEventLogger uiEventLogger) {
+            DialogLaunchAnimator dialogLaunchAnimator, UiEventLogger uiEventLogger,
+            UserTracker userTracker) {
         mContext = context;
         mNoMan = mContext.getSystemService(NotificationManager.class);
         mPowerMan = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
@@ -196,6 +198,7 @@
         mDialogLaunchAnimator = dialogLaunchAnimator;
         mUseSevereDialog = mContext.getResources().getBoolean(R.bool.config_severe_battery_dialog);
         mUiEventLogger = uiEventLogger;
+        mUserTracker = userTracker;
     }
 
     @Override
@@ -692,7 +695,7 @@
                         Secure.putIntForUser(
                                 resolver,
                                 Secure.LOW_POWER_WARNING_ACKNOWLEDGED,
-                                1, UserHandle.USER_CURRENT);
+                                1, mUserTracker.getUserId());
                     });
         } else {
             d.setTitle(R.string.battery_saver_confirmation_title);
@@ -843,7 +846,8 @@
                 logEvent(BatteryWarningEvents
                         .LowBatteryWarningEvent.LOW_BATTERY_NOTIFICATION_SETTINGS);
                 dismissLowBatteryNotification();
-                mContext.startActivityAsUser(mOpenBatterySaverSettings, UserHandle.CURRENT);
+                mContext.startActivityAsUser(mOpenBatterySaverSettings,
+                        mUserTracker.getUserHandle());
             } else if (action.equals(ACTION_START_SAVER)) {
                 logEvent(BatteryWarningEvents
                         .LowBatteryWarningEvent.LOW_BATTERY_NOTIFICATION_TURN_ON);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index f8fb4e8..8ad102e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -19,6 +19,8 @@
 import static com.android.systemui.media.dagger.MediaModule.QS_PANEL;
 import static com.android.systemui.media.dagger.MediaModule.QUICK_QS_PANEL;
 import static com.android.systemui.statusbar.DisableFlagsLogger.DisableState;
+import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
+import static com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -47,6 +49,7 @@
 import com.android.systemui.R;
 import com.android.systemui.animation.Interpolators;
 import com.android.systemui.animation.ShadeInterpolation;
+import com.android.systemui.compose.ComposeFacade;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.media.controls.ui.MediaHost;
@@ -66,6 +69,7 @@
 import com.android.systemui.statusbar.policy.BrightnessMirrorController;
 import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
 import com.android.systemui.util.LifecycleFragment;
+import com.android.systemui.util.Utils;
 
 import java.io.PrintWriter;
 import java.util.Arrays;
@@ -124,7 +128,7 @@
      * we're on keyguard but use {@link #isKeyguardState()} instead since that is more accurate
      * during state transitions which often call into us.
      */
-    private int mState;
+    private int mStatusBarState = -1;
     private QSContainerImplController mQSContainerImplController;
     private int[] mTmpLocation = new int[2];
     private int mLastViewHeight;
@@ -225,9 +229,7 @@
 
         mQSFooterActionsViewModel = mFooterActionsViewModelFactory.create(/* lifecycleOwner */
                 this);
-        LinearLayout footerActionsView = view.findViewById(R.id.qs_footer_actions);
-        FooterActionsViewBinder.bind(footerActionsView, mQSFooterActionsViewModel,
-                mListeningAndVisibilityLifecycleOwner);
+        bindFooterActionsView(view);
         mFooterActionsController.init();
 
         mQSPanelScrollView = view.findViewById(R.id.expanded_qs_scroll_view);
@@ -288,6 +290,33 @@
                 });
     }
 
+    private void bindFooterActionsView(View root) {
+        LinearLayout footerActionsView = root.findViewById(R.id.qs_footer_actions);
+
+        if (!ComposeFacade.INSTANCE.isComposeAvailable()) {
+            Log.d(TAG, "Binding the View implementation of the QS footer actions");
+            FooterActionsViewBinder.bind(footerActionsView, mQSFooterActionsViewModel,
+                    mListeningAndVisibilityLifecycleOwner);
+            return;
+        }
+
+        // Compose is available, so let's use the Compose implementation of the footer actions.
+        Log.d(TAG, "Binding the Compose implementation of the QS footer actions");
+        View composeView = ComposeFacade.INSTANCE.createFooterActionsView(root.getContext(),
+                mQSFooterActionsViewModel, mListeningAndVisibilityLifecycleOwner);
+
+        // The id R.id.qs_footer_actions is used by QSContainerImpl to set the horizontal margin
+        // to all views except for qs_footer_actions, so we set it to the Compose view.
+        composeView.setId(R.id.qs_footer_actions);
+
+        // Replace the View by the Compose provided one.
+        ViewGroup parent = (ViewGroup) footerActionsView.getParent();
+        ViewGroup.LayoutParams layoutParams = footerActionsView.getLayoutParams();
+        int index = parent.indexOfChild(footerActionsView);
+        parent.removeViewAt(index);
+        parent.addView(composeView, index, layoutParams);
+    }
+
     @Override
     public void setScrollListener(ScrollListener listener) {
         mScrollListener = listener;
@@ -457,7 +486,7 @@
     private boolean isKeyguardState() {
         // We want the freshest state here since otherwise we'll have some weirdness if earlier
         // listeners trigger updates
-        return mStatusBarStateController.getState() == StatusBarState.KEYGUARD;
+        return mStatusBarStateController.getCurrentOrUpcomingState() == KEYGUARD;
     }
 
     private void updateShowCollapsedOnKeyguard() {
@@ -672,8 +701,8 @@
             mQSAnimator.setPosition(expansion);
         }
         if (!mInSplitShade
-                || mStatusBarStateController.getState() == StatusBarState.KEYGUARD
-                || mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED) {
+                || mStatusBarStateController.getState() == KEYGUARD
+                || mStatusBarStateController.getState() == SHADE_LOCKED) {
             // At beginning, state is 0 and will apply wrong squishiness to MediaHost in lockscreen
             // and media player expect no change by squishiness in lock screen shade. Don't bother
             // squishing mQsMediaHost when not in split shade to prevent problems with stale state.
@@ -681,7 +710,7 @@
         } else {
             mQsMediaHost.setSquishFraction(mSquishinessFraction);
         }
-
+        updateMediaPositions();
     }
 
     private void setAlphaAnimationProgress(float progress) {
@@ -703,8 +732,8 @@
             // Large screens in landscape.
             // Need to check upcoming state as for unlocked -> AOD transition current state is
             // not updated yet, but we're transitioning and UI should already follow KEYGUARD state
-            if (mTransitioningToFullShade || mStatusBarStateController.getCurrentOrUpcomingState()
-                    == StatusBarState.KEYGUARD) {
+            if (mTransitioningToFullShade
+                    || mStatusBarStateController.getCurrentOrUpcomingState() == KEYGUARD) {
                 // Always use "mFullShadeProgress" on keyguard, because
                 // "panelExpansionFractions" is always 1 on keyguard split shade.
                 return mLockscreenToShadeProgress;
@@ -756,9 +785,24 @@
                         - mQSPanelController.getPaddingBottom());
     }
 
+    private void updateMediaPositions() {
+        if (Utils.useQsMediaPlayer(getContext())) {
+            View hostView = mQsMediaHost.getHostView();
+            // Make sure the media appears a bit from the top to make it look nicer
+            if (mLastQSExpansion > 0 && !isKeyguardState() && !mQqsMediaHost.getVisible()
+                    && !mQSPanelController.shouldUseHorizontalLayout() && !mInSplitShade) {
+                float interpolation = 1.0f - mLastQSExpansion;
+                interpolation = Interpolators.ACCELERATE.getInterpolation(interpolation);
+                float translationY = -hostView.getHeight() * 1.3f * interpolation;
+                hostView.setTranslationY(translationY);
+            } else {
+                hostView.setTranslationY(0);
+            }
+        }
+    }
+
     private boolean headerWillBeAnimating() {
-        return mState == StatusBarState.KEYGUARD && mShowCollapsedOnKeyguard
-                && !isKeyguardState();
+        return mStatusBarState == KEYGUARD && mShowCollapsedOnKeyguard && !isKeyguardState();
     }
 
     @Override
@@ -891,9 +935,23 @@
     };
 
     @Override
+    public void onUpcomingStateChanged(int upcomingState) {
+        if (upcomingState == KEYGUARD) {
+            // refresh state of QS as soon as possible - while it's still upcoming - so in case of
+            // transition to KEYGUARD (e.g. from unlocked to AOD) all objects are aware they should
+            // already behave like on keyguard. Otherwise we might be doing extra work,
+            // e.g. QSAnimator making QS visible and then quickly invisible
+            onStateChanged(upcomingState);
+        }
+    }
+
+    @Override
     public void onStateChanged(int newState) {
-        mState = newState;
-        setKeyguardShowing(newState == StatusBarState.KEYGUARD);
+        if (newState == mStatusBarState) {
+            return;
+        }
+        mStatusBarState = newState;
+        setKeyguardShowing(newState == KEYGUARD);
         updateShowCollapsedOnKeyguard();
     }
 
@@ -921,7 +979,7 @@
         indentingPw.println("mTemp: " + Arrays.toString(mLocationTemp));
         indentingPw.println("mShowCollapsedOnKeyguard: " + mShowCollapsedOnKeyguard);
         indentingPw.println("mLastKeyguardAndExpanded: " + mLastKeyguardAndExpanded);
-        indentingPw.println("mState: " + StatusBarState.toString(mState));
+        indentingPw.println("mStatusBarState: " + StatusBarState.toString(mStatusBarState));
         indentingPw.println("mTmpLocation: " + Arrays.toString(mTmpLocation));
         indentingPw.println("mLastViewHeight: " + mLastViewHeight);
         indentingPw.println("mLastHeaderTranslation: " + mLastHeaderTranslation);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSHost.java
index 7cf63f6..1da30ad 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSHost.java
@@ -36,7 +36,6 @@
     void removeCallback(Callback callback);
     void removeTile(String tileSpec);
     void removeTiles(Collection<String> specs);
-    void unmarkTileAsAutoAdded(String tileSpec);
 
     int indexOf(String tileSpec);
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
index 7bb672c..e85d0a3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
@@ -372,18 +372,18 @@
         if (mUsingHorizontalLayout) {
             // Only height remaining
             parameters.getDisappearSize().set(0.0f, 0.4f);
-            // Disappearing on the right side on the bottom
-            parameters.getGonePivot().set(1.0f, 1.0f);
+            // Disappearing on the right side on the top
+            parameters.getGonePivot().set(1.0f, 0.0f);
             // translating a bit horizontal
             parameters.getContentTranslationFraction().set(0.25f, 1.0f);
             parameters.setDisappearEnd(0.6f);
         } else {
             // Only width remaining
             parameters.getDisappearSize().set(1.0f, 0.0f);
-            // Disappearing on the bottom
-            parameters.getGonePivot().set(0.0f, 1.0f);
+            // Disappearing on the top
+            parameters.getGonePivot().set(0.0f, 0.0f);
             // translating a bit vertical
-            parameters.getContentTranslationFraction().set(0.0f, 1.05f);
+            parameters.getContentTranslationFraction().set(0.0f, 1f);
             parameters.setDisappearEnd(0.95f);
         }
         parameters.setFadeStartPosition(0.95f);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index cad296b..100853c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -427,11 +427,6 @@
         mMainExecutor.execute(() -> changeTileSpecs(tileSpecs -> tileSpecs.removeAll(specs)));
     }
 
-    @Override
-    public void unmarkTileAsAutoAdded(String spec) {
-        if (mAutoTiles != null) mAutoTiles.unmarkTileAsAutoAdded(spec);
-    }
-
     /**
      * Add a tile to the end
      *
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ReduceBrightColorsController.java b/packages/SystemUI/src/com/android/systemui/qs/ReduceBrightColorsController.java
index 39d081d..36dc743 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ReduceBrightColorsController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/ReduceBrightColorsController.java
@@ -83,8 +83,7 @@
                     if (mListeners.size() > 0) {
                         mSecureSettings.unregisterContentObserver(mContentObserver);
                         mSecureSettings.registerContentObserverForUser(
-                                Settings.Secure.getUriFor(
-                                        Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED),
+                                Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED,
                                 false, mContentObserver, newUser);
                     }
                 }
@@ -100,8 +99,7 @@
                 mListeners.add(listener);
                 if (mListeners.size() == 1) {
                     mSecureSettings.registerContentObserverForUser(
-                            Settings.Secure.getUriFor(
-                                    Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED),
+                            Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED,
                             false, mContentObserver, mUserTracker.getUserId());
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index 79fcc7d..1712490 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -24,6 +24,7 @@
 import android.util.TypedValue;
 import android.view.LayoutInflater;
 import android.view.Menu;
+import android.view.MenuItem;
 import android.view.View;
 import android.widget.LinearLayout;
 import android.widget.Toolbar;
@@ -74,8 +75,8 @@
         toolbar.setNavigationIcon(
                 getResources().getDrawable(value.resourceId, mContext.getTheme()));
 
-        toolbar.getMenu().add(Menu.NONE, MENU_RESET, 0,
-                mContext.getString(com.android.internal.R.string.reset));
+        toolbar.getMenu().add(Menu.NONE, MENU_RESET, 0, com.android.internal.R.string.reset)
+                .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
         toolbar.setTitle(R.string.qs_edit);
         mRecyclerView = findViewById(android.R.id.list);
         mTransparentView = findViewById(R.id.customizer_transparent_view);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
index 3d48fd1..84a18d8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
@@ -132,7 +132,7 @@
             final String slot = tile.getComponent().getClassName();
             // TileServices doesn't know how to add more than 1 icon per slot, so remove all
             mMainHandler.post(() -> mHost.getIconController()
-                    .removeAllIconsForSlot(slot));
+                    .removeAllIconsForExternalSlot(slot));
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt
index 30f8124..1921586 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt
@@ -219,9 +219,9 @@
             // Small button with the number only.
             foregroundServicesWithTextView.isVisible = false
 
-            foregroundServicesWithNumberView.visibility = View.VISIBLE
+            foregroundServicesWithNumberView.isVisible = true
             foregroundServicesWithNumberView.setOnClickListener {
-                foregroundServices.onClick(Expandable.fromView(foregroundServicesWithTextView))
+                foregroundServices.onClick(Expandable.fromView(foregroundServicesWithNumberView))
             }
             foregroundServicesWithNumberHolder.number.text = foregroundServicesCount.toString()
             foregroundServicesWithNumberHolder.number.contentDescription = foregroundServices.text
diff --git a/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt b/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
index d682853f5..d32ef32 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
@@ -18,12 +18,13 @@
 
 import android.service.quicksettings.Tile
 import com.android.systemui.log.dagger.QSLog
+import com.android.systemui.plugins.log.ConstantStringsLogger
+import com.android.systemui.plugins.log.ConstantStringsLoggerImpl
 import com.android.systemui.plugins.log.LogBuffer
 import com.android.systemui.plugins.log.LogLevel
 import com.android.systemui.plugins.log.LogLevel.DEBUG
 import com.android.systemui.plugins.log.LogLevel.ERROR
 import com.android.systemui.plugins.log.LogLevel.VERBOSE
-import com.android.systemui.plugins.log.LogLevel.WARNING
 import com.android.systemui.plugins.log.LogMessage
 import com.android.systemui.plugins.qs.QSTile
 import com.android.systemui.statusbar.StatusBarState
@@ -32,17 +33,8 @@
 
 private const val TAG = "QSLog"
 
-class QSLogger @Inject constructor(
-    @QSLog private val buffer: LogBuffer
-) {
-
-    fun d(@CompileTimeConstant msg: String) = buffer.log(TAG, DEBUG, msg)
-
-    fun e(@CompileTimeConstant msg: String) = buffer.log(TAG, ERROR, msg)
-
-    fun v(@CompileTimeConstant msg: String) = buffer.log(TAG, VERBOSE, msg)
-
-    fun w(@CompileTimeConstant msg: String) = buffer.log(TAG, WARNING, msg)
+class QSLogger @Inject constructor(@QSLog private val buffer: LogBuffer) :
+    ConstantStringsLogger by ConstantStringsLoggerImpl(buffer, TAG) {
 
     fun logException(@CompileTimeConstant logMsg: String, ex: Exception) {
         buffer.log(TAG, ERROR, {}, { logMsg }, exception = ex)
@@ -57,109 +49,135 @@
     }
 
     fun logTileAdded(tileSpec: String) {
-        log(DEBUG, {
-            str1 = tileSpec
-        }, {
-            "[$str1] Tile added"
-        })
+        buffer.log(TAG, DEBUG, { str1 = tileSpec }, { "[$str1] Tile added" })
     }
 
     fun logTileDestroyed(tileSpec: String, reason: String) {
-        log(DEBUG, {
-            str1 = tileSpec
-            str2 = reason
-        }, {
-            "[$str1] Tile destroyed. Reason: $str2"
-        })
+        buffer.log(
+            TAG,
+            DEBUG,
+            {
+                str1 = tileSpec
+                str2 = reason
+            },
+            { "[$str1] Tile destroyed. Reason: $str2" }
+        )
     }
 
     fun logTileChangeListening(tileSpec: String, listening: Boolean) {
-        log(VERBOSE, {
-            bool1 = listening
-            str1 = tileSpec
-        }, {
-            "[$str1] Tile listening=$bool1"
-        })
+        buffer.log(
+            TAG,
+            VERBOSE,
+            {
+                bool1 = listening
+                str1 = tileSpec
+            },
+            { "[$str1] Tile listening=$bool1" }
+        )
     }
 
     fun logAllTilesChangeListening(listening: Boolean, containerName: String, allSpecs: String) {
-        log(DEBUG, {
-            bool1 = listening
-            str1 = containerName
-            str2 = allSpecs
-        }, {
-            "Tiles listening=$bool1 in $str1. $str2"
-        })
+        buffer.log(
+            TAG,
+            DEBUG,
+            {
+                bool1 = listening
+                str1 = containerName
+                str2 = allSpecs
+            },
+            { "Tiles listening=$bool1 in $str1. $str2" }
+        )
     }
 
     fun logTileClick(tileSpec: String, statusBarState: Int, state: Int, eventId: Int) {
-        log(DEBUG, {
-            str1 = tileSpec
-            int1 = eventId
-            str2 = StatusBarState.toString(statusBarState)
-            str3 = toStateString(state)
-        }, {
-            "[$str1][$int1] Tile clicked. StatusBarState=$str2. TileState=$str3"
-        })
+        buffer.log(
+            TAG,
+            DEBUG,
+            {
+                str1 = tileSpec
+                int1 = eventId
+                str2 = StatusBarState.toString(statusBarState)
+                str3 = toStateString(state)
+            },
+            { "[$str1][$int1] Tile clicked. StatusBarState=$str2. TileState=$str3" }
+        )
     }
 
     fun logHandleClick(tileSpec: String, eventId: Int) {
-        log(DEBUG, {
-            str1 = tileSpec
-            int1 = eventId
-        }, {
-            "[$str1][$int1] Tile handling click."
-        })
+        buffer.log(
+            TAG,
+            DEBUG,
+            {
+                str1 = tileSpec
+                int1 = eventId
+            },
+            { "[$str1][$int1] Tile handling click." }
+        )
     }
 
     fun logTileSecondaryClick(tileSpec: String, statusBarState: Int, state: Int, eventId: Int) {
-        log(DEBUG, {
-            str1 = tileSpec
-            int1 = eventId
-            str2 = StatusBarState.toString(statusBarState)
-            str3 = toStateString(state)
-        }, {
-            "[$str1][$int1] Tile secondary clicked. StatusBarState=$str2. TileState=$str3"
-        })
+        buffer.log(
+            TAG,
+            DEBUG,
+            {
+                str1 = tileSpec
+                int1 = eventId
+                str2 = StatusBarState.toString(statusBarState)
+                str3 = toStateString(state)
+            },
+            { "[$str1][$int1] Tile secondary clicked. StatusBarState=$str2. TileState=$str3" }
+        )
     }
 
     fun logHandleSecondaryClick(tileSpec: String, eventId: Int) {
-        log(DEBUG, {
-            str1 = tileSpec
-            int1 = eventId
-        }, {
-            "[$str1][$int1] Tile handling secondary click."
-        })
+        buffer.log(
+            TAG,
+            DEBUG,
+            {
+                str1 = tileSpec
+                int1 = eventId
+            },
+            { "[$str1][$int1] Tile handling secondary click." }
+        )
     }
 
     fun logTileLongClick(tileSpec: String, statusBarState: Int, state: Int, eventId: Int) {
-        log(DEBUG, {
-            str1 = tileSpec
-            int1 = eventId
-            str2 = StatusBarState.toString(statusBarState)
-            str3 = toStateString(state)
-        }, {
-            "[$str1][$int1] Tile long clicked. StatusBarState=$str2. TileState=$str3"
-        })
+        buffer.log(
+            TAG,
+            DEBUG,
+            {
+                str1 = tileSpec
+                int1 = eventId
+                str2 = StatusBarState.toString(statusBarState)
+                str3 = toStateString(state)
+            },
+            { "[$str1][$int1] Tile long clicked. StatusBarState=$str2. TileState=$str3" }
+        )
     }
 
     fun logHandleLongClick(tileSpec: String, eventId: Int) {
-        log(DEBUG, {
-            str1 = tileSpec
-            int1 = eventId
-        }, {
-            "[$str1][$int1] Tile handling long click."
-        })
+        buffer.log(
+            TAG,
+            DEBUG,
+            {
+                str1 = tileSpec
+                int1 = eventId
+            },
+            { "[$str1][$int1] Tile handling long click." }
+        )
     }
 
     fun logInternetTileUpdate(tileSpec: String, lastType: Int, callback: String) {
-        log(VERBOSE, {
-            str1 = tileSpec
-            int1 = lastType
-            str2 = callback
-        }, {
-            "[$str1] mLastTileState=$int1, Callback=$str2."
-        })
+        buffer.log(
+            TAG,
+            VERBOSE,
+            {
+                str1 = tileSpec
+                int1 = lastType
+                str2 = callback
+            },
+            { "[$str1] mLastTileState=$int1, Callback=$str2." }
+        )
     }
 
     // TODO(b/250618218): Remove this method once we know the root cause of b/250618218.
@@ -175,58 +193,75 @@
         if (tileSpec != "internet") {
             return
         }
-        log(VERBOSE, {
-            str1 = tileSpec
-            int1 = state
-            bool1 = disabledByPolicy
-            int2 = color
-        }, {
-            "[$str1] state=$int1, disabledByPolicy=$bool1, color=$int2."
-        })
+        buffer.log(
+            TAG,
+            VERBOSE,
+            {
+                str1 = tileSpec
+                int1 = state
+                bool1 = disabledByPolicy
+                int2 = color
+            },
+            { "[$str1] state=$int1, disabledByPolicy=$bool1, color=$int2." }
+        )
     }
 
     fun logTileUpdated(tileSpec: String, state: QSTile.State) {
-        log(VERBOSE, {
-            str1 = tileSpec
-            str2 = state.label?.toString()
-            str3 = state.icon?.toString()
-            int1 = state.state
-            if (state is QSTile.SignalState) {
-                bool1 = true
-                bool2 = state.activityIn
-                bool3 = state.activityOut
+        buffer.log(
+            TAG,
+            VERBOSE,
+            {
+                str1 = tileSpec
+                str2 = state.label?.toString()
+                str3 = state.icon?.toString()
+                int1 = state.state
+                if (state is QSTile.SignalState) {
+                    bool1 = true
+                    bool2 = state.activityIn
+                    bool3 = state.activityOut
+                }
+            },
+            {
+                "[$str1] Tile updated. Label=$str2. State=$int1. Icon=$str3." +
+                    if (bool1) " Activity in/out=$bool2/$bool3" else ""
             }
-        }, {
-            "[$str1] Tile updated. Label=$str2. State=$int1. Icon=$str3." +
-                if (bool1) " Activity in/out=$bool2/$bool3" else ""
-        })
+        )
     }
 
     fun logPanelExpanded(expanded: Boolean, containerName: String) {
-        log(DEBUG, {
-            str1 = containerName
-            bool1 = expanded
-        }, {
-            "$str1 expanded=$bool1"
-        })
+        buffer.log(
+            TAG,
+            DEBUG,
+            {
+                str1 = containerName
+                bool1 = expanded
+            },
+            { "$str1 expanded=$bool1" }
+        )
     }
 
     fun logOnViewAttached(orientation: Int, containerName: String) {
-        log(DEBUG, {
-            str1 = containerName
-            int1 = orientation
-        }, {
-            "onViewAttached: $str1 orientation $int1"
-        })
+        buffer.log(
+            TAG,
+            DEBUG,
+            {
+                str1 = containerName
+                int1 = orientation
+            },
+            { "onViewAttached: $str1 orientation $int1" }
+        )
     }
 
     fun logOnViewDetached(orientation: Int, containerName: String) {
-        log(DEBUG, {
-            str1 = containerName
-            int1 = orientation
-        }, {
-            "onViewDetached: $str1 orientation $int1"
-        })
+        buffer.log(
+            TAG,
+            DEBUG,
+            {
+                str1 = containerName
+                int1 = orientation
+            },
+            { "onViewDetached: $str1 orientation $int1" }
+        )
     }
 
     fun logOnConfigurationChanged(
@@ -234,13 +269,16 @@
         newOrientation: Int,
         containerName: String
     ) {
-        log(DEBUG, {
-            str1 = containerName
-            int1 = lastOrientation
-            int2 = newOrientation
-        }, {
-            "configuration change: $str1 orientation was $int1, now $int2"
-        })
+        buffer.log(
+            TAG,
+            DEBUG,
+            {
+                str1 = containerName
+                int1 = lastOrientation
+                int2 = newOrientation
+            },
+            { "configuration change: $str1 orientation was $int1, now $int2" }
+        )
     }
 
     fun logSwitchTileLayout(
@@ -249,32 +287,41 @@
         force: Boolean,
         containerName: String
     ) {
-        log(DEBUG, {
-            str1 = containerName
-            bool1 = after
-            bool2 = before
-            bool3 = force
-        }, {
-            "change tile layout: $str1 horizontal=$bool1 (was $bool2), force? $bool3"
-        })
+        buffer.log(
+            TAG,
+            DEBUG,
+            {
+                str1 = containerName
+                bool1 = after
+                bool2 = before
+                bool3 = force
+            },
+            { "change tile layout: $str1 horizontal=$bool1 (was $bool2), force? $bool3" }
+        )
     }
 
     fun logTileDistributionInProgress(tilesPerPageCount: Int, totalTilesCount: Int) {
-        log(DEBUG, {
-            int1 = tilesPerPageCount
-            int2 = totalTilesCount
-        }, {
-            "Distributing tiles: [tilesPerPageCount=$int1] [totalTilesCount=$int2]"
-        })
+        buffer.log(
+            TAG,
+            DEBUG,
+            {
+                int1 = tilesPerPageCount
+                int2 = totalTilesCount
+            },
+            { "Distributing tiles: [tilesPerPageCount=$int1] [totalTilesCount=$int2]" }
+        )
     }
 
     fun logTileDistributed(tileName: String, pageIndex: Int) {
-        log(DEBUG, {
-            str1 = tileName
-            int1 = pageIndex
-        }, {
-            "Adding $str1 to page number $int1"
-        })
+        buffer.log(
+            TAG,
+            DEBUG,
+            {
+                str1 = tileName
+                int1 = pageIndex
+            },
+            { "Adding $str1 to page number $int1" }
+        )
     }
 
     private fun toStateString(state: Int): String {
@@ -285,12 +332,4 @@
             else -> "wrong state"
         }
     }
-
-    private inline fun log(
-        logLevel: LogLevel,
-        initializer: LogMessage.() -> Unit,
-        noinline printer: LogMessage.() -> String
-    ) {
-        buffer.log(TAG, logLevel, initializer, printer)
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
index a92c7e3..24a4f60b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
@@ -33,7 +33,6 @@
 import com.android.systemui.qs.tiles.BluetoothTile;
 import com.android.systemui.qs.tiles.CameraToggleTile;
 import com.android.systemui.qs.tiles.CastTile;
-import com.android.systemui.qs.tiles.CellularTile;
 import com.android.systemui.qs.tiles.ColorCorrectionTile;
 import com.android.systemui.qs.tiles.ColorInversionTile;
 import com.android.systemui.qs.tiles.DataSaverTile;
@@ -54,7 +53,6 @@
 import com.android.systemui.qs.tiles.RotationLockTile;
 import com.android.systemui.qs.tiles.ScreenRecordTile;
 import com.android.systemui.qs.tiles.UiModeNightTile;
-import com.android.systemui.qs.tiles.WifiTile;
 import com.android.systemui.qs.tiles.WorkModeTile;
 import com.android.systemui.util.leak.GarbageMonitor;
 
@@ -68,10 +66,8 @@
 
     private static final String TAG = "QSFactory";
 
-    private final Provider<WifiTile> mWifiTileProvider;
     private final Provider<InternetTile> mInternetTileProvider;
     private final Provider<BluetoothTile> mBluetoothTileProvider;
-    private final Provider<CellularTile> mCellularTileProvider;
     private final Provider<DndTile> mDndTileProvider;
     private final Provider<ColorCorrectionTile> mColorCorrectionTileProvider;
     private final Provider<ColorInversionTile> mColorInversionTileProvider;
@@ -106,10 +102,8 @@
     public QSFactoryImpl(
             Lazy<QSHost> qsHostLazy,
             Provider<CustomTile.Builder> customTileBuilderProvider,
-            Provider<WifiTile> wifiTileProvider,
             Provider<InternetTile> internetTileProvider,
             Provider<BluetoothTile> bluetoothTileProvider,
-            Provider<CellularTile> cellularTileProvider,
             Provider<DndTile> dndTileProvider,
             Provider<ColorInversionTile> colorInversionTileProvider,
             Provider<AirplaneModeTile> airplaneModeTileProvider,
@@ -139,10 +133,8 @@
         mQsHostLazy = qsHostLazy;
         mCustomTileBuilderProvider = customTileBuilderProvider;
 
-        mWifiTileProvider = wifiTileProvider;
         mInternetTileProvider = internetTileProvider;
         mBluetoothTileProvider = bluetoothTileProvider;
-        mCellularTileProvider = cellularTileProvider;
         mDndTileProvider = dndTileProvider;
         mColorInversionTileProvider = colorInversionTileProvider;
         mAirplaneModeTileProvider = airplaneModeTileProvider;
@@ -186,14 +178,10 @@
     protected QSTileImpl createTileInternal(String tileSpec) {
         // Stock tiles.
         switch (tileSpec) {
-            case "wifi":
-                return mWifiTileProvider.get();
             case "internet":
                 return mInternetTileProvider.get();
             case "bt":
                 return mBluetoothTileProvider.get();
-            case "cell":
-                return mCellularTileProvider.get();
             case "dnd":
                 return mDndTileProvider.get();
             case "inversion":
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
index b355d4b..29d7fb0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
@@ -145,7 +145,6 @@
     private val launchableViewDelegate = LaunchableViewDelegate(
         this,
         superSetVisibility = { super.setVisibility(it) },
-        superSetTransitionVisibility = { super.setTransitionVisibility(it) },
     )
     private var lastDisabledByPolicy = false
 
@@ -362,10 +361,6 @@
         launchableViewDelegate.setVisibility(visibility)
     }
 
-    override fun setTransitionVisibility(visibility: Int) {
-        launchableViewDelegate.setTransitionVisibility(visibility)
-    }
-
     // Accessibility
 
     override fun onInitializeAccessibilityEvent(event: AccessibilityEvent) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
deleted file mode 100644
index 04a25fc..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.qs.tiles;
-
-import static com.android.systemui.Prefs.Key.QS_HAS_TURNED_OFF_MOBILE_DATA;
-
-import android.annotation.NonNull;
-import android.app.AlertDialog;
-import android.app.AlertDialog.Builder;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.service.quicksettings.Tile;
-import android.telephony.SubscriptionManager;
-import android.text.Html;
-import android.text.TextUtils;
-import android.view.View;
-import android.view.WindowManager.LayoutParams;
-import android.widget.Switch;
-
-import androidx.annotation.Nullable;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settingslib.net.DataUsageController;
-import com.android.systemui.Prefs;
-import com.android.systemui.R;
-import com.android.systemui.dagger.qualifiers.Background;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.plugins.qs.QSIconView;
-import com.android.systemui.plugins.qs.QSTile.SignalState;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.qs.QSHost;
-import com.android.systemui.qs.SignalTileView;
-import com.android.systemui.qs.logging.QSLogger;
-import com.android.systemui.qs.tileimpl.QSTileImpl;
-import com.android.systemui.statusbar.connectivity.IconState;
-import com.android.systemui.statusbar.connectivity.MobileDataIndicators;
-import com.android.systemui.statusbar.connectivity.NetworkController;
-import com.android.systemui.statusbar.connectivity.SignalCallback;
-import com.android.systemui.statusbar.phone.SystemUIDialog;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-
-import javax.inject.Inject;
-
-/** Quick settings tile: Cellular **/
-public class CellularTile extends QSTileImpl<SignalState> {
-    private static final String ENABLE_SETTINGS_DATA_PLAN = "enable.settings.data.plan";
-
-    private final NetworkController mController;
-    private final DataUsageController mDataController;
-    private final KeyguardStateController mKeyguard;
-    private final CellSignalCallback mSignalCallback = new CellSignalCallback();
-
-    @Inject
-    public CellularTile(
-            QSHost host,
-            @Background Looper backgroundLooper,
-            @Main Handler mainHandler,
-            FalsingManager falsingManager,
-            MetricsLogger metricsLogger,
-            StatusBarStateController statusBarStateController,
-            ActivityStarter activityStarter,
-            QSLogger qsLogger,
-            NetworkController networkController,
-            KeyguardStateController keyguardStateController
-
-    ) {
-        super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
-                statusBarStateController, activityStarter, qsLogger);
-        mController = networkController;
-        mKeyguard = keyguardStateController;
-        mDataController = mController.getMobileDataController();
-        mController.observe(getLifecycle(), mSignalCallback);
-    }
-
-    @Override
-    public SignalState newTileState() {
-        return new SignalState();
-    }
-
-    @Override
-    public QSIconView createTileView(Context context) {
-        return new SignalTileView(context);
-    }
-
-    @Override
-    public Intent getLongClickIntent() {
-        if (getState().state == Tile.STATE_UNAVAILABLE) {
-            return new Intent(Settings.ACTION_WIRELESS_SETTINGS);
-        }
-        return getCellularSettingIntent();
-    }
-
-    @Override
-    protected void handleClick(@Nullable View view) {
-        if (getState().state == Tile.STATE_UNAVAILABLE) {
-            return;
-        }
-        if (mDataController.isMobileDataEnabled()) {
-            maybeShowDisableDialog();
-        } else {
-            mDataController.setMobileDataEnabled(true);
-        }
-    }
-
-    private void maybeShowDisableDialog() {
-        if (Prefs.getBoolean(mContext, QS_HAS_TURNED_OFF_MOBILE_DATA, false)) {
-            // Directly turn off mobile data if the user has seen the dialog before.
-            mDataController.setMobileDataEnabled(false);
-            return;
-        }
-        String carrierName = mController.getMobileDataNetworkName();
-        boolean isInService = mController.isMobileDataNetworkInService();
-        if (TextUtils.isEmpty(carrierName) || !isInService) {
-            carrierName = mContext.getString(R.string.mobile_data_disable_message_default_carrier);
-        }
-        AlertDialog dialog = new Builder(mContext)
-                .setTitle(R.string.mobile_data_disable_title)
-                .setMessage(mContext.getString(R.string.mobile_data_disable_message, carrierName))
-                .setNegativeButton(android.R.string.cancel, null)
-                .setPositiveButton(
-                        com.android.internal.R.string.alert_windows_notification_turn_off_action,
-                        (d, w) -> {
-                            mDataController.setMobileDataEnabled(false);
-                            Prefs.putBoolean(mContext, QS_HAS_TURNED_OFF_MOBILE_DATA, true);
-                        })
-                .create();
-        dialog.getWindow().setType(LayoutParams.TYPE_KEYGUARD_DIALOG);
-        SystemUIDialog.setShowForAllUsers(dialog, true);
-        SystemUIDialog.registerDismissListener(dialog);
-        SystemUIDialog.setWindowOnTop(dialog, mKeyguard.isShowing());
-        dialog.show();
-    }
-
-    @Override
-    protected void handleSecondaryClick(@Nullable View view) {
-        handleLongClick(view);
-    }
-
-    @Override
-    public CharSequence getTileLabel() {
-        return mContext.getString(R.string.quick_settings_cellular_detail_title);
-    }
-
-    @Override
-    protected void handleUpdateState(SignalState state, Object arg) {
-        CallbackInfo cb = (CallbackInfo) arg;
-        if (cb == null) {
-            cb = mSignalCallback.mInfo;
-        }
-
-        final Resources r = mContext.getResources();
-        state.label = r.getString(R.string.mobile_data);
-        boolean mobileDataEnabled = mDataController.isMobileDataSupported()
-                && mDataController.isMobileDataEnabled();
-        state.value = mobileDataEnabled;
-        state.activityIn = mobileDataEnabled && cb.activityIn;
-        state.activityOut = mobileDataEnabled && cb.activityOut;
-        state.expandedAccessibilityClassName = Switch.class.getName();
-        if (cb.noSim) {
-            state.icon = ResourceIcon.get(R.drawable.ic_qs_no_sim);
-        } else {
-            state.icon = ResourceIcon.get(R.drawable.ic_swap_vert);
-        }
-
-        if (cb.noSim) {
-            state.state = Tile.STATE_UNAVAILABLE;
-            state.secondaryLabel = r.getString(R.string.keyguard_missing_sim_message_short);
-        } else if (cb.airplaneModeEnabled) {
-            state.state = Tile.STATE_UNAVAILABLE;
-            state.secondaryLabel = r.getString(R.string.status_bar_airplane);
-        } else if (mobileDataEnabled) {
-            state.state = Tile.STATE_ACTIVE;
-            state.secondaryLabel = appendMobileDataType(
-                    // Only show carrier name if there are more than 1 subscription
-                    cb.multipleSubs ? cb.dataSubscriptionName : "",
-                    getMobileDataContentName(cb));
-        } else {
-            state.state = Tile.STATE_INACTIVE;
-            state.secondaryLabel = r.getString(R.string.cell_data_off);
-        }
-
-        state.contentDescription = state.label;
-        if (state.state == Tile.STATE_INACTIVE) {
-            // This information is appended later by converting the Tile.STATE_INACTIVE state.
-            state.stateDescription = "";
-        } else {
-            state.stateDescription = state.secondaryLabel;
-        }
-    }
-
-    private CharSequence appendMobileDataType(CharSequence current, CharSequence dataType) {
-        if (TextUtils.isEmpty(dataType)) {
-            return Html.fromHtml(current.toString(), 0);
-        }
-        if (TextUtils.isEmpty(current)) {
-            return Html.fromHtml(dataType.toString(), 0);
-        }
-        String concat = mContext.getString(R.string.mobile_carrier_text_format, current, dataType);
-        return Html.fromHtml(concat, 0);
-    }
-
-    private CharSequence getMobileDataContentName(CallbackInfo cb) {
-        if (cb.roaming && !TextUtils.isEmpty(cb.dataContentDescription)) {
-            String roaming = mContext.getString(R.string.data_connection_roaming);
-            String dataDescription = cb.dataContentDescription.toString();
-            return mContext.getString(R.string.mobile_data_text_format, roaming, dataDescription);
-        }
-        if (cb.roaming) {
-            return mContext.getString(R.string.data_connection_roaming);
-        }
-        return cb.dataContentDescription;
-    }
-
-    @Override
-    public int getMetricsCategory() {
-        return MetricsEvent.QS_CELLULAR;
-    }
-
-    @Override
-    public boolean isAvailable() {
-        return mController.hasMobileDataFeature()
-            && mHost.getUserContext().getUserId() == UserHandle.USER_SYSTEM;
-    }
-
-    private static final class CallbackInfo {
-        boolean airplaneModeEnabled;
-        @Nullable
-        CharSequence dataSubscriptionName;
-        @Nullable
-        CharSequence dataContentDescription;
-        boolean activityIn;
-        boolean activityOut;
-        boolean noSim;
-        boolean roaming;
-        boolean multipleSubs;
-    }
-
-    private final class CellSignalCallback implements SignalCallback {
-        private final CallbackInfo mInfo = new CallbackInfo();
-
-        @Override
-        public void setMobileDataIndicators(@NonNull MobileDataIndicators indicators) {
-            if (indicators.qsIcon == null) {
-                // Not data sim, don't display.
-                return;
-            }
-            mInfo.dataSubscriptionName = mController.getMobileDataNetworkName();
-            mInfo.dataContentDescription = indicators.qsDescription != null
-                    ? indicators.typeContentDescriptionHtml : null;
-            mInfo.activityIn = indicators.activityIn;
-            mInfo.activityOut = indicators.activityOut;
-            mInfo.roaming = indicators.roaming;
-            mInfo.multipleSubs = mController.getNumberSubscriptions() > 1;
-            refreshState(mInfo);
-        }
-
-        @Override
-        public void setNoSims(boolean show, boolean simDetected) {
-            mInfo.noSim = show;
-            refreshState(mInfo);
-        }
-
-        @Override
-        public void setIsAirplaneMode(@NonNull IconState icon) {
-            mInfo.airplaneModeEnabled = icon.visible;
-            refreshState(mInfo);
-        }
-    }
-
-    static Intent getCellularSettingIntent() {
-        Intent intent = new Intent(Settings.ACTION_NETWORK_OPERATOR_SETTINGS);
-        int dataSub = SubscriptionManager.getDefaultDataSubscriptionId();
-        if (dataSub != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            intent.putExtra(Settings.EXTRA_SUB_ID,
-                    SubscriptionManager.getDefaultDataSubscriptionId());
-        }
-        return intent;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
index 57a00c9..b6b657e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
@@ -204,15 +204,6 @@
             Trace.endSection();
         }
 
-        @Override
-        public void onUserListItemClicked(@NonNull UserRecord record,
-                @Nullable UserSwitchDialogController.DialogShower dialogShower) {
-            if (dialogShower != null) {
-                mDialogShower.dismiss();
-            }
-            super.onUserListItemClicked(record, dialogShower);
-        }
-
         public void linkToViewGroup(ViewGroup viewGroup) {
             PseudoGridView.ViewGroupAdapterBridge.link(viewGroup, this);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
deleted file mode 100644
index b2be56cc..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.qs.tiles;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.os.Handler;
-import android.os.Looper;
-import android.provider.Settings;
-import android.service.quicksettings.Tile;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.View;
-import android.widget.Switch;
-
-import androidx.annotation.Nullable;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
-import com.android.systemui.dagger.qualifiers.Background;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.plugins.qs.QSIconView;
-import com.android.systemui.plugins.qs.QSTile;
-import com.android.systemui.plugins.qs.QSTile.SignalState;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.qs.AlphaControlledSignalTileView;
-import com.android.systemui.qs.QSHost;
-import com.android.systemui.qs.logging.QSLogger;
-import com.android.systemui.qs.tileimpl.QSIconViewImpl;
-import com.android.systemui.qs.tileimpl.QSTileImpl;
-import com.android.systemui.statusbar.connectivity.AccessPointController;
-import com.android.systemui.statusbar.connectivity.NetworkController;
-import com.android.systemui.statusbar.connectivity.SignalCallback;
-import com.android.systemui.statusbar.connectivity.WifiIcons;
-import com.android.systemui.statusbar.connectivity.WifiIndicators;
-
-import javax.inject.Inject;
-
-/** Quick settings tile: Wifi **/
-public class WifiTile extends QSTileImpl<SignalState> {
-    private static final Intent WIFI_SETTINGS = new Intent(Settings.ACTION_WIFI_SETTINGS);
-
-    protected final NetworkController mController;
-    private final AccessPointController mWifiController;
-    private final QSTile.SignalState mStateBeforeClick = newTileState();
-
-    protected final WifiSignalCallback mSignalCallback = new WifiSignalCallback();
-    private boolean mExpectDisabled;
-
-    @Inject
-    public WifiTile(
-            QSHost host,
-            @Background Looper backgroundLooper,
-            @Main Handler mainHandler,
-            FalsingManager falsingManager,
-            MetricsLogger metricsLogger,
-            StatusBarStateController statusBarStateController,
-            ActivityStarter activityStarter,
-            QSLogger qsLogger,
-            NetworkController networkController,
-            AccessPointController accessPointController
-    ) {
-        super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
-                statusBarStateController, activityStarter, qsLogger);
-        mController = networkController;
-        mWifiController = accessPointController;
-        mController.observe(getLifecycle(), mSignalCallback);
-        mStateBeforeClick.spec = "wifi";
-    }
-
-    @Override
-    public SignalState newTileState() {
-        return new SignalState();
-    }
-
-    @Override
-    public QSIconView createTileView(Context context) {
-        return new AlphaControlledSignalTileView(context);
-    }
-
-    @Override
-    public Intent getLongClickIntent() {
-        return WIFI_SETTINGS;
-    }
-
-    @Override
-    protected void handleClick(@Nullable View view) {
-        // Secondary clicks are header clicks, just toggle.
-        mState.copyTo(mStateBeforeClick);
-        boolean wifiEnabled = mState.value;
-        // Immediately enter transient state when turning on wifi.
-        refreshState(wifiEnabled ? null : ARG_SHOW_TRANSIENT_ENABLING);
-        mController.setWifiEnabled(!wifiEnabled);
-        mExpectDisabled = wifiEnabled;
-        if (mExpectDisabled) {
-            mHandler.postDelayed(() -> {
-                if (mExpectDisabled) {
-                    mExpectDisabled = false;
-                    refreshState();
-                }
-            }, QSIconViewImpl.QS_ANIM_LENGTH);
-        }
-    }
-
-    @Override
-    protected void handleSecondaryClick(@Nullable View view) {
-        if (!mWifiController.canConfigWifi()) {
-            mActivityStarter.postStartActivityDismissingKeyguard(
-                    new Intent(Settings.ACTION_WIFI_SETTINGS), 0);
-            return;
-        }
-        if (!mState.value) {
-            mController.setWifiEnabled(true);
-        }
-    }
-
-    @Override
-    public CharSequence getTileLabel() {
-        return mContext.getString(R.string.quick_settings_wifi_label);
-    }
-
-    @Override
-    protected void handleUpdateState(SignalState state, Object arg) {
-        if (DEBUG) Log.d(TAG, "handleUpdateState arg=" + arg);
-        final CallbackInfo cb = mSignalCallback.mInfo;
-        if (mExpectDisabled) {
-            if (cb.enabled) {
-                return; // Ignore updates until disabled event occurs.
-            } else {
-                mExpectDisabled = false;
-            }
-        }
-        boolean transientEnabling = arg == ARG_SHOW_TRANSIENT_ENABLING;
-        boolean wifiConnected = cb.enabled && (cb.wifiSignalIconId > 0)
-                && (cb.ssid != null || cb.wifiSignalIconId != WifiIcons.QS_WIFI_NO_NETWORK);
-        boolean wifiNotConnected = (cb.ssid == null)
-                && (cb.wifiSignalIconId == WifiIcons.QS_WIFI_NO_NETWORK);
-        if (state.slash == null) {
-            state.slash = new SlashState();
-            state.slash.rotation = 6;
-        }
-        state.slash.isSlashed = false;
-        boolean isTransient = transientEnabling || cb.isTransient;
-        state.secondaryLabel = getSecondaryLabel(isTransient, cb.statusLabel);
-        state.state = Tile.STATE_ACTIVE;
-        state.dualTarget = true;
-        state.value = transientEnabling || cb.enabled;
-        state.activityIn = cb.enabled && cb.activityIn;
-        state.activityOut = cb.enabled && cb.activityOut;
-        final StringBuffer minimalContentDescription = new StringBuffer();
-        final StringBuffer minimalStateDescription = new StringBuffer();
-        final Resources r = mContext.getResources();
-        if (isTransient) {
-            state.icon = ResourceIcon.get(
-                    com.android.internal.R.drawable.ic_signal_wifi_transient_animation);
-            state.label = r.getString(R.string.quick_settings_wifi_label);
-        } else if (!state.value) {
-            state.slash.isSlashed = true;
-            state.state = Tile.STATE_INACTIVE;
-            state.icon = ResourceIcon.get(WifiIcons.QS_WIFI_DISABLED);
-            state.label = r.getString(R.string.quick_settings_wifi_label);
-        } else if (wifiConnected) {
-            state.icon = ResourceIcon.get(cb.wifiSignalIconId);
-            state.label = cb.ssid != null ? removeDoubleQuotes(cb.ssid) : getTileLabel();
-        } else if (wifiNotConnected) {
-            state.icon = ResourceIcon.get(WifiIcons.QS_WIFI_NO_NETWORK);
-            state.label = r.getString(R.string.quick_settings_wifi_label);
-        } else {
-            state.icon = ResourceIcon.get(WifiIcons.QS_WIFI_NO_NETWORK);
-            state.label = r.getString(R.string.quick_settings_wifi_label);
-        }
-        minimalContentDescription.append(
-                mContext.getString(R.string.quick_settings_wifi_label)).append(",");
-        if (state.value) {
-            if (wifiConnected) {
-                minimalStateDescription.append(cb.wifiSignalContentDescription);
-                minimalContentDescription.append(removeDoubleQuotes(cb.ssid));
-                if (!TextUtils.isEmpty(state.secondaryLabel)) {
-                    minimalContentDescription.append(",").append(state.secondaryLabel);
-                }
-            }
-        }
-        state.stateDescription = minimalStateDescription.toString();
-        state.contentDescription = minimalContentDescription.toString();
-        state.dualLabelContentDescription = r.getString(
-                R.string.accessibility_quick_settings_open_settings, getTileLabel());
-        state.expandedAccessibilityClassName = Switch.class.getName();
-    }
-
-    private CharSequence getSecondaryLabel(boolean isTransient, String statusLabel) {
-        return isTransient
-                ? mContext.getString(R.string.quick_settings_wifi_secondary_label_transient)
-                : statusLabel;
-    }
-
-    @Override
-    public int getMetricsCategory() {
-        return MetricsEvent.QS_WIFI;
-    }
-
-    @Override
-    public boolean isAvailable() {
-        return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI);
-    }
-
-    @Nullable
-    private static String removeDoubleQuotes(String string) {
-        if (string == null) return null;
-        final int length = string.length();
-        if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) {
-            return string.substring(1, length - 1);
-        }
-        return string;
-    }
-
-    protected static final class CallbackInfo {
-        boolean enabled;
-        boolean connected;
-        int wifiSignalIconId;
-        @Nullable
-        String ssid;
-        boolean activityIn;
-        boolean activityOut;
-        @Nullable
-        String wifiSignalContentDescription;
-        boolean isTransient;
-        @Nullable
-        public String statusLabel;
-
-        @Override
-        public String toString() {
-            return new StringBuilder("CallbackInfo[")
-                    .append("enabled=").append(enabled)
-                    .append(",connected=").append(connected)
-                    .append(",wifiSignalIconId=").append(wifiSignalIconId)
-                    .append(",ssid=").append(ssid)
-                    .append(",activityIn=").append(activityIn)
-                    .append(",activityOut=").append(activityOut)
-                    .append(",wifiSignalContentDescription=").append(wifiSignalContentDescription)
-                    .append(",isTransient=").append(isTransient)
-                    .append(']').toString();
-        }
-    }
-
-    protected final class WifiSignalCallback implements SignalCallback {
-        final CallbackInfo mInfo = new CallbackInfo();
-
-        @Override
-        public void setWifiIndicators(@NonNull WifiIndicators indicators) {
-            if (DEBUG) Log.d(TAG, "onWifiSignalChanged enabled=" + indicators.enabled);
-            if (indicators.qsIcon == null) {
-                return;
-            }
-            mInfo.enabled = indicators.enabled;
-            mInfo.connected = indicators.qsIcon.visible;
-            mInfo.wifiSignalIconId = indicators.qsIcon.icon;
-            mInfo.ssid = indicators.description;
-            mInfo.activityIn = indicators.activityIn;
-            mInfo.activityOut = indicators.activityOut;
-            mInfo.wifiSignalContentDescription = indicators.qsIcon.contentDescription;
-            mInfo.isTransient = indicators.isTransient;
-            mInfo.statusLabel = indicators.statusLabel;
-            refreshState();
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
index a6c7781..72c6bfe 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
@@ -101,7 +101,6 @@
     @MainThread
     public void onManagedProfileRemoved() {
         mHost.removeTile(getTileSpec());
-        mHost.unmarkTileAsAutoAdded(getTileSpec());
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt b/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt
index 314252b..4c9c99c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt
@@ -36,6 +36,7 @@
 import com.android.systemui.qs.QSUserSwitcherEvent
 import com.android.systemui.qs.tiles.UserDetailView
 import com.android.systemui.statusbar.phone.SystemUIDialog
+import com.android.systemui.user.ui.dialog.DialogShowerImpl
 import javax.inject.Inject
 import javax.inject.Provider
 
@@ -130,19 +131,6 @@
         }
     }
 
-    private class DialogShowerImpl(
-        private val animateFrom: Dialog,
-        private val dialogLaunchAnimator: DialogLaunchAnimator
-    ) : DialogInterface by animateFrom, DialogShower {
-        override fun showDialog(dialog: Dialog, cuj: DialogCuj) {
-            dialogLaunchAnimator.showFromDialog(
-                dialog,
-                animateFrom = animateFrom,
-                cuj
-            )
-        }
-    }
-
     interface DialogShower : DialogInterface {
         fun showDialog(dialog: Dialog, cuj: DialogCuj)
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 4d005be..1151475 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -21,7 +21,6 @@
 import static android.view.MotionEvent.ACTION_CANCEL;
 import static android.view.MotionEvent.ACTION_DOWN;
 import static android.view.MotionEvent.ACTION_UP;
-import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_OVERVIEW;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
 
 import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME;
@@ -44,8 +43,6 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
-import android.graphics.Insets;
-import android.graphics.Rect;
 import android.graphics.Region;
 import android.hardware.input.InputManager;
 import android.os.Binder;
@@ -77,6 +74,7 @@
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.policy.ScreenDecorationsUtils;
 import com.android.internal.util.ScreenshotHelper;
+import com.android.internal.util.ScreenshotRequest;
 import com.android.systemui.Dumpable;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
@@ -94,7 +92,6 @@
 import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.shared.recents.ISystemUiProxy;
-import com.android.systemui.shared.recents.model.Task;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
@@ -311,7 +308,7 @@
                         intent.setClassName(CHOOSER_PACKAGE_NAME, chooserClassName);
                         intent.addFlags(
                                 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
-                        mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+                        mContext.startActivityAsUser(intent, mUserTracker.getUserHandle());
                     });
         }
 
@@ -322,18 +319,8 @@
         }
 
         @Override
-        public void handleImageBundleAsScreenshot(Bundle screenImageBundle, Rect locationInScreen,
-                Insets visibleInsets, Task.TaskKey task) {
-            mScreenshotHelper.provideScreenshot(
-                    screenImageBundle,
-                    locationInScreen,
-                    visibleInsets,
-                    task.id,
-                    task.userId,
-                    task.sourceComponent,
-                    SCREENSHOT_OVERVIEW,
-                    mHandler,
-                    null);
+        public void takeScreenshot(ScreenshotRequest request) {
+            mScreenshotHelper.takeScreenshot(request, mHandler, null);
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt
index 44b18ec..68e3dcd 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt
@@ -23,6 +23,7 @@
 import android.os.Handler
 import android.os.Looper
 import android.os.ResultReceiver
+import android.os.UserHandle
 import android.view.View
 import android.view.View.GONE
 import android.view.View.VISIBLE
@@ -77,6 +78,14 @@
                     MediaProjectionAppSelectorActivity.EXTRA_CAPTURE_REGION_RESULT_RECEIVER,
                     CaptureTargetResultReceiver()
                 )
+
+                // Send SystemUI's user handle as the host app user handle because SystemUI
+                // is the 'host app' (the app that receives screen capture data)
+                intent.putExtra(
+                    MediaProjectionAppSelectorActivity.EXTRA_HOST_APP_USER_HANDLE,
+                    UserHandle.of(UserHandle.myUserId())
+                )
+
                 val animationController = dialogLaunchAnimator.createActivityLaunchController(v!!)
                 if (animationController == null) {
                     dismiss()
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
index 5450db9..d64b33b 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
@@ -49,6 +49,7 @@
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
 import com.android.systemui.screenshot.ScrollCaptureController.LongScreenshot;
+import com.android.systemui.settings.UserTracker;
 
 import com.google.common.util.concurrent.ListenableFuture;
 
@@ -79,6 +80,7 @@
     private final LongScreenshotData mLongScreenshotHolder;
     private final ActionIntentExecutor mActionExecutor;
     private final FeatureFlags mFeatureFlags;
+    private final UserTracker mUserTracker;
 
     private ImageView mPreview;
     private ImageView mTransitionView;
@@ -110,7 +112,7 @@
     public LongScreenshotActivity(UiEventLogger uiEventLogger, ImageExporter imageExporter,
             @Main Executor mainExecutor, @Background Executor bgExecutor,
             LongScreenshotData longScreenshotHolder, ActionIntentExecutor actionExecutor,
-            FeatureFlags featureFlags) {
+            FeatureFlags featureFlags, UserTracker userTracker) {
         mUiEventLogger = uiEventLogger;
         mUiExecutor = mainExecutor;
         mBackgroundExecutor = bgExecutor;
@@ -118,6 +120,7 @@
         mLongScreenshotHolder = longScreenshotHolder;
         mActionExecutor = actionExecutor;
         mFeatureFlags = featureFlags;
+        mUserTracker = userTracker;
     }
 
 
@@ -375,7 +378,7 @@
             Intent sharingChooserIntent = Intent.createChooser(intent, null)
                     .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
 
-            startActivityAsUser(sharingChooserIntent, UserHandle.CURRENT);
+            startActivityAsUser(sharingChooserIntent, mUserTracker.getUserHandle());
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt b/packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt
index 95cc0dc..f011aab 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt
@@ -19,27 +19,26 @@
 import android.graphics.Insets
 import android.util.Log
 import android.view.WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE
-import com.android.internal.util.ScreenshotHelper.HardwareBitmapBundler
-import com.android.internal.util.ScreenshotHelper.ScreenshotRequest
+import com.android.internal.util.ScreenshotRequest
 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.SCREENSHOT_WORK_PROFILE_POLICY
-import java.util.function.Consumer
-import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.launch
+import java.util.function.Consumer
+import javax.inject.Inject
 
 /**
  * Processes a screenshot request sent from {@link ScreenshotHelper}.
  */
 @SysUISingleton
 class RequestProcessor @Inject constructor(
-    private val capture: ImageCapture,
-    private val policy: ScreenshotPolicy,
-    private val flags: FeatureFlags,
-    /** For the Java Async version, to invoke the callback. */
-    @Application private val mainScope: CoroutineScope
+        private val capture: ImageCapture,
+        private val policy: ScreenshotPolicy,
+        private val flags: FeatureFlags,
+        /** For the Java Async version, to invoke the callback. */
+        @Application private val mainScope: CoroutineScope
 ) {
     /**
      * Inspects the incoming request, returning a potentially modified request depending on policy.
@@ -58,7 +57,7 @@
         // regardless of the managed profile status.
 
         if (request.type != TAKE_SCREENSHOT_PROVIDED_IMAGE &&
-            flags.isEnabled(SCREENSHOT_WORK_PROFILE_POLICY)
+                flags.isEnabled(SCREENSHOT_WORK_PROFILE_POLICY)
         ) {
 
             val info = policy.findPrimaryContent(policy.getDefaultDisplayId())
@@ -66,17 +65,21 @@
 
             result = if (policy.isManagedProfile(info.user.identifier)) {
                 val image = capture.captureTask(info.taskId)
-                    ?: error("Task snapshot returned a null Bitmap!")
+                        ?: error("Task snapshot returned a null Bitmap!")
 
                 // Provide the task snapshot as the screenshot
-                ScreenshotRequest(
-                    TAKE_SCREENSHOT_PROVIDED_IMAGE, request.source,
-                    HardwareBitmapBundler.hardwareBitmapToBundle(image),
-                    info.bounds, Insets.NONE, info.taskId, info.user.identifier, info.component
-                )
+                ScreenshotRequest.Builder(TAKE_SCREENSHOT_PROVIDED_IMAGE, request.source)
+                        .setTopComponent(info.component)
+                        .setTaskId(info.taskId)
+                        .setUserId(info.user.identifier)
+                        .setBitmap(image)
+                        .setBoundsOnScreen(info.bounds)
+                        .setInsets(Insets.NONE)
+                        .build()
             } else {
                 // Create a new request of the same type which includes the top component
-                ScreenshotRequest(request.type, request.source, info.component)
+                ScreenshotRequest.Builder(request.type, request.source)
+                        .setTopComponent(info.component).build()
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
index b4934cf..bf5fbd2 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
@@ -20,8 +20,7 @@
 import static com.android.systemui.screenshot.LogConfig.DEBUG_CALLBACK;
 import static com.android.systemui.screenshot.LogConfig.DEBUG_STORAGE;
 import static com.android.systemui.screenshot.LogConfig.logTag;
-import static com.android.systemui.screenshot.ScreenshotNotificationSmartActionsProvider.ScreenshotSmartActionType.QUICK_SHARE_ACTION;
-import static com.android.systemui.screenshot.ScreenshotNotificationSmartActionsProvider.ScreenshotSmartActionType.REGULAR_SMART_ACTIONS;
+import static com.android.systemui.screenshot.ScreenshotNotificationSmartActionsProvider.ScreenshotSmartActionType;
 
 import android.app.ActivityTaskManager;
 import android.app.Notification;
@@ -155,7 +154,8 @@
 
             CompletableFuture<List<Notification.Action>> smartActionsFuture =
                     mScreenshotSmartActions.getSmartActionsFuture(
-                            mScreenshotId, uri, image, mSmartActionsProvider, REGULAR_SMART_ACTIONS,
+                            mScreenshotId, uri, image, mSmartActionsProvider,
+                            ScreenshotSmartActionType.REGULAR_SMART_ACTIONS,
                             smartActionsEnabled, user);
             List<Notification.Action> smartActions = new ArrayList<>();
             if (smartActionsEnabled) {
@@ -166,7 +166,8 @@
                 smartActions.addAll(buildSmartActions(
                         mScreenshotSmartActions.getSmartActions(
                                 mScreenshotId, smartActionsFuture, timeoutMs,
-                                mSmartActionsProvider, REGULAR_SMART_ACTIONS),
+                                mSmartActionsProvider,
+                                ScreenshotSmartActionType.REGULAR_SMART_ACTIONS),
                         mContext));
             }
 
@@ -476,7 +477,7 @@
         CompletableFuture<List<Notification.Action>> quickShareActionsFuture =
                 mScreenshotSmartActions.getSmartActionsFuture(
                         mScreenshotId, null, image, mSmartActionsProvider,
-                        QUICK_SHARE_ACTION,
+                        ScreenshotSmartActionType.QUICK_SHARE_ACTION,
                         true /* smartActionsEnabled */, user);
         int timeoutMs = DeviceConfig.getInt(
                 DeviceConfig.NAMESPACE_SYSTEMUI,
@@ -485,7 +486,8 @@
         List<Notification.Action> quickShareActions =
                 mScreenshotSmartActions.getSmartActions(
                         mScreenshotId, quickShareActionsFuture, timeoutMs,
-                        mSmartActionsProvider, QUICK_SHARE_ACTION);
+                        mSmartActionsProvider,
+                        ScreenshotSmartActionType.QUICK_SHARE_ACTION);
         if (!quickShareActions.isEmpty()) {
             mQuickShareData.quickShareAction = quickShareActions.get(0);
             mParams.mQuickShareActionsReadyListener.onActionsReady(mQuickShareData);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index 5716a1d72..6d87922 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -280,6 +280,7 @@
     private final TimeoutHandler mScreenshotHandler;
     private final ActionIntentExecutor mActionExecutor;
     private final UserManager mUserManager;
+    private final WorkProfileMessageController mWorkProfileMessageController;
 
     private final OnBackInvokedCallback mOnBackInvokedCallback = () -> {
         if (DEBUG_INPUT) {
@@ -326,7 +327,8 @@
             BroadcastSender broadcastSender,
             ScreenshotNotificationSmartActionsProvider screenshotNotificationSmartActionsProvider,
             ActionIntentExecutor actionExecutor,
-            UserManager userManager
+            UserManager userManager,
+            WorkProfileMessageController workProfileMessageController
     ) {
         mScreenshotSmartActions = screenshotSmartActions;
         mNotificationsController = screenshotNotificationsController;
@@ -358,6 +360,7 @@
         mFlags = flags;
         mActionExecutor = actionExecutor;
         mUserManager = userManager;
+        mWorkProfileMessageController = workProfileMessageController;
 
         mAccessibilityManager = AccessibilityManager.getInstance(mContext);
 
@@ -413,10 +416,11 @@
         }
 
         boolean showFlash = false;
-        if (!aspectRatiosMatch(screenshot, visibleInsets, screenshotScreenBounds)) {
+        if (screenshotScreenBounds == null
+                || !aspectRatiosMatch(screenshot, visibleInsets, screenshotScreenBounds)) {
             showFlash = true;
             visibleInsets = Insets.NONE;
-            screenshotScreenBounds.set(0, 0, screenshot.getWidth(), screenshot.getHeight());
+            screenshotScreenBounds = new Rect(0, 0, screenshot.getWidth(), screenshot.getHeight());
         }
         mCurrentRequestCallback = requestCallback;
         saveScreenshot(screenshot, finisher, screenshotScreenBounds, visibleInsets, topComponent,
@@ -550,6 +554,10 @@
             Log.d(TAG, "adding OnComputeInternalInsetsListener");
         }
         mScreenshotView.getViewTreeObserver().addOnComputeInternalInsetsListener(mScreenshotView);
+        if (DEBUG_WINDOW) {
+            Log.d(TAG, "setContentView: " + mScreenshotView);
+        }
+        setContentView(mScreenshotView);
     }
 
     /**
@@ -631,6 +639,7 @@
 
         // The window is focusable by default
         setWindowFocusable(true);
+        mScreenshotView.requestFocus();
 
         // Wait until this window is attached to request because it is
         // the reference used to locate the target window (below).
@@ -683,16 +692,12 @@
                         return true;
                     }
                 });
-
         if (mFlags.isEnabled(SCREENSHOT_WORK_PROFILE_POLICY)) {
-            mScreenshotView.badgeScreenshot(
-                    mContext.getPackageManager().getUserBadgeForDensity(owner, 0));
+            mScreenshotView.badgeScreenshot(mContext.getPackageManager().getUserBadgedIcon(
+                    mContext.getDrawable(R.drawable.overlay_badge_background), owner));
         }
         mScreenshotView.setScreenshot(mScreenBitmap, screenInsets);
-        if (DEBUG_WINDOW) {
-            Log.d(TAG, "setContentView: " + mScreenshotView);
-        }
-        setContentView(mScreenshotView);
+
         // ignore system bar insets for the purpose of window layout
         mWindow.getDecorView().setOnApplyWindowInsetsListener(
                 (v, insets) -> WindowInsets.CONSUMED);
@@ -784,9 +789,9 @@
             mLongScreenshotHolder.setLongScreenshot(longScreenshot);
             mLongScreenshotHolder.setTransitionDestinationCallback(
                     (transitionDestination, onTransitionEnd) -> {
-                            mScreenshotView.startLongScreenshotTransition(
-                                    transitionDestination, onTransitionEnd,
-                                    longScreenshot);
+                        mScreenshotView.startLongScreenshotTransition(
+                                transitionDestination, onTransitionEnd,
+                                longScreenshot);
                         // TODO: Do this via ActionIntentExecutor instead.
                         mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
                     }
@@ -1037,10 +1042,8 @@
 
     private void doPostAnimation(ScreenshotController.SavedImageData imageData) {
         mScreenshotView.setChipIntents(imageData);
-        if (mFlags.isEnabled(SCREENSHOT_WORK_PROFILE_POLICY)
-                && mUserManager.isManagedProfile(imageData.owner.getIdentifier())) {
-            // TODO: Read app from configuration
-            mScreenshotView.showWorkProfileMessage("Files");
+        if (mFlags.isEnabled(SCREENSHOT_WORK_PROFILE_POLICY)) {
+            mWorkProfileMessageController.onScreenshotTaken(imageData.owner, mScreenshotView);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
index e8ceb52..200a7dc 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
@@ -33,6 +33,7 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ValueAnimator;
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.Notification;
 import android.app.PendingIntent;
@@ -100,7 +101,8 @@
  * Handles the visual elements and animations for the screenshot flow.
  */
 public class ScreenshotView extends FrameLayout implements
-        ViewTreeObserver.OnComputeInternalInsetsListener {
+        ViewTreeObserver.OnComputeInternalInsetsListener,
+        WorkProfileMessageController.WorkProfileMessageDisplay {
 
     interface ScreenshotViewCallback {
         void onUserInteraction();
@@ -351,13 +353,23 @@
      * been taken and which app can be used to view it.
      *
      * @param appName The name of the app to use to view screenshots
+     * @param appIcon Optional icon for the relevant files app
+     * @param onDismiss Runnable to be run when the user dismisses this message
      */
-    void showWorkProfileMessage(String appName) {
+    @Override
+    public void showWorkProfileMessage(CharSequence appName, @Nullable Drawable appIcon,
+            Runnable onDismiss) {
+        if (appIcon != null) {
+            // Replace the default icon if one is provided.
+            ImageView imageView = mMessageContainer.findViewById(R.id.screenshot_message_icon);
+            imageView.setImageDrawable(appIcon);
+        }
         mMessageContent.setText(
                 mContext.getString(R.string.screenshot_work_profile_notification, appName));
         mMessageContainer.setVisibility(VISIBLE);
         mMessageContainer.findViewById(R.id.message_dismiss_button).setOnClickListener((v) -> {
             mMessageContainer.setVisibility(View.GONE);
+            onDismiss.run();
         });
     }
 
@@ -1078,7 +1090,7 @@
         mScreenshotBadge.setVisibility(View.GONE);
         mScreenshotBadge.setImageDrawable(null);
         mPendingSharedTransition = false;
-        mActionsContainerBackground.setVisibility(View.GONE);
+        mActionsContainerBackground.setVisibility(View.INVISIBLE);
         mActionsContainer.setVisibility(View.GONE);
         mDismissButton.setVisibility(View.GONE);
         mScrollingScrim.setVisibility(View.GONE);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
index 2176825..7b271a8 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
@@ -21,7 +21,6 @@
 
 import static com.android.internal.util.ScreenshotHelper.SCREENSHOT_MSG_PROCESS_COMPLETE;
 import static com.android.internal.util.ScreenshotHelper.SCREENSHOT_MSG_URI;
-import static com.android.systemui.flags.Flags.SCREENSHOT_REQUEST_PROCESSOR;
 import static com.android.systemui.flags.Flags.SCREENSHOT_WORK_PROFILE_POLICY;
 import static com.android.systemui.screenshot.LogConfig.DEBUG_CALLBACK;
 import static com.android.systemui.screenshot.LogConfig.DEBUG_DISMISS;
@@ -55,7 +54,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.UiEventLogger;
-import com.android.internal.util.ScreenshotHelper;
+import com.android.internal.util.ScreenshotRequest;
 import com.android.systemui.R;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.flags.FeatureFlags;
@@ -122,7 +121,6 @@
         mContext = context;
         mBgExecutor = bgExecutor;
         mFeatureFlags = featureFlags;
-        mFeatureFlags.addListener(SCREENSHOT_REQUEST_PROCESSOR, FlagEvent::requestNoRestart);
         mFeatureFlags.addListener(SCREENSHOT_WORK_PROFILE_POLICY, FlagEvent::requestNoRestart);
         mProcessor = processor;
     }
@@ -188,8 +186,7 @@
         final Consumer<Uri> onSaved = (uri) -> reportUri(replyTo, uri);
         RequestCallback callback = new RequestCallbackImpl(replyTo);
 
-        ScreenshotHelper.ScreenshotRequest request =
-                (ScreenshotHelper.ScreenshotRequest) msg.obj;
+        ScreenshotRequest request = (ScreenshotRequest) msg.obj;
 
         handleRequest(request, onSaved, callback);
         return true;
@@ -197,7 +194,7 @@
 
     @MainThread
     @VisibleForTesting
-    void handleRequest(ScreenshotHelper.ScreenshotRequest request, Consumer<Uri> onSaved,
+    void handleRequest(ScreenshotRequest request, Consumer<Uri> onSaved,
             RequestCallback callback) {
         // If the storage for this user is locked, we have no place to store
         // the screenshot, so skip taking it instead of showing a misleading
@@ -224,17 +221,11 @@
             return;
         }
 
-        if (mFeatureFlags.isEnabled(SCREENSHOT_REQUEST_PROCESSOR)) {
-            Log.d(TAG, "handleMessage: Using request processor");
-            mProcessor.processAsync(request,
-                    (r) -> dispatchToController(r, onSaved, callback));
-            return;
-        }
-
-        dispatchToController(request, onSaved, callback);
+        mProcessor.processAsync(request,
+                (r) -> dispatchToController(r, onSaved, callback));
     }
 
-    private void dispatchToController(ScreenshotHelper.ScreenshotRequest request,
+    private void dispatchToController(ScreenshotRequest request,
             Consumer<Uri> uriConsumer, RequestCallback callback) {
 
         ComponentName topComponent = request.getTopComponent();
@@ -252,8 +243,7 @@
                 if (DEBUG_SERVICE) {
                     Log.d(TAG, "handleMessage: TAKE_SCREENSHOT_PROVIDED_IMAGE");
                 }
-                Bitmap screenshot = ScreenshotHelper.HardwareBitmapBundler.bundleToHardwareBitmap(
-                        request.getBitmapBundle());
+                Bitmap screenshot = request.getBitmap();
                 Rect screenBounds = request.getBoundsInScreen();
                 Insets insets = request.getInsets();
                 int taskId = request.getTaskId();
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt
new file mode 100644
index 0000000..5d7e56f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt
@@ -0,0 +1,106 @@
+/*
+ * 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.screenshot
+
+import android.content.ComponentName
+import android.content.Context
+import android.content.pm.PackageManager
+import android.graphics.drawable.Drawable
+import android.os.UserHandle
+import android.os.UserManager
+import android.util.Log
+import com.android.systemui.R
+import javax.inject.Inject
+
+/**
+ * Handles all the non-UI portions of the work profile first run:
+ * - Track whether the user has already dismissed it.
+ * - Load the proper icon and app name.
+ */
+class WorkProfileMessageController
+@Inject
+constructor(
+    private val context: Context,
+    private val userManager: UserManager,
+    private val packageManager: PackageManager,
+) {
+
+    /**
+     * Determine if a message should be shown to the user, send message details to messageDisplay if
+     * appropriate.
+     */
+    fun onScreenshotTaken(userHandle: UserHandle, messageDisplay: WorkProfileMessageDisplay) {
+        if (userManager.isManagedProfile(userHandle.identifier) && !messageAlreadyDismissed()) {
+            var badgedIcon: Drawable? = null
+            var label: CharSequence? = null
+            val fileManager = fileManagerComponentName()
+            try {
+                val info =
+                    packageManager.getActivityInfo(
+                        fileManager,
+                        PackageManager.ComponentInfoFlags.of(0)
+                    )
+                val icon = packageManager.getActivityIcon(fileManager)
+                badgedIcon = packageManager.getUserBadgedIcon(icon, userHandle)
+                label = info.loadLabel(packageManager)
+            } catch (e: PackageManager.NameNotFoundException) {
+                Log.w(TAG, "Component $fileManager not found")
+            }
+
+            // If label wasn't loaded, use a default
+            val badgedLabel =
+                packageManager.getUserBadgedLabel(label ?: defaultFileAppName(), userHandle)
+
+            messageDisplay.showWorkProfileMessage(badgedLabel, badgedIcon) { onMessageDismissed() }
+        }
+    }
+
+    private fun messageAlreadyDismissed(): Boolean {
+        return sharedPreference().getBoolean(PREFERENCE_KEY, false)
+    }
+
+    private fun onMessageDismissed() {
+        val editor = sharedPreference().edit()
+        editor.putBoolean(PREFERENCE_KEY, true)
+        editor.apply()
+    }
+
+    private fun sharedPreference() =
+        context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)
+
+    private fun fileManagerComponentName() =
+        ComponentName.unflattenFromString(
+            context.getString(R.string.config_sceenshotWorkProfileFilesApp)
+        )
+
+    private fun defaultFileAppName() = context.getString(R.string.screenshot_default_files_app_name)
+
+    /** UI that can show work profile messages (ScreenshotView in practice) */
+    interface WorkProfileMessageDisplay {
+        /**
+         * Show the given message and icon, calling onDismiss if the user explicitly dismisses the
+         * message.
+         */
+        fun showWorkProfileMessage(text: CharSequence, icon: Drawable?, onDismiss: Runnable)
+    }
+
+    companion object {
+        const val TAG = "WorkProfileMessageCtrl"
+        const val SHARED_PREFERENCES_NAME = "com.android.systemui.screenshot"
+        const val PREFERENCE_KEY = "work_profile_first_run"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
index 28da38b..61390c5 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
@@ -112,7 +112,7 @@
             // These get called when a managed profile goes in or out of quiet mode.
             addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE)
             addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)
-
+            addAction(Intent.ACTION_MANAGED_PROFILE_ADDED)
             addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED)
             addAction(Intent.ACTION_MANAGED_PROFILE_UNLOCKED)
         }
@@ -129,6 +129,7 @@
             Intent.ACTION_USER_INFO_CHANGED,
             Intent.ACTION_MANAGED_PROFILE_AVAILABLE,
             Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE,
+            Intent.ACTION_MANAGED_PROFILE_ADDED,
             Intent.ACTION_MANAGED_PROFILE_REMOVED,
             Intent.ACTION_MANAGED_PROFILE_UNLOCKED -> {
                 handleProfilesChanged()
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java
index 5880003..2f6081b 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java
@@ -218,7 +218,7 @@
             automatic = Settings.System.getIntForUser(mContext.getContentResolver(),
                     Settings.System.SCREEN_BRIGHTNESS_MODE,
                     Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL,
-                    UserHandle.USER_CURRENT);
+                    mUserTracker.getUserId());
             mAutomatic = automatic != Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt
index 5011227..b3d31f2 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt
@@ -69,7 +69,8 @@
         }
         return ConstraintsChanges(
             qqsConstraintsChanges = change,
-            qsConstraintsChanges = change
+            qsConstraintsChanges = change,
+            largeScreenConstraintsChanges = change,
         )
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
index 7fc0a5f..8867637 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
@@ -113,7 +113,7 @@
             QQS_HEADER_CONSTRAINT -> "QQS Header"
             QS_HEADER_CONSTRAINT -> "QS Header"
             LARGE_SCREEN_HEADER_CONSTRAINT -> "Large Screen Header"
-            else -> "Unknown state"
+            else -> "Unknown state $this"
         }
     }
 
@@ -175,9 +175,10 @@
      */
     var shadeExpandedFraction = -1f
         set(value) {
-            if (visible && field != value) {
+            if (field != value) {
                 header.alpha = ShadeInterpolation.getContentAlpha(value)
                 field = value
+                updateVisibility()
             }
         }
 
@@ -295,6 +296,9 @@
 
     override fun onViewAttached() {
         privacyIconsController.chipVisibilityListener = chipVisibilityListener
+        updateVisibility()
+        updateTransition()
+
         if (header is MotionLayout) {
             header.setOnApplyWindowInsetsListener(insetListener)
             clock.addOnLayoutChangeListener { v, _, _, _, _, _, _, _, _ ->
@@ -307,9 +311,6 @@
         dumpManager.registerDumpable(this)
         configurationController.addCallback(configurationControllerListener)
         demoModeController.addCallback(demoModeReceiver)
-
-        updateVisibility()
-        updateTransition()
     }
 
     override fun onViewDetached() {
@@ -331,6 +332,9 @@
                 .setDuration(duration)
                 .alpha(if (show) 0f else 1f)
                 .setInterpolator(if (show) Interpolators.ALPHA_OUT else Interpolators.ALPHA_IN)
+                .setUpdateListener {
+                    updateVisibility()
+                }
                 .start()
     }
 
@@ -414,7 +418,7 @@
     private fun updateVisibility() {
         val visibility = if (!largeScreenActive && !combinedHeaders || qsDisabled) {
             View.GONE
-        } else if (qsVisible) {
+        } else if (qsVisible && header.alpha > 0f) {
             View.VISIBLE
         } else {
             View.INVISIBLE
@@ -432,15 +436,14 @@
         header as MotionLayout
         if (largeScreenActive) {
             logInstantEvent("Large screen constraints set")
-            header.setTransition(HEADER_TRANSITION_ID)
-            header.transitionToStart()
+            header.setTransition(LARGE_SCREEN_HEADER_TRANSITION_ID)
         } else {
             logInstantEvent("Small screen constraints set")
             header.setTransition(HEADER_TRANSITION_ID)
-            header.transitionToStart()
-            updatePosition()
-            updateScrollY()
         }
+        header.jumpToState(header.startState)
+        updatePosition()
+        updateScrollY()
     }
 
     private fun updatePosition() {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 8f512d0..392a851 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -138,12 +138,16 @@
 import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
 import com.android.systemui.fragments.FragmentService;
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
+import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
 import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor;
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
 import com.android.systemui.keyguard.shared.model.TransitionState;
 import com.android.systemui.keyguard.shared.model.TransitionStep;
 import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingTransitionViewModel;
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenToOccludedTransitionViewModel;
 import com.android.systemui.keyguard.ui.viewmodel.OccludedToLockscreenTransitionViewModel;
 import com.android.systemui.media.controls.pipeline.MediaDataManager;
 import com.android.systemui.media.controls.ui.KeyguardMediaController;
@@ -360,6 +364,7 @@
     private final FragmentListener mQsFragmentListener = new QsFragmentListener();
     private final AccessibilityDelegate mAccessibilityDelegate = new ShadeAccessibilityDelegate();
     private final NotificationGutsManager mGutsManager;
+    private final AlternateBouncerInteractor mAlternateBouncerInteractor;
 
     private long mDownTime;
     private boolean mTouchSlopExceededBeforeDown;
@@ -445,6 +450,7 @@
     private float mDownY;
     private int mDisplayTopInset = 0; // in pixels
     private int mDisplayRightInset = 0; // in pixels
+    private int mDisplayLeftInset = 0; // in pixels
     private int mLargeScreenShadeHeaderHeight;
     private int mSplitShadeNotificationsScrimMarginBottom;
 
@@ -687,12 +693,18 @@
     private boolean mExpandLatencyTracking;
     private DreamingToLockscreenTransitionViewModel mDreamingToLockscreenTransitionViewModel;
     private OccludedToLockscreenTransitionViewModel mOccludedToLockscreenTransitionViewModel;
+    private LockscreenToDreamingTransitionViewModel mLockscreenToDreamingTransitionViewModel;
+    private GoneToDreamingTransitionViewModel mGoneToDreamingTransitionViewModel;
+    private LockscreenToOccludedTransitionViewModel mLockscreenToOccludedTransitionViewModel;
 
     private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
     private CoroutineDispatcher mMainDispatcher;
-    private boolean mIsToLockscreenTransitionRunning = false;
+    private boolean mIsOcclusionTransitionRunning = false;
     private int mDreamingToLockscreenTransitionTranslationY;
     private int mOccludedToLockscreenTransitionTranslationY;
+    private int mLockscreenToDreamingTransitionTranslationY;
+    private int mGoneToDreamingTransitionTranslationY;
+    private int mLockscreenToOccludedTransitionTranslationY;
     private boolean mUnocclusionTransitionFlagEnabled = false;
 
     private final Runnable mFlingCollapseRunnable = () -> fling(0, false /* expand */,
@@ -704,20 +716,38 @@
         updatePanelExpansionAndVisibility();
     };
     private final Runnable mMaybeHideExpandedRunnable = () -> {
-        if (getExpansionFraction() == 0.0f) {
+        if (getExpandedFraction() == 0.0f) {
             postToView(mHideExpandedRunnable);
         }
     };
 
     private final Consumer<TransitionStep> mDreamingToLockscreenTransition =
             (TransitionStep step) -> {
-                mIsToLockscreenTransitionRunning =
+                mIsOcclusionTransitionRunning =
                     step.getTransitionState() == TransitionState.RUNNING;
             };
 
     private final Consumer<TransitionStep> mOccludedToLockscreenTransition =
             (TransitionStep step) -> {
-                mIsToLockscreenTransitionRunning =
+                mIsOcclusionTransitionRunning =
+                    step.getTransitionState() == TransitionState.RUNNING;
+            };
+
+    private final Consumer<TransitionStep> mLockscreenToDreamingTransition =
+            (TransitionStep step) -> {
+                mIsOcclusionTransitionRunning =
+                    step.getTransitionState() == TransitionState.RUNNING;
+            };
+
+    private final Consumer<TransitionStep> mGoneToDreamingTransition =
+            (TransitionStep step) -> {
+                mIsOcclusionTransitionRunning =
+                    step.getTransitionState() == TransitionState.RUNNING;
+            };
+
+    private final Consumer<TransitionStep> mLockscreenToOccludedTransition =
+            (TransitionStep step) -> {
+                mIsOcclusionTransitionRunning =
                     step.getTransitionState() == TransitionState.RUNNING;
             };
 
@@ -789,8 +819,12 @@
             SystemClock systemClock,
             KeyguardBottomAreaViewModel keyguardBottomAreaViewModel,
             KeyguardBottomAreaInteractor keyguardBottomAreaInteractor,
+            AlternateBouncerInteractor alternateBouncerInteractor,
             DreamingToLockscreenTransitionViewModel dreamingToLockscreenTransitionViewModel,
             OccludedToLockscreenTransitionViewModel occludedToLockscreenTransitionViewModel,
+            LockscreenToDreamingTransitionViewModel lockscreenToDreamingTransitionViewModel,
+            GoneToDreamingTransitionViewModel goneToDreamingTransitionViewModel,
+            LockscreenToOccludedTransitionViewModel lockscreenToOccludedTransitionViewModel,
             @Main CoroutineDispatcher mainDispatcher,
             KeyguardTransitionInteractor keyguardTransitionInteractor,
             DumpManager dumpManager) {
@@ -810,6 +844,9 @@
         mGutsManager = gutsManager;
         mDreamingToLockscreenTransitionViewModel = dreamingToLockscreenTransitionViewModel;
         mOccludedToLockscreenTransitionViewModel = occludedToLockscreenTransitionViewModel;
+        mLockscreenToDreamingTransitionViewModel = lockscreenToDreamingTransitionViewModel;
+        mGoneToDreamingTransitionViewModel = goneToDreamingTransitionViewModel;
+        mLockscreenToOccludedTransitionViewModel = lockscreenToOccludedTransitionViewModel;
         mKeyguardTransitionInteractor = keyguardTransitionInteractor;
         mView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
             @Override
@@ -980,6 +1017,7 @@
                         unlockAnimationStarted(playingCannedAnimation, isWakeAndUnlock, startDelay);
                     }
                 });
+        mAlternateBouncerInteractor = alternateBouncerInteractor;
         dumpManager.registerDumpable(this);
     }
 
@@ -1117,22 +1155,55 @@
             collectFlow(mView, mKeyguardTransitionInteractor.getDreamingToLockscreenTransition(),
                     mDreamingToLockscreenTransition, mMainDispatcher);
             collectFlow(mView, mDreamingToLockscreenTransitionViewModel.getLockscreenAlpha(),
-                    toLockscreenTransitionAlpha(mNotificationStackScrollLayoutController),
+                    setTransitionAlpha(mNotificationStackScrollLayoutController),
                     mMainDispatcher);
             collectFlow(mView, mDreamingToLockscreenTransitionViewModel.lockscreenTranslationY(
                     mDreamingToLockscreenTransitionTranslationY),
-                    toLockscreenTransitionY(mNotificationStackScrollLayoutController),
+                    setTransitionY(mNotificationStackScrollLayoutController),
                     mMainDispatcher);
 
             // Occluded->Lockscreen
             collectFlow(mView, mKeyguardTransitionInteractor.getOccludedToLockscreenTransition(),
                     mOccludedToLockscreenTransition, mMainDispatcher);
             collectFlow(mView, mOccludedToLockscreenTransitionViewModel.getLockscreenAlpha(),
-                    toLockscreenTransitionAlpha(mNotificationStackScrollLayoutController),
+                    setTransitionAlpha(mNotificationStackScrollLayoutController),
                     mMainDispatcher);
             collectFlow(mView, mOccludedToLockscreenTransitionViewModel.lockscreenTranslationY(
                     mOccludedToLockscreenTransitionTranslationY),
-                    toLockscreenTransitionY(mNotificationStackScrollLayoutController),
+                    setTransitionY(mNotificationStackScrollLayoutController),
+                    mMainDispatcher);
+
+            // Lockscreen->Dreaming
+            collectFlow(mView, mKeyguardTransitionInteractor.getLockscreenToDreamingTransition(),
+                    mLockscreenToDreamingTransition, mMainDispatcher);
+            collectFlow(mView, mLockscreenToDreamingTransitionViewModel.getLockscreenAlpha(),
+                    setTransitionAlpha(mNotificationStackScrollLayoutController),
+                    mMainDispatcher);
+            collectFlow(mView, mLockscreenToDreamingTransitionViewModel.lockscreenTranslationY(
+                    mLockscreenToDreamingTransitionTranslationY),
+                    setTransitionY(mNotificationStackScrollLayoutController),
+                    mMainDispatcher);
+
+            // Gone->Dreaming
+            collectFlow(mView, mKeyguardTransitionInteractor.getGoneToDreamingTransition(),
+                    mGoneToDreamingTransition, mMainDispatcher);
+            collectFlow(mView, mGoneToDreamingTransitionViewModel.getLockscreenAlpha(),
+                    setTransitionAlpha(mNotificationStackScrollLayoutController),
+                    mMainDispatcher);
+            collectFlow(mView, mGoneToDreamingTransitionViewModel.lockscreenTranslationY(
+                    mGoneToDreamingTransitionTranslationY),
+                    setTransitionY(mNotificationStackScrollLayoutController),
+                    mMainDispatcher);
+
+            // Lockscreen->Occluded
+            collectFlow(mView, mKeyguardTransitionInteractor.getLockscreenToOccludedTransition(),
+                    mLockscreenToOccludedTransition, mMainDispatcher);
+            collectFlow(mView, mLockscreenToOccludedTransitionViewModel.getLockscreenAlpha(),
+                    setTransitionAlpha(mNotificationStackScrollLayoutController),
+                    mMainDispatcher);
+            collectFlow(mView, mLockscreenToOccludedTransitionViewModel.lockscreenTranslationY(
+                    mLockscreenToOccludedTransitionTranslationY),
+                    setTransitionY(mNotificationStackScrollLayoutController),
                     mMainDispatcher);
         }
     }
@@ -1173,6 +1244,12 @@
                 R.dimen.dreaming_to_lockscreen_transition_lockscreen_translation_y);
         mOccludedToLockscreenTransitionTranslationY = mResources.getDimensionPixelSize(
                 R.dimen.occluded_to_lockscreen_transition_lockscreen_translation_y);
+        mLockscreenToDreamingTransitionTranslationY = mResources.getDimensionPixelSize(
+                R.dimen.lockscreen_to_dreaming_transition_lockscreen_translation_y);
+        mGoneToDreamingTransitionTranslationY = mResources.getDimensionPixelSize(
+                R.dimen.gone_to_dreaming_transition_lockscreen_translation_y);
+        mLockscreenToOccludedTransitionTranslationY = mResources.getDimensionPixelSize(
+                R.dimen.lockscreen_to_occluded_transition_lockscreen_translation_y);
     }
 
     private void updateViewControllers(KeyguardStatusView keyguardStatusView,
@@ -1836,7 +1913,7 @@
     }
 
     private void updateClock() {
-        if (mIsToLockscreenTransitionRunning) {
+        if (mIsOcclusionTransitionRunning) {
             return;
         }
         float alpha = mClockPositionResult.clockAlpha * mKeyguardOnlyContentAlpha;
@@ -2020,7 +2097,17 @@
         }
     }
 
-    public void expandWithoutQs() {
+    /**
+     * Expand shade so that notifications are visible.
+     * Non-split shade: just expanding shade or collapsing QS when they're expanded.
+     * Split shade: only expanding shade, notifications are always visible
+     *
+     * Called when `adb shell cmd statusbar expand-notifications` is executed.
+     */
+    public void expandShadeToNotifications() {
+        if (mSplitShadeEnabled && (isShadeFullyOpen() || isExpanding())) {
+            return;
+        }
         if (isQsExpanded()) {
             flingSettings(0 /* velocity */, FLING_COLLAPSE);
         } else {
@@ -2288,7 +2375,7 @@
             // When false, down but not synthesized motion event.
             mLastEventSynthesizedDown = mExpectingSynthesizedDown;
             mLastDownEvents.insert(
-                    mSystemClock.currentTimeMillis(),
+                    event.getEventTime(),
                     mDownX,
                     mDownY,
                     mQsTouchAboveFalsingThreshold,
@@ -2421,7 +2508,7 @@
             mInitialTouchY = event.getY();
             mInitialTouchX = event.getX();
         }
-        if (!isFullyCollapsed()) {
+        if (!isFullyCollapsed() && !isShadeOrQsHeightAnimationRunning()) {
             handleQsDown(event);
         }
         // defer touches on QQS to shade while shade is collapsing. Added margin for error
@@ -2727,7 +2814,7 @@
         } else if (statusBarState == KEYGUARD
                 || statusBarState == StatusBarState.SHADE_LOCKED) {
             mKeyguardBottomArea.setVisibility(View.VISIBLE);
-            if (!mIsToLockscreenTransitionRunning) {
+            if (!mIsOcclusionTransitionRunning) {
                 mKeyguardBottomArea.setAlpha(1f);
             }
         } else {
@@ -2935,7 +3022,7 @@
             // left bounds can ignore insets, it should always reach the edge of the screen
             return 0;
         } else {
-            return mNotificationStackScrollLayoutController.getLeft();
+            return mNotificationStackScrollLayoutController.getLeft() + mDisplayLeftInset;
         }
     }
 
@@ -2943,7 +3030,7 @@
         if (mIsFullWidth) {
             return mView.getRight() + mDisplayRightInset;
         } else {
-            return mNotificationStackScrollLayoutController.getRight();
+            return mNotificationStackScrollLayoutController.getRight() + mDisplayLeftInset;
         }
     }
 
@@ -3067,8 +3154,8 @@
 
         // Convert global clipping coordinates to local ones,
         // relative to NotificationStackScrollLayout
-        int nsslLeft = left - mNotificationStackScrollLayoutController.getLeft();
-        int nsslRight = right - mNotificationStackScrollLayoutController.getLeft();
+        int nsslLeft = calculateNsslLeft(left);
+        int nsslRight = calculateNsslRight(right);
         int nsslTop = getNotificationsClippingTopBounds(top);
         int nsslBottom = bottom - mNotificationStackScrollLayoutController.getTop();
         int bottomRadius = mSplitShadeEnabled ? radius : 0;
@@ -3077,6 +3164,22 @@
                 nsslLeft, nsslTop, nsslRight, nsslBottom, topRadius, bottomRadius);
     }
 
+    private int calculateNsslLeft(int nsslLeftAbsolute) {
+        int left = nsslLeftAbsolute - mNotificationStackScrollLayoutController.getLeft();
+        if (mIsFullWidth) {
+            return left;
+        }
+        return left - mDisplayLeftInset;
+    }
+
+    private int calculateNsslRight(int nsslRightAbsolute) {
+        int right = nsslRightAbsolute - mNotificationStackScrollLayoutController.getLeft();
+        if (mIsFullWidth) {
+            return right;
+        }
+        return right - mDisplayLeftInset;
+    }
+
     private int getNotificationsClippingTopBounds(int qsTop) {
         if (mSplitShadeEnabled && mExpandingFromHeadsUp) {
             // in split shade nssl has extra top margin so clipping at top 0 is not enough, we need
@@ -3596,7 +3699,7 @@
     }
 
     private void updateNotificationTranslucency() {
-        if (mIsToLockscreenTransitionRunning) {
+        if (mIsOcclusionTransitionRunning) {
             return;
         }
         float alpha = 1f;
@@ -3654,7 +3757,7 @@
     }
 
     private void updateKeyguardBottomAreaAlpha() {
-        if (mIsToLockscreenTransitionRunning) {
+        if (mIsOcclusionTransitionRunning) {
             return;
         }
         // There are two possible panel expansion behaviors:
@@ -4093,9 +4196,7 @@
     }
 
     private void updateStatusBarIcons() {
-        boolean showIconsWhenExpanded =
-                (isPanelVisibleBecauseOfHeadsUp() || mIsFullWidth)
-                        && getExpandedHeight() < getOpeningHeight();
+        boolean showIconsWhenExpanded = getExpandedHeight() < getOpeningHeight();
         if (showIconsWhenExpanded && isOnKeyguard()) {
             showIconsWhenExpanded = false;
         }
@@ -4162,7 +4263,7 @@
                 && mHeadsUpAppearanceController.shouldBeVisible()) {
             return false;
         }
-        return !mIsFullWidth || !mShowIconsWhenExpanded;
+        return !mShowIconsWhenExpanded;
     }
 
     private void onQsPanelScrollChanged(int scrollY) {
@@ -4474,6 +4575,7 @@
         ipw.print("mDownY="); ipw.println(mDownY);
         ipw.print("mDisplayTopInset="); ipw.println(mDisplayTopInset);
         ipw.print("mDisplayRightInset="); ipw.println(mDisplayRightInset);
+        ipw.print("mDisplayLeftInset="); ipw.println(mDisplayLeftInset);
         ipw.print("mLargeScreenShadeHeaderHeight="); ipw.println(mLargeScreenShadeHeaderHeight);
         ipw.print("mSplitShadeNotificationsScrimMarginBottom=");
         ipw.println(mSplitShadeNotificationsScrimMarginBottom);
@@ -4902,7 +5004,7 @@
                 mUpdateFlingVelocity = vel;
             }
         } else if (!mCentralSurfaces.isBouncerShowing()
-                && !mStatusBarKeyguardViewManager.isShowingAlternateBouncer()
+                && !mAlternateBouncerInteractor.isVisibleState()
                 && !mKeyguardStateController.isKeyguardGoingAway()) {
             onEmptySpaceClick();
             onTrackingStopped(true);
@@ -5211,6 +5313,11 @@
         }
     }
 
+    /** Returns whether a shade or QS expansion animation is running */
+    private boolean isShadeOrQsHeightAnimationRunning() {
+        return mHeightAnimator != null && !mHintAnimationRunning && !mIsSpringBackAnimation;
+    }
+
     /**
      * Phase 2: Bounce down.
      */
@@ -5370,10 +5477,6 @@
                 InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
     }
 
-    private float getExpansionFraction() {
-        return mExpandedFraction;
-    }
-
     private ShadeExpansionStateManager getShadeExpansionStateManager() {
         return mShadeExpansionStateManager;
     }
@@ -5443,7 +5546,7 @@
 
         @Override
         public void flingTopOverscroll(float velocity, boolean open) {
-            // in split shade mode we want to expand/collapse QS only when touch happens within QS
+            // in split shade touches affect QS only when touch happens within QS
             if (isSplitShadeAndTouchXOutsideQs(mInitialTouchX)) {
                 return;
             }
@@ -5850,6 +5953,7 @@
         Insets combinedInsets = insets.getInsetsIgnoringVisibility(insetTypes);
         mDisplayTopInset = combinedInsets.top;
         mDisplayRightInset = combinedInsets.right;
+        mDisplayLeftInset = combinedInsets.left;
 
         mNavigationBarBottomHeight = insets.getStableInsetBottom();
         updateMaxHeadsUpTranslation();
@@ -5886,7 +5990,7 @@
         mCurrentPanelState = state;
     }
 
-    private Consumer<Float> toLockscreenTransitionAlpha(
+    private Consumer<Float> setTransitionAlpha(
             NotificationStackScrollLayoutController stackScroller) {
         return (Float alpha) -> {
             mKeyguardStatusViewController.setAlpha(alpha);
@@ -5904,7 +6008,7 @@
         };
     }
 
-    private Consumer<Float> toLockscreenTransitionY(
+    private Consumer<Float> setTransitionY(
                 NotificationStackScrollLayoutController stackScroller) {
         return (Float translationY) -> {
             mKeyguardStatusViewController.setTranslationY(translationY,  /* excludeMedia= */false);
@@ -6228,8 +6332,7 @@
                     mCollapsedAndHeadsUpOnDown =
                             isFullyCollapsed() && mHeadsUpManager.hasPinnedHeadsUp();
                     addMovement(event);
-                    boolean regularHeightAnimationRunning = mHeightAnimator != null
-                            && !mHintAnimationRunning && !mIsSpringBackAnimation;
+                    boolean regularHeightAnimationRunning = isShadeOrQsHeightAnimationRunning();
                     if (!mGestureWaitForTouchSlop || regularHeightAnimationRunning) {
                         mTouchSlopExceeded = regularHeightAnimationRunning
                                 || mTouchSlopExceededBeforeDown;
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
index 8698c04..ab2e692 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
@@ -19,6 +19,7 @@
 import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_OPTIMIZE_MEASURE;
 
 import static com.android.systemui.DejankUtils.whitelistIpcs;
 import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT;
@@ -52,13 +53,13 @@
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.dump.DumpsysTableLogger;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
@@ -71,12 +72,9 @@
 import java.io.PrintWriter;
 import java.lang.ref.Reference;
 import java.lang.ref.WeakReference;
-import java.lang.reflect.Field;
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
-import java.util.Set;
 import java.util.function.Consumer;
 import java.util.stream.Collectors;
 
@@ -90,12 +88,14 @@
         Dumpable, ConfigurationListener {
 
     private static final String TAG = "NotificationShadeWindowController";
+    private static final int MAX_STATE_CHANGES_BUFFER_SIZE = 100;
 
     private final Context mContext;
     private final WindowManager mWindowManager;
     private final IActivityManager mActivityManager;
     private final DozeParameters mDozeParameters;
     private final KeyguardStateController mKeyguardStateController;
+    private final ShadeWindowLogger mLogger;
     private final LayoutParams mLpChanged;
     private final long mLockScreenDisplayTimeout;
     private final float mKeyguardPreferredRefreshRate; // takes precedence over max
@@ -108,7 +108,7 @@
     private boolean mHasTopUi;
     private boolean mHasTopUiChanged;
     private float mScreenBrightnessDoze;
-    private final State mCurrentState = new State();
+    private final NotificationShadeWindowState mCurrentState = new NotificationShadeWindowState();
     private OtherwisedCollapsedListener mListener;
     private ForcePluginOpenListener mForcePluginOpenListener;
     private Consumer<Integer> mScrimsVisibilityListener;
@@ -125,6 +125,9 @@
     private int mDeferWindowLayoutParams;
     private boolean mLastKeyguardRotationAllowed;
 
+    private final NotificationShadeWindowState.Buffer mStateBuffer =
+            new NotificationShadeWindowState.Buffer(MAX_STATE_CHANGES_BUFFER_SIZE);
+
     @Inject
     public NotificationShadeWindowControllerImpl(Context context, WindowManager windowManager,
             IActivityManager activityManager, DozeParameters dozeParameters,
@@ -137,12 +140,14 @@
             KeyguardStateController keyguardStateController,
             ScreenOffAnimationController screenOffAnimationController,
             AuthController authController,
-            ShadeExpansionStateManager shadeExpansionStateManager) {
+            ShadeExpansionStateManager shadeExpansionStateManager,
+            ShadeWindowLogger logger) {
         mContext = context;
         mWindowManager = windowManager;
         mActivityManager = activityManager;
         mDozeParameters = dozeParameters;
         mKeyguardStateController = keyguardStateController;
+        mLogger = logger;
         mScreenBrightnessDoze = mDozeParameters.getScreenBrightnessDoze();
         mLpChanged = new LayoutParams();
         mKeyguardViewMediator = keyguardViewMediator;
@@ -208,8 +213,8 @@
 
     @VisibleForTesting
     void onShadeExpansionFullyChanged(Boolean isExpanded) {
-        if (mCurrentState.mPanelExpanded != isExpanded) {
-            mCurrentState.mPanelExpanded = isExpanded;
+        if (mCurrentState.panelExpanded != isExpanded) {
+            mCurrentState.panelExpanded = isExpanded;
             apply(mCurrentState);
         }
     }
@@ -249,6 +254,7 @@
         mLp.setTitle("NotificationShade");
         mLp.packageName = mContext.getPackageName();
         mLp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+        mLp.privateFlags |= PRIVATE_FLAG_OPTIMIZE_MEASURE;
 
         // We use BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE here, however, there is special logic in
         // window manager which disables the transient show behavior.
@@ -294,10 +300,10 @@
         mNotificationShadeView.setSystemUiVisibility(vis);
     }
 
-    private void applyKeyguardFlags(State state) {
-        final boolean keyguardOrAod = state.mKeyguardShowing
-                || (state.mDozing && mDozeParameters.getAlwaysOn());
-        if ((keyguardOrAod && !state.mBackdropShowing && !state.mLightRevealScrimOpaque)
+    private void applyKeyguardFlags(NotificationShadeWindowState state) {
+        final boolean keyguardOrAod = state.keyguardShowing
+                || (state.dozing && mDozeParameters.getAlwaysOn());
+        if ((keyguardOrAod && !state.mediaBackdropShowing && !state.lightRevealScrimOpaque)
                 || mKeyguardViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind()) {
             // Show the wallpaper if we're on keyguard/AOD and the wallpaper is not occluded by a
             // solid backdrop. Also, show it if we are currently animating between the
@@ -308,28 +314,31 @@
             mLpChanged.flags &= ~LayoutParams.FLAG_SHOW_WALLPAPER;
         }
 
-        if (state.mDozing) {
+        if (state.dozing) {
             mLpChanged.privateFlags |= LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
         } else {
             mLpChanged.privateFlags &= ~LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
         }
 
         if (mKeyguardPreferredRefreshRate > 0) {
-            boolean onKeyguard = state.mStatusBarState == StatusBarState.KEYGUARD
-                    && !state.mKeyguardFadingAway && !state.mKeyguardGoingAway;
+            boolean onKeyguard = state.statusBarState == StatusBarState.KEYGUARD
+                    && !state.keyguardFadingAway && !state.keyguardGoingAway;
             if (onKeyguard
                     && mAuthController.isUdfpsEnrolled(KeyguardUpdateMonitor.getCurrentUser())) {
+                // both max and min display refresh rate must be set to take effect:
                 mLpChanged.preferredMaxDisplayRefreshRate = mKeyguardPreferredRefreshRate;
+                mLpChanged.preferredMinDisplayRefreshRate = mKeyguardPreferredRefreshRate;
             } else {
                 mLpChanged.preferredMaxDisplayRefreshRate = 0;
+                mLpChanged.preferredMinDisplayRefreshRate = 0;
             }
             Trace.setCounter("display_set_preferred_refresh_rate",
                     (long) mKeyguardPreferredRefreshRate);
         } else if (mKeyguardMaxRefreshRate > 0) {
             boolean bypassOnKeyguard = mKeyguardBypassController.getBypassEnabled()
-                    && state.mStatusBarState == StatusBarState.KEYGUARD
-                    && !state.mKeyguardFadingAway && !state.mKeyguardGoingAway;
-            if (state.mDozing || bypassOnKeyguard) {
+                    && state.statusBarState == StatusBarState.KEYGUARD
+                    && !state.keyguardFadingAway && !state.keyguardGoingAway;
+            if (state.dozing || bypassOnKeyguard) {
                 mLpChanged.preferredMaxDisplayRefreshRate = mKeyguardMaxRefreshRate;
             } else {
                 mLpChanged.preferredMaxDisplayRefreshRate = 0;
@@ -338,7 +347,7 @@
                     (long) mLpChanged.preferredMaxDisplayRefreshRate);
         }
 
-        if (state.mBouncerShowing && !isDebuggable()) {
+        if (state.bouncerShowing && !isDebuggable()) {
             mLpChanged.flags |= LayoutParams.FLAG_SECURE;
         } else {
             mLpChanged.flags &= ~LayoutParams.FLAG_SECURE;
@@ -349,8 +358,8 @@
         return Build.IS_DEBUGGABLE;
     }
 
-    private void adjustScreenOrientation(State state) {
-        if (state.mBouncerShowing || state.isKeyguardShowingAndNotOccluded() || state.mDozing) {
+    private void adjustScreenOrientation(NotificationShadeWindowState state) {
+        if (state.bouncerShowing || state.isKeyguardShowingAndNotOccluded() || state.dozing) {
             if (mKeyguardStateController.isKeyguardScreenRotationAllowed()) {
                 mLpChanged.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_USER;
             } else {
@@ -361,10 +370,10 @@
         }
     }
 
-    private void applyFocusableFlag(State state) {
-        boolean panelFocusable = state.mNotificationShadeFocusable && state.mPanelExpanded;
-        if (state.mBouncerShowing && (state.mKeyguardOccluded || state.mKeyguardNeedsInput)
-                || ENABLE_REMOTE_INPUT && state.mRemoteInputActive
+    private void applyFocusableFlag(NotificationShadeWindowState state) {
+        boolean panelFocusable = state.notificationShadeFocusable && state.panelExpanded;
+        if (state.bouncerShowing && (state.keyguardOccluded || state.keyguardNeedsInput)
+                || ENABLE_REMOTE_INPUT && state.remoteInputActive
                 // Make the panel focusable if we're doing the screen off animation, since the light
                 // reveal scrim is drawing in the panel and should consume touch events so that they
                 // don't go to the app behind.
@@ -374,7 +383,7 @@
         } else if (state.isKeyguardShowingAndNotOccluded() || panelFocusable) {
             mLpChanged.flags &= ~LayoutParams.FLAG_NOT_FOCUSABLE;
             // Make sure to remove FLAG_ALT_FOCUSABLE_IM when keyguard needs input.
-            if (state.mKeyguardNeedsInput && state.isKeyguardShowingAndNotOccluded()) {
+            if (state.keyguardNeedsInput && state.isKeyguardShowingAndNotOccluded()) {
                 mLpChanged.flags &= ~LayoutParams.FLAG_ALT_FOCUSABLE_IM;
             } else {
                 mLpChanged.flags |= LayoutParams.FLAG_ALT_FOCUSABLE_IM;
@@ -385,22 +394,24 @@
         }
     }
 
-    private void applyForceShowNavigationFlag(State state) {
-        if (state.mPanelExpanded || state.mBouncerShowing
-                || ENABLE_REMOTE_INPUT && state.mRemoteInputActive) {
+    private void applyForceShowNavigationFlag(NotificationShadeWindowState state) {
+        if (state.panelExpanded || state.bouncerShowing
+                || ENABLE_REMOTE_INPUT && state.remoteInputActive) {
             mLpChanged.privateFlags |= LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
         } else {
             mLpChanged.privateFlags &= ~LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
         }
     }
 
-    private void applyVisibility(State state) {
+    private void applyVisibility(NotificationShadeWindowState state) {
         boolean visible = isExpanded(state);
-        if (state.mForcePluginOpen) {
+        mLogger.logApplyVisibility(visible);
+        if (state.forcePluginOpen) {
             if (mListener != null) {
                 mListener.setWouldOtherwiseCollapse(visible);
             }
             visible = true;
+            mLogger.d("Visibility forced to be true");
         }
         if (mNotificationShadeView != null) {
             if (visible) {
@@ -411,16 +422,16 @@
         }
     }
 
-    private boolean isExpanded(State state) {
-        return !state.mForceCollapsed && (state.isKeyguardShowingAndNotOccluded()
-                || state.mPanelVisible || state.mKeyguardFadingAway || state.mBouncerShowing
-                || state.mHeadsUpShowing
-                || state.mScrimsVisibility != ScrimController.TRANSPARENT)
-                || state.mBackgroundBlurRadius > 0
-                || state.mLaunchingActivity;
+    private boolean isExpanded(NotificationShadeWindowState state) {
+        return !state.forceWindowCollapsed && (state.isKeyguardShowingAndNotOccluded()
+                || state.panelVisible || state.keyguardFadingAway || state.bouncerShowing
+                || state.headsUpNotificationShowing
+                || state.scrimsVisibility != ScrimController.TRANSPARENT)
+                || state.backgroundBlurRadius > 0
+                || state.launchingActivityFromNotification;
     }
 
-    private void applyFitsSystemWindows(State state) {
+    private void applyFitsSystemWindows(NotificationShadeWindowState state) {
         boolean fitsSystemWindows = !state.isKeyguardShowingAndNotOccluded();
         if (mNotificationShadeView != null
                 && mNotificationShadeView.getFitsSystemWindows() != fitsSystemWindows) {
@@ -429,21 +440,21 @@
         }
     }
 
-    private void applyUserActivityTimeout(State state) {
+    private void applyUserActivityTimeout(NotificationShadeWindowState state) {
         if (state.isKeyguardShowingAndNotOccluded()
-                && state.mStatusBarState == StatusBarState.KEYGUARD
-                && !state.mQsExpanded) {
-            mLpChanged.userActivityTimeout = state.mBouncerShowing
+                && state.statusBarState == StatusBarState.KEYGUARD
+                && !state.qsExpanded) {
+            mLpChanged.userActivityTimeout = state.bouncerShowing
                     ? KeyguardViewMediator.AWAKE_INTERVAL_BOUNCER_MS : mLockScreenDisplayTimeout;
         } else {
             mLpChanged.userActivityTimeout = -1;
         }
     }
 
-    private void applyInputFeatures(State state) {
+    private void applyInputFeatures(NotificationShadeWindowState state) {
         if (state.isKeyguardShowingAndNotOccluded()
-                && state.mStatusBarState == StatusBarState.KEYGUARD
-                && !state.mQsExpanded && !state.mForceUserActivity) {
+                && state.statusBarState == StatusBarState.KEYGUARD
+                && !state.qsExpanded && !state.forceUserActivity) {
             mLpChanged.inputFeatures |=
                     LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;
         } else {
@@ -452,7 +463,7 @@
         }
     }
 
-    private void applyStatusBarColorSpaceAgnosticFlag(State state) {
+    private void applyStatusBarColorSpaceAgnosticFlag(NotificationShadeWindowState state) {
         if (!isExpanded(state)) {
             mLpChanged.privateFlags |= LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC;
         } else {
@@ -463,6 +474,7 @@
 
     private void applyWindowLayoutParams() {
         if (mDeferWindowLayoutParams == 0 && mLp != null && mLp.copyFrom(mLpChanged) != 0) {
+            mLogger.logApplyingWindowLayoutParams(mLp);
             Trace.beginSection("updateViewLayout");
             mWindowManager.updateViewLayout(mNotificationShadeView, mLp);
             Trace.endSection();
@@ -477,7 +489,8 @@
         applyWindowLayoutParams();
     }
 
-    private void apply(State state) {
+    private void apply(NotificationShadeWindowState state) {
+        logState(state);
         applyKeyguardFlags(state);
         applyFocusableFlag(state);
         applyForceShowNavigationFlag(state);
@@ -506,6 +519,38 @@
         notifyStateChangedCallbacks();
     }
 
+    private void logState(NotificationShadeWindowState state) {
+        mStateBuffer.insert(
+                state.keyguardShowing,
+                state.keyguardOccluded,
+                state.keyguardNeedsInput,
+                state.panelVisible,
+                state.panelExpanded,
+                state.notificationShadeFocusable,
+                state.bouncerShowing,
+                state.keyguardFadingAway,
+                state.keyguardGoingAway,
+                state.qsExpanded,
+                state.headsUpNotificationShowing,
+                state.lightRevealScrimOpaque,
+                state.forceWindowCollapsed,
+                state.forceDozeBrightness,
+                state.forceUserActivity,
+                state.launchingActivityFromNotification,
+                state.mediaBackdropShowing,
+                state.wallpaperSupportsAmbientMode,
+                state.windowNotTouchable,
+                state.componentsForcingTopUi,
+                state.forceOpenTokens,
+                state.statusBarState,
+                state.remoteInputActive,
+                state.forcePluginOpen,
+                state.dozing,
+                state.scrimsVisibility,
+                state.backgroundBlurRadius
+        );
+    }
+
     @Override
     public void notifyStateChangedCallbacks() {
         // Copy callbacks to separate ArrayList to avoid concurrent modification
@@ -514,36 +559,36 @@
                 .filter(Objects::nonNull)
                 .collect(Collectors.toList());
         for (StatusBarWindowCallback cb : activeCallbacks) {
-            cb.onStateChanged(mCurrentState.mKeyguardShowing,
-                    mCurrentState.mKeyguardOccluded,
-                    mCurrentState.mBouncerShowing,
-                    mCurrentState.mDozing,
-                    mCurrentState.mPanelExpanded);
+            cb.onStateChanged(mCurrentState.keyguardShowing,
+                    mCurrentState.keyguardOccluded,
+                    mCurrentState.bouncerShowing,
+                    mCurrentState.dozing,
+                    mCurrentState.panelExpanded);
         }
     }
 
-    private void applyModalFlag(State state) {
-        if (state.mHeadsUpShowing) {
+    private void applyModalFlag(NotificationShadeWindowState state) {
+        if (state.headsUpNotificationShowing) {
             mLpChanged.flags |= LayoutParams.FLAG_NOT_TOUCH_MODAL;
         } else {
             mLpChanged.flags &= ~LayoutParams.FLAG_NOT_TOUCH_MODAL;
         }
     }
 
-    private void applyBrightness(State state) {
-        if (state.mForceDozeBrightness) {
+    private void applyBrightness(NotificationShadeWindowState state) {
+        if (state.forceDozeBrightness) {
             mLpChanged.screenBrightness = mScreenBrightnessDoze;
         } else {
             mLpChanged.screenBrightness = LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
         }
     }
 
-    private void applyHasTopUi(State state) {
-        mHasTopUiChanged = !state.mComponentsForcingTopUi.isEmpty() || isExpanded(state);
+    private void applyHasTopUi(NotificationShadeWindowState state) {
+        mHasTopUiChanged = !state.componentsForcingTopUi.isEmpty() || isExpanded(state);
     }
 
-    private void applyNotTouchable(State state) {
-        if (state.mNotTouchable) {
+    private void applyNotTouchable(NotificationShadeWindowState state) {
+        if (state.windowNotTouchable) {
             mLpChanged.flags |= LayoutParams.FLAG_NOT_TOUCHABLE;
         } else {
             mLpChanged.flags &= ~LayoutParams.FLAG_NOT_TOUCHABLE;
@@ -565,86 +610,88 @@
 
     @Override
     public void setKeyguardShowing(boolean showing) {
-        mCurrentState.mKeyguardShowing = showing;
+        mCurrentState.keyguardShowing = showing;
         apply(mCurrentState);
     }
 
     @Override
     public void setKeyguardOccluded(boolean occluded) {
-        mCurrentState.mKeyguardOccluded = occluded;
+        mCurrentState.keyguardOccluded = occluded;
         apply(mCurrentState);
     }
 
     @Override
     public void setKeyguardNeedsInput(boolean needsInput) {
-        mCurrentState.mKeyguardNeedsInput = needsInput;
+        mCurrentState.keyguardNeedsInput = needsInput;
         apply(mCurrentState);
     }
 
     @Override
     public void setPanelVisible(boolean visible) {
-        if (mCurrentState.mPanelVisible == visible
-                && mCurrentState.mNotificationShadeFocusable == visible) {
+        if (mCurrentState.panelVisible == visible
+                && mCurrentState.notificationShadeFocusable == visible) {
             return;
         }
-        mCurrentState.mPanelVisible = visible;
-        mCurrentState.mNotificationShadeFocusable = visible;
+        mLogger.logShadeVisibleAndFocusable(visible);
+        mCurrentState.panelVisible = visible;
+        mCurrentState.notificationShadeFocusable = visible;
         apply(mCurrentState);
     }
 
     @Override
     public void setNotificationShadeFocusable(boolean focusable) {
-        mCurrentState.mNotificationShadeFocusable = focusable;
+        mLogger.logShadeFocusable(focusable);
+        mCurrentState.notificationShadeFocusable = focusable;
         apply(mCurrentState);
     }
 
     @Override
     public void setBouncerShowing(boolean showing) {
-        mCurrentState.mBouncerShowing = showing;
+        mCurrentState.bouncerShowing = showing;
         apply(mCurrentState);
     }
 
     @Override
     public void setBackdropShowing(boolean showing) {
-        mCurrentState.mBackdropShowing = showing;
+        mCurrentState.mediaBackdropShowing = showing;
         apply(mCurrentState);
     }
 
     @Override
     public void setKeyguardFadingAway(boolean keyguardFadingAway) {
-        mCurrentState.mKeyguardFadingAway = keyguardFadingAway;
+        mCurrentState.keyguardFadingAway = keyguardFadingAway;
         apply(mCurrentState);
     }
 
     private void onQsExpansionChanged(Boolean expanded) {
-        mCurrentState.mQsExpanded = expanded;
+        mCurrentState.qsExpanded = expanded;
         apply(mCurrentState);
     }
 
     @Override
     public void setForceUserActivity(boolean forceUserActivity) {
-        mCurrentState.mForceUserActivity = forceUserActivity;
+        mCurrentState.forceUserActivity = forceUserActivity;
         apply(mCurrentState);
     }
 
     @Override
     public void setLaunchingActivity(boolean launching) {
-        mCurrentState.mLaunchingActivity = launching;
+        mCurrentState.launchingActivityFromNotification = launching;
         apply(mCurrentState);
     }
 
     @Override
     public boolean isLaunchingActivity() {
-        return mCurrentState.mLaunchingActivity;
+        return mCurrentState.launchingActivityFromNotification;
     }
 
     @Override
     public void setScrimsVisibility(int scrimsVisibility) {
-        if (scrimsVisibility == mCurrentState.mScrimsVisibility) {
+        if (scrimsVisibility == mCurrentState.scrimsVisibility) {
             return;
         }
         boolean wasExpanded = isExpanded(mCurrentState);
-        mCurrentState.mScrimsVisibility = scrimsVisibility;
+        mCurrentState.scrimsVisibility = scrimsVisibility;
         if (wasExpanded != isExpanded(mCurrentState)) {
             apply(mCurrentState);
         }
@@ -658,31 +705,31 @@
      */
     @Override
     public void setBackgroundBlurRadius(int backgroundBlurRadius) {
-        if (mCurrentState.mBackgroundBlurRadius == backgroundBlurRadius) {
+        if (mCurrentState.backgroundBlurRadius == backgroundBlurRadius) {
             return;
         }
-        mCurrentState.mBackgroundBlurRadius = backgroundBlurRadius;
+        mCurrentState.backgroundBlurRadius = backgroundBlurRadius;
         apply(mCurrentState);
     }
 
     @Override
     public void setHeadsUpShowing(boolean showing) {
-        mCurrentState.mHeadsUpShowing = showing;
+        mCurrentState.headsUpNotificationShowing = showing;
         apply(mCurrentState);
     }
 
     @Override
     public void setLightRevealScrimOpaque(boolean opaque) {
-        if (mCurrentState.mLightRevealScrimOpaque == opaque) {
+        if (mCurrentState.lightRevealScrimOpaque == opaque) {
             return;
         }
-        mCurrentState.mLightRevealScrimOpaque = opaque;
+        mCurrentState.lightRevealScrimOpaque = opaque;
         apply(mCurrentState);
     }
 
     @Override
     public void setWallpaperSupportsAmbientMode(boolean supportsAmbientMode) {
-        mCurrentState.mWallpaperSupportsAmbientMode = supportsAmbientMode;
+        mCurrentState.wallpaperSupportsAmbientMode = supportsAmbientMode;
         apply(mCurrentState);
     }
 
@@ -690,7 +737,7 @@
      * @param state The {@link StatusBarStateController} of the status bar.
      */
     private void setStatusBarState(int state) {
-        mCurrentState.mStatusBarState = state;
+        mCurrentState.statusBarState = state;
         apply(mCurrentState);
     }
 
@@ -701,13 +748,13 @@
      */
     @Override
     public void setForceWindowCollapsed(boolean force) {
-        mCurrentState.mForceCollapsed = force;
+        mCurrentState.forceWindowCollapsed = force;
         apply(mCurrentState);
     }
 
     @Override
     public void onRemoteInputActive(boolean remoteInputActive) {
-        mCurrentState.mRemoteInputActive = remoteInputActive;
+        mCurrentState.remoteInputActive = remoteInputActive;
         apply(mCurrentState);
     }
 
@@ -717,33 +764,32 @@
      */
     @Override
     public void setForceDozeBrightness(boolean forceDozeBrightness) {
-        if (mCurrentState.mForceDozeBrightness == forceDozeBrightness) {
+        if (mCurrentState.forceDozeBrightness == forceDozeBrightness) {
             return;
         }
-        mCurrentState.mForceDozeBrightness = forceDozeBrightness;
+        mCurrentState.forceDozeBrightness = forceDozeBrightness;
         apply(mCurrentState);
     }
 
     @Override
     public void setDozing(boolean dozing) {
-        mCurrentState.mDozing = dozing;
+        mCurrentState.dozing = dozing;
         apply(mCurrentState);
     }
 
-    private final Set<Object> mForceOpenTokens = new HashSet<>();
     @Override
     public void setForcePluginOpen(boolean forceOpen, Object token) {
         if (forceOpen) {
-            mForceOpenTokens.add(token);
+            mCurrentState.forceOpenTokens.add(token);
         } else {
-            mForceOpenTokens.remove(token);
+            mCurrentState.forceOpenTokens.remove(token);
         }
-        final boolean previousForceOpenState = mCurrentState.mForcePluginOpen;
-        mCurrentState.mForcePluginOpen = !mForceOpenTokens.isEmpty();
-        if (previousForceOpenState != mCurrentState.mForcePluginOpen) {
+        final boolean previousForceOpenState = mCurrentState.forcePluginOpen;
+        mCurrentState.forcePluginOpen = !mCurrentState.forceOpenTokens.isEmpty();
+        if (previousForceOpenState != mCurrentState.forcePluginOpen) {
             apply(mCurrentState);
             if (mForcePluginOpenListener != null) {
-                mForcePluginOpenListener.onChange(mCurrentState.mForcePluginOpen);
+                mForcePluginOpenListener.onChange(mCurrentState.forcePluginOpen);
             }
         }
     }
@@ -753,12 +799,12 @@
      */
     @Override
     public boolean getForcePluginOpen() {
-        return mCurrentState.mForcePluginOpen;
+        return mCurrentState.forcePluginOpen;
     }
 
     @Override
     public void setNotTouchable(boolean notTouchable) {
-        mCurrentState.mNotTouchable = notTouchable;
+        mCurrentState.windowNotTouchable = notTouchable;
         apply(mCurrentState);
     }
 
@@ -767,7 +813,7 @@
      */
     @Override
     public boolean getPanelExpanded() {
-        return mCurrentState.mPanelExpanded;
+        return mCurrentState.panelExpanded;
     }
 
     @Override
@@ -790,11 +836,16 @@
         if (mNotificationShadeView != null && mNotificationShadeView.getViewRootImpl() != null) {
             mNotificationShadeView.getViewRootImpl().dump("  ", pw);
         }
+        new DumpsysTableLogger(
+                TAG,
+                NotificationShadeWindowState.TABLE_HEADERS,
+                mStateBuffer.toList()
+        ).printTableData(pw);
     }
 
     @Override
     public boolean isShowingWallpaper() {
-        return !mCurrentState.mBackdropShowing;
+        return !mCurrentState.mediaBackdropShowing;
     }
 
     @Override
@@ -824,7 +875,7 @@
      */
     @Override
     public void setKeyguardGoingAway(boolean goingAway) {
-        mCurrentState.mKeyguardGoingAway = goingAway;
+        mCurrentState.keyguardGoingAway = goingAway;
         apply(mCurrentState);
     }
 
@@ -836,77 +887,13 @@
     @Override
     public void setRequestTopUi(boolean requestTopUi, String componentTag) {
         if (requestTopUi) {
-            mCurrentState.mComponentsForcingTopUi.add(componentTag);
+            mCurrentState.componentsForcingTopUi.add(componentTag);
         } else {
-            mCurrentState.mComponentsForcingTopUi.remove(componentTag);
+            mCurrentState.componentsForcingTopUi.remove(componentTag);
         }
         apply(mCurrentState);
     }
 
-    private static class State {
-        boolean mKeyguardShowing;
-        boolean mKeyguardOccluded;
-        boolean mKeyguardNeedsInput;
-        boolean mPanelVisible;
-        boolean mPanelExpanded;
-        boolean mNotificationShadeFocusable;
-        boolean mBouncerShowing;
-        boolean mKeyguardFadingAway;
-        boolean mKeyguardGoingAway;
-        boolean mQsExpanded;
-        boolean mHeadsUpShowing;
-        boolean mLightRevealScrimOpaque;
-        boolean mForceCollapsed;
-        boolean mForceDozeBrightness;
-        boolean mForceUserActivity;
-        boolean mLaunchingActivity;
-        boolean mBackdropShowing;
-        boolean mWallpaperSupportsAmbientMode;
-        boolean mNotTouchable;
-        Set<String> mComponentsForcingTopUi = new HashSet<>();
-
-        /**
-         * The status bar state from {@link CentralSurfaces}.
-         */
-        int mStatusBarState;
-
-        boolean mRemoteInputActive;
-        boolean mForcePluginOpen;
-        boolean mDozing;
-        int mScrimsVisibility;
-        int mBackgroundBlurRadius;
-
-        private boolean isKeyguardShowingAndNotOccluded() {
-            return mKeyguardShowing && !mKeyguardOccluded;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder result = new StringBuilder();
-            String newLine = "\n";
-            result.append("Window State {");
-            result.append(newLine);
-
-            Field[] fields = this.getClass().getDeclaredFields();
-
-            // Print field names paired with their values
-            for (Field field : fields) {
-                result.append("  ");
-                try {
-                    result.append(field.getName());
-                    result.append(": ");
-                    //requires access to private field:
-                    result.append(field.get(this));
-                } catch (IllegalAccessException ex) {
-                }
-                result.append(newLine);
-            }
-            result.append("}");
-
-            return result.toString();
-        }
-    }
-
     private final StateListener mStateListener = new StateListener() {
         @Override
         public void onStateChanged(int newState) {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowState.kt b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowState.kt
new file mode 100644
index 0000000..736404aa
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowState.kt
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.shade
+
+import com.android.systemui.dump.DumpsysTableLogger
+import com.android.systemui.dump.Row
+import com.android.systemui.plugins.util.RingBuffer
+import com.android.systemui.shade.NotificationShadeWindowState.Buffer
+import com.android.systemui.statusbar.StatusBarState
+
+/**
+ * Represents state of shade window, used by [NotificationShadeWindowControllerImpl].
+ * Contains nested class [Buffer] for pretty table logging in bug reports.
+ */
+class NotificationShadeWindowState(
+    @JvmField var keyguardShowing: Boolean = false,
+    @JvmField var keyguardOccluded: Boolean = false,
+    @JvmField var keyguardNeedsInput: Boolean = false,
+    @JvmField var panelVisible: Boolean = false,
+    /** shade panel is expanded (expansion fraction > 0) */
+    @JvmField var panelExpanded: Boolean = false,
+    @JvmField var notificationShadeFocusable: Boolean = false,
+    @JvmField var bouncerShowing: Boolean = false,
+    @JvmField var keyguardFadingAway: Boolean = false,
+    @JvmField var keyguardGoingAway: Boolean = false,
+    @JvmField var qsExpanded: Boolean = false,
+    @JvmField var headsUpNotificationShowing: Boolean = false,
+    @JvmField var lightRevealScrimOpaque: Boolean = false,
+    @JvmField var forceWindowCollapsed: Boolean = false,
+    @JvmField var forceDozeBrightness: Boolean = false,
+    // TODO: forceUserActivity seems to be unused, delete?
+    @JvmField var forceUserActivity: Boolean = false,
+    @JvmField var launchingActivityFromNotification: Boolean = false,
+    @JvmField var mediaBackdropShowing: Boolean = false,
+    @JvmField var wallpaperSupportsAmbientMode: Boolean = false,
+    @JvmField var windowNotTouchable: Boolean = false,
+    @JvmField var componentsForcingTopUi: MutableSet<String> = mutableSetOf(),
+    @JvmField var forceOpenTokens: MutableSet<Any> = mutableSetOf(),
+    /** one of [StatusBarState] */
+    @JvmField var statusBarState: Int = 0,
+    @JvmField var remoteInputActive: Boolean = false,
+    @JvmField var forcePluginOpen: Boolean = false,
+    @JvmField var dozing: Boolean = false,
+    @JvmField var scrimsVisibility: Int = 0,
+    @JvmField var backgroundBlurRadius: Int = 0,
+) {
+
+    fun isKeyguardShowingAndNotOccluded(): Boolean {
+        return keyguardShowing && !keyguardOccluded
+    }
+
+    /** List of [String] to be used as a [Row] with [DumpsysTableLogger]. */
+    val asStringList: List<String> by lazy {
+        listOf(
+            keyguardShowing.toString(),
+            keyguardOccluded.toString(),
+            keyguardNeedsInput.toString(),
+            panelVisible.toString(),
+            panelExpanded.toString(),
+            notificationShadeFocusable.toString(),
+            bouncerShowing.toString(),
+            keyguardFadingAway.toString(),
+            keyguardGoingAway.toString(),
+            qsExpanded.toString(),
+            headsUpNotificationShowing.toString(),
+            lightRevealScrimOpaque.toString(),
+            forceWindowCollapsed.toString(),
+            forceDozeBrightness.toString(),
+            forceUserActivity.toString(),
+            launchingActivityFromNotification.toString(),
+            mediaBackdropShowing.toString(),
+            wallpaperSupportsAmbientMode.toString(),
+            windowNotTouchable.toString(),
+            componentsForcingTopUi.toString(),
+            forceOpenTokens.toString(),
+            StatusBarState.toString(statusBarState),
+            remoteInputActive.toString(),
+            forcePluginOpen.toString(),
+            dozing.toString(),
+            scrimsVisibility.toString(),
+            backgroundBlurRadius.toString()
+        )
+    }
+
+    /**
+     * [RingBuffer] to store [NotificationShadeWindowState]. After the buffer is full, it will
+     * recycle old events.
+     */
+    class Buffer(capacity: Int) {
+
+        private val buffer = RingBuffer(capacity) { NotificationShadeWindowState() }
+
+        /** Insert a new element in the buffer. */
+        fun insert(
+            keyguardShowing: Boolean,
+            keyguardOccluded: Boolean,
+            keyguardNeedsInput: Boolean,
+            panelVisible: Boolean,
+            panelExpanded: Boolean,
+            notificationShadeFocusable: Boolean,
+            bouncerShowing: Boolean,
+            keyguardFadingAway: Boolean,
+            keyguardGoingAway: Boolean,
+            qsExpanded: Boolean,
+            headsUpShowing: Boolean,
+            lightRevealScrimOpaque: Boolean,
+            forceCollapsed: Boolean,
+            forceDozeBrightness: Boolean,
+            forceUserActivity: Boolean,
+            launchingActivity: Boolean,
+            backdropShowing: Boolean,
+            wallpaperSupportsAmbientMode: Boolean,
+            notTouchable: Boolean,
+            componentsForcingTopUi: MutableSet<String>,
+            forceOpenTokens: MutableSet<Any>,
+            statusBarState: Int,
+            remoteInputActive: Boolean,
+            forcePluginOpen: Boolean,
+            dozing: Boolean,
+            scrimsVisibility: Int,
+            backgroundBlurRadius: Int,
+        ) {
+            buffer.advance().apply {
+                this.keyguardShowing = keyguardShowing
+                this.keyguardOccluded = keyguardOccluded
+                this.keyguardNeedsInput = keyguardNeedsInput
+                this.panelVisible = panelVisible
+                this.panelExpanded = panelExpanded
+                this.notificationShadeFocusable = notificationShadeFocusable
+                this.bouncerShowing = bouncerShowing
+                this.keyguardFadingAway = keyguardFadingAway
+                this.keyguardGoingAway = keyguardGoingAway
+                this.qsExpanded = qsExpanded
+                this.headsUpNotificationShowing = headsUpShowing
+                this.lightRevealScrimOpaque = lightRevealScrimOpaque
+                this.forceWindowCollapsed = forceCollapsed
+                this.forceDozeBrightness = forceDozeBrightness
+                this.forceUserActivity = forceUserActivity
+                this.launchingActivityFromNotification = launchingActivity
+                this.mediaBackdropShowing = backdropShowing
+                this.wallpaperSupportsAmbientMode = wallpaperSupportsAmbientMode
+                this.windowNotTouchable = notTouchable
+                this.componentsForcingTopUi.clear()
+                this.componentsForcingTopUi.addAll(componentsForcingTopUi)
+                this.forceOpenTokens.clear()
+                this.forceOpenTokens.addAll(forceOpenTokens)
+                this.statusBarState = statusBarState
+                this.remoteInputActive = remoteInputActive
+                this.forcePluginOpen = forcePluginOpen
+                this.dozing = dozing
+                this.scrimsVisibility = scrimsVisibility
+                this.backgroundBlurRadius = backgroundBlurRadius
+            }
+        }
+
+        /**
+         * Returns the content of the buffer (sorted from latest to newest).
+         *
+         * @see [NotificationShadeWindowState.asStringList]
+         */
+        fun toList(): List<Row> {
+            return buffer.asSequence().map { it.asStringList }.toList()
+        }
+    }
+
+    companion object {
+        /** Headers for dumping a table using [DumpsysTableLogger]. */
+        @JvmField
+        val TABLE_HEADERS =
+            listOf(
+                "keyguardShowing",
+                "keyguardOccluded",
+                "keyguardNeedsInput",
+                "panelVisible",
+                "panelExpanded",
+                "notificationShadeFocusable",
+                "bouncerShowing",
+                "keyguardFadingAway",
+                "keyguardGoingAway",
+                "qsExpanded",
+                "headsUpShowing",
+                "lightRevealScrimOpaque",
+                "forceCollapsed",
+                "forceDozeBrightness",
+                "forceUserActivity",
+                "launchingActivity",
+                "backdropShowing",
+                "wallpaperSupportsAmbientMode",
+                "notTouchable",
+                "componentsForcingTopUi",
+                "forceOpenTokens",
+                "statusBarState",
+                "remoteInputActive",
+                "forcePluginOpen",
+                "dozing",
+                "scrimsVisibility",
+                "backgroundBlurRadius"
+            )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
index 6acf417..1f0cbf9 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
@@ -58,6 +58,7 @@
 import com.android.internal.view.FloatingActionMode;
 import com.android.internal.widget.floatingtoolbar.FloatingToolbar;
 import com.android.systemui.R;
+import com.android.systemui.compose.ComposeFacade;
 
 /**
  * Combined keyguard and notification panel view. Also holding backdrop and scrims.
@@ -149,6 +150,18 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         setWillNotDraw(!DEBUG);
+
+        if (ComposeFacade.INSTANCE.isComposeAvailable()) {
+            ComposeFacade.INSTANCE.composeInitializer().onAttachedToWindow(this);
+        }
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        if (ComposeFacade.INSTANCE.isComposeAvailable()) {
+            ComposeFacade.INSTANCE.composeInitializer().onDetachedFromWindow(this);
+        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index 5c1ddd6..7ed6e3e 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.shade;
 
+import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
+
 import android.app.StatusBarManager;
 import android.media.AudioManager;
 import android.media.session.MediaSessionLegacyHelper;
@@ -39,6 +41,10 @@
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
+import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
+import com.android.systemui.keyguard.shared.model.TransitionState;
+import com.android.systemui.keyguard.shared.model.TransitionStep;
 import com.android.systemui.keyguard.ui.binder.KeyguardBouncerViewBinder;
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel;
 import com.android.systemui.statusbar.DragDownHelper;
@@ -57,6 +63,7 @@
 import com.android.systemui.statusbar.window.StatusBarWindowStateController;
 
 import java.io.PrintWriter;
+import java.util.function.Consumer;
 
 import javax.inject.Inject;
 
@@ -79,6 +86,7 @@
     private final AmbientState mAmbientState;
     private final PulsingGestureListener mPulsingGestureListener;
     private final NotificationInsetsController mNotificationInsetsController;
+    private final AlternateBouncerInteractor mAlternateBouncerInteractor;
 
     private GestureDetector mPulsingWakeupGestureHandler;
     private View mBrightnessMirror;
@@ -96,6 +104,13 @@
     private final ShadeExpansionStateManager mShadeExpansionStateManager;
 
     private boolean mIsTrackingBarGesture = false;
+    private boolean mIsOcclusionTransitionRunning = false;
+
+    private final Consumer<TransitionStep> mLockscreenToDreamingTransition =
+            (TransitionStep step) -> {
+                mIsOcclusionTransitionRunning =
+                    step.getTransitionState() == TransitionState.RUNNING;
+            };
 
     @Inject
     public NotificationShadeWindowViewController(
@@ -119,7 +134,9 @@
             PulsingGestureListener pulsingGestureListener,
             FeatureFlags featureFlags,
             KeyguardBouncerViewModel keyguardBouncerViewModel,
-            KeyguardBouncerComponent.Factory keyguardBouncerComponentFactory
+            KeyguardBouncerComponent.Factory keyguardBouncerComponentFactory,
+            AlternateBouncerInteractor alternateBouncerInteractor,
+            KeyguardTransitionInteractor keyguardTransitionInteractor
     ) {
         mLockscreenShadeTransitionController = transitionController;
         mFalsingCollector = falsingCollector;
@@ -139,6 +156,7 @@
         mAmbientState = ambientState;
         mPulsingGestureListener = pulsingGestureListener;
         mNotificationInsetsController = notificationInsetsController;
+        mAlternateBouncerInteractor = alternateBouncerInteractor;
 
         // This view is not part of the newly inflated expanded status bar.
         mBrightnessMirror = mView.findViewById(R.id.brightness_mirror_container);
@@ -148,6 +166,11 @@
                     keyguardBouncerViewModel,
                     keyguardBouncerComponentFactory);
         }
+
+        if (featureFlags.isEnabled(Flags.UNOCCLUSION_TRANSITION)) {
+            collectFlow(mView, keyguardTransitionInteractor.getLockscreenToDreamingTransition(),
+                    mLockscreenToDreamingTransition);
+        }
     }
 
     /**
@@ -215,6 +238,10 @@
                     return true;
                 }
 
+                if (mIsOcclusionTransitionRunning) {
+                    return false;
+                }
+
                 mFalsingCollector.onTouchEvent(ev);
                 mPulsingWakeupGestureHandler.onTouchEvent(ev);
                 mStatusBarKeyguardViewManager.onTouch(ev);
@@ -292,7 +319,7 @@
                     return true;
                 }
 
-                if (mStatusBarKeyguardViewManager.isShowingAlternateBouncer()) {
+                if (mAlternateBouncerInteractor.isVisibleState()) {
                     // capture all touches if the alt auth bouncer is showing
                     return true;
                 }
@@ -330,7 +357,7 @@
                     handled = !mService.isPulsing();
                 }
 
-                if (mStatusBarKeyguardViewManager.isShowingAlternateBouncer()) {
+                if (mAlternateBouncerInteractor.isVisibleState()) {
                     // eat the touch
                     handled = true;
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt b/packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt
index db70065..b42bdaa 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt
@@ -19,7 +19,6 @@
 import android.hardware.display.AmbientDisplayConfiguration
 import android.os.PowerManager
 import android.os.SystemClock
-import android.os.UserHandle
 import android.provider.Settings
 import android.view.GestureDetector
 import android.view.MotionEvent
@@ -29,6 +28,7 @@
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.plugins.FalsingManager.LOW_PENALTY
 import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.settings.UserTracker
 import com.android.systemui.statusbar.phone.CentralSurfaces
 import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent
 import com.android.systemui.tuner.TunerService
@@ -54,6 +54,7 @@
         private val ambientDisplayConfiguration: AmbientDisplayConfiguration,
         private val statusBarStateController: StatusBarStateController,
         private val shadeLogger: ShadeLogger,
+        userTracker: UserTracker,
         tunerService: TunerService,
         dumpManager: DumpManager
 ) : GestureDetector.SimpleOnGestureListener(), Dumpable {
@@ -65,10 +66,10 @@
             when (key) {
                 Settings.Secure.DOZE_DOUBLE_TAP_GESTURE ->
                     doubleTapEnabled = ambientDisplayConfiguration.doubleTapGestureEnabled(
-                            UserHandle.USER_CURRENT)
+                            userTracker.userId)
                 Settings.Secure.DOZE_TAP_SCREEN_GESTURE ->
                     singleTapEnabled = ambientDisplayConfiguration.tapGestureEnabled(
-                            UserHandle.USER_CURRENT)
+                            userTracker.userId)
             }
         }
         tunerService.addTunable(tunable,
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
index 5fedbeb..11617be 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
@@ -36,16 +36,9 @@
         buffer.log(TAG, LogLevel.DEBUG, msg)
     }
 
-    private inline fun log(
-        logLevel: LogLevel,
-        initializer: LogMessage.() -> Unit,
-        noinline printer: LogMessage.() -> String
-    ) {
-        buffer.log(TAG, logLevel, initializer, printer)
-    }
-
     fun onQsInterceptMoveQsTrackingEnabled(h: Float) {
-        log(
+        buffer.log(
+            TAG,
             LogLevel.VERBOSE,
             { double1 = h.toDouble() },
             { "onQsIntercept: move action, QS tracking enabled. h = $double1" }
@@ -62,7 +55,8 @@
         keyguardShowing: Boolean,
         qsExpansionEnabled: Boolean
     ) {
-        log(
+        buffer.log(
+            TAG,
             LogLevel.VERBOSE,
             {
                 int1 = initialTouchY.toInt()
@@ -82,7 +76,8 @@
     }
 
     fun logMotionEvent(event: MotionEvent, message: String) {
-        log(
+        buffer.log(
+            TAG,
             LogLevel.VERBOSE,
             {
                 str1 = message
@@ -99,7 +94,8 @@
     }
 
     fun logMotionEventStatusBarState(event: MotionEvent, statusBarState: Int, message: String) {
-        log(
+        buffer.log(
+                TAG,
                 LogLevel.VERBOSE,
                 {
                     str1 = message
@@ -128,25 +124,33 @@
             tracking: Boolean,
             dragDownPxAmount: Float,
     ) {
-        log(LogLevel.VERBOSE, {
-            str1 = message
-            double1 = fraction.toDouble()
-            bool1 = expanded
-            bool2 = tracking
-            long1 = dragDownPxAmount.toLong()
-        }, {
-            "$str1 fraction=$double1,expanded=$bool1," +
+        buffer.log(
+            TAG,
+            LogLevel.VERBOSE,
+            {
+                str1 = message
+                double1 = fraction.toDouble()
+                bool1 = expanded
+                bool2 = tracking
+                long1 = dragDownPxAmount.toLong()
+            },
+            {
+                "$str1 fraction=$double1,expanded=$bool1," +
                     "tracking=$bool2," + "dragDownPxAmount=$dragDownPxAmount"
-        })
+            }
+        )
     }
 
     fun logHasVibrated(hasVibratedOnOpen: Boolean, fraction: Float) {
-        log(LogLevel.VERBOSE, {
-            bool1 = hasVibratedOnOpen
-            double1 = fraction.toDouble()
-        }, {
-            "hasVibratedOnOpen=$bool1, expansionFraction=$double1"
-        })
+        buffer.log(
+            TAG,
+            LogLevel.VERBOSE,
+            {
+                bool1 = hasVibratedOnOpen
+                double1 = fraction.toDouble()
+            },
+            { "hasVibratedOnOpen=$bool1, expansionFraction=$double1" }
+        )
     }
 
     fun logQsExpansionChanged(
@@ -159,42 +163,56 @@
             qsAnimatorExpand: Boolean,
             animatingQs: Boolean
     ) {
-        log(LogLevel.VERBOSE, {
-            str1 = message
-            bool1 = qsExpanded
-            int1 = qsMinExpansionHeight
-            int2 = qsMaxExpansionHeight
-            bool2 = stackScrollerOverscrolling
-            bool3 = dozing
-            bool4 = qsAnimatorExpand
-            // 0 = false, 1 = true
-            long1 = animatingQs.compareTo(false).toLong()
-        }, {
-            "$str1 qsExpanded=$bool1,qsMinExpansionHeight=$int1,qsMaxExpansionHeight=$int2," +
+        buffer.log(
+            TAG,
+            LogLevel.VERBOSE,
+            {
+                str1 = message
+                bool1 = qsExpanded
+                int1 = qsMinExpansionHeight
+                int2 = qsMaxExpansionHeight
+                bool2 = stackScrollerOverscrolling
+                bool3 = dozing
+                bool4 = qsAnimatorExpand
+                // 0 = false, 1 = true
+                long1 = animatingQs.compareTo(false).toLong()
+            },
+            {
+                "$str1 qsExpanded=$bool1,qsMinExpansionHeight=$int1,qsMaxExpansionHeight=$int2," +
                     "stackScrollerOverscrolling=$bool2,dozing=$bool3,qsAnimatorExpand=$bool4," +
                     "animatingQs=$long1"
-        })
+            }
+        )
     }
 
     fun logSingleTapUp(isDozing: Boolean, singleTapEnabled: Boolean, isNotDocked: Boolean) {
-        log(LogLevel.DEBUG, {
-            bool1 = isDozing
-            bool2 = singleTapEnabled
-            bool3 = isNotDocked
-        }, {
-            "PulsingGestureListener#onSingleTapUp all of this must true for single " +
-              "tap to be detected: isDozing: $bool1, singleTapEnabled: $bool2, isNotDocked: $bool3"
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                bool1 = isDozing
+                bool2 = singleTapEnabled
+                bool3 = isNotDocked
+            },
+            {
+                "PulsingGestureListener#onSingleTapUp all of this must true for single " +
+               "tap to be detected: isDozing: $bool1, singleTapEnabled: $bool2, isNotDocked: $bool3"
         })
     }
 
     fun logSingleTapUpFalsingState(proximityIsNotNear: Boolean, isNotFalseTap: Boolean) {
-        log(LogLevel.DEBUG, {
-            bool1 = proximityIsNotNear
-            bool2 = isNotFalseTap
-        }, {
-            "PulsingGestureListener#onSingleTapUp all of this must true for single " +
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                bool1 = proximityIsNotNear
+                bool2 = isNotFalseTap
+            },
+            {
+                "PulsingGestureListener#onSingleTapUp all of this must true for single " +
                     "tap to be detected: proximityIsNotNear: $bool1, isNotFalseTap: $bool2"
-        })
+            }
+        )
     }
 
     fun logNotInterceptingTouchInstantExpanding(
@@ -202,13 +220,18 @@
             notificationsDragEnabled: Boolean,
             touchDisabled: Boolean
     ) {
-        log(LogLevel.VERBOSE, {
-            bool1 = instantExpanding
-            bool2 = notificationsDragEnabled
-            bool3 = touchDisabled
-        }, {
-            "NPVC not intercepting touch, instantExpanding: $bool1, " +
+        buffer.log(
+            TAG,
+            LogLevel.VERBOSE,
+            {
+                bool1 = instantExpanding
+                bool2 = notificationsDragEnabled
+                bool3 = touchDisabled
+            },
+            {
+                "NPVC not intercepting touch, instantExpanding: $bool1, " +
                     "!notificationsDragEnabled: $bool2, touchDisabled: $bool3"
-        })
+            }
+        )
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeWindowLogger.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeWindowLogger.kt
new file mode 100644
index 0000000..9851625
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeWindowLogger.kt
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.shade
+
+import android.view.WindowManager
+import com.android.systemui.log.dagger.ShadeWindowLog
+import com.android.systemui.plugins.log.ConstantStringsLogger
+import com.android.systemui.plugins.log.ConstantStringsLoggerImpl
+import com.android.systemui.plugins.log.LogBuffer
+import com.android.systemui.plugins.log.LogLevel
+import com.android.systemui.plugins.log.LogLevel.DEBUG
+import com.android.systemui.plugins.log.LogMessage
+import javax.inject.Inject
+
+private const val TAG = "systemui.shadewindow"
+
+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,
+            DEBUG,
+            { str1 = state.toString() },
+            { "Applying new state: $str1" }
+        )
+    }
+
+    private inline fun log(
+        logLevel: LogLevel,
+        initializer: LogMessage.() -> Unit,
+        noinline printer: LogMessage.() -> String
+    ) {
+        buffer.log(TAG, logLevel, initializer, printer)
+    }
+
+    fun logApplyVisibility(visible: Boolean) {
+        buffer.log(
+            TAG,
+            DEBUG,
+            { bool1 = visible },
+            { "Updating visibility, should be visible : $bool1" })
+    }
+
+    fun logShadeVisibleAndFocusable(visible: Boolean) {
+        buffer.log(
+            TAG,
+            DEBUG,
+            { bool1 = visible },
+            { "Updating shade, should be visible and focusable: $bool1" }
+        )
+    }
+
+    fun logShadeFocusable(focusable: Boolean) {
+        buffer.log(
+            TAG,
+            DEBUG,
+            { bool1 = focusable },
+            { "Updating shade, should be focusable : $bool1" }
+        )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/config/BcSmartspaceConfigProvider.kt b/packages/SystemUI/src/com/android/systemui/smartspace/config/BcSmartspaceConfigProvider.kt
new file mode 100644
index 0000000..ab0d6e3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/smartspace/config/BcSmartspaceConfigProvider.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.smartspace.config
+
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.plugins.BcSmartspaceConfigPlugin
+
+class BcSmartspaceConfigProvider(private val featureFlags: FeatureFlags) :
+    BcSmartspaceConfigPlugin {
+    override val isDefaultDateWeatherDisabled: Boolean
+        get() = featureFlags.isEnabled(Flags.SMARTSPACE_DATE_WEATHER_DECOUPLED)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AlphaOptimizedFrameLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/AlphaOptimizedFrameLayout.java
index 662f70e..438b0f6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/AlphaOptimizedFrameLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AlphaOptimizedFrameLayout.java
@@ -36,10 +36,6 @@
             visibility -> {
                 super.setVisibility(visibility);
                 return Unit.INSTANCE;
-            },
-            visibility -> {
-                super.setTransitionVisibility(visibility);
-                return Unit.INSTANCE;
             });
 
     public AlphaOptimizedFrameLayout(Context context) {
@@ -73,9 +69,4 @@
     public void setVisibility(int visibility) {
         mLaunchableViewDelegate.setVisibility(visibility);
     }
-
-    @Override
-    public void setTransitionVisibility(int visibility) {
-        mLaunchableViewDelegate.setTransitionVisibility(visibility);
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 750d004..1758379 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -23,8 +23,6 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
 
-import static com.android.systemui.statusbar.phone.CentralSurfacesImpl.ONLY_CORE_APPS;
-
 import android.annotation.Nullable;
 import android.app.ITransientNotificationCallback;
 import android.app.StatusBarManager;
@@ -45,12 +43,14 @@
 import android.inputmethodservice.InputMethodService.BackDispositionMode;
 import android.media.INearbyMediaDevicesProvider;
 import android.media.MediaRoute2Info;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
+import android.os.Process;
 import android.os.RemoteException;
 import android.util.Pair;
 import android.util.SparseArray;
@@ -168,6 +168,7 @@
     private static final int MSG_SHOW_REAR_DISPLAY_DIALOG = 69 << MSG_SHIFT;
     private static final int MSG_GO_TO_FULLSCREEN_FROM_SPLIT = 70 << MSG_SHIFT;
     private static final int MSG_ENTER_STAGE_SPLIT_FROM_RUNNING_APP = 71 << MSG_SHIFT;
+    private static final int MSG_SHOW_MEDIA_OUTPUT_SWITCHER = 72 << MSG_SHIFT;
 
     public static final int FLAG_EXCLUDE_NONE = 0;
     public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -334,7 +335,7 @@
         /**
          * @see IStatusBar#setBiometicContextListener(IBiometricContextListener)
          */
-        default void setBiometicContextListener(IBiometricContextListener listener) {
+        default void setBiometricContextListener(IBiometricContextListener listener) {
         }
 
         /**
@@ -492,6 +493,11 @@
          * @see IStatusBar#enterStageSplitFromRunningApp
          */
         default void enterStageSplitFromRunningApp(boolean leftOrTop) {}
+
+        /**
+         * @see IStatusBar#showMediaOutputSwitcher
+         */
+        default void showMediaOutputSwitcher(String packageName) {}
     }
 
     public CommandQueue(Context context) {
@@ -535,8 +541,7 @@
         final int disabled1 = getDisabled1(DEFAULT_DISPLAY);
         final int disabled2 = getDisabled2(DEFAULT_DISPLAY);
         return (disabled1 & StatusBarManager.DISABLE_EXPAND) == 0
-                && (disabled2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) == 0
-                && !ONLY_CORE_APPS;
+                && (disabled2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) == 0;
     }
 
     @Override
@@ -1262,6 +1267,19 @@
     }
 
     @Override
+    public void showMediaOutputSwitcher(String packageName) {
+        int callingUid = Binder.getCallingUid();
+        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
+            throw new SecurityException("Call only allowed from system server.");
+        }
+        synchronized (mLock) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = packageName;
+            mHandler.obtainMessage(MSG_SHOW_MEDIA_OUTPUT_SWITCHER, args).sendToTarget();
+        }
+    }
+
+    @Override
     public void requestAddTile(
             @NonNull ComponentName componentName,
             @NonNull CharSequence appName,
@@ -1583,7 +1601,7 @@
                 }
                 case MSG_SET_BIOMETRICS_LISTENER:
                     for (int i = 0; i < mCallbacks.size(); i++) {
-                        mCallbacks.get(i).setBiometicContextListener(
+                        mCallbacks.get(i).setBiometricContextListener(
                                 (IBiometricContextListener) msg.obj);
                     }
                     break;
@@ -1777,6 +1795,13 @@
                         mCallbacks.get(i).enterStageSplitFromRunningApp((Boolean) msg.obj);
                     }
                     break;
+                case MSG_SHOW_MEDIA_OUTPUT_SWITCHER:
+                    args = (SomeArgs) msg.obj;
+                    String clientPackageName = (String) args.arg1;
+                    for (int i = 0; i < mCallbacks.size(); i++) {
+                        mCallbacks.get(i).showMediaOutputSwitcher(clientPackageName);
+                    }
+                    break;
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutsModule.java
new file mode 100644
index 0000000..a797d4a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutsModule.java
@@ -0,0 +1,40 @@
+/*
+ * 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.content.BroadcastReceiver;
+
+import dagger.Binds;
+import dagger.Module;
+import dagger.multibindings.ClassKey;
+import dagger.multibindings.IntoMap;
+
+/**
+ * Module for {@link com.android.systemui.KeyboardShortcutsReceiver}.
+ */
+@Module
+public abstract class KeyboardShortcutsModule {
+
+    /**
+     *
+     */
+    @Binds
+    @IntoMap
+    @ClassKey(KeyboardShortcutsReceiver.class)
+    public abstract BroadcastReceiver bindKeyboardShortcutsReceiver(
+            KeyboardShortcutsReceiver broadcastReceiver);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index b7001e4..006b552 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -41,6 +41,7 @@
 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_USER_LOCKED;
 import static com.android.systemui.keyguard.ScreenLifecycle.SCREEN_ON;
 import static com.android.systemui.plugins.FalsingManager.LOW_PENALTY;
+import static com.android.systemui.plugins.log.LogLevel.ERROR;
 
 import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
@@ -90,6 +91,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.AlternateBouncerInteractor;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
@@ -155,6 +157,7 @@
     private final KeyguardBypassController mKeyguardBypassController;
     private final AccessibilityManager mAccessibilityManager;
     private final Handler mHandler;
+    private final AlternateBouncerInteractor mAlternateBouncerInteractor;
 
     @VisibleForTesting
     public KeyguardIndicationRotateTextViewController mRotateTextViewController;
@@ -234,7 +237,8 @@
             KeyguardBypassController keyguardBypassController,
             AccessibilityManager accessibilityManager,
             FaceHelpMessageDeferral faceHelpMessageDeferral,
-            KeyguardLogger keyguardLogger) {
+            KeyguardLogger keyguardLogger,
+            AlternateBouncerInteractor alternateBouncerInteractor) {
         mContext = context;
         mBroadcastDispatcher = broadcastDispatcher;
         mDevicePolicyManager = devicePolicyManager;
@@ -256,6 +260,7 @@
         mScreenLifecycle = screenLifecycle;
         mKeyguardLogger = keyguardLogger;
         mScreenLifecycle.addObserver(mScreenObserver);
+        mAlternateBouncerInteractor = alternateBouncerInteractor;
 
         mFaceAcquiredMessageDeferral = faceHelpMessageDeferral;
         mCoExFaceAcquisitionMsgIdsToShow = new HashSet<>();
@@ -928,9 +933,10 @@
         }
 
         if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
-            if (mStatusBarKeyguardViewManager.isShowingAlternateBouncer()) {
+            if (mAlternateBouncerInteractor.isVisibleState()) {
                 return; // udfps affordance is highlighted, no need to show action to unlock
-            } else if (mKeyguardUpdateMonitor.isFaceEnrolled()) {
+            } else if (mKeyguardUpdateMonitor.isFaceEnrolled()
+                    && !mKeyguardUpdateMonitor.getIsFaceAuthenticated()) {
                 String message = mContext.getString(R.string.keyguard_retry);
                 mStatusBarKeyguardViewManager.setKeyguardMessage(message, mInitialTextColorState);
             }
@@ -1027,7 +1033,7 @@
                 mChargingTimeRemaining = mPowerPluggedIn
                         ? mBatteryInfo.computeChargeTimeRemaining() : -1;
             } catch (RemoteException e) {
-                mKeyguardLogger.logException(e, "Error calling IBatteryStats");
+                mKeyguardLogger.log(TAG, ERROR, "Error calling IBatteryStats", e);
                 mChargingTimeRemaining = -1;
             }
             updateDeviceEntryIndication(!wasPluggedIn && mPowerPluggedInWired);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
index 905cc3f..f565f3d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
@@ -509,9 +509,14 @@
      * If secure with redaction: Show bouncer, go to unlocked shade.
      * If secure without redaction or no security: Go to [StatusBarState.SHADE_LOCKED].
      *
+     * Split shade is special case and [needsQSAnimation] will be always overridden to true.
+     * That's because handheld shade will automatically follow notifications animation, but that's
+     * not the case for split shade.
+     *
      * @param expandView The view to expand after going to the shade
      * @param needsQSAnimation if this needs the quick settings to slide in from the top or if
-     *                         that's already handled separately
+     *                         that's already handled separately. This argument will be ignored on
+     *                         split shade as there QS animation can't be handled separately.
      */
     @JvmOverloads
     fun goToLockedShade(expandedView: View?, needsQSAnimation: Boolean = true) {
@@ -519,7 +524,7 @@
         logger.logTryGoToLockedShade(isKeyguard)
         if (isKeyguard) {
             val animationHandler: ((Long) -> Unit)?
-            if (needsQSAnimation) {
+            if (needsQSAnimation || useSplitShade) {
                 // Let's use the default animation
                 animationHandler = null
             } else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
index 56b689e..7d0ac18 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
@@ -290,7 +290,8 @@
                     false,
                     null,
                     0,
-                    false
+                    false,
+                    0
             );
         }
         return ranking;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index 8f9365c..99081e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -65,8 +65,6 @@
 import com.android.systemui.util.DumpUtilsKt;
 import com.android.systemui.util.ListenerSet;
 
-import dagger.Lazy;
-
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
@@ -74,6 +72,8 @@
 import java.util.Optional;
 import java.util.function.Consumer;
 
+import dagger.Lazy;
+
 /**
  * Class for handling remote input state over a set of notifications. This class handles things
  * like keeping notifications temporarily that were cancelled as a response to a remote input
@@ -465,8 +465,7 @@
         riv.getController().setRemoteInput(input);
         riv.getController().setRemoteInputs(inputs);
         riv.getController().setEditedSuggestionInfo(editedSuggestionInfo);
-        ViewGroup parent = view.getParent() != null ? (ViewGroup) view.getParent() : null;
-        riv.focusAnimated(parent);
+        riv.focusAnimated();
         if (userMessageContent != null) {
             riv.setEditTextContent(userMessageContent);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkController.java
index f960eb7..ed32008 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkController.java
@@ -47,8 +47,6 @@
     void addEmergencyListener(EmergencyListener listener);
     /** */
     void removeEmergencyListener(EmergencyListener listener);
-    /** */
-    boolean hasEmergencyCryptKeeperText();
 
     /** */
     boolean isRadioOn();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
index 5f5418f..6e74542 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
@@ -84,7 +84,6 @@
 import com.android.systemui.statusbar.policy.DataSaverControllerImpl;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
-import com.android.systemui.statusbar.policy.EncryptionHelper;
 import com.android.systemui.telephony.TelephonyListenerManager;
 import com.android.systemui.util.CarrierConfigTracker;
 
@@ -1486,11 +1485,6 @@
     }
 
     /** */
-    public boolean hasEmergencyCryptKeeperText() {
-        return EncryptionHelper.IS_DATA_ENCRYPTED;
-    }
-
-    /** */
     public boolean isRadioOn() {
         return !mAirplaneMode;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
index 14d0d7e..9a65e34 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
@@ -31,6 +31,7 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dump.DumpHandler;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
 import com.android.systemui.media.controls.pipeline.MediaDataManager;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -61,7 +62,6 @@
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.phone.StatusBarIconControllerImpl;
 import com.android.systemui.statusbar.phone.StatusBarIconList;
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.phone.StatusBarRemoteInputCallback;
 import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
 import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallFlags;
@@ -280,7 +280,7 @@
     @SysUISingleton
     static DialogLaunchAnimator provideDialogLaunchAnimator(IDreamManager dreamManager,
             KeyguardStateController keyguardStateController,
-            Lazy<StatusBarKeyguardViewManager> statusBarKeyguardViewManager,
+            Lazy<AlternateBouncerInteractor> alternateBouncerInteractor,
             InteractionJankMonitor interactionJankMonitor) {
         DialogLaunchAnimator.Callback callback = new DialogLaunchAnimator.Callback() {
             @Override
@@ -300,7 +300,7 @@
 
             @Override
             public boolean isShowingAlternateAuthOnUnlock() {
-                return statusBarKeyguardViewManager.get().canShowAlternateBouncer();
+                return alternateBouncerInteractor.get().canShowAlternateBouncerForFingerprint();
             }
         };
         return new DialogLaunchAnimator(callback, interactionJankMonitor);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
index 1e7fc93..197cf56 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
@@ -54,7 +54,7 @@
  * their respective views based on the progress of the animator. Interpolation differences TBD
  */
 @SysUISingleton
-class SystemStatusAnimationScheduler @Inject constructor(
+open class SystemStatusAnimationScheduler @Inject constructor(
     private val coordinator: SystemEventCoordinator,
     private val chipAnimationController: SystemEventChipAnimationController,
     private val statusBarWindowController: StatusBarWindowController,
@@ -66,7 +66,7 @@
     companion object {
         private const val PROPERTY_ENABLE_IMMERSIVE_INDICATOR = "enable_immersive_indicator"
     }
-    private fun isImmersiveIndicatorEnabled(): Boolean {
+    public fun isImmersiveIndicatorEnabled(): Boolean {
         return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
                 PROPERTY_ENABLE_IMMERSIVE_INDICATOR, true)
     }
@@ -76,18 +76,22 @@
 
     /** True if the persistent privacy dot should be active */
     var hasPersistentDot = false
-        private set
+        protected set
 
     private var scheduledEvent: StatusEvent? = null
     private var cancelExecutionRunnable: Runnable? = null
     private val listeners = mutableSetOf<SystemStatusAnimationCallback>()
 
+    fun getListeners(): MutableSet<SystemStatusAnimationCallback> {
+        return listeners
+    }
+
     init {
         coordinator.attachScheduler(this)
         dumpManager.registerDumpable(TAG, this)
     }
 
-    fun onStatusEvent(event: StatusEvent) {
+    open fun onStatusEvent(event: StatusEvent) {
         // Ignore any updates until the system is up and running
         if (isTooEarly() || !isImmersiveIndicatorEnabled()) {
             return
@@ -139,7 +143,7 @@
         }
     }
 
-    private fun isTooEarly(): Boolean {
+    public fun isTooEarly(): Boolean {
         return systemClock.uptimeMillis() - Process.getStartUptimeMillis() < MIN_UPTIME
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeStatusBarAwayGestureHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeStatusBarAwayGestureHandler.kt
index 6115819..5ab3d7c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeStatusBarAwayGestureHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeStatusBarAwayGestureHandler.kt
@@ -17,90 +17,25 @@
 package com.android.systemui.statusbar.gesture
 
 import android.content.Context
-import android.view.InputEvent
 import android.view.MotionEvent
-import android.view.MotionEvent.ACTION_CANCEL
-import android.view.MotionEvent.ACTION_DOWN
-import android.view.MotionEvent.ACTION_MOVE
-import android.view.MotionEvent.ACTION_UP
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.statusbar.window.StatusBarWindowController
 import javax.inject.Inject
 
-/**
- * A class to detect when a user swipes away the status bar. To be notified when the swipe away
- * gesture is detected, add a callback via [addOnGestureDetectedCallback].
- */
+/** A class to detect when a user swipes away the status bar. */
 @SysUISingleton
-open class SwipeStatusBarAwayGestureHandler @Inject constructor(
+class SwipeStatusBarAwayGestureHandler
+@Inject
+constructor(
     context: Context,
+    logger: SwipeUpGestureLogger,
     private val statusBarWindowController: StatusBarWindowController,
-    private val logger: SwipeStatusBarAwayGestureLogger
-) : GenericGestureDetector(SwipeStatusBarAwayGestureHandler::class.simpleName!!) {
-
-    private var startY: Float = 0f
-    private var startTime: Long = 0L
-    private var monitoringCurrentTouch: Boolean = false
-
-    private var swipeDistanceThreshold: Int = context.resources.getDimensionPixelSize(
-        com.android.internal.R.dimen.system_gestures_start_threshold
-    )
-
-    override fun onInputEvent(ev: InputEvent) {
-        if (ev !is MotionEvent) {
-            return
-        }
-
-        when (ev.actionMasked) {
-            ACTION_DOWN -> {
-                if (
-                    // Gesture starts just below the status bar
-                    ev.y >= statusBarWindowController.statusBarHeight
-                    && ev.y <= 3 * statusBarWindowController.statusBarHeight
-                ) {
-                    logger.logGestureDetectionStarted(ev.y.toInt())
-                    startY = ev.y
-                    startTime = ev.eventTime
-                    monitoringCurrentTouch = true
-                } else {
-                    monitoringCurrentTouch = false
-                }
-            }
-            ACTION_MOVE -> {
-                if (!monitoringCurrentTouch) {
-                    return
-                }
-                if (
-                    // Gesture is up
-                    ev.y < startY
-                    // Gesture went far enough
-                    && (startY - ev.y) >= swipeDistanceThreshold
-                    // Gesture completed quickly enough
-                    && (ev.eventTime - startTime) < SWIPE_TIMEOUT_MS
-                ) {
-                    monitoringCurrentTouch = false
-                    logger.logGestureDetected(ev.y.toInt())
-                    onGestureDetected(ev)
-                }
-            }
-            ACTION_CANCEL, ACTION_UP -> {
-                if (monitoringCurrentTouch) {
-                    logger.logGestureDetectionEndedWithoutTriggering(ev.y.toInt())
-                }
-                monitoringCurrentTouch = false
-            }
-        }
-    }
-
-    override fun startGestureListening() {
-        super.startGestureListening()
-        logger.logInputListeningStarted()
-    }
-
-    override fun stopGestureListening() {
-        super.stopGestureListening()
-        logger.logInputListeningStopped()
+) : SwipeUpGestureHandler(context, logger, loggerTag = LOGGER_TAG) {
+    override fun startOfGestureIsWithinBounds(ev: MotionEvent): Boolean {
+        // Gesture starts just below the status bar
+        return ev.y >= statusBarWindowController.statusBarHeight &&
+            ev.y <= 3 * statusBarWindowController.statusBarHeight
     }
 }
 
-private const val SWIPE_TIMEOUT_MS: Long = 500
+private const val LOGGER_TAG = "SwipeStatusBarAway"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeUpGestureHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeUpGestureHandler.kt
new file mode 100644
index 0000000..5ecc35c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeUpGestureHandler.kt
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.gesture
+
+import android.content.Context
+import android.view.InputEvent
+import android.view.MotionEvent
+import android.view.MotionEvent.ACTION_CANCEL
+import android.view.MotionEvent.ACTION_DOWN
+import android.view.MotionEvent.ACTION_MOVE
+import android.view.MotionEvent.ACTION_UP
+import com.android.systemui.dagger.SysUISingleton
+
+/**
+ * A class to detect a generic "swipe up" gesture. To be notified when the swipe up gesture is
+ * detected, add a callback via [addOnGestureDetectedCallback].
+ */
+@SysUISingleton
+abstract class SwipeUpGestureHandler(
+    context: Context,
+    private val logger: SwipeUpGestureLogger,
+    private val loggerTag: String,
+) : GenericGestureDetector(SwipeUpGestureHandler::class.simpleName!!) {
+
+    private var startY: Float = 0f
+    private var startTime: Long = 0L
+    private var monitoringCurrentTouch: Boolean = false
+
+    private var swipeDistanceThreshold: Int = context.resources.getDimensionPixelSize(
+        com.android.internal.R.dimen.system_gestures_start_threshold
+    )
+
+    override fun onInputEvent(ev: InputEvent) {
+        if (ev !is MotionEvent) {
+            return
+        }
+
+        when (ev.actionMasked) {
+            ACTION_DOWN -> {
+                if (
+                    startOfGestureIsWithinBounds(ev)
+                ) {
+                    logger.logGestureDetectionStarted(loggerTag, ev.y.toInt())
+                    startY = ev.y
+                    startTime = ev.eventTime
+                    monitoringCurrentTouch = true
+                } else {
+                    monitoringCurrentTouch = false
+                }
+            }
+            ACTION_MOVE -> {
+                if (!monitoringCurrentTouch) {
+                    return
+                }
+                if (
+                    // Gesture is up
+                    ev.y < startY &&
+                    // Gesture went far enough
+                    (startY - ev.y) >= swipeDistanceThreshold &&
+                    // Gesture completed quickly enough
+                    (ev.eventTime - startTime) < SWIPE_TIMEOUT_MS
+                ) {
+                    monitoringCurrentTouch = false
+                    logger.logGestureDetected(loggerTag, ev.y.toInt())
+                    onGestureDetected(ev)
+                }
+            }
+            ACTION_CANCEL, ACTION_UP -> {
+                if (monitoringCurrentTouch) {
+                    logger.logGestureDetectionEndedWithoutTriggering(loggerTag, ev.y.toInt())
+                }
+                monitoringCurrentTouch = false
+            }
+        }
+    }
+
+    /**
+     * Returns true if the [ACTION_DOWN] event falls within bounds for this specific swipe-up
+     * gesture.
+     *
+     * Implementations must override this method to specify what part(s) of the screen are valid
+     * locations for the swipe up gesture to start at.
+     */
+    abstract fun startOfGestureIsWithinBounds(ev: MotionEvent): Boolean
+
+    override fun startGestureListening() {
+        super.startGestureListening()
+        logger.logInputListeningStarted(loggerTag)
+    }
+
+    override fun stopGestureListening() {
+        super.stopGestureListening()
+        logger.logInputListeningStopped(loggerTag)
+    }
+}
+
+private const val SWIPE_TIMEOUT_MS: Long = 500
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeStatusBarAwayGestureLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeUpGestureLogger.kt
similarity index 64%
rename from packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeStatusBarAwayGestureLogger.kt
rename to packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeUpGestureLogger.kt
index 9bdff92..9ce6b02 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeStatusBarAwayGestureLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeUpGestureLogger.kt
@@ -16,49 +16,49 @@
 
 package com.android.systemui.statusbar.gesture
 
-import com.android.systemui.log.dagger.SwipeStatusBarAwayLog
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.log.dagger.SwipeUpLog
 import com.android.systemui.plugins.log.LogBuffer
 import com.android.systemui.plugins.log.LogLevel
 import javax.inject.Inject
 
-/** Log messages for [SwipeStatusBarAwayGestureHandler]. */
-class SwipeStatusBarAwayGestureLogger @Inject constructor(
-    @SwipeStatusBarAwayLog private val buffer: LogBuffer
+/** Log messages for [SwipeUpGestureHandler]. */
+@SysUISingleton
+class SwipeUpGestureLogger @Inject constructor(
+    @SwipeUpLog private val buffer: LogBuffer,
 ) {
-    fun logGestureDetectionStarted(y: Int) {
+    fun logGestureDetectionStarted(tag: String, y: Int) {
         buffer.log(
-            TAG,
+            tag,
             LogLevel.DEBUG,
             { int1 = y },
             { "Beginning gesture detection. y=$int1" }
         )
     }
 
-    fun logGestureDetectionEndedWithoutTriggering(y: Int) {
+    fun logGestureDetectionEndedWithoutTriggering(tag: String, y: Int) {
         buffer.log(
-            TAG,
+            tag,
             LogLevel.DEBUG,
             { int1 = y },
             { "Gesture finished; no swipe up gesture detected. Final y=$int1" }
         )
     }
 
-    fun logGestureDetected(y: Int) {
+    fun logGestureDetected(tag: String, y: Int) {
         buffer.log(
-            TAG,
+            tag,
             LogLevel.INFO,
             { int1 = y },
             { "Gesture detected; notifying callbacks. y=$int1" }
         )
     }
 
-    fun logInputListeningStarted() {
-        buffer.log(TAG, LogLevel.VERBOSE, {}, { "Input listening started "})
+    fun logInputListeningStarted(tag: String) {
+        buffer.log(tag, LogLevel.VERBOSE, {}, { "Input listening started "})
     }
 
-    fun logInputListeningStopped() {
-        buffer.log(TAG, LogLevel.VERBOSE, {}, { "Input listening stopped "})
+    fun logInputListeningStopped(tag: String) {
+        buffer.log(tag, LogLevel.VERBOSE, {}, { "Input listening stopped "})
     }
 }
-
-private const val TAG = "SwipeStatusBarAwayGestureHandler"
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
index 154518d..2849739 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
@@ -43,6 +43,7 @@
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.BcSmartspaceConfigPlugin
 import com.android.systemui.plugins.BcSmartspaceDataPlugin
 import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceTargetListener
 import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceView
@@ -60,11 +61,11 @@
 import java.util.concurrent.Executor
 import javax.inject.Inject
 
-/**
- * Controller for managing the smartspace view on the lockscreen
- */
+/** Controller for managing the smartspace view on the lockscreen */
 @SysUISingleton
-class LockscreenSmartspaceController @Inject constructor(
+class LockscreenSmartspaceController
+@Inject
+constructor(
         private val context: Context,
         private val featureFlags: FeatureFlags,
         private val smartspaceManager: SmartspaceManager,
@@ -81,7 +82,8 @@
         @Main private val uiExecutor: Executor,
         @Background private val bgExecutor: Executor,
         @Main private val handler: Handler,
-        optionalPlugin: Optional<BcSmartspaceDataPlugin>
+        optionalPlugin: Optional<BcSmartspaceDataPlugin>,
+        optionalConfigPlugin: Optional<BcSmartspaceConfigPlugin>,
 ) {
     companion object {
         private const val TAG = "LockscreenSmartspaceController"
@@ -89,6 +91,7 @@
 
     private var session: SmartspaceSession? = null
     private val plugin: BcSmartspaceDataPlugin? = optionalPlugin.orElse(null)
+    private val configPlugin: BcSmartspaceConfigPlugin? = optionalConfigPlugin.orElse(null)
 
     // Smartspace can be used on multiple displays, such as when the user casts their screen
     private var smartspaceViews = mutableSetOf<SmartspaceView>()
@@ -238,7 +241,9 @@
         }
 
         val ssView = plugin.getView(parent)
+        ssView.setUiSurface(BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD)
         ssView.registerDataProvider(plugin)
+        ssView.registerConfigProvider(configPlugin)
 
         ssView.setIntentStarter(object : BcSmartspaceDataPlugin.IntentStarter {
             override fun startIntent(view: View, intent: Intent, showOnLockscreen: Boolean) {
@@ -281,8 +286,10 @@
         }
 
         val newSession = smartspaceManager.createSmartspaceSession(
-                SmartspaceConfig.Builder(context, "lockscreen").build())
-        Log.d(TAG, "Starting smartspace session for lockscreen")
+                SmartspaceConfig.Builder(
+                        context, BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD).build())
+        Log.d(TAG, "Starting smartspace session for " +
+                BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD)
         newSession.addOnTargetsAvailableListener(uiExecutor, sessionListener)
         this.session = newSession
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt
index 3072c81..635ed7c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt
@@ -25,6 +25,10 @@
     val context: Context,
     val featureFlags: FeatureFlags
 ) {
+    init {
+        featureFlags.addListener(Flags.DISABLE_FSI) { event -> event.requestNoRestart() }
+    }
+
     fun isDevLoggingEnabled(): Boolean =
         featureFlags.isEnabled(Flags.NOTIFICATION_PIPELINE_DEVELOPER_LOGGING)
 
@@ -35,13 +39,7 @@
 
     fun fsiOnDNDUpdate(): Boolean = featureFlags.isEnabled(Flags.FSI_ON_DND_UPDATE)
 
-    val isStabilityIndexFixEnabled: Boolean by lazy {
-        featureFlags.isEnabled(Flags.STABILITY_INDEX_FIX)
-    }
-
-    val isSemiStableSortEnabled: Boolean by lazy {
-        featureFlags.isEnabled(Flags.SEMI_STABLE_SORT)
-    }
+    fun disableFsi(): Boolean = featureFlags.isEnabled(Flags.DISABLE_FSI)
 
     val shouldFilterUnseenNotifsOnKeyguard: Boolean by lazy {
         featureFlags.isEnabled(Flags.FILTER_UNSEEN_NOTIFS_ON_KEYGUARD)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt
index dc9b416..a35617c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt
@@ -252,6 +252,21 @@
     }
 
     /**
+     * Request the roundness 0f for a [SourceType].
+     *
+     * The top/bottom roundness of a [Roundable] can be defined by different [sourceType]. In case
+     * more origins require different roundness, for the same property, the maximum value will
+     * always be chosen.
+     *
+     * @param sourceType the source from which the request for roundness comes.
+     * @param animate true if it should animate to that value.
+     */
+    @JvmDefault
+    fun requestRoundnessReset(sourceType: SourceType, animate: Boolean) {
+        requestRoundness(top = 0f, bottom = 0f, sourceType = sourceType, animate = animate)
+    }
+
+    /**
      * Request the roundness 0f for a [SourceType]. Animate the roundness if the view is shown.
      *
      * The top/bottom roundness of a [Roundable] can be defined by different [sourceType]. In case
@@ -262,7 +277,7 @@
      */
     @JvmDefault
     fun requestRoundnessReset(sourceType: SourceType) {
-        requestRoundness(top = 0f, bottom = 0f, sourceType = sourceType)
+        requestRoundnessReset(sourceType = sourceType, animate = roundableState.targetView.isShown)
     }
 
     /** Apply the roundness changes, usually means invalidate the [RoundableState.targetView]. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListAttachState.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListAttachState.kt
index 84ab0d1..b5fce41 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListAttachState.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListAttachState.kt
@@ -98,13 +98,11 @@
      * This can happen if the entry is removed from a group that was broken up or if the entry was
      * filtered out during any of the filtering steps.
      */
-    fun detach(includingStableIndex: Boolean) {
+    fun detach() {
         parent = null
         section = null
         promoter = null
-        if (includingStableIndex) {
-            stableIndex = -1
-        }
+        stableIndex = -1
     }
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
index 65a21a4..4065b98 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
@@ -965,8 +965,7 @@
      * filtered out during any of the filtering steps.
      */
     private void annulAddition(ListEntry entry) {
-        // NOTE(b/241229236): Don't clear stableIndex until we fix stability fragility
-        entry.getAttachState().detach(/* includingStableIndex= */ mFlags.isSemiStableSortEnabled());
+        entry.getAttachState().detach();
     }
 
     private void assignSections() {
@@ -986,50 +985,10 @@
 
     private void sortListAndGroups() {
         Trace.beginSection("ShadeListBuilder.sortListAndGroups");
-        if (mFlags.isSemiStableSortEnabled()) {
-            sortWithSemiStableSort();
-        } else {
-            sortWithLegacyStability();
-        }
+        sortWithSemiStableSort();
         Trace.endSection();
     }
 
-    private void sortWithLegacyStability() {
-        // Sort all groups and the top level list
-        for (ListEntry entry : mNotifList) {
-            if (entry instanceof GroupEntry) {
-                GroupEntry parent = (GroupEntry) entry;
-                parent.sortChildren(mGroupChildrenComparator);
-            }
-        }
-        mNotifList.sort(mTopLevelComparator);
-        assignIndexes(mNotifList);
-
-        // Check for suppressed order changes
-        if (!getStabilityManager().isEveryChangeAllowed()) {
-            mForceReorderable = true;
-            boolean isSorted = isShadeSortedLegacy();
-            mForceReorderable = false;
-            if (!isSorted) {
-                getStabilityManager().onEntryReorderSuppressed();
-            }
-        }
-    }
-
-    private boolean isShadeSortedLegacy() {
-        if (!isSorted(mNotifList, mTopLevelComparator)) {
-            return false;
-        }
-        for (ListEntry entry : mNotifList) {
-            if (entry instanceof GroupEntry) {
-                if (!isSorted(((GroupEntry) entry).getChildren(), mGroupChildrenComparator)) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
     private void sortWithSemiStableSort() {
         // Sort each group's children
         boolean allSorted = true;
@@ -1100,29 +1059,16 @@
                 sectionMemberIndex = 0;
                 currentSection = section;
             }
-            if (mFlags.isStabilityIndexFixEnabled()) {
-                entry.getAttachState().setStableIndex(sectionMemberIndex++);
-                if (entry instanceof GroupEntry) {
-                    final GroupEntry parent = (GroupEntry) entry;
-                    final NotificationEntry summary = parent.getSummary();
-                    if (summary != null) {
-                        summary.getAttachState().setStableIndex(sectionMemberIndex++);
-                    }
-                    for (NotificationEntry child : parent.getChildren()) {
-                        child.getAttachState().setStableIndex(sectionMemberIndex++);
-                    }
+            entry.getAttachState().setStableIndex(sectionMemberIndex++);
+            if (entry instanceof GroupEntry) {
+                final GroupEntry parent = (GroupEntry) entry;
+                final NotificationEntry summary = parent.getSummary();
+                if (summary != null) {
+                    summary.getAttachState().setStableIndex(sectionMemberIndex++);
                 }
-            } else {
-                // This old implementation uses the same index number for the group as the first
-                // child, and fails to assign an index to the summary.  Remove once tested.
-                entry.getAttachState().setStableIndex(sectionMemberIndex);
-                if (entry instanceof GroupEntry) {
-                    final GroupEntry parent = (GroupEntry) entry;
-                    for (NotificationEntry child : parent.getChildren()) {
-                        child.getAttachState().setStableIndex(sectionMemberIndex++);
-                    }
+                for (NotificationEntry child : parent.getChildren()) {
+                    child.getAttachState().setStableIndex(sectionMemberIndex++);
                 }
-                sectionMemberIndex++;
             }
         }
     }
@@ -1272,11 +1218,6 @@
                 o2.getSectionIndex());
         if (cmp != 0) return cmp;
 
-        cmp = mFlags.isSemiStableSortEnabled() ? 0 : Integer.compare(
-                getStableOrderIndex(o1),
-                getStableOrderIndex(o2));
-        if (cmp != 0) return cmp;
-
         NotifComparator sectionComparator = getSectionComparator(o1, o2);
         if (sectionComparator != null) {
             cmp = sectionComparator.compare(o1, o2);
@@ -1301,12 +1242,7 @@
 
 
     private final Comparator<NotificationEntry> mGroupChildrenComparator = (o1, o2) -> {
-        int cmp = mFlags.isSemiStableSortEnabled() ? 0 : Integer.compare(
-                getStableOrderIndex(o1),
-                getStableOrderIndex(o2));
-        if (cmp != 0) return cmp;
-
-        cmp = Integer.compare(
+        int cmp = Integer.compare(
                 o1.getRepresentativeEntry().getRanking().getRank(),
                 o2.getRepresentativeEntry().getRanking().getRank());
         if (cmp != 0) return cmp;
@@ -1317,25 +1253,6 @@
         return cmp;
     };
 
-    /**
-     * A flag that is set to true when we want to run the comparators as if all reordering is
-     * allowed.  This is used to check if the list is "out of order" after the sort is complete.
-     */
-    private boolean mForceReorderable = false;
-
-    private int getStableOrderIndex(ListEntry entry) {
-        if (mForceReorderable) {
-            // this is used to determine if the list is correctly sorted
-            return -1;
-        }
-        if (getStabilityManager().isEntryReorderingAllowed(entry)) {
-            // let the stability manager constrain or allow reordering
-            return -1;
-        }
-        // NOTE(b/241229236): Can't use cleared section index until we fix stability fragility
-        return entry.getPreviousAttachState().getStableIndex();
-    }
-
     @Nullable
     private Integer getStableOrderRank(ListEntry entry) {
         if (getStabilityManager().isEntryReorderingAllowed(entry)) {
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 76252d0..e996b78 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
@@ -114,10 +114,10 @@
             .onStart { emit(Unit) }
             // for each change, lookup the new value
             .map {
-                secureSettings.getBoolForUser(
+                secureSettings.getIntForUser(
                     Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS,
                     UserHandle.USER_CURRENT,
-                )
+                ) == 1
             }
             // perform lookups on the bg thread pool
             .flowOn(bgDispatcher)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java
index 7136cad..bc881ce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java
@@ -31,6 +31,10 @@
      */
     enum FullScreenIntentDecision {
         /**
+         * Full screen intents are disabled.
+         */
+        NO_FSI_DISABLED(false),
+        /**
          * No full screen intent included, so there is nothing to show.
          */
         NO_FULL_SCREEN_INTENT(false),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
index d9dacfd..9bcf92d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
@@ -28,7 +28,6 @@
 import android.os.Handler;
 import android.os.PowerManager;
 import android.os.RemoteException;
-import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.dreams.IDreamManager;
 import android.service.notification.StatusBarNotification;
@@ -40,6 +39,7 @@
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.NotifPipelineFlags;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -74,6 +74,7 @@
     private final NotifPipelineFlags mFlags;
     private final KeyguardNotificationVisibilityProvider mKeyguardNotificationVisibilityProvider;
     private final UiEventLogger mUiEventLogger;
+    private final UserTracker mUserTracker;
 
     @VisibleForTesting
     protected boolean mUseHeadsUp = false;
@@ -114,7 +115,8 @@
             @Main Handler mainHandler,
             NotifPipelineFlags flags,
             KeyguardNotificationVisibilityProvider keyguardNotificationVisibilityProvider,
-            UiEventLogger uiEventLogger) {
+            UiEventLogger uiEventLogger,
+            UserTracker userTracker) {
         mContentResolver = contentResolver;
         mPowerManager = powerManager;
         mDreamManager = dreamManager;
@@ -127,6 +129,7 @@
         mFlags = flags;
         mKeyguardNotificationVisibilityProvider = keyguardNotificationVisibilityProvider;
         mUiEventLogger = uiEventLogger;
+        mUserTracker = userTracker;
         ContentObserver headsUpObserver = new ContentObserver(mainHandler) {
             @Override
             public void onChange(boolean selfChange) {
@@ -236,6 +239,9 @@
 
     @Override
     public FullScreenIntentDecision getFullScreenIntentDecision(NotificationEntry entry) {
+        if (mFlags.disableFsi()) {
+            return FullScreenIntentDecision.NO_FSI_DISABLED;
+        }
         if (entry.getSbn().getNotification().fullScreenIntent == null) {
             return FullScreenIntentDecision.NO_FULL_SCREEN_INTENT;
         }
@@ -325,6 +331,9 @@
         final int uid = entry.getSbn().getUid();
         final String packageName = entry.getSbn().getPackageName();
         switch (decision) {
+            case NO_FSI_DISABLED:
+                mLogger.logNoFullscreen(entry, "Disabled");
+                return;
             case NO_FULL_SCREEN_INTENT:
                 return;
             case NO_FSI_SUPPRESSED_BY_DND:
@@ -450,7 +459,7 @@
      * @return true if the entry should ambient pulse, false otherwise
      */
     private boolean shouldHeadsUpWhenDozing(NotificationEntry entry, boolean log) {
-        if (!mAmbientDisplayConfiguration.pulseOnNotificationEnabled(UserHandle.USER_CURRENT)) {
+        if (!mAmbientDisplayConfiguration.pulseOnNotificationEnabled(mUserTracker.getUserId())) {
             if (log) mLogger.logNoPulsingSettingDisabled(entry);
             return false;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryDumper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryDumper.kt
index ffd931c..197ae1a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryDumper.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryDumper.kt
@@ -18,9 +18,12 @@
 package com.android.systemui.statusbar.notification.logging
 
 import android.stats.sysui.NotificationEnums
+import android.util.Log
 import com.android.systemui.Dumpable
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dump.DumpManager
+import com.android.systemui.dump.DumpsysTableLogger
+import com.android.systemui.dump.Row
 import com.android.systemui.statusbar.notification.collection.NotifPipeline
 import java.io.PrintWriter
 import javax.inject.Inject
@@ -33,6 +36,7 @@
 
     fun init() {
         dumpManager.registerNormalDumpable(javaClass.simpleName, this)
+        Log.i("NotificationMemory", "Registered dumpable.")
     }
 
     override fun dump(pw: PrintWriter, args: Array<out String>) {
@@ -45,27 +49,36 @@
 
     /** Renders a table of notification object usage into passed [PrintWriter]. */
     private fun dumpNotificationObjects(pw: PrintWriter, memoryUse: List<NotificationMemoryUsage>) {
-        pw.println("Notification Object Usage")
-        pw.println("-----------")
-        pw.println(
-            "Package".padEnd(35) +
-                "\t\tSmall\tLarge\t${"Style".padEnd(15)}\t\tStyle\tBig\tExtend.\tExtras\tCustom"
-        )
-        pw.println("".padEnd(35) + "\t\tIcon\tIcon\t${"".padEnd(15)}\t\tIcon\tPicture\t \t \tView")
-        pw.println()
-
-        memoryUse.forEach { use ->
-            pw.println(
-                use.packageName.padEnd(35) +
-                    "\t\t" +
-                    "${use.objectUsage.smallIcon}\t${use.objectUsage.largeIcon}\t" +
-                    (styleEnumToString(use.objectUsage.style).take(15) ?: "").padEnd(15) +
-                    "\t\t${use.objectUsage.styleIcon}\t" +
-                    "${use.objectUsage.bigPicture}\t${use.objectUsage.extender}\t" +
-                    "${use.objectUsage.extras}\t${use.objectUsage.hasCustomView}\t" +
-                    use.notificationKey
+        val columns =
+            listOf(
+                "Package",
+                "Small Icon",
+                "Large Icon",
+                "Style",
+                "Style Icon",
+                "Big Picture",
+                "Extender",
+                "Extras",
+                "Custom View",
+                "Key"
             )
-        }
+        val rows: List<Row> =
+            memoryUse.map {
+                listOf(
+                    it.packageName,
+                    toKb(it.objectUsage.smallIcon),
+                    toKb(it.objectUsage.largeIcon),
+                    styleEnumToString(it.objectUsage.style),
+                    toKb(it.objectUsage.styleIcon),
+                    toKb(it.objectUsage.bigPicture),
+                    toKb(it.objectUsage.extender),
+                    toKb(it.objectUsage.extras),
+                    it.objectUsage.hasCustomView.toString(),
+                    // | is a  field delimiter in the output format so we need to replace
+                    // it to avoid breakage.
+                    it.notificationKey.replace('|', '│')
+                )
+            }
 
         // Calculate totals for easily glanceable summary.
         data class Totals(
@@ -88,18 +101,23 @@
                 t
             }
 
-        pw.println()
-        pw.println("TOTALS")
-        pw.println(
-            "".padEnd(35) +
-                "\t\t" +
-                "${toKb(totals.smallIcon)}\t${toKb(totals.largeIcon)}\t" +
-                "".padEnd(15) +
-                "\t\t${toKb(totals.styleIcon)}\t" +
-                "${toKb(totals.bigPicture)}\t${toKb(totals.extender)}\t" +
-                toKb(totals.extras)
-        )
-        pw.println()
+        val totalsRow: List<Row> =
+            listOf(
+                listOf(
+                    "TOTALS",
+                    toKb(totals.smallIcon),
+                    toKb(totals.largeIcon),
+                    "",
+                    toKb(totals.styleIcon),
+                    toKb(totals.bigPicture),
+                    toKb(totals.extender),
+                    toKb(totals.extras),
+                    "",
+                    ""
+                )
+            )
+        val tableLogger = DumpsysTableLogger("Notification Object Usage", columns, rows + totalsRow)
+        tableLogger.printTableData(pw)
     }
 
     /** Renders a table of notification view usage into passed [PrintWriter] */
@@ -116,40 +134,65 @@
             var softwareBitmapsPenalty: Int = 0,
         )
 
-        val totals = Totals()
-        pw.println("Notification View Usage")
-        pw.println("-----------")
-        pw.println("View Type".padEnd(24) + "\tSmall\tLarge\tStyle\tCustom\tSoftware")
-        pw.println("".padEnd(24) + "\tIcon\tIcon\tUse\tView\tBitmaps")
-        pw.println()
-        memoryUse
-            .filter { it.viewUsage.isNotEmpty() }
-            .forEach { use ->
-                pw.println(use.packageName + " " + use.notificationKey)
-                use.viewUsage.forEach { view ->
-                    pw.println(
-                        "  ${view.viewType.toString().padEnd(24)}\t${view.smallIcon}" +
-                            "\t${view.largeIcon}\t${view.style}" +
-                            "\t${view.customViews}\t${view.softwareBitmapsPenalty}"
-                    )
-
-                    if (view.viewType == ViewType.TOTAL) {
-                        totals.smallIcon += view.smallIcon
-                        totals.largeIcon += view.largeIcon
-                        totals.style += view.style
-                        totals.customViews += view.customViews
-                        totals.softwareBitmapsPenalty += view.softwareBitmapsPenalty
+        val columns =
+            listOf(
+                "Package",
+                "View Type",
+                "Small Icon",
+                "Large Icon",
+                "Style Use",
+                "Custom View",
+                "Software Bitmaps",
+                "Key"
+            )
+        val rows =
+            memoryUse
+                .filter { it.viewUsage.isNotEmpty() }
+                .flatMap { use ->
+                    use.viewUsage.map { view ->
+                        listOf(
+                            use.packageName,
+                            view.viewType.toString(),
+                            toKb(view.smallIcon),
+                            toKb(view.largeIcon),
+                            toKb(view.style),
+                            toKb(view.customViews),
+                            toKb(view.softwareBitmapsPenalty),
+                            // | is a  field delimiter in the output format so we need to replace
+                            // it to avoid breakage.
+                            use.notificationKey.replace('|', '│')
+                        )
                     }
                 }
+
+        val totals = Totals()
+        memoryUse
+            .filter { it.viewUsage.isNotEmpty() }
+            .map { it.viewUsage.firstOrNull { view -> view.viewType == ViewType.TOTAL } }
+            .filterNotNull()
+            .forEach { view ->
+                totals.smallIcon += view.smallIcon
+                totals.largeIcon += view.largeIcon
+                totals.style += view.style
+                totals.customViews += view.customViews
+                totals.softwareBitmapsPenalty += view.softwareBitmapsPenalty
             }
-        pw.println()
-        pw.println("TOTALS")
-        pw.println(
-            "  ${"".padEnd(24)}\t${toKb(totals.smallIcon)}" +
-                "\t${toKb(totals.largeIcon)}\t${toKb(totals.style)}" +
-                "\t${toKb(totals.customViews)}\t${toKb(totals.softwareBitmapsPenalty)}"
-        )
-        pw.println()
+
+        val totalsRow: List<Row> =
+            listOf(
+                listOf(
+                    "TOTALS",
+                    "",
+                    toKb(totals.smallIcon),
+                    toKb(totals.largeIcon),
+                    toKb(totals.style),
+                    toKb(totals.customViews),
+                    toKb(totals.softwareBitmapsPenalty),
+                    ""
+                )
+            )
+        val tableLogger = DumpsysTableLogger("Notification View Usage", columns, rows + totalsRow)
+        tableLogger.printTableData(pw)
     }
 
     private fun styleEnumToString(styleEnum: Int): String =
@@ -168,6 +211,10 @@
         }
 
     private fun toKb(bytes: Int): String {
-        return (bytes / 1024).toString() + " KB"
+        if (bytes == 0) {
+            return "--"
+        }
+
+        return "%.2f KB".format(bytes / 1024f)
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index fbe88df..7addc8f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -24,6 +24,7 @@
 import android.graphics.Point;
 import android.util.AttributeSet;
 import android.util.MathUtils;
+import android.view.Choreographer;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.accessibility.AccessibilityManager;
@@ -492,12 +493,9 @@
         if (animationListener != null) {
             mAppearAnimator.addListener(animationListener);
         }
-        if (delay > 0) {
-            // we need to apply the initial state already to avoid drawn frames in the wrong state
-            updateAppearAnimationAlpha();
-            updateAppearRect();
-            mAppearAnimator.setStartDelay(delay);
-        }
+        // we need to apply the initial state already to avoid drawn frames in the wrong state
+        updateAppearAnimationAlpha();
+        updateAppearRect();
         mAppearAnimator.addListener(new AnimatorListenerAdapter() {
             private boolean mWasCancelled;
 
@@ -528,7 +526,20 @@
                 mWasCancelled = true;
             }
         });
-        mAppearAnimator.start();
+
+        // Cache the original animator so we can check if the animation should be started in the
+        // Choreographer callback. It's possible that the original animator (mAppearAnimator) is
+        // replaced with a new value before the callback is called.
+        ValueAnimator cachedAnimator = mAppearAnimator;
+        // Even when delay=0, starting the animation on the next frame is necessary to avoid jank.
+        // Not doing so will increase the chances our Animator will be forced to skip a value of
+        // the animation's progression, causing stutter.
+        Choreographer.getInstance().postFrameCallbackDelayed(
+                frameTimeNanos -> {
+                    if (mAppearAnimator == cachedAnimator) {
+                        mAppearAnimator.start();
+                    }
+                }, delay);
     }
 
     private int getCujType(boolean isAppearing) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java
index c496102..b084a76 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java
@@ -109,7 +109,7 @@
                 return true;
             }
             if (ev.getAction() == MotionEvent.ACTION_UP) {
-                mView.setLastActionUpTime(SystemClock.uptimeMillis());
+                mView.setLastActionUpTime(ev.getEventTime());
             }
             // With a11y, just do nothing.
             if (mAccessibilityManager.isTouchExplorationEnabled()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index c1173e4..9275e2b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -79,6 +79,8 @@
 import com.android.systemui.R;
 import com.android.systemui.animation.Interpolators;
 import com.android.systemui.classifier.FalsingCollector;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
@@ -177,6 +179,7 @@
     private PeopleNotificationIdentifier mPeopleNotificationIdentifier;
     private Optional<BubblesManager> mBubblesManagerOptional;
     private MetricsLogger mMetricsLogger;
+    private FeatureFlags mFeatureFlags;
     private int mIconTransformContentShift;
     private int mMaxHeadsUpHeightBeforeN;
     private int mMaxHeadsUpHeightBeforeP;
@@ -277,7 +280,7 @@
     private boolean mChildIsExpanding;
 
     private boolean mJustClicked;
-    private boolean mIconAnimationRunning;
+    private boolean mAnimationRunning;
     private boolean mShowNoBackground;
     private ExpandableNotificationRow mNotificationParent;
     private OnExpandClickListener mOnExpandClickListener;
@@ -451,10 +454,26 @@
         return mPublicLayout;
     }
 
-    public void setIconAnimationRunning(boolean running) {
-        for (NotificationContentView l : mLayouts) {
-            setIconAnimationRunning(running, l);
+    /**
+     * Sets animations running in the layouts of this row, including public, private, and children.
+     * @param running whether the animations should be started running or stopped.
+     */
+    public void setAnimationRunning(boolean running) {
+        // Sets animations running in the private/public layouts.
+        if (mFeatureFlags.isEnabled(Flags.NOTIFICATION_ANIMATE_BIG_PICTURE)) {
+            for (NotificationContentView l : mLayouts) {
+                if (l != null) {
+                    l.setContentAnimationRunning(running);
+                    setIconAnimationRunning(running, l);
+                }
+            }
+        } else {
+            for (NotificationContentView l : mLayouts) {
+                setIconAnimationRunning(running, l);
+            }
         }
+        // For groups summaries with children, we want to set the children containers
+        // animating as well.
         if (mIsSummaryWithChildren) {
             NotificationViewWrapper viewWrapper = mChildrenContainer.getNotificationViewWrapper();
             if (viewWrapper != null) {
@@ -468,12 +487,18 @@
                     mChildrenContainer.getAttachedChildren();
             for (int i = 0; i < notificationChildren.size(); i++) {
                 ExpandableNotificationRow child = notificationChildren.get(i);
-                child.setIconAnimationRunning(running);
+                child.setAnimationRunning(running);
             }
         }
-        mIconAnimationRunning = running;
+        mAnimationRunning = running;
     }
 
+    /**
+     * Starts or stops animations of the icons in all potential content views (regardless of
+     * whether they're contracted, expanded, etc).
+     *
+     * @param running whether to start or stop the icon's animation.
+     */
     private void setIconAnimationRunning(boolean running, NotificationContentView layout) {
         if (layout != null) {
             View contractedChild = layout.getContractedChild();
@@ -485,16 +510,29 @@
         }
     }
 
+    /**
+     * Starts or stops animations of the icon in the provided view's icon and right icon.
+     *
+     * @param running whether to start or stop the icon's animation.
+     * @param child   the view with the icon to start or stop.
+     */
     private void setIconAnimationRunningForChild(boolean running, View child) {
         if (child != null) {
             ImageView icon = child.findViewById(com.android.internal.R.id.icon);
-            setIconRunning(icon, running);
+            setImageViewAnimationRunning(icon, running);
             ImageView rightIcon = child.findViewById(com.android.internal.R.id.right_icon);
-            setIconRunning(rightIcon, running);
+            setImageViewAnimationRunning(rightIcon, running);
         }
     }
 
-    private void setIconRunning(ImageView imageView, boolean running) {
+    /**
+     * Starts or stops the animation of a provided image view if it's an AnimationDrawable or an
+     * AnimatedVectorDrawable.
+     *
+     * @param imageView the image view on which to start/stop animation.
+     * @param running   whether to start or stop the view's animation.
+     */
+    private void setImageViewAnimationRunning(ImageView imageView, boolean running) {
         if (imageView != null) {
             Drawable drawable = imageView.getDrawable();
             if (drawable instanceof AnimationDrawable) {
@@ -561,8 +599,8 @@
             mChildrenContainer.recreateNotificationHeader(mExpandClickListener, isConversation());
             mChildrenContainer.onNotificationUpdated();
         }
-        if (mIconAnimationRunning) {
-            setIconAnimationRunning(true);
+        if (mAnimationRunning) {
+            setAnimationRunning(true);
         }
         if (mLastChronometerRunning) {
             setChronometerRunning(true);
@@ -1038,7 +1076,7 @@
             notifyHeightChanged(false /* needsAnimation */);
         }
         if (pinned) {
-            setIconAnimationRunning(true);
+            setAnimationRunning(true);
             mExpandedWhenPinned = false;
         } else if (mExpandedWhenPinned) {
             setUserExpanded(true);
@@ -1627,6 +1665,11 @@
         );
     }
 
+    /**
+     * Constructs an ExpandableNotificationRow.
+     * @param context context passed to image resolver
+     * @param attrs attributes used to initialize parent view
+     */
     public ExpandableNotificationRow(Context context, AttributeSet attrs) {
         super(context, attrs);
         mImageResolver = new NotificationInlineImageResolver(context,
@@ -1662,7 +1705,8 @@
             NotificationGutsManager gutsManager,
             MetricsLogger metricsLogger,
             SmartReplyConstants smartReplyConstants,
-            SmartReplyController smartReplyController) {
+            SmartReplyController smartReplyController,
+            FeatureFlags featureFlags) {
         mEntry = entry;
         mAppName = appName;
         if (mMenuRow == null) {
@@ -1697,6 +1741,7 @@
         mBubblesManagerOptional = bubblesManagerOptional;
         mNotificationGutsManager = gutsManager;
         mMetricsLogger = metricsLogger;
+        mFeatureFlags = featureFlags;
     }
 
     private void initDimens() {
@@ -3487,7 +3532,8 @@
                 mChildrenContainer.requestRoundness(
                         /* top = */ getTopRoundness(),
                         /* bottom = */ getBottomRoundness(),
-                        FROM_PARENT);
+                        /* sourceType = */ FROM_PARENT,
+                        /* animate = */ false);
             } else {
                 mChildrenContainer.requestBottomRoundness(
                         getBottomRoundness(),
@@ -3587,11 +3633,13 @@
     @VisibleForTesting
     protected void setPrivateLayout(NotificationContentView privateLayout) {
         mPrivateLayout = privateLayout;
+        mLayouts = new NotificationContentView[]{mPrivateLayout, mPublicLayout};
     }
 
     @VisibleForTesting
     protected void setPublicLayout(NotificationContentView publicLayout) {
         mPublicLayout = publicLayout;
+        mLayouts = new NotificationContentView[]{mPrivateLayout, mPublicLayout};
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
index d113860..bb92dfc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
@@ -219,7 +219,8 @@
                 mNotificationGutsManager,
                 mMetricsLogger,
                 mSmartReplyConstants,
-                mSmartReplyController
+                mSmartReplyController,
+                mFeatureFlags
         );
         mView.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
         if (mAllowLongPress) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
index 49dc655..21f4cb5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
@@ -16,15 +16,22 @@
 
 package com.android.systemui.statusbar.notification.row;
 
+import android.annotation.ColorInt;
+import android.annotation.DrawableRes;
+import android.annotation.StringRes;
 import android.content.Context;
+import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.IndentingPrintWriter;
 import android.view.View;
+import android.widget.TextView;
 
 import androidx.annotation.NonNull;
 
+import com.android.settingslib.Utils;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
 import com.android.systemui.statusbar.notification.stack.ViewState;
@@ -41,6 +48,11 @@
     private String mManageNotificationText;
     private String mManageNotificationHistoryText;
 
+    // Footer label
+    private TextView mSeenNotifsFooterTextView;
+    private @StringRes int mSeenNotifsFilteredText;
+    private int mUnlockIconSize;
+
     public FooterView(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
@@ -73,10 +85,41 @@
         super.onFinishInflate();
         mClearAllButton = (FooterViewButton) findSecondaryView();
         mManageButton = findViewById(R.id.manage_text);
+        mSeenNotifsFooterTextView = findViewById(R.id.unlock_prompt_footer);
         updateResources();
         updateText();
     }
 
+    public void setFooterLabelTextAndIcon(@StringRes int text, @DrawableRes int icon) {
+        mSeenNotifsFilteredText = text;
+        if (mSeenNotifsFilteredText != 0) {
+            mSeenNotifsFooterTextView.setText(mSeenNotifsFilteredText);
+        } else {
+            mSeenNotifsFooterTextView.setText(null);
+        }
+        Drawable drawable;
+        if (icon == 0) {
+            drawable = null;
+        } else {
+            drawable = getResources().getDrawable(icon);
+            drawable.setBounds(0, 0, mUnlockIconSize, mUnlockIconSize);
+        }
+        mSeenNotifsFooterTextView.setCompoundDrawablesRelative(drawable, null, null, null);
+        updateFooterVisibilityMode();
+    }
+
+    private void updateFooterVisibilityMode() {
+        if (mSeenNotifsFilteredText != 0) {
+            mManageButton.setVisibility(View.GONE);
+            mClearAllButton.setVisibility(View.GONE);
+            mSeenNotifsFooterTextView.setVisibility(View.VISIBLE);
+        } else {
+            mManageButton.setVisibility(View.VISIBLE);
+            mClearAllButton.setVisibility(View.VISIBLE);
+            mSeenNotifsFooterTextView.setVisibility(View.GONE);
+        }
+    }
+
     public void setManageButtonClickListener(OnClickListener listener) {
         mManageButton.setOnClickListener(listener);
     }
@@ -135,12 +178,19 @@
         mClearAllButton.setTextColor(textColor);
         mManageButton.setBackground(theme.getDrawable(R.drawable.notif_footer_btn_background));
         mManageButton.setTextColor(textColor);
+        final @ColorInt int labelTextColor =
+                Utils.getColorAttrDefaultColor(mContext, android.R.attr.textColorPrimary);
+        mSeenNotifsFooterTextView.setTextColor(labelTextColor);
+        mSeenNotifsFooterTextView.setCompoundDrawableTintList(
+                ColorStateList.valueOf(labelTextColor));
     }
 
     private void updateResources() {
         mManageNotificationText = getContext().getString(R.string.manage_notifications_text);
         mManageNotificationHistoryText = getContext()
                 .getString(R.string.manage_notifications_history_text);
+        mUnlockIconSize = getResources()
+                .getDimensionPixelSize(R.dimen.notifications_unseen_footer_icon_size);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index e46bf52..4a023c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -184,6 +184,8 @@
     private boolean mRemoteInputVisible;
     private int mUnrestrictedContentHeight;
 
+    private boolean mContentAnimating;
+
     public NotificationContentView(Context context, AttributeSet attrs) {
         super(context, attrs);
         mHybridGroupManager = new HybridGroupManager(getContext());
@@ -2129,8 +2131,49 @@
         return false;
     }
 
+    /**
+     * Starts and stops animations in the underlying views.
+     * Avoids restarting the animations by checking whether they're already running first.
+     * Return value is used for testing.
+     *
+     * @param running whether to start animations running, or stop them.
+     * @return true if the state of animations changed.
+     */
+    public boolean setContentAnimationRunning(boolean running) {
+        boolean stateChangeRequired = (running != mContentAnimating);
+        if (stateChangeRequired) {
+            // Starts or stops the animations in the potential views.
+            if (mContractedWrapper != null) {
+                mContractedWrapper.setAnimationsRunning(running);
+            }
+            if (mExpandedWrapper != null) {
+                mExpandedWrapper.setAnimationsRunning(running);
+            }
+            if (mHeadsUpWrapper != null) {
+                mHeadsUpWrapper.setAnimationsRunning(running);
+            }
+            // Updates the state tracker.
+            mContentAnimating = running;
+            return true;
+        }
+        return false;
+    }
+
     private static class RemoteInputViewData {
         @Nullable RemoteInputView mView;
         @Nullable RemoteInputViewController mController;
     }
+
+    @VisibleForTesting
+    protected void setContractedWrapper(NotificationViewWrapper contractedWrapper) {
+        mContractedWrapper = contractedWrapper;
+    }
+    @VisibleForTesting
+    protected void setExpandedWrapper(NotificationViewWrapper expandedWrapper) {
+        mExpandedWrapper = expandedWrapper;
+    }
+    @VisibleForTesting
+    protected void setHeadsUpWrapper(NotificationViewWrapper headsUpWrapper) {
+        mHeadsUpWrapper = headsUpWrapper;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java
index 8732696..175ba15 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java
@@ -18,11 +18,15 @@
 
 import android.app.Notification;
 import android.content.Context;
+import android.graphics.drawable.AnimatedImageDrawable;
+import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
 import android.os.Bundle;
 import android.service.notification.StatusBarNotification;
 import android.view.View;
 
+import com.android.internal.R;
+import com.android.internal.widget.BigPictureNotificationImageView;
 import com.android.systemui.statusbar.notification.ImageTransformState;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 
@@ -31,6 +35,8 @@
  */
 public class NotificationBigPictureTemplateViewWrapper extends NotificationTemplateViewWrapper {
 
+    private BigPictureNotificationImageView mImageView;
+
     protected NotificationBigPictureTemplateViewWrapper(Context ctx, View view,
             ExpandableNotificationRow row) {
         super(ctx, view, row);
@@ -39,9 +45,14 @@
     @Override
     public void onContentUpdated(ExpandableNotificationRow row) {
         super.onContentUpdated(row);
+        resolveViews();
         updateImageTag(row.getEntry().getSbn());
     }
 
+    private void resolveViews() {
+        mImageView = mView.findViewById(R.id.big_picture);
+    }
+
     private void updateImageTag(StatusBarNotification sbn) {
         final Bundle extras = sbn.getNotification().extras;
         Icon bigLargeIcon = extras.getParcelable(Notification.EXTRA_LARGE_ICON_BIG, Icon.class);
@@ -54,4 +65,25 @@
             mRightIcon.setTag(ImageTransformState.ICON_TAG, getLargeIcon(sbn.getNotification()));
         }
     }
+
+    /**
+     * Starts or stops the animations in any drawables contained in this BigPicture Notification.
+     *
+     * @param running Whether the animations should be set to run.
+     */
+    @Override
+    public void setAnimationsRunning(boolean running) {
+        if (mImageView == null) {
+            return;
+        }
+        Drawable d = mImageView.getDrawable();
+        if (d instanceof AnimatedImageDrawable) {
+            AnimatedImageDrawable animatedImageDrawable = (AnimatedImageDrawable) d;
+            if (running) {
+                animatedImageDrawable.start();
+            } else {
+                animatedImageDrawable.stop();
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
index e136055..10753f2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
@@ -17,16 +17,20 @@
 package com.android.systemui.statusbar.notification.row.wrapper
 
 import android.content.Context
+import android.graphics.drawable.AnimatedImageDrawable
 import android.view.View
 import android.view.ViewGroup
 import com.android.internal.widget.CachingIconView
 import com.android.internal.widget.ConversationLayout
+import com.android.internal.widget.MessagingGroup
+import com.android.internal.widget.MessagingImageMessage
 import com.android.internal.widget.MessagingLinearLayout
 import com.android.systemui.R
 import com.android.systemui.statusbar.notification.NotificationFadeAware
 import com.android.systemui.statusbar.notification.NotificationUtils
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.row.wrapper.NotificationMessagingTemplateViewWrapper.setCustomImageMessageTransform
+import com.android.systemui.util.children
 
 /**
  * Wraps a notification containing a conversation template
@@ -49,6 +53,7 @@
     private lateinit var expandBtn: View
     private lateinit var expandBtnContainer: View
     private lateinit var imageMessageContainer: ViewGroup
+    private lateinit var messageContainers: ArrayList<MessagingGroup>
     private lateinit var messagingLinearLayout: MessagingLinearLayout
     private lateinit var conversationTitleView: View
     private lateinit var importanceRing: View
@@ -60,6 +65,7 @@
     private fun resolveViews() {
         messagingLinearLayout = conversationLayout.messagingLinearLayout
         imageMessageContainer = conversationLayout.imageMessageContainer
+        messageContainers = conversationLayout.messagingGroups
         with(conversationLayout) {
             conversationIconContainer =
                     requireViewById(com.android.internal.R.id.conversation_icon_container)
@@ -146,4 +152,26 @@
         NotificationFadeAware.setLayerTypeForFaded(expandBtn, faded)
         NotificationFadeAware.setLayerTypeForFaded(conversationIconContainer, faded)
     }
+
+    // Starts or stops the animations in any drawables contained in this Conversation Notification.
+    override fun setAnimationsRunning(running: Boolean) {
+        // We apply to both the child message containers in a conversation group,
+        // and the top level image message container.
+        val containers = messageContainers.asSequence().map { it.messageContainer } +
+                sequenceOf(imageMessageContainer)
+        val drawables =
+                containers
+                        .flatMap { it.children }
+                        .mapNotNull { child ->
+                            (child as? MessagingImageMessage)?.let { imageMessage ->
+                                imageMessage.drawable as? AnimatedImageDrawable
+                            }
+                        }
+        drawables.toSet().forEach {
+            when {
+                running -> it.start()
+                !running -> it.stop()
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMessagingTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMessagingTemplateViewWrapper.java
index c587ce0..4592fde 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMessagingTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMessagingTemplateViewWrapper.java
@@ -17,9 +17,13 @@
 package com.android.systemui.statusbar.notification.row.wrapper;
 
 import android.content.Context;
+import android.graphics.drawable.AnimatedImageDrawable;
+import android.graphics.drawable.Drawable;
 import android.view.View;
 import android.view.ViewGroup;
 
+import com.android.internal.widget.MessagingGroup;
+import com.android.internal.widget.MessagingImageMessage;
 import com.android.internal.widget.MessagingLayout;
 import com.android.internal.widget.MessagingLinearLayout;
 import com.android.systemui.R;
@@ -127,4 +131,40 @@
         }
         return super.getMinLayoutHeight();
     }
+
+    /**
+     * Starts or stops the animations in any drawables contained in this Messaging Notification.
+     *
+     * @param running Whether the animations should be set to run.
+     */
+    @Override
+    public void setAnimationsRunning(boolean running) {
+        if (mMessagingLayout == null) {
+            return;
+        }
+
+        for (MessagingGroup group : mMessagingLayout.getMessagingGroups()) {
+            for (int i = 0; i < group.getMessageContainer().getChildCount(); i++) {
+                View view = group.getMessageContainer().getChildAt(i);
+                // We only need to set animations in MessagingImageMessages.
+                if (!(view instanceof MessagingImageMessage)) {
+                    continue;
+                }
+                MessagingImageMessage imageMessage =
+                        (com.android.internal.widget.MessagingImageMessage) view;
+
+                // If the drawable isn't an AnimatedImageDrawable, we can't set it to animate.
+                Drawable d = imageMessage.getDrawable();
+                if (!(d instanceof AnimatedImageDrawable)) {
+                    continue;
+                }
+                AnimatedImageDrawable animatedImageDrawable = (AnimatedImageDrawable) d;
+                if (running) {
+                    animatedImageDrawable.start();
+                } else {
+                    animatedImageDrawable.stop();
+                }
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
index 1c22f09..ff5b9cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
@@ -403,4 +403,12 @@
         NotificationFadeAware.setLayerTypeForFaded(getIcon(), faded);
         NotificationFadeAware.setLayerTypeForFaded(getExpandButton(), faded);
     }
+
+    /**
+     * Starts or stops the animations in any drawables contained in this Notification.
+     *
+     * @param running Whether the animations should be set to run.
+     */
+    public void setAnimationsRunning(boolean running) {
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index 4d1451e..9b93d7b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -367,7 +367,7 @@
         }
 
         if (mUseRoundnessSourceTypes) {
-            row.requestRoundnessReset(FROM_PARENT);
+            row.requestRoundnessReset(FROM_PARENT, /* animate = */ false);
             applyRoundnessAndInvalidate();
         }
     }
@@ -1431,6 +1431,22 @@
     @Override
     public void applyRoundnessAndInvalidate() {
         boolean last = true;
+        if (mUseRoundnessSourceTypes) {
+            if (mNotificationHeaderWrapper != null) {
+                mNotificationHeaderWrapper.requestTopRoundness(
+                        /* value = */ getTopRoundness(),
+                        /* sourceType = */ FROM_PARENT,
+                        /* animate = */ false
+                );
+            }
+            if (mNotificationHeaderWrapperLowPriority != null) {
+                mNotificationHeaderWrapperLowPriority.requestTopRoundness(
+                        /* value = */ getTopRoundness(),
+                        /* sourceType = */ FROM_PARENT,
+                        /* animate = */ false
+                );
+            }
+        }
         for (int i = mAttachedChildren.size() - 1; i >= 0; i--) {
             ExpandableNotificationRow child = mAttachedChildren.get(i);
             if (child.getVisibility() == View.GONE) {
@@ -1440,7 +1456,8 @@
                 child.requestRoundness(
                         /* top = */ 0f,
                         /* bottom = */ last ? getBottomRoundness() : 0f,
-                        FROM_PARENT);
+                        /* sourceType = */ FROM_PARENT,
+                        /* animate = */ false);
             } else {
                 child.requestRoundness(
                         /* top = */ 0f,
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 ca1e397..aab36da 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
@@ -538,6 +538,7 @@
     private NotificationStackScrollLayoutController.TouchHandler mTouchHandler;
     private final ScreenOffAnimationController mScreenOffAnimationController;
     private boolean mShouldUseSplitNotificationShade;
+    private boolean mHasFilteredOutSeenNotifications;
 
     private final ExpandableView.OnHeightChangedListener mOnChildHeightChangedListener =
             new ExpandableView.OnHeightChangedListener() {
@@ -684,6 +685,10 @@
         updateFooter();
     }
 
+    void setHasFilteredOutSeenNotifications(boolean hasFilteredOutSeenNotifications) {
+        mHasFilteredOutSeenNotifications = hasFilteredOutSeenNotifications;
+    }
+
     @VisibleForTesting
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void updateFooter() {
@@ -1811,9 +1816,7 @@
     @Override
     @ShadeViewRefactor(RefactorComponent.COORDINATOR)
     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
-        mBottomInset = insets.getSystemWindowInsetBottom()
-                + insets.getInsets(WindowInsets.Type.ime()).bottom;
-
+        mBottomInset = insets.getInsets(WindowInsets.Type.ime()).bottom;
         mWaterfallTopInset = 0;
         final DisplayCutout cutout = insets.getDisplayCutout();
         if (cutout != null) {
@@ -2262,7 +2265,11 @@
 
     @ShadeViewRefactor(RefactorComponent.COORDINATOR)
     private int getImeInset() {
-        return Math.max(0, mBottomInset - (getRootView().getHeight() - getHeight()));
+        // The NotificationStackScrollLayout does not extend all the way to the bottom of the
+        // display. Therefore, subtract that space from the mBottomInset, in order to only include
+        // the portion of the bottom inset that actually overlaps the NotificationStackScrollLayout.
+        return Math.max(0, mBottomInset
+                - (getRootView().getHeight() - getHeight() - getLocationOnScreen()[1]));
     }
 
     /**
@@ -2970,12 +2977,19 @@
             childInGroup = (ExpandableNotificationRow) requestedView;
             requestedView = requestedRow = childInGroup.getNotificationParent();
         }
-        int position = 0;
+        final float scrimTopPadding = mAmbientState.isOnKeyguard() ? 0 : mMinimumPaddings;
+        int position = (int) scrimTopPadding;
+        int visibleIndex = -1;
+        ExpandableView lastVisibleChild = null;
         for (int i = 0; i < getChildCount(); i++) {
             ExpandableView child = getChildAtIndex(i);
             boolean notGone = child.getVisibility() != View.GONE;
+            if (notGone) visibleIndex++;
             if (notGone && !child.hasNoContentHeight()) {
-                if (position != 0) {
+                if (position != scrimTopPadding) {
+                    if (lastVisibleChild != null) {
+                        position += calculateGapHeight(lastVisibleChild, child, visibleIndex);
+                    }
                     position += mPaddingBetweenElements;
                 }
             }
@@ -2987,6 +3001,7 @@
             }
             if (notGone) {
                 position += getIntrinsicHeight(child);
+                lastVisibleChild = child;
             }
         }
         return 0;
@@ -3122,7 +3137,7 @@
     private void updateAnimationState(boolean running, View child) {
         if (child instanceof ExpandableNotificationRow) {
             ExpandableNotificationRow row = (ExpandableNotificationRow) child;
-            row.setIconAnimationRunning(running);
+            row.setAnimationRunning(running);
         }
     }
 
@@ -4602,13 +4617,12 @@
     }
 
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-    void updateEmptyShadeView(
-            boolean visible, boolean areNotificationsHiddenInShade, boolean areSeenNotifsFiltered) {
+    void updateEmptyShadeView(boolean visible, boolean areNotificationsHiddenInShade) {
         mEmptyShadeView.setVisible(visible, mIsExpanded && mAnimationsEnabled);
 
         if (areNotificationsHiddenInShade) {
             updateEmptyShadeView(R.string.dnd_suppressing_shade_text, 0, 0);
-        } else if (areSeenNotifsFiltered) {
+        } else if (mHasFilteredOutSeenNotifications) {
             updateEmptyShadeView(
                     R.string.no_unseen_notif_text,
                     R.string.unlock_to_see_notif_text,
@@ -4647,13 +4661,20 @@
 
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void updateFooterView(boolean visible, boolean showDismissView, boolean showHistory) {
-        if (mFooterView == null) {
+        if (mFooterView == null || mNotificationStackSizeCalculator == null) {
             return;
         }
         boolean animate = mIsExpanded && mAnimationsEnabled;
         mFooterView.setVisible(visible, animate);
         mFooterView.setSecondaryVisible(showDismissView, animate);
         mFooterView.showHistory(showHistory);
+        if (mHasFilteredOutSeenNotifications) {
+            mFooterView.setFooterLabelTextAndIcon(
+                    R.string.unlock_to_see_notif_text,
+                    R.drawable.ic_friction_lock_closed);
+        } else {
+            mFooterView.setFooterLabelTextAndIcon(0, 0);
+        }
     }
 
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index c2c38a7..42d122d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -120,6 +120,7 @@
 import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.util.Compile;
+import com.android.systemui.util.settings.SecureSettings;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -189,6 +190,7 @@
     private final FeatureFlags mFeatureFlags;
     private final boolean mUseRoundnessSourceTypes;
     private final NotificationTargetsHelper mNotificationTargetsHelper;
+    private final SecureSettings mSecureSettings;
 
     private View mLongPressedView;
 
@@ -667,7 +669,8 @@
             NotificationStackScrollLogger logger,
             NotificationStackSizeCalculator notificationStackSizeCalculator,
             FeatureFlags featureFlags,
-            NotificationTargetsHelper notificationTargetsHelper) {
+            NotificationTargetsHelper notificationTargetsHelper,
+            SecureSettings secureSettings) {
         mStackStateLogger = stackLogger;
         mLogger = logger;
         mAllowLongPress = allowLongPress;
@@ -709,6 +712,7 @@
         mFeatureFlags = featureFlags;
         mUseRoundnessSourceTypes = featureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES);
         mNotificationTargetsHelper = notificationTargetsHelper;
+        mSecureSettings = secureSettings;
         updateResources();
     }
 
@@ -1015,8 +1019,7 @@
                 Log.wtf(TAG, "isHistoryEnabled failed to initialize its value");
                 return false;
             }
-            mHistoryEnabled = historyEnabled = Settings.Secure.getIntForUser(
-                    mView.getContext().getContentResolver(),
+            mHistoryEnabled = historyEnabled = mSecureSettings.getIntForUser(
                     Settings.Secure.NOTIFICATION_HISTORY_ENABLED,
                     0,
                     UserHandle.USER_CURRENT) == 1;
@@ -1242,11 +1245,7 @@
                 // For more details, see: b/228790482
                 && !isInTransitionToKeyguard();
 
-        mView.updateEmptyShadeView(
-                shouldShow,
-                mZenModeController.areNotificationsHiddenInShade(),
-                mNotifPipelineFlags.getShouldFilterUnseenNotifsOnKeyguard()
-                        && mSeenNotificationsProvider.getHasFilteredOutSeenNotifications());
+        mView.updateEmptyShadeView(shouldShow, mZenModeController.areNotificationsHiddenInShade());
 
         Trace.endSection();
     }
@@ -1902,8 +1901,10 @@
             }
             if (ev.getActionMasked() == MotionEvent.ACTION_UP) {
                 // Ensure the falsing manager records the touch. we don't do anything with it
-                // at the moment.
-                mFalsingManager.isFalseTouch(Classifier.SHADE_DRAG);
+                // at the moment, but it may trigger a global falsing event.
+                if (!horizontalSwipeWantsIt) {
+                    mFalsingManager.isFalseTouch(Classifier.SHADE_DRAG);
+                }
                 mView.setCheckForLeaveBehind(true);
             }
             traceJankOnTouchEvent(ev.getActionMasked(), scrollerWantsIt);
@@ -1940,6 +1941,9 @@
         @Override
         public void setNotifStats(@NonNull NotifStats notifStats) {
             mNotifStats = notifStats;
+            mView.setHasFilteredOutSeenNotifications(
+                    mNotifPipelineFlags.getShouldFilterUnseenNotifsOnKeyguard()
+                            && mSeenNotificationsProvider.getHasFilteredOutSeenNotifications());
             updateFooter();
             updateShowEmptyShadeView();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java
index 3ccef9d..eb81c46 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java
@@ -16,25 +16,35 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static android.view.accessibility.AccessibilityManager.FLAG_CONTENT_CONTROLS;
+
 import android.content.Context;
 import android.os.Handler;
 import android.os.RemoteException;
 import android.util.Log;
 import android.view.IWindowManager;
 import android.view.MotionEvent;
+import android.view.accessibility.AccessibilityManager;
+
+import androidx.annotation.NonNull;
 
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.dump.DumpManager;
 import com.android.systemui.statusbar.AutoHideUiElement;
 
+import java.io.PrintWriter;
+
 import javax.inject.Inject;
 
 /** A controller to control all auto-hide things. Also see {@link AutoHideUiElement}. */
 @SysUISingleton
 public class AutoHideController {
     private static final String TAG = "AutoHideController";
-    private static final long AUTO_HIDE_TIMEOUT_MS = 2250;
+    private static final int AUTO_HIDE_TIMEOUT_MS = 2250;
+    private static final int USER_AUTO_HIDE_TIMEOUT_MS = 350;
 
+    private final AccessibilityManager mAccessibilityManager;
     private final IWindowManager mWindowManagerService;
     private final Handler mHandler;
 
@@ -52,11 +62,12 @@
     };
 
     @Inject
-    public AutoHideController(Context context, @Main Handler handler,
+    public AutoHideController(Context context,
+            @Main Handler handler,
             IWindowManager iWindowManager) {
+        mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
         mHandler = handler;
         mWindowManagerService = iWindowManager;
-
         mDisplayId = context.getDisplayId();
     }
 
@@ -138,7 +149,12 @@
 
     private void scheduleAutoHide() {
         cancelAutoHide();
-        mHandler.postDelayed(mAutoHide, AUTO_HIDE_TIMEOUT_MS);
+        mHandler.postDelayed(mAutoHide, getAutoHideTimeout());
+    }
+
+    private int getAutoHideTimeout() {
+        return mAccessibilityManager.getRecommendedTimeoutMillis(AUTO_HIDE_TIMEOUT_MS,
+                FLAG_CONTENT_CONTROLS);
     }
 
     public void checkUserAutoHide(MotionEvent event) {
@@ -160,7 +176,13 @@
 
     private void userAutoHide() {
         cancelAutoHide();
-        mHandler.postDelayed(mAutoHide, 350); // longer than app gesture -> flag clear
+        // longer than app gesture -> flag clear
+        mHandler.postDelayed(mAutoHide, getUserAutoHideTimeout());
+    }
+
+    private int getUserAutoHideTimeout() {
+        return mAccessibilityManager.getRecommendedTimeoutMillis(USER_AUTO_HIDE_TIMEOUT_MS,
+                FLAG_CONTENT_CONTROLS);
     }
 
     private boolean isAnyTransientBarShown() {
@@ -175,6 +197,15 @@
         return false;
     }
 
+    public void dump(@NonNull PrintWriter pw) {
+        pw.println("AutoHideController:");
+        pw.println("\tmAutoHideSuspended=" + mAutoHideSuspended);
+        pw.println("\tisAnyTransientBarShown=" + isAnyTransientBarShown());
+        pw.println("\thasPendingAutoHide=" + mHandler.hasCallbacks(mAutoHide));
+        pw.println("\tgetAutoHideTimeout=" + getAutoHideTimeout());
+        pw.println("\tgetUserAutoHideTimeout=" + getUserAutoHideTimeout());
+    }
+
     /**
      * Injectable factory for creating a {@link AutoHideController}.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
index 9070ead..149ec54 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -154,9 +154,7 @@
         if (!mAutoTracker.isAdded(SAVER)) {
             mDataSaverController.addCallback(mDataSaverListener);
         }
-        if (!mAutoTracker.isAdded(WORK)) {
-            mManagedProfileController.addCallback(mProfileCallback);
-        }
+        mManagedProfileController.addCallback(mProfileCallback);
         if (!mAutoTracker.isAdded(NIGHT)
                 && ColorDisplayManager.isNightDisplayAvailable(mContext)) {
             mNightDisplayListener.setCallback(mNightDisplayCallback);
@@ -275,18 +273,18 @@
         return mCurrentUser.getIdentifier();
     }
 
-    public void unmarkTileAsAutoAdded(String tabSpec) {
-        mAutoTracker.setTileRemoved(tabSpec);
-    }
-
     private final ManagedProfileController.Callback mProfileCallback =
             new ManagedProfileController.Callback() {
                 @Override
                 public void onManagedProfileChanged() {
-                    if (mAutoTracker.isAdded(WORK)) return;
                     if (mManagedProfileController.hasActiveProfile()) {
+                        if (mAutoTracker.isAdded(WORK)) return;
                         mHost.addTile(WORK);
                         mAutoTracker.setTileAdded(WORK);
+                    } else {
+                        if (!mAutoTracker.isAdded(WORK)) return;
+                        mHost.removeTile(WORK);
+                        mAutoTracker.setTileRemoved(WORK);
                     }
                 }
 
@@ -429,7 +427,7 @@
                 initSafetyTile();
             } else if (!isSafetyCenterEnabled && mAutoTracker.isAdded(mSafetySpec)) {
                 mHost.removeTile(mSafetySpec);
-                mHost.unmarkTileAsAutoAdded(mSafetySpec);
+                mAutoTracker.setTileRemoved(mSafetySpec);
             }
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index 895a293..db2c0a0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -18,6 +18,8 @@
 
 import static android.app.StatusBarManager.SESSION_KEYGUARD;
 
+import static com.android.systemui.keyguard.WakefulnessLifecycle.UNKNOWN_LAST_WAKE_TIME;
+
 import android.annotation.IntDef;
 import android.content.res.Resources;
 import android.hardware.biometrics.BiometricFaceConstants;
@@ -27,7 +29,6 @@
 import android.metrics.LogMaker;
 import android.os.Handler;
 import android.os.PowerManager;
-import android.os.SystemClock;
 import android.os.Trace;
 
 import androidx.annotation.Nullable;
@@ -62,6 +63,7 @@
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.VibratorHelper;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.time.SystemClock;
 
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
@@ -78,6 +80,7 @@
  */
 @SysUISingleton
 public class BiometricUnlockController extends KeyguardUpdateMonitorCallback implements Dumpable {
+    private static final long RECENT_POWER_BUTTON_PRESS_THRESHOLD_MS = 400L;
     private static final long BIOMETRIC_WAKELOCK_TIMEOUT_MS = 15 * 1000;
     private static final String BIOMETRIC_WAKE_LOCK_NAME = "wake-and-unlock:wakelock";
     private static final UiEventLogger UI_EVENT_LOGGER = new UiEventLoggerImpl();
@@ -169,9 +172,11 @@
     private final MetricsLogger mMetricsLogger;
     private final AuthController mAuthController;
     private final StatusBarStateController mStatusBarStateController;
+    private final WakefulnessLifecycle mWakefulnessLifecycle;
     private final LatencyTracker mLatencyTracker;
     private final VibratorHelper mVibratorHelper;
     private final BiometricUnlockLogger mLogger;
+    private final SystemClock mSystemClock;
 
     private long mLastFpFailureUptimeMillis;
     private int mNumConsecutiveFpFailures;
@@ -279,14 +284,17 @@
             SessionTracker sessionTracker,
             LatencyTracker latencyTracker,
             ScreenOffAnimationController screenOffAnimationController,
-            VibratorHelper vibrator) {
+            VibratorHelper vibrator,
+            SystemClock systemClock
+    ) {
         mPowerManager = powerManager;
         mShadeController = shadeController;
         mUpdateMonitor = keyguardUpdateMonitor;
         mUpdateMonitor.registerCallback(this);
         mMediaManager = notificationMediaManager;
         mLatencyTracker = latencyTracker;
-        wakefulnessLifecycle.addObserver(mWakefulnessObserver);
+        mWakefulnessLifecycle = wakefulnessLifecycle;
+        mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
         screenLifecycle.addObserver(mScreenObserver);
 
         mNotificationShadeWindowController = notificationShadeWindowController;
@@ -306,6 +314,7 @@
         mScreenOffAnimationController = screenOffAnimationController;
         mVibratorHelper = vibrator;
         mLogger = biometricUnlockLogger;
+        mSystemClock = systemClock;
 
         dumpManager.registerDumpable(getClass().getName(), this);
     }
@@ -429,8 +438,11 @@
         Runnable wakeUp = ()-> {
             if (!wasDeviceInteractive || mUpdateMonitor.isDreaming()) {
                 mLogger.i("bio wakelock: Authenticated, waking up...");
-                mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_BIOMETRIC,
-                        "android.policy:BIOMETRIC");
+                mPowerManager.wakeUp(
+                        mSystemClock.uptimeMillis(),
+                        PowerManager.WAKE_REASON_BIOMETRIC,
+                        "android.policy:BIOMETRIC"
+                );
             }
             Trace.beginSection("release wake-and-unlock");
             releaseBiometricWakeLock();
@@ -670,7 +682,7 @@
             startWakeAndUnlock(MODE_ONLY_WAKE);
         } else if (biometricSourceType == BiometricSourceType.FINGERPRINT
                 && mUpdateMonitor.isUdfpsSupported()) {
-            long currUptimeMillis = SystemClock.uptimeMillis();
+            long currUptimeMillis = mSystemClock.uptimeMillis();
             if (currUptimeMillis - mLastFpFailureUptimeMillis < mConsecutiveFpFailureThreshold) {
                 mNumConsecutiveFpFailures += 1;
             } else {
@@ -718,12 +730,26 @@
         cleanup();
     }
 
-    //these haptics are for device-entry only
+    // these haptics are for device-entry only
     private void vibrateSuccess(BiometricSourceType type) {
+        if (mAuthController.isSfpsEnrolled(KeyguardUpdateMonitor.getCurrentUser())
+                && lastWakeupFromPowerButtonWithinHapticThreshold()) {
+            mLogger.d("Skip auth success haptic. Power button was recently pressed.");
+            return;
+        }
         mVibratorHelper.vibrateAuthSuccess(
                 getClass().getSimpleName() + ", type =" + type + "device-entry::success");
     }
 
+    private boolean lastWakeupFromPowerButtonWithinHapticThreshold() {
+        final boolean lastWakeupFromPowerButton = mWakefulnessLifecycle.getLastWakeReason()
+                == PowerManager.WAKE_REASON_POWER_BUTTON;
+        return lastWakeupFromPowerButton
+                && mWakefulnessLifecycle.getLastWakeTime() != UNKNOWN_LAST_WAKE_TIME
+                && mSystemClock.uptimeMillis() - mWakefulnessLifecycle.getLastWakeTime()
+                < RECENT_POWER_BUTTON_PRESS_THRESHOLD_MS;
+    }
+
     private void vibrateError(BiometricSourceType type) {
         mVibratorHelper.vibrateAuthError(
                 getClass().getSimpleName() + ", type =" + type + "device-entry::error");
@@ -816,7 +842,7 @@
         if (mUpdateMonitor.isUdfpsSupported()) {
             pw.print("   mNumConsecutiveFpFailures="); pw.println(mNumConsecutiveFpFailures);
             pw.print("   time since last failure=");
-            pw.println(SystemClock.uptimeMillis() - mLastFpFailureUptimeMillis);
+            pw.println(mSystemClock.uptimeMillis() - mLastFpFailureUptimeMillis);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
index 2dad8e0..ccde3c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
@@ -31,7 +31,6 @@
 import android.os.Bundle;
 import android.os.PowerManager;
 import android.os.SystemClock;
-import android.os.UserHandle;
 import android.os.VibrationAttributes;
 import android.os.VibrationEffect;
 import android.os.Vibrator;
@@ -55,6 +54,7 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.qs.QSPanelController;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shade.CameraLauncher;
 import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.shade.ShadeController;
@@ -99,6 +99,7 @@
     private final Optional<Vibrator> mVibratorOptional;
     private final DisableFlagsLogger mDisableFlagsLogger;
     private final int mDisplayId;
+    private final UserTracker mUserTracker;
     private final boolean mVibrateOnOpening;
     private final VibrationEffect mCameraLaunchGestureVibrationEffect;
     private final SystemBarAttributesListener mSystemBarAttributesListener;
@@ -133,7 +134,8 @@
             DisableFlagsLogger disableFlagsLogger,
             @DisplayId int displayId,
             SystemBarAttributesListener systemBarAttributesListener,
-            Lazy<CameraLauncher> cameraLauncherLazy) {
+            Lazy<CameraLauncher> cameraLauncherLazy,
+            UserTracker userTracker) {
         mCentralSurfaces = centralSurfaces;
         mContext = context;
         mShadeController = shadeController;
@@ -157,6 +159,7 @@
         mDisableFlagsLogger = disableFlagsLogger;
         mDisplayId = displayId;
         mCameraLauncherLazy = cameraLauncherLazy;
+        mUserTracker = userTracker;
 
         mVibrateOnOpening = resources.getBoolean(R.bool.config_vibrateOnIconAnimation);
         mCameraLaunchGestureVibrationEffect = getCameraGestureVibrationEffect(
@@ -215,7 +218,7 @@
             return;
         }
 
-        mNotificationPanelViewController.expandWithoutQs();
+        mNotificationPanelViewController.expandShadeToNotifications();
     }
 
     @Override
@@ -375,7 +378,7 @@
             mCentralSurfaces.startActivityDismissingKeyguard(cameraIntent,
                     false /* onlyProvisioned */, true /* dismissShade */,
                     true /* disallowEnterPictureInPictureWhileLaunching */, null /* callback */, 0,
-                    null /* animationController */, UserHandle.CURRENT);
+                    null /* animationController */, mUserTracker.getUserHandle());
         } else {
             if (!mCentralSurfaces.isDeviceInteractive()) {
                 // Avoid flickering of the scrim when we instant launch the camera and the bouncer
@@ -432,7 +435,7 @@
             mCentralSurfaces.startActivityDismissingKeyguard(emergencyIntent,
                     false /* onlyProvisioned */, true /* dismissShade */,
                     true /* disallowEnterPictureInPictureWhileLaunching */, null /* callback */, 0,
-                    null /* animationController */, UserHandle.CURRENT);
+                    null /* animationController */, mUserTracker.getUserHandle());
             return;
         }
 
@@ -447,7 +450,7 @@
             if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
                 mStatusBarKeyguardViewManager.reset(true /* hide */);
             }
-            mContext.startActivityAsUser(emergencyIntent, UserHandle.CURRENT);
+            mContext.startActivityAsUser(emergencyIntent, mUserTracker.getUserHandle());
             return;
         }
         // We need to defer the emergency action launch until the screen comes on, since otherwise
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 198572a..dd75d35 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -64,7 +64,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.res.Configuration;
@@ -162,6 +161,7 @@
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
 import com.android.systemui.keyguard.ui.binder.LightRevealScrimViewBinder;
 import com.android.systemui.keyguard.ui.viewmodel.LightRevealScrimViewModel;
 import com.android.systemui.navigationbar.NavigationBarController;
@@ -179,6 +179,7 @@
 import com.android.systemui.qs.QSPanelController;
 import com.android.systemui.recents.ScreenPinningRequest;
 import com.android.systemui.scrim.ScrimView;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.settings.brightness.BrightnessSliderController;
 import com.android.systemui.shade.CameraLauncher;
 import com.android.systemui.shade.NotificationPanelViewController;
@@ -291,26 +292,9 @@
 
     private static final UiEventLogger sUiEventLogger = new UiEventLoggerImpl();
 
-    /**
-     * If true, the system is in the half-boot-to-decryption-screen state.
-     * Prudently disable QS and notifications.
-     */
-    public static final boolean ONLY_CORE_APPS;
-
-    static {
-        boolean onlyCoreApps;
-        try {
-            IPackageManager packageManager =
-                    IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
-            onlyCoreApps = packageManager != null && packageManager.isOnlyCoreApps();
-        } catch (RemoteException e) {
-            onlyCoreApps = false;
-        }
-        ONLY_CORE_APPS = onlyCoreApps;
-    }
-
     private final Context mContext;
     private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
+    private final DeviceStateManager mDeviceStateManager;
     private CentralSurfacesCommandQueueCallbacks mCommandQueueCallbacks;
     private float mTransitionToFullShadeProgress = 0f;
     private NotificationListContainer mNotifListContainer;
@@ -485,6 +469,7 @@
     private final ShadeController mShadeController;
     private final InitController mInitController;
     private final Lazy<CameraLauncher> mCameraLauncherLazy;
+    private final AlternateBouncerInteractor mAlternateBouncerInteractor;
 
     private final PluginDependencyProvider mPluginDependencyProvider;
     private final KeyguardDismissUtil mKeyguardDismissUtil;
@@ -521,6 +506,7 @@
     private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
     private final MessageRouter mMessageRouter;
     private final WallpaperManager mWallpaperManager;
+    private final UserTracker mUserTracker;
 
     private CentralSurfacesComponent mCentralSurfacesComponent;
 
@@ -763,7 +749,10 @@
             WiredChargingRippleController wiredChargingRippleController,
             IDreamManager dreamManager,
             Lazy<CameraLauncher> cameraLauncherLazy,
-            Lazy<LightRevealScrimViewModel> lightRevealScrimViewModelLazy) {
+            Lazy<LightRevealScrimViewModel> lightRevealScrimViewModelLazy,
+            AlternateBouncerInteractor alternateBouncerInteractor,
+            UserTracker userTracker
+    ) {
         mContext = context;
         mNotificationsController = notificationsController;
         mFragmentService = fragmentService;
@@ -841,6 +830,8 @@
         mWallpaperManager = wallpaperManager;
         mJankMonitor = jankMonitor;
         mCameraLauncherLazy = cameraLauncherLazy;
+        mAlternateBouncerInteractor = alternateBouncerInteractor;
+        mUserTracker = userTracker;
 
         mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
         mStartingSurfaceOptional = startingSurfaceOptional;
@@ -874,11 +865,15 @@
         mMessageRouter.subscribeTo(MSG_LAUNCH_TRANSITION_TIMEOUT,
                 id -> onLaunchTransitionTimeout());
 
-        deviceStateManager.registerCallback(mMainExecutor,
-                new FoldStateListener(mContext, this::onFoldedStateChanged));
+        mDeviceStateManager = deviceStateManager;
         wiredChargingRippleController.registerCallbacks();
 
         mLightRevealScrimViewModelLazy = lightRevealScrimViewModelLazy;
+
+        // Based on teamfood flag, turn predictive back dispatch on at runtime.
+        if (mFeatureFlags.isEnabled(Flags.WM_ENABLE_PREDICTIVE_BACK_SYSUI)) {
+            mContext.getApplicationInfo().setEnableOnBackInvokedCallback(true);
+        }
     }
 
     @Override
@@ -993,11 +988,6 @@
         // Lastly, call to the icon policy to install/update all the icons.
         mIconPolicy.init();
 
-        // Based on teamfood flag, turn predictive back dispatch on at runtime.
-        if (mFeatureFlags.isEnabled(Flags.WM_ENABLE_PREDICTIVE_BACK_SYSUI)) {
-            mContext.getApplicationInfo().setEnableOnBackInvokedCallback(true);
-        }
-
         mKeyguardStateController.addCallback(new KeyguardStateController.Callback() {
             @Override
             public void onUnlockedChanged() {
@@ -1064,6 +1054,8 @@
             }
         });
 
+        registerCallbacks();
+
         mFalsingManager.addFalsingBeliefListener(mFalsingBeliefListener);
 
         mPluginManager.addPluginListener(
@@ -1119,6 +1111,14 @@
     }
 
     @VisibleForTesting
+    /** Registers listeners/callbacks with external dependencies. */
+    void registerCallbacks() {
+        //TODO(b/264502026) move the rest of the listeners here.
+        mDeviceStateManager.registerCallback(mMainExecutor,
+                new FoldStateListener(mContext, this::onFoldedStateChanged));
+    }
+
+    @VisibleForTesting
     void initShadeVisibilityListener() {
         mShadeController.setVisibilityListener(new ShadeController.ShadeVisibilityListener() {
             @Override
@@ -1399,6 +1399,7 @@
         // Things that mean we're not swiping to dismiss the keyguard, and should ignore this
         // expansion:
         // - Keyguard isn't even visible.
+        // - We're swiping on the bouncer, not the lockscreen.
         // - Keyguard is occluded. Expansion changes here are the shade being expanded over the
         //   occluding activity.
         // - Keyguard is visible, but can't be dismissed (swiping up will show PIN/password prompt).
@@ -1408,6 +1409,7 @@
         // - QS is expanded and we're swiping - swiping up now will hide QS, not dismiss the
         //   keyguard.
         if (!isKeyguardShowing()
+                || mStatusBarKeyguardViewManager.primaryBouncerIsOrWillBeShowing()
                 || isOccluded()
                 || !mKeyguardStateController.canDismissLockScreen()
                 || mKeyguardViewMediator.isAnySimPinSecure()
@@ -1687,8 +1689,7 @@
                         || !mUserSwitcherController.isSimpleUserSwitcher())
                 && !isShadeDisabled()
                 && ((mDisabled2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) == 0)
-                && !mDozing
-                && !ONLY_CORE_APPS;
+                && !mDozing;
         mNotificationPanelViewController.setQsExpansionEnabledPolicy(expandEnabled);
         Log.d(TAG, "updateQsExpansionEnabled - QS Expand enabled: " + expandEnabled);
     }
@@ -3257,8 +3258,7 @@
     private void showBouncerOrLockScreenIfKeyguard() {
         // If the keyguard is animating away, we aren't really the keyguard anymore and should not
         // show the bouncer/lockscreen.
-        if (!mKeyguardViewMediator.isHiding()
-                && !mKeyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()) {
+        if (!mKeyguardViewMediator.isHiding() && !mKeyguardUpdateMonitor.isKeyguardGoingAway()) {
             if (mState == StatusBarState.SHADE_LOCKED) {
                 // shade is showing while locked on the keyguard, so go back to showing the
                 // lock screen where users can use the UDFPS affordance to enter the device
@@ -3737,7 +3737,7 @@
         boolean launchingAffordanceWithPreview = mLaunchingAffordance;
         mScrimController.setLaunchingAffordanceWithPreview(launchingAffordanceWithPreview);
 
-        if (mStatusBarKeyguardViewManager.isShowingAlternateBouncer()) {
+        if (mAlternateBouncerInteractor.isVisibleState()) {
             if (mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED
                     || mTransitionToFullShadeProgress > 0f) {
                 mScrimController.transitionTo(ScrimState.AUTH_SCRIMMED_SHADE);
@@ -4158,7 +4158,7 @@
                 Log.wtf(TAG, "WallpaperManager not supported");
                 return;
             }
-            WallpaperInfo info = mWallpaperManager.getWallpaperInfo(UserHandle.USER_CURRENT);
+            WallpaperInfo info = mWallpaperManager.getWallpaperInfo(mUserTracker.getUserId());
             mWallpaperController.onWallpaperInfoUpdated(info);
 
             final boolean deviceSupportsAodWallpaper = mContext.getResources().getBoolean(
@@ -4262,8 +4262,7 @@
 
                 @Override
                 public void onDozeAmountChanged(float linear, float eased) {
-                    if (mFeatureFlags.isEnabled(Flags.LOCKSCREEN_ANIMATIONS)
-                            && !mFeatureFlags.isEnabled(Flags.LIGHT_REVEAL_MIGRATION)
+                    if (!mFeatureFlags.isEnabled(Flags.LIGHT_REVEAL_MIGRATION)
                             && !(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)) {
                         mLightRevealScrim.setRevealAmount(1f - linear);
                     }
@@ -4383,6 +4382,6 @@
                 return new UserHandle(UserHandle.myUserId());
             }
         }
-        return UserHandle.CURRENT;
+        return mUserTracker.getUserHandle();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index de7b152..c248a50 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -44,10 +44,10 @@
 import com.android.systemui.doze.AlwaysOnDisplayPolicy;
 import com.android.systemui.doze.DozeScreenState;
 import com.android.systemui.dump.DumpManager;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.DevicePostureController;
 import com.android.systemui.tuner.TunerService;
@@ -82,10 +82,10 @@
     private final AlwaysOnDisplayPolicy mAlwaysOnPolicy;
     private final Resources mResources;
     private final BatteryController mBatteryController;
-    private final FeatureFlags mFeatureFlags;
     private final ScreenOffAnimationController mScreenOffAnimationController;
     private final FoldAodAnimationController mFoldAodAnimationController;
     private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
+    private final UserTracker mUserTracker;
 
     private final Set<Callback> mCallbacks = new HashSet<>();
 
@@ -125,13 +125,13 @@
             BatteryController batteryController,
             TunerService tunerService,
             DumpManager dumpManager,
-            FeatureFlags featureFlags,
             ScreenOffAnimationController screenOffAnimationController,
             Optional<SysUIUnfoldComponent> sysUiUnfoldComponent,
             UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
             ConfigurationController configurationController,
-            StatusBarStateController statusBarStateController) {
+            StatusBarStateController statusBarStateController,
+            UserTracker userTracker) {
         mResources = resources;
         mAmbientDisplayConfiguration = ambientDisplayConfiguration;
         mAlwaysOnPolicy = alwaysOnDisplayPolicy;
@@ -141,9 +141,9 @@
         mControlScreenOffAnimation = !getDisplayNeedsBlanking();
         mPowerManager = powerManager;
         mPowerManager.setDozeAfterScreenOff(!mControlScreenOffAnimation);
-        mFeatureFlags = featureFlags;
         mScreenOffAnimationController = screenOffAnimationController;
         mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
+        mUserTracker = userTracker;
 
         keyguardUpdateMonitor.registerCallback(mKeyguardVisibilityCallback);
         tunerService.addTunable(
@@ -162,11 +162,18 @@
 
         SettingsObserver quickPickupSettingsObserver = new SettingsObserver(context, handler);
         quickPickupSettingsObserver.observe();
+
+        batteryController.addCallback(new BatteryStateChangeCallback() {
+                @Override
+                public void onPowerSaveChanged(boolean isPowerSave) {
+                    dispatchAlwaysOnEvent();
+                }
+            });
     }
 
     private void updateQuickPickupEnabled() {
         mIsQuickPickupEnabled =
-                mAmbientDisplayConfiguration.quickPickupSensorEnabled(UserHandle.USER_CURRENT);
+                mAmbientDisplayConfiguration.quickPickupSensorEnabled(mUserTracker.getUserId());
     }
 
     public boolean getDisplayStateSupported() {
@@ -300,13 +307,10 @@
 
     /**
      * Whether we're capable of controlling the screen off animation if we want to. This isn't
-     * possible if AOD isn't even enabled or if the flag is disabled, or if the display needs
-     * blanking.
+     * possible if AOD isn't even enabled or if the display needs blanking.
      */
     public boolean canControlUnlockedScreenOff() {
-        return getAlwaysOn()
-                && mFeatureFlags.isEnabled(Flags.LOCKSCREEN_ANIMATIONS)
-                && !getDisplayNeedsBlanking();
+        return getAlwaysOn() && !getDisplayNeedsBlanking();
     }
 
     /**
@@ -418,15 +422,13 @@
 
     @Override
     public void onTuningChanged(String key, String newValue) {
-        mDozeAlwaysOn = mAmbientDisplayConfiguration.alwaysOnEnabled(UserHandle.USER_CURRENT);
+        mDozeAlwaysOn = mAmbientDisplayConfiguration.alwaysOnEnabled(mUserTracker.getUserId());
 
         if (key.equals(Settings.Secure.DOZE_ALWAYS_ON)) {
             updateControlScreenOff();
         }
 
-        for (Callback callback : mCallbacks) {
-            callback.onAlwaysOnChange();
-        }
+        dispatchAlwaysOnEvent();
         mScreenOffAnimationController.onAlwaysOnChanged(getAlwaysOn());
     }
 
@@ -463,6 +465,12 @@
         pw.print("isQuickPickupEnabled(): "); pw.println(isQuickPickupEnabled());
     }
 
+    private void dispatchAlwaysOnEvent() {
+        for (Callback callback : mCallbacks) {
+            callback.onAlwaysOnChange();
+        }
+    }
+
     private boolean getPostureSpecificBool(
             int[] postureMapping,
             boolean defaultSensorBool,
@@ -477,7 +485,8 @@
         return bool;
     }
 
-    interface Callback {
+    /** Callbacks for doze parameter related information */
+    public interface Callback {
         /**
          * Invoked when the value of getAlwaysOn may have changed.
          */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index 000fe14..d318759 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -17,6 +17,8 @@
 package com.android.systemui.statusbar.phone;
 
 import static com.android.keyguard.KeyguardSecurityModel.SecurityMode;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_HIDDEN;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_VISIBLE;
 import static com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 
 import android.content.Context;
@@ -44,6 +46,8 @@
 import com.android.systemui.classifier.FalsingCollector;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
+import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor.KeyguardResetCallback;
+import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback;
 import com.android.systemui.shared.system.SysUiStatsLog;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.ListenerSet;
@@ -64,14 +68,6 @@
     private static final String TAG = "PrimaryKeyguardBouncer";
     static final long BOUNCER_FACE_DELAY = 1200;
     public static final float ALPHA_EXPANSION_THRESHOLD = 0.95f;
-    /**
-     * Values for the bouncer expansion represented as the panel expansion.
-     * Panel expansion 1f = panel fully showing = bouncer fully hidden
-     * Panel expansion 0f = panel fully hiding = bouncer fully showing
-     */
-    public static final float EXPANSION_HIDDEN = 1f;
-    public static final float EXPANSION_VISIBLE = 0f;
-
     protected final Context mContext;
     protected final ViewMediatorCallback mCallback;
     protected final ViewGroup mContainer;
@@ -664,56 +660,6 @@
         mExpansionCallbacks.remove(callback);
     }
 
-    /**
-     * Callback updated when the primary bouncer's show and hide states change.
-     */
-    public interface PrimaryBouncerExpansionCallback {
-        /**
-         * Invoked when the bouncer expansion reaches {@link KeyguardBouncer#EXPANSION_VISIBLE}.
-         * This is NOT called each time the bouncer is shown, but rather only when the fully
-         * shown amount has changed based on the panel expansion. The bouncer's visibility
-         * can still change when the expansion amount hasn't changed.
-         * See {@link KeyguardBouncer#isShowing()} for the checks for the bouncer showing state.
-         */
-        default void onFullyShown() {
-        }
-
-        /**
-         * Invoked when the bouncer is starting to transition to a hidden state.
-         */
-        default void onStartingToHide() {
-        }
-
-        /**
-         * Invoked when the bouncer is starting to transition to a visible state.
-         */
-        default void onStartingToShow() {
-        }
-
-        /**
-         * Invoked when the bouncer expansion reaches {@link KeyguardBouncer#EXPANSION_HIDDEN}.
-         */
-        default void onFullyHidden() {
-        }
-
-        /**
-         * From 0f {@link KeyguardBouncer#EXPANSION_VISIBLE} when fully visible
-         * to 1f {@link KeyguardBouncer#EXPANSION_HIDDEN} when fully hidden
-         */
-        default void onExpansionChanged(float bouncerHideAmount) {}
-
-        /**
-         * Invoked when visibility of KeyguardBouncer has changed.
-         * Note the bouncer expansion can be {@link KeyguardBouncer#EXPANSION_VISIBLE}, but the
-         * view's visibility can be {@link View.INVISIBLE}.
-         */
-        default void onVisibilityChanged(boolean isVisible) {}
-    }
-
-    public interface KeyguardResetCallback {
-        void onKeyguardReset();
-    }
-
     /** Create a {@link KeyguardBouncer} once a container and bouncer callback are available. */
     public static class Factory {
         private final Context mContext;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
index b965ac9..ff1b31d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
@@ -30,6 +30,9 @@
 import com.android.systemui.statusbar.NotificationLockscreenUserManager
 import com.android.systemui.statusbar.StatusBarState
 import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm
+import com.android.systemui.statusbar.policy.DevicePostureController
+import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_UNKNOWN
+import com.android.systemui.statusbar.policy.DevicePostureController.DevicePostureInt
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.tuner.TunerService
 import java.io.PrintWriter
@@ -40,11 +43,19 @@
 
     private val mKeyguardStateController: KeyguardStateController
     private val statusBarStateController: StatusBarStateController
+    private val devicePostureController: DevicePostureController
     @BypassOverride private val bypassOverride: Int
     private var hasFaceFeature: Boolean
+    @DevicePostureInt private val configFaceAuthSupportedPosture: Int
+    @DevicePostureInt private var postureState: Int = DEVICE_POSTURE_UNKNOWN
     private var pendingUnlock: PendingUnlock? = null
     private val listeners = mutableListOf<OnBypassStateChangedListener>()
-
+    private val postureCallback = DevicePostureController.Callback { posture ->
+        if (postureState != posture) {
+            postureState = posture
+            notifyListeners()
+        }
+    }
     private val faceAuthEnabledChangedCallback = object : KeyguardStateController.Callback {
         override fun onFaceAuthEnabledChanged() = notifyListeners()
     }
@@ -86,7 +97,8 @@
                 FACE_UNLOCK_BYPASS_NEVER -> false
                 else -> field
             }
-            return enabled && mKeyguardStateController.isFaceAuthEnabled
+            return enabled && mKeyguardStateController.isFaceAuthEnabled &&
+                    isPostureAllowedForFaceAuth()
         }
         private set(value) {
             field = value
@@ -106,18 +118,31 @@
         lockscreenUserManager: NotificationLockscreenUserManager,
         keyguardStateController: KeyguardStateController,
         shadeExpansionStateManager: ShadeExpansionStateManager,
+        devicePostureController: DevicePostureController,
         dumpManager: DumpManager
     ) {
         this.mKeyguardStateController = keyguardStateController
         this.statusBarStateController = statusBarStateController
+        this.devicePostureController = devicePostureController
 
         bypassOverride = context.resources.getInteger(R.integer.config_face_unlock_bypass_override)
+        configFaceAuthSupportedPosture =
+            context.resources.getInteger(R.integer.config_face_auth_supported_posture)
 
-        hasFaceFeature = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)
+        hasFaceFeature = context.packageManager.hasSystemFeature(PackageManager.FEATURE_FACE)
         if (!hasFaceFeature) {
             return
         }
 
+        if (configFaceAuthSupportedPosture != DEVICE_POSTURE_UNKNOWN) {
+            devicePostureController.addCallback { posture ->
+                if (postureState != posture) {
+                    postureState = posture
+                    notifyListeners()
+                }
+            }
+        }
+
         dumpManager.registerDumpable("KeyguardBypassController", this)
         statusBarStateController.addCallback(object : StatusBarStateController.StateListener {
             override fun onStateChanged(newState: Int) {
@@ -203,6 +228,13 @@
         pendingUnlock = null
     }
 
+    fun isPostureAllowedForFaceAuth(): Boolean {
+        return when (configFaceAuthSupportedPosture) {
+            DEVICE_POSTURE_UNKNOWN -> true
+            else -> (postureState == configFaceAuthSupportedPosture)
+        }
+    }
+
     override fun dump(pw: PrintWriter, args: Array<out String>) {
         pw.println("KeyguardBypassController:")
         if (pendingUnlock != null) {
@@ -219,6 +251,7 @@
         pw.println("  launchingAffordance: $launchingAffordance")
         pw.println("  qSExpanded: $qsExpanded")
         pw.println("  hasFaceFeature: $hasFaceFeature")
+        pw.println("  postureState: $postureState")
     }
 
     /** Registers a listener for bypass state changes. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
index 3483574..cba0897 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
@@ -45,6 +45,7 @@
 import com.android.systemui.animation.Interpolators;
 import com.android.systemui.battery.BatteryMeterViewController;
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.plugins.log.LogLevel;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.statusbar.CommandQueue;
@@ -76,6 +77,7 @@
 
 /** View Controller for {@link com.android.systemui.statusbar.phone.KeyguardStatusBarView}. */
 public class KeyguardStatusBarViewController extends ViewController<KeyguardStatusBarView> {
+    private static final String TAG = "KeyguardStatusBarViewController";
     private static final AnimationProperties KEYGUARD_HUN_PROPERTIES =
             new AnimationProperties().setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
 
@@ -355,7 +357,7 @@
         mView.setOnApplyWindowInsetsListener(
                 (view, windowInsets) -> mView.updateWindowInsets(windowInsets, mInsetsProvider));
         mSecureSettings.registerContentObserverForUser(
-                Settings.Secure.getUriFor(Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON),
+                Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON,
                 false,
                 mVolumeSettingObserver,
                 UserHandle.USER_ALL);
@@ -422,7 +424,7 @@
 
     /** Animate the keyguard status bar in. */
     public void animateKeyguardStatusBarIn() {
-        mLogger.d("animating status bar in");
+        mLogger.log(TAG, LogLevel.DEBUG, "animating status bar in");
         if (mDisableStateTracker.isDisabled()) {
             // If our view is disabled, don't allow us to animate in.
             return;
@@ -438,7 +440,7 @@
 
     /** Animate the keyguard status bar out. */
     public void animateKeyguardStatusBarOut(long startDelay, long duration) {
-        mLogger.d("animating status bar out");
+        mLogger.log(TAG, LogLevel.DEBUG, "animating status bar out");
         ValueAnimator anim = ValueAnimator.ofFloat(mView.getAlpha(), 0f);
         anim.addUpdateListener(mAnimatorUpdateListener);
         anim.setStartDelay(startDelay);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 48e58fc..6c532a5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -35,7 +35,6 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.RemoteException;
-import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings.Global;
 import android.service.notification.ZenModeConfig;
@@ -58,6 +57,7 @@
 import com.android.systemui.qs.tiles.DndTile;
 import com.android.systemui.qs.tiles.RotationLockTile;
 import com.android.systemui.screenrecord.RecordingController;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.policy.BluetoothController;
 import com.android.systemui.statusbar.policy.CastController;
@@ -136,6 +136,7 @@
     private final UserInfoController mUserInfoController;
     private final IActivityManager mIActivityManager;
     private final UserManager mUserManager;
+    private final UserTracker mUserTracker;
     private final DevicePolicyManager mDevicePolicyManager;
     private final StatusBarIconController mIconController;
     private final CommandQueue mCommandQueue;
@@ -176,7 +177,7 @@
             KeyguardStateController keyguardStateController,
             LocationController locationController,
             SensorPrivacyController sensorPrivacyController, IActivityManager iActivityManager,
-            AlarmManager alarmManager, UserManager userManager,
+            AlarmManager alarmManager, UserManager userManager, UserTracker userTracker,
             DevicePolicyManager devicePolicyManager, RecordingController recordingController,
             @Nullable TelecomManager telecomManager, @DisplayId int displayId,
             @Main SharedPreferences sharedPreferences, DateFormatUtil dateFormatUtil,
@@ -196,6 +197,7 @@
         mUserInfoController = userInfoController;
         mIActivityManager = iActivityManager;
         mUserManager = userManager;
+        mUserTracker = userTracker;
         mDevicePolicyManager = devicePolicyManager;
         mRotationLockController = rotationLockController;
         mDataSaver = dataSaverController;
@@ -366,7 +368,7 @@
     }
 
     private void updateAlarm() {
-        final AlarmClockInfo alarm = mAlarmManager.getNextAlarmClock(UserHandle.USER_CURRENT);
+        final AlarmClockInfo alarm = mAlarmManager.getNextAlarmClock(mUserTracker.getUserId());
         final boolean hasAlarm = alarm != null && alarm.getTriggerTime() > 0;
         int zen = mZenController.getZen();
         final boolean zenNone = zen == Global.ZEN_MODE_NO_INTERRUPTIONS;
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 ee8b861..80093a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -53,6 +53,7 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
+import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants;
 import com.android.systemui.scrim.ScrimView;
 import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.statusbar.notification.stack.ViewState;
@@ -147,7 +148,7 @@
      * 0, the bouncer is visible.
      */
     @FloatRange(from = 0, to = 1)
-    private float mBouncerHiddenFraction = KeyguardBouncer.EXPANSION_HIDDEN;
+    private float mBouncerHiddenFraction = KeyguardBouncerConstants.EXPANSION_HIDDEN;
 
     /**
      * Set whether an unocclusion animation is currently running on the notification panel. Used
@@ -790,27 +791,35 @@
             if (!mScreenOffAnimationController.shouldExpandNotifications()
                     && !mAnimatingPanelExpansionOnUnlock
                     && !occluding) {
-                float behindFraction = getInterpolatedFraction();
-                behindFraction = (float) Math.pow(behindFraction, 0.8f);
                 if (mClipsQsScrim) {
+                    float behindFraction = getInterpolatedFraction();
+                    behindFraction = (float) Math.pow(behindFraction, 0.8f);
                     mBehindAlpha = mTransparentScrimBackground ? 0 : 1;
                     mNotificationsAlpha =
                             mTransparentScrimBackground ? 0 : behindFraction * mDefaultScrimAlpha;
                 } else {
-                    mBehindAlpha =
-                            mTransparentScrimBackground ? 0 : behindFraction * mDefaultScrimAlpha;
-                    // Delay fade-in of notification scrim a bit further, to coincide with the
-                    // view fade in. Otherwise the empty panel can be quite jarring.
-                    mNotificationsAlpha = mTransparentScrimBackground
-                            ? 0 : MathUtils.constrainedMap(0f, 1f, 0.3f, 0.75f,
-                            mPanelExpansionFraction);
+                    if (mTransparentScrimBackground) {
+                        mBehindAlpha = 0;
+                        mNotificationsAlpha = 0;
+                    } else {
+                        // Behind scrim will finish fading in at 30% expansion.
+                        float behindFraction = MathUtils
+                                .constrainedMap(0f, 1f, 0f, 0.3f, mPanelExpansionFraction);
+                        mBehindAlpha = behindFraction * mDefaultScrimAlpha;
+                        // Delay fade-in of notification scrim a bit further, to coincide with the
+                        // behind scrim finishing fading in.
+                        // Also to coincide with the view starting to fade in, otherwise the empty
+                        // panel can be quite jarring.
+                        mNotificationsAlpha = MathUtils
+                                .constrainedMap(0f, 1f, 0.3f, 0.75f, mPanelExpansionFraction);
+                    }
                 }
                 mBehindTint = mState.getBehindTint();
                 mInFrontAlpha = 0;
             }
 
             if (mState == ScrimState.DREAMING
-                    && mBouncerHiddenFraction != KeyguardBouncer.EXPANSION_HIDDEN) {
+                    && mBouncerHiddenFraction != KeyguardBouncerConstants.EXPANSION_HIDDEN) {
                 final float interpolatedFraction =
                         BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(
                                 mBouncerHiddenFraction);
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 1a14a036..24ad55d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -79,12 +79,30 @@
 
     /** Refresh the state of an IconManager by recreating the views */
     void refreshIconGroup(IconManager iconManager);
-    /** */
+
+    /**
+     * Adds or updates an icon for a given slot for a **tile service icon**.
+     *
+     * TODO(b/265307726): Merge with {@link #setIcon(String, StatusBarIcon)} or make this method
+     *   much more clearly distinct from that method.
+     */
     void setExternalIcon(String slot);
-    /** */
+
+    /**
+     * Adds or updates an icon for the given slot for **internal system icons**.
+     *
+     * TODO(b/265307726): Rename to `setInternalIcon`, or merge this appropriately with the
+     * {@link #setIcon(String, StatusBarIcon)} method.
+     */
     void setIcon(String slot, int resourceId, CharSequence contentDescription);
-    /** */
+
+    /**
+     * Adds or updates an icon for the given slot for an **externally-provided icon**.
+     *
+     * TODO(b/265307726): Rename to `setExternalIcon` or something similar.
+     */
     void setIcon(String slot, StatusBarIcon icon);
+
     /** */
     void setWifiIcon(String slot, WifiIconState state);
 
@@ -133,9 +151,17 @@
      * TAG_PRIMARY to refer to the first icon at a given slot.
      */
     void removeIcon(String slot, int tag);
+
     /** */
     void removeAllIconsForSlot(String slot);
 
+    /**
+     * Removes all the icons for the given slot.
+     *
+     * Only use this for icons that have come from **an external process**.
+     */
+    void removeAllIconsForExternalSlot(String slot);
+
     // TODO: See if we can rename this tunable name.
     String ICON_HIDE_LIST = "icon_blacklist";
 
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 9fbe6cb..416bc71 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
@@ -28,6 +28,8 @@
 import android.util.Log;
 import android.view.ViewGroup;
 
+import androidx.annotation.VisibleForTesting;
+
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.systemui.Dumpable;
 import com.android.systemui.R;
@@ -63,6 +65,10 @@
         ConfigurationListener, Dumpable, CommandQueue.Callbacks, StatusBarIconController, DemoMode {
 
     private static final String TAG = "StatusBarIconController";
+    // Use this suffix to prevent external icon slot names from unintentionally overriding our
+    // internal, system-level slot names. See b/255428281.
+    @VisibleForTesting
+    protected static final String EXTERNAL_SLOT_SUFFIX = "__external";
 
     private final StatusBarIconList mStatusBarIconList;
     private final ArrayList<IconManager> mIconGroups = new ArrayList<>();
@@ -346,21 +352,26 @@
 
     @Override
     public void setExternalIcon(String slot) {
-        int viewIndex = mStatusBarIconList.getViewIndex(slot, 0);
+        String slotName = createExternalSlotName(slot);
+        int viewIndex = mStatusBarIconList.getViewIndex(slotName, 0);
         int height = mContext.getResources().getDimensionPixelSize(
                 R.dimen.status_bar_icon_drawing_size);
         mIconGroups.forEach(l -> l.onIconExternal(viewIndex, height));
     }
 
-    //TODO: remove this (used in command queue and for 3rd party tiles?)
+    // Override for *both* CommandQueue.Callbacks AND StatusBarIconController.
+    // TODO(b/265307726): Pull out the CommandQueue callbacks into a member variable to
+    //  differentiate between those callback methods and StatusBarIconController methods.
+    @Override
     public void setIcon(String slot, StatusBarIcon icon) {
+        String slotName = createExternalSlotName(slot);
         if (icon == null) {
-            removeAllIconsForSlot(slot);
+            removeAllIconsForSlot(slotName);
             return;
         }
 
         StatusBarIconHolder holder = StatusBarIconHolder.fromIcon(icon);
-        setIcon(slot, holder);
+        setIcon(slotName, holder);
     }
 
     private void setIcon(String slot, @NonNull StatusBarIconHolder holder) {
@@ -406,10 +417,12 @@
         }
     }
 
-    /** */
+    // CommandQueue.Callbacks override
+    // TODO(b/265307726): Pull out the CommandQueue callbacks into a member variable to
+    //  differentiate between those callback methods and StatusBarIconController methods.
     @Override
     public void removeIcon(String slot) {
-        removeAllIconsForSlot(slot);
+        removeAllIconsForExternalSlot(slot);
     }
 
     /** */
@@ -423,6 +436,11 @@
         mIconGroups.forEach(l -> l.onRemoveIcon(viewIndex));
     }
 
+    @Override
+    public void removeAllIconsForExternalSlot(String slotName) {
+        removeAllIconsForSlot(createExternalSlotName(slotName));
+    }
+
     /** */
     @Override
     public void removeAllIconsForSlot(String slotName) {
@@ -506,4 +524,12 @@
     public void onDensityOrFontScaleChanged() {
         refreshIconGroups();
     }
+
+    private String createExternalSlotName(String slot) {
+        if (slot.endsWith(EXTERNAL_SLOT_SUFFIX)) {
+            return slot;
+        } else {
+            return slot + EXTERNAL_SLOT_SUFFIX;
+        }
+    }
 }
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 d480fab..8e22bf4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -18,6 +18,7 @@
 
 import static android.view.WindowInsets.Type.navigationBars;
 
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_HIDDEN;
 import static com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
 import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
@@ -36,7 +37,8 @@
 import android.view.ViewGroup;
 import android.view.ViewRootImpl;
 import android.view.WindowManagerGlobal;
-import android.window.OnBackInvokedCallback;
+import android.window.BackEvent;
+import android.window.OnBackAnimationCallback;
 import android.window.OnBackInvokedDispatcher;
 
 import androidx.annotation.NonNull;
@@ -58,7 +60,9 @@
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
 import com.android.systemui.keyguard.data.BouncerView;
+import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor;
+import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback;
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor;
 import com.android.systemui.navigationbar.NavigationBarView;
 import com.android.systemui.navigationbar.NavigationModeController;
@@ -75,7 +79,6 @@
 import com.android.systemui.statusbar.RemoteInputController;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
-import com.android.systemui.statusbar.phone.KeyguardBouncer.PrimaryBouncerExpansionCallback;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.unfold.FoldAodAnimationController;
@@ -134,6 +137,7 @@
     private KeyguardMessageAreaController<AuthKeyguardMessageArea> mKeyguardMessageAreaController;
     private final PrimaryBouncerCallbackInteractor mPrimaryBouncerCallbackInteractor;
     private final PrimaryBouncerInteractor mPrimaryBouncerInteractor;
+    private final AlternateBouncerInteractor mAlternateBouncerInteractor;
     private final BouncerView mPrimaryBouncerView;
     private final Lazy<ShadeController> mShadeController;
 
@@ -182,8 +186,7 @@
                         isVisible && mDreamOverlayStateController.isOverlayActive());
 
                 if (!isVisible) {
-                    mCentralSurfaces.setPrimaryBouncerHiddenFraction(
-                            KeyguardBouncer.EXPANSION_HIDDEN);
+                    mCentralSurfaces.setPrimaryBouncerHiddenFraction(EXPANSION_HIDDEN);
                 }
 
                 /* Register predictive back callback when keyguard becomes visible, and unregister
@@ -196,11 +199,38 @@
             }
     };
 
-    private final OnBackInvokedCallback mOnBackInvokedCallback = () -> {
-        if (DEBUG) {
-            Log.d(TAG, "onBackInvokedCallback() called, invoking onBackPressed()");
+    private final OnBackAnimationCallback mOnBackInvokedCallback = new OnBackAnimationCallback() {
+        @Override
+        public void onBackInvoked() {
+            if (DEBUG) {
+                Log.d(TAG, "onBackInvokedCallback() called, invoking onBackPressed()");
+            }
+            onBackPressed();
+            if (shouldPlayBackAnimation()) {
+                mPrimaryBouncerView.getDelegate().getBackCallback().onBackInvoked();
+            }
         }
-        onBackPressed();
+
+        @Override
+        public void onBackProgressed(BackEvent event) {
+            if (shouldPlayBackAnimation()) {
+                mPrimaryBouncerView.getDelegate().getBackCallback().onBackProgressed(event);
+            }
+        }
+
+        @Override
+        public void onBackCancelled() {
+            if (shouldPlayBackAnimation()) {
+                mPrimaryBouncerView.getDelegate().getBackCallback().onBackCancelled();
+            }
+        }
+
+        @Override
+        public void onBackStarted(BackEvent event) {
+            if (shouldPlayBackAnimation()) {
+                mPrimaryBouncerView.getDelegate().getBackCallback().onBackStarted(event);
+            }
+        }
     };
     private boolean mIsBackCallbackRegistered = false;
 
@@ -253,6 +283,8 @@
     final Set<KeyguardViewManagerCallback> mCallbacks = new HashSet<>();
     private boolean mIsModernBouncerEnabled;
     private boolean mIsUnoccludeTransitionFlagEnabled;
+    private boolean mIsModernAlternateBouncerEnabled;
+    private boolean mIsBackAnimationEnabled;
 
     private OnDismissAction mAfterKeyguardGoneAction;
     private Runnable mKeyguardGoneCancelAction;
@@ -269,7 +301,7 @@
     private final LatencyTracker mLatencyTracker;
     private final KeyguardSecurityModel mKeyguardSecurityModel;
     @Nullable private KeyguardBypassController mBypassController;
-    @Nullable private AlternateBouncer mAlternateBouncer;
+    @Nullable private OccludingAppBiometricUI mOccludingAppBiometricUI;
 
     private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
             new KeyguardUpdateMonitorCallback() {
@@ -306,7 +338,8 @@
             FeatureFlags featureFlags,
             PrimaryBouncerCallbackInteractor primaryBouncerCallbackInteractor,
             PrimaryBouncerInteractor primaryBouncerInteractor,
-            BouncerView primaryBouncerView) {
+            BouncerView primaryBouncerView,
+            AlternateBouncerInteractor alternateBouncerInteractor) {
         mContext = context;
         mViewMediatorCallback = callback;
         mLockPatternUtils = lockPatternUtils;
@@ -331,6 +364,10 @@
                 .map(SysUIUnfoldComponent::getFoldAodAnimationController).orElse(null);
         mIsModernBouncerEnabled = featureFlags.isEnabled(Flags.MODERN_BOUNCER);
         mIsUnoccludeTransitionFlagEnabled = featureFlags.isEnabled(Flags.UNOCCLUSION_TRANSITION);
+        mIsModernAlternateBouncerEnabled = featureFlags.isEnabled(Flags.MODERN_ALTERNATE_BOUNCER);
+        mAlternateBouncerInteractor = alternateBouncerInteractor;
+        mIsBackAnimationEnabled =
+                featureFlags.isEnabled(Flags.WM_ENABLE_PREDICTIVE_BACK_BOUNCER_ANIM);
     }
 
     @Override
@@ -363,23 +400,51 @@
     }
 
     /**
-     * Sets the given alt auth interceptor to null if it's the current auth interceptor. Else,
-     * does nothing.
+     * Sets the given legacy alternate bouncer to null if it's the current alternate bouncer. Else,
+     * does nothing. Only used if modern alternate bouncer is NOT enabled.
      */
-    public void removeAlternateAuthInterceptor(@NonNull AlternateBouncer authInterceptor) {
-        if (Objects.equals(mAlternateBouncer, authInterceptor)) {
-            mAlternateBouncer = null;
-            hideAlternateBouncer(true);
+    public void removeLegacyAlternateBouncer(
+            @NonNull LegacyAlternateBouncer alternateBouncerLegacy) {
+        if (!mIsModernAlternateBouncerEnabled) {
+            if (Objects.equals(mAlternateBouncerInteractor.getLegacyAlternateBouncer(),
+                    alternateBouncerLegacy)) {
+                mAlternateBouncerInteractor.setLegacyAlternateBouncer(null);
+                hideAlternateBouncer(true);
+            }
         }
     }
 
     /**
-     * Sets a new alt auth interceptor.
+     * Sets a new legacy alternate bouncer. Only used if mdoern alternate bouncer is NOT enable.
      */
-    public void setAlternateBouncer(@NonNull AlternateBouncer authInterceptor) {
-        if (!Objects.equals(mAlternateBouncer, authInterceptor)) {
-            mAlternateBouncer = authInterceptor;
-            hideAlternateBouncer(false);
+    public void setLegacyAlternateBouncer(@NonNull LegacyAlternateBouncer alternateBouncerLegacy) {
+        if (!mIsModernAlternateBouncerEnabled) {
+            if (!Objects.equals(mAlternateBouncerInteractor.getLegacyAlternateBouncer(),
+                    alternateBouncerLegacy)) {
+                mAlternateBouncerInteractor.setLegacyAlternateBouncer(alternateBouncerLegacy);
+                hideAlternateBouncer(false);
+            }
+        }
+
+    }
+
+
+    /**
+     * Sets the given OccludingAppBiometricUI to null if it's the current auth interceptor. Else,
+     * does nothing.
+     */
+    public void removeOccludingAppBiometricUI(@NonNull OccludingAppBiometricUI biometricUI) {
+        if (Objects.equals(mOccludingAppBiometricUI, biometricUI)) {
+            mOccludingAppBiometricUI = null;
+        }
+    }
+
+    /**
+     * Sets a new OccludingAppBiometricUI.
+     */
+    public void setOccludingAppBiometricUI(@NonNull OccludingAppBiometricUI biometricUI) {
+        if (!Objects.equals(mOccludingAppBiometricUI, biometricUI)) {
+            mOccludingAppBiometricUI = biometricUI;
         }
     }
 
@@ -438,6 +503,11 @@
         }
     }
 
+    private boolean shouldPlayBackAnimation() {
+        // Suppress back animation when bouncer shouldn't be dismissed on back invocation.
+        return !needsFullscreenBouncer() && mIsBackAnimationEnabled;
+    }
+
     @Override
     public void onDensityOrFontScaleChanged() {
         hideBouncer(true /* destroyView */);
@@ -451,7 +521,7 @@
                         || mNotificationPanelViewController.isExpanding());
 
         final boolean isUserTrackingStarted =
-                event.getFraction() != KeyguardBouncer.EXPANSION_HIDDEN && event.getTracking();
+                event.getFraction() != EXPANSION_HIDDEN && event.getTracking();
 
         return mKeyguardStateController.isShowing()
                 && !primaryBouncerIsOrWillBeShowing()
@@ -501,9 +571,9 @@
             }
         } else {
             if (mPrimaryBouncer != null) {
-                mPrimaryBouncer.setExpansion(KeyguardBouncer.EXPANSION_HIDDEN);
+                mPrimaryBouncer.setExpansion(EXPANSION_HIDDEN);
             } else {
-                mPrimaryBouncerInteractor.setPanelExpansion(KeyguardBouncer.EXPANSION_HIDDEN);
+                mPrimaryBouncerInteractor.setPanelExpansion(EXPANSION_HIDDEN);
             }
         }
     }
@@ -566,18 +636,11 @@
      *                 {@see KeyguardBouncer#show(boolean, boolean)}
      */
     public void showBouncer(boolean scrimmed) {
-        if (canShowAlternateBouncer()) {
-            updateAlternateBouncerShowing(mAlternateBouncer.showAlternateBouncer());
-            return;
+        if (!mAlternateBouncerInteractor.show()) {
+            showPrimaryBouncer(scrimmed);
+        } else {
+            updateAlternateBouncerShowing(mAlternateBouncerInteractor.isVisibleState());
         }
-
-        showPrimaryBouncer(scrimmed);
-    }
-
-    /** Whether we can show the alternate bouncer instead of the primary bouncer. */
-    public boolean canShowAlternateBouncer() {
-        return mAlternateBouncer != null
-                && mKeyguardUpdateManager.isUnlockingWithBiometricAllowed(true);
     }
 
     /**
@@ -641,9 +704,9 @@
                 mKeyguardGoneCancelAction = cancelAction;
                 mDismissActionWillAnimateOnKeyguard = r != null && r.willRunAnimationOnKeyguard();
 
-                // If there is an an alternate auth interceptor (like the UDFPS), show that one
+                // If there is an alternate auth interceptor (like the UDFPS), show that one
                 // instead of the bouncer.
-                if (canShowAlternateBouncer()) {
+                if (mAlternateBouncerInteractor.canShowAlternateBouncerForFingerprint()) {
                     if (!afterKeyguardGone) {
                         if (mPrimaryBouncer != null) {
                             mPrimaryBouncer.setDismissAction(mAfterKeyguardGoneAction,
@@ -656,7 +719,7 @@
                         mKeyguardGoneCancelAction = null;
                     }
 
-                    updateAlternateBouncerShowing(mAlternateBouncer.showAlternateBouncer());
+                    updateAlternateBouncerShowing(mAlternateBouncerInteractor.show());
                     return;
                 }
 
@@ -725,10 +788,7 @@
 
     @Override
     public void hideAlternateBouncer(boolean forceUpdateScrim) {
-        final boolean updateScrim = (mAlternateBouncer != null
-                && mAlternateBouncer.hideAlternateBouncer())
-                || forceUpdateScrim;
-        updateAlternateBouncerShowing(updateScrim);
+        updateAlternateBouncerShowing(mAlternateBouncerInteractor.hide() || forceUpdateScrim);
     }
 
     private void updateAlternateBouncerShowing(boolean updateScrim) {
@@ -738,7 +798,7 @@
             return;
         }
 
-        final boolean isShowingAlternateBouncer = isShowingAlternateBouncer();
+        final boolean isShowingAlternateBouncer = mAlternateBouncerInteractor.isVisibleState();
         if (mKeyguardMessageAreaController != null) {
             mKeyguardMessageAreaController.setIsVisible(isShowingAlternateBouncer);
             mKeyguardMessageAreaController.setMessage("");
@@ -1087,7 +1147,7 @@
             if (hideImmediately) {
                 mStatusBarStateController.setLeaveOpenOnKeyguardHide(false);
             } else {
-                mNotificationPanelViewController.expandWithoutQs();
+                mNotificationPanelViewController.expandShadeToNotifications();
             }
         }
         return;
@@ -1095,7 +1155,7 @@
 
     @Override
     public boolean isBouncerShowing() {
-        return primaryBouncerIsShowing() || isShowingAlternateBouncer();
+        return primaryBouncerIsShowing() || mAlternateBouncerInteractor.isVisibleState();
     }
 
     @Override
@@ -1339,7 +1399,7 @@
             mPrimaryBouncerInteractor.notifyKeyguardAuthenticated(strongAuth);
         }
 
-        if (mAlternateBouncer != null && isShowingAlternateBouncer()) {
+        if (mAlternateBouncerInteractor.isVisibleState()) {
             hideAlternateBouncer(false);
             executeAfterKeyguardGoneAction();
         }
@@ -1347,7 +1407,7 @@
 
     /** Display security message to relevant KeyguardMessageArea. */
     public void setKeyguardMessage(String message, ColorStateList colorState) {
-        if (isShowingAlternateBouncer()) {
+        if (mAlternateBouncerInteractor.isVisibleState()) {
             if (mKeyguardMessageAreaController != null) {
                 mKeyguardMessageAreaController.setMessage(message);
             }
@@ -1421,6 +1481,7 @@
 
     public void dump(PrintWriter pw) {
         pw.println("StatusBarKeyguardViewManager:");
+        pw.println("  mIsModernAlternateBouncerEnabled: " + mIsModernAlternateBouncerEnabled);
         pw.println("  mRemoteInputActive: " + mRemoteInputActive);
         pw.println("  mDozing: " + mDozing);
         pw.println("  mAfterKeyguardGoneAction: " + mAfterKeyguardGoneAction);
@@ -1438,9 +1499,9 @@
             mPrimaryBouncer.dump(pw);
         }
 
-        if (mAlternateBouncer != null) {
-            pw.println("AlternateBouncer:");
-            mAlternateBouncer.dump(pw);
+        if (mOccludingAppBiometricUI != null) {
+            pw.println("mOccludingAppBiometricUI:");
+            mOccludingAppBiometricUI.dump(pw);
         }
     }
 
@@ -1492,14 +1553,17 @@
         return mPrimaryBouncer;
     }
 
-    public boolean isShowingAlternateBouncer() {
-        return mAlternateBouncer != null && mAlternateBouncer.isShowingAlternateBouncer();
-    }
-
     /**
-     * Forward touches to callbacks.
+     * For any touches on the NPVC, show the primary bouncer if the alternate bouncer is currently
+     * showing.
      */
     public void onTouch(MotionEvent event) {
+        if (mAlternateBouncerInteractor.isVisibleState()
+                && mAlternateBouncerInteractor.hasAlternateBouncerShownWithMinTime()) {
+            showPrimaryBouncer(true);
+        }
+
+        // Forward NPVC touches to callbacks in case they want to respond to touches
         for (KeyguardViewManagerCallback callback: mCallbacks) {
             callback.onTouch(event);
         }
@@ -1542,8 +1606,8 @@
      */
     public void requestFp(boolean request, int udfpsColor) {
         mKeyguardUpdateManager.requestFingerprintAuthOnOccludingApp(request);
-        if (mAlternateBouncer != null) {
-            mAlternateBouncer.requestUdfps(request, udfpsColor);
+        if (mOccludingAppBiometricUI != null) {
+            mOccludingAppBiometricUI.requestUdfps(request, udfpsColor);
         }
     }
 
@@ -1614,10 +1678,9 @@
     }
 
     /**
-     * Delegate used to send show and hide events to an alternate authentication method instead of
-     * the regular pin/pattern/password bouncer.
+     * @Deprecated Delegate used to send show and hide events to an alternate bouncer.
      */
-    public interface AlternateBouncer {
+    public interface LegacyAlternateBouncer {
         /**
          * Show alternate authentication bouncer.
          * @return whether alternate auth method was newly shown
@@ -1634,7 +1697,13 @@
          * @return true if the alternate auth bouncer is showing
          */
         boolean isShowingAlternateBouncer();
+    }
 
+    /**
+     * Delegate used to send show and hide events to an alternate authentication method instead of
+     * the regular pin/pattern/password bouncer.
+     */
+    public interface OccludingAppBiometricUI {
         /**
          * Use when an app occluding the keyguard would like to give the user ability to
          * unlock the device using udfps.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index be6e0cc..078a00d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -53,6 +53,7 @@
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.shade.ShadeController;
 import com.android.systemui.statusbar.NotificationClickNotifier;
@@ -118,6 +119,7 @@
     private final NotificationPanelViewController mNotificationPanel;
     private final ActivityLaunchAnimator mActivityLaunchAnimator;
     private final NotificationLaunchAnimatorControllerProvider mNotificationAnimationProvider;
+    private final UserTracker mUserTracker;
     private final OnUserInteractionCallback mOnUserInteractionCallback;
 
     private boolean mIsCollapsingToShowActivityOverLockscreen;
@@ -153,7 +155,8 @@
             ActivityLaunchAnimator activityLaunchAnimator,
             NotificationLaunchAnimatorControllerProvider notificationAnimationProvider,
             LaunchFullScreenIntentProvider launchFullScreenIntentProvider,
-            FeatureFlags featureFlags) {
+            FeatureFlags featureFlags,
+            UserTracker userTracker) {
         mContext = context;
         mMainThreadHandler = mainThreadHandler;
         mUiBgExecutor = uiBgExecutor;
@@ -184,6 +187,7 @@
         mNotificationPanel = panel;
         mActivityLaunchAnimator = activityLaunchAnimator;
         mNotificationAnimationProvider = notificationAnimationProvider;
+        mUserTracker = userTracker;
 
         launchFullScreenIntentProvider.registerListener(entry -> launchFullScreenIntent(entry));
     }
@@ -518,7 +522,7 @@
                             intent.getPackage(),
                             (adapter) -> tsb.startActivities(
                                     getActivityOptions(mCentralSurfaces.getDisplayId(), adapter),
-                                    UserHandle.CURRENT));
+                                    mUserTracker.getUserHandle()));
                 });
                 return true;
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemBarAttributesListener.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemBarAttributesListener.kt
index 6cd8c78..9e6bb20 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemBarAttributesListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemBarAttributesListener.kt
@@ -16,7 +16,9 @@
 
 package com.android.systemui.statusbar.phone
 
+import android.view.InsetsFlags
 import android.view.InsetsVisibilities
+import android.view.ViewDebug
 import android.view.WindowInsetsController.Appearance
 import android.view.WindowInsetsController.Behavior
 import com.android.internal.statusbar.LetterboxDetails
@@ -148,4 +150,20 @@
 ) {
     val letterboxesArray = letterboxes.toTypedArray()
     val appearanceRegionsArray = appearanceRegions.toTypedArray()
+    override fun toString(): String {
+        val appearanceToString =
+                ViewDebug.flagsToString(InsetsFlags::class.java, "appearance", appearance)
+        return """SystemBarAttributesParams(
+            displayId=$displayId,
+            appearance=$appearanceToString,
+            appearanceRegions=$appearanceRegions,
+            navbarColorManagedByIme=$navbarColorManagedByIme,
+            behavior=$behavior,
+            requestedVisibilities=$requestedVisibilities,
+            packageName='$packageName',
+            letterboxes=$letterboxes,
+            letterboxesArray=${letterboxesArray.contentToString()},
+            appearanceRegionsArray=${appearanceRegionsArray.contentToString()}
+            )""".trimMargin()
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
index 26bc3e3..608bfa6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
@@ -189,7 +189,8 @@
         // for foldables that often go from large <=> small screen when folding/unfolding.
         ViewRootImpl.addConfigCallback(this);
         mDialogManager.setShowing(this, true);
-        mSysUiState.setFlag(QuickStepContract.SYSUI_STATE_DIALOG_SHOWING, true);
+        mSysUiState.setFlag(QuickStepContract.SYSUI_STATE_DIALOG_SHOWING, true)
+                .commitUpdate(mContext.getDisplayId());
     }
 
     @Override
@@ -202,7 +203,8 @@
 
         ViewRootImpl.removeConfigCallback(this);
         mDialogManager.setShowing(this, false);
-        mSysUiState.setFlag(QuickStepContract.SYSUI_STATE_DIALOG_SHOWING, false);
+        mSysUiState.setFlag(QuickStepContract.SYSUI_STATE_DIALOG_SHOWING, false)
+                .commitUpdate(mContext.getDisplayId());
     }
 
     public void setShowForAllUsers(boolean show) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
index 206c0aa..344d233 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
@@ -46,7 +46,6 @@
 import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.NotificationShelfController;
 import com.android.systemui.statusbar.OperatorNameViewController;
-import com.android.systemui.statusbar.connectivity.NetworkController;
 import com.android.systemui.statusbar.core.StatusBarInitializer.OnStatusBarViewInitializedListener;
 import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
 import com.android.systemui.statusbar.notification.row.dagger.NotificationShelfComponent;
@@ -293,7 +292,6 @@
             StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
             KeyguardStateController keyguardStateController,
             NotificationPanelViewController notificationPanelViewController,
-            NetworkController networkController,
             StatusBarStateController statusBarStateController,
             CommandQueue commandQueue,
             CarrierConfigTracker carrierConfigTracker,
@@ -315,7 +313,6 @@
                 statusBarHideIconsForBouncerManager,
                 keyguardStateController,
                 notificationPanelViewController,
-                networkController,
                 statusBarStateController,
                 commandQueue,
                 carrierConfigTracker,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
index 9f3fd72..9354c5e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
@@ -24,7 +24,6 @@
 import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.SHOWING_PERSISTENT_DOT;
 
 import android.animation.Animator;
-import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
 import android.app.Fragment;
@@ -59,9 +58,6 @@
 import com.android.systemui.statusbar.OperatorNameView;
 import com.android.systemui.statusbar.OperatorNameViewController;
 import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.connectivity.IconState;
-import com.android.systemui.statusbar.connectivity.NetworkController;
-import com.android.systemui.statusbar.connectivity.SignalCallback;
 import com.android.systemui.statusbar.events.SystemStatusAnimationCallback;
 import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
 import com.android.systemui.statusbar.phone.NotificationIconAreaController;
@@ -75,7 +71,6 @@
 import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent.Startable;
 import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
 import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallListener;
-import com.android.systemui.statusbar.policy.EncryptionHelper;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.CarrierConfigTracker;
 import com.android.systemui.util.CarrierConfigTracker.CarrierConfigChangedListener;
@@ -110,7 +105,6 @@
     private final StatusBarStateController mStatusBarStateController;
     private final KeyguardStateController mKeyguardStateController;
     private final NotificationPanelViewController mNotificationPanelViewController;
-    private final NetworkController mNetworkController;
     private LinearLayout mEndSideContent;
     private View mClockView;
     private View mOngoingCallChip;
@@ -139,13 +133,6 @@
     private List<String> mBlockedIcons = new ArrayList<>();
     private Map<Startable, Startable.State> mStartableStates = new ArrayMap<>();
 
-    private SignalCallback mSignalCallback = new SignalCallback() {
-        @Override
-        public void setIsAirplaneMode(@NonNull IconState icon) {
-            mCommandQueue.recomputeDisableFlags(getContext().getDisplayId(), true /* animate */);
-        }
-    };
-
     private final OngoingCallListener mOngoingCallListener = new OngoingCallListener() {
         @Override
         public void onOngoingCallStateChanged(boolean animate) {
@@ -191,7 +178,6 @@
             StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
             KeyguardStateController keyguardStateController,
             NotificationPanelViewController notificationPanelViewController,
-            NetworkController networkController,
             StatusBarStateController statusBarStateController,
             CommandQueue commandQueue,
             CarrierConfigTracker carrierConfigTracker,
@@ -213,7 +199,6 @@
         mDarkIconManagerFactory = darkIconManagerFactory;
         mKeyguardStateController = keyguardStateController;
         mNotificationPanelViewController = notificationPanelViewController;
-        mNetworkController = networkController;
         mStatusBarStateController = statusBarStateController;
         mCommandQueue = commandQueue;
         mCarrierConfigTracker = carrierConfigTracker;
@@ -261,7 +246,6 @@
         mOngoingCallChip = mStatusBar.findViewById(R.id.ongoing_call_chip);
         showEndSideContent(false);
         showClock(false);
-        initEmergencyCryptkeeperText();
         initOperatorName();
         initNotificationIconArea();
         mSystemEventAnimator =
@@ -320,7 +304,7 @@
         mAnimationScheduler.addCallback(this);
 
         mSecureSettings.registerContentObserverForUser(
-                Settings.Secure.getUriFor(Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON),
+                Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON,
                 false,
                 mVolumeSettingObserver,
                 UserHandle.USER_ALL);
@@ -340,9 +324,6 @@
     public void onDestroyView() {
         super.onDestroyView();
         mStatusBarIconController.removeIconGroup(mDarkIconManager);
-        if (mNetworkController.hasEmergencyCryptKeeperText()) {
-            mNetworkController.removeCallback(mSignalCallback);
-        }
         mCarrierConfigTracker.removeCallback(mCarrierConfigCallback);
         mCarrierConfigTracker.removeDataSubscriptionChangedListener(mDefaultDataListener);
 
@@ -444,15 +425,6 @@
             state |= DISABLE_CLOCK;
         }
 
-        if (mNetworkController != null && EncryptionHelper.IS_DATA_ENCRYPTED) {
-            if (mNetworkController.hasEmergencyCryptKeeperText()) {
-                state |= DISABLE_NOTIFICATION_ICONS;
-            }
-            if (!mNetworkController.isRadioOn()) {
-                state |= DISABLE_SYSTEM_INFO;
-            }
-        }
-
         if (mOngoingCallController.hasOngoingCall()) {
             state &= ~DISABLE_ONGOING_CALL_CHIP;
         } else {
@@ -620,19 +592,6 @@
         }
     }
 
-    private void initEmergencyCryptkeeperText() {
-        View emergencyViewStub = mStatusBar.findViewById(R.id.emergency_cryptkeeper_text);
-        if (mNetworkController.hasEmergencyCryptKeeperText()) {
-            if (emergencyViewStub != null) {
-                ((ViewStub) emergencyViewStub).inflate();
-            }
-            mNetworkController.addCallback(mSignalCallback);
-        } else if (emergencyViewStub != null) {
-            ViewGroup parent = (ViewGroup) emergencyViewStub.getParent();
-            parent.removeView(emergencyViewStub);
-        }
-    }
-
     private void initOperatorName() {
         int subId = SubscriptionManager.getDefaultDataSubscriptionId();
         if (mCarrierConfigTracker.getShowOperatorNameInStatusBarConfig(subId)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/StatusBarPipelineFlags.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/StatusBarPipelineFlags.kt
index 4d914fe..15fed32 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/StatusBarPipelineFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/StatusBarPipelineFlags.kt
@@ -49,9 +49,9 @@
         featureFlags.isEnabled(Flags.NEW_STATUS_BAR_WIFI_ICON_BACKEND) || useNewWifiIcon()
 
     /**
-     * Returns true if we should apply some coloring to the wifi icon that was rendered with the new
+     * Returns true if we should apply some coloring to the icons that were rendered with the new
      * pipeline to help with debugging.
      */
-    fun useWifiDebugColoring(): Boolean =
+    fun useDebugColoring(): Boolean =
         featureFlags.isEnabled(Flags.NEW_STATUS_BAR_ICONS_DEBUG_COLORING)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
index 0d01715..0993ab370 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.pipeline.dagger
 
+import android.net.wifi.WifiManager
 import com.android.systemui.CoreStartable
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.log.table.TableLogBuffer
@@ -35,8 +36,11 @@
 import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxyImpl
 import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository
 import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepositoryImpl
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.RealWifiRepository
 import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository
 import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositorySwitcher
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.DisabledWifiRepository
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl
 import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor
 import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractorImpl
 import dagger.Binds
@@ -78,9 +82,23 @@
     @ClassKey(MobileUiAdapter::class)
     abstract fun bindFeature(impl: MobileUiAdapter): CoreStartable
 
-    @Module
     companion object {
-        @JvmStatic
+        @Provides
+        @SysUISingleton
+        fun provideRealWifiRepository(
+            wifiManager: WifiManager?,
+            disabledWifiRepository: DisabledWifiRepository,
+            wifiRepositoryImplFactory: WifiRepositoryImpl.Factory,
+        ): RealWifiRepository {
+            // If we have a null [WifiManager], then the wifi repository should be permanently
+            // disabled.
+            return if (wifiManager == null) {
+                disabledWifiRepository
+            } else {
+                wifiRepositoryImplFactory.create(wifiManager)
+            }
+        }
+
         @Provides
         @SysUISingleton
         @WifiTableLog
@@ -88,7 +106,6 @@
             return factory.create("WifiTableLog", 100)
         }
 
-        @JvmStatic
         @Provides
         @SysUISingleton
         @AirplaneTableLog
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileConnectionModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileConnectionModel.kt
index 1aa954f..012b9ec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileConnectionModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileConnectionModel.kt
@@ -51,6 +51,16 @@
      */
     val operatorAlphaShort: String? = null,
 
+    /**
+     * TODO (b/263167683): Clarify this field
+     *
+     * This check comes from [com.android.settingslib.Utils.isInService]. It is intended to be a
+     * mapping from a ServiceState to a notion of connectivity. Notably, it will consider a
+     * connection to be in-service if either the voice registration state is IN_SERVICE or the data
+     * registration state is IN_SERVICE and NOT IWLAN.
+     */
+    val isInService: Boolean = false,
+
     /** Fields below from [SignalStrengthsListener.onSignalStrengthsChanged] */
     val isGsm: Boolean = false,
     @IntRange(from = 0, to = 4)
@@ -99,6 +109,10 @@
             row.logChange(COL_OPERATOR, operatorAlphaShort)
         }
 
+        if (prevVal.isInService != isInService) {
+            row.logChange(COL_IS_IN_SERVICE, isInService)
+        }
+
         if (prevVal.isGsm != isGsm) {
             row.logChange(COL_IS_GSM, isGsm)
         }
@@ -129,6 +143,7 @@
         row.logChange(COL_EMERGENCY, isEmergencyOnly)
         row.logChange(COL_ROAMING, isRoaming)
         row.logChange(COL_OPERATOR, operatorAlphaShort)
+        row.logChange(COL_IS_IN_SERVICE, isInService)
         row.logChange(COL_IS_GSM, isGsm)
         row.logChange(COL_CDMA_LEVEL, cdmaLevel)
         row.logChange(COL_PRIMARY_LEVEL, primaryLevel)
@@ -141,6 +156,7 @@
         const val COL_EMERGENCY = "EmergencyOnly"
         const val COL_ROAMING = "Roaming"
         const val COL_OPERATOR = "OperatorName"
+        const val COL_IS_IN_SERVICE = "IsInService"
         const val COL_IS_GSM = "IsGsm"
         const val COL_CDMA_LEVEL = "CdmaLevel"
         const val COL_PRIMARY_LEVEL = "PrimaryLevel"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/ResolvedNetworkType.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/ResolvedNetworkType.kt
index dd93541..5562e73 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/ResolvedNetworkType.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/ResolvedNetworkType.kt
@@ -17,7 +17,8 @@
 package com.android.systemui.statusbar.pipeline.mobile.data.model
 
 import android.telephony.Annotation.NetworkType
-import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
+import com.android.settingslib.SignalIcon
+import com.android.settingslib.mobile.TelephonyIcons
 import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
 
 /**
@@ -26,21 +27,25 @@
  * methods on [MobileMappingsProxy] to generate an icon lookup key.
  */
 sealed interface ResolvedNetworkType {
-    @NetworkType val type: Int
     val lookupKey: String
 
     object UnknownNetworkType : ResolvedNetworkType {
-        override val type: Int = NETWORK_TYPE_UNKNOWN
         override val lookupKey: String = "unknown"
     }
 
     data class DefaultNetworkType(
-        @NetworkType override val type: Int,
         override val lookupKey: String,
     ) : ResolvedNetworkType
 
     data class OverrideNetworkType(
-        @NetworkType override val type: Int,
         override val lookupKey: String,
     ) : ResolvedNetworkType
+
+    /** Represents the carrier merged network. See [CarrierMergedConnectionRepository]. */
+    object CarrierMergedNetworkType : ResolvedNetworkType {
+        // Effectively unused since [iconGroupOverride] is used instead.
+        override val lookupKey: String = "cwf"
+
+        val iconGroupOverride: SignalIcon.MobileIconGroup = TelephonyIcons.CARRIER_MERGED_WIFI
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt
index 40e9ba1..6187f64 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt
@@ -17,13 +17,11 @@
 package com.android.systemui.statusbar.pipeline.mobile.data.repository
 
 import android.telephony.SubscriptionInfo
-import android.telephony.SubscriptionManager
 import android.telephony.TelephonyCallback
 import android.telephony.TelephonyManager
 import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
-import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.StateFlow
 
 /**
@@ -51,14 +49,13 @@
      * A flow that aggregates all necessary callbacks from [TelephonyCallback] into a single
      * listener + model.
      */
-    val connectionInfo: Flow<MobileConnectionModel>
+    val connectionInfo: StateFlow<MobileConnectionModel>
+
+    /** The total number of levels. Used with [SignalDrawable]. */
+    val numberOfLevels: StateFlow<Int>
+
     /** Observable tracking [TelephonyManager.isDataConnectionAllowed] */
     val dataEnabled: StateFlow<Boolean>
-    /**
-     * True if this connection represents the default subscription per
-     * [SubscriptionManager.getDefaultDataSubscriptionId]
-     */
-    val isDefaultDataSubscription: StateFlow<Boolean>
 
     /**
      * See [TelephonyManager.getCdmaEnhancedRoamingIndicatorDisplayNumber]. This bit only matters if
@@ -70,4 +67,9 @@
 
     /** The service provider name for this network connection, or the default name */
     val networkName: StateFlow<NetworkNameModel>
+
+    companion object {
+        /** The default number of levels to use for [numberOfLevels]. */
+        const val DEFAULT_NUM_LEVELS = 4
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt
index 498c0b9..e0d156a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt
@@ -38,6 +38,12 @@
     /** Observable for the subscriptionId of the current mobile data connection */
     val activeMobileDataSubscriptionId: StateFlow<Int>
 
+    /**
+     * Observable event for when the active data sim switches but the group stays the same. E.g.,
+     * CBRS switching would trigger this
+     */
+    val activeSubChangedInGroupEvent: Flow<Unit>
+
     /** Tracks [SubscriptionManager.getDefaultDataSubscriptionId] */
     val defaultDataSubId: StateFlow<Int>
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt
index db9d24f..b939856 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt
@@ -124,6 +124,9 @@
                 realRepository.activeMobileDataSubscriptionId.value
             )
 
+    override val activeSubChangedInGroupEvent: Flow<Unit> =
+        activeRepo.flatMapLatest { it.activeSubChangedInGroupEvent }
+
     override val defaultDataSubRatConfig: StateFlow<MobileMappings.Config> =
         activeRepo
             .flatMapLatest { it.defaultDataSubRatConfig }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt
index b252de8..1088345 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt
@@ -34,15 +34,21 @@
 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel.Mobile
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel.MobileDisabled
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.CarrierMergedConnectionRepository.Companion.createCarrierMergedConnectionModel
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Factory.Companion.MOBILE_CONNECTION_BUFFER_SIZE
 import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.DemoModeWifiDataSource
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.model.FakeWifiEventModel
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.Job
+import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.SharingStarted
@@ -59,15 +65,19 @@
 class DemoMobileConnectionsRepository
 @Inject
 constructor(
-    private val dataSource: DemoModeMobileConnectionDataSource,
+    private val mobileDataSource: DemoModeMobileConnectionDataSource,
+    private val wifiDataSource: DemoModeWifiDataSource,
     @Application private val scope: CoroutineScope,
     context: Context,
     private val logFactory: TableLogBufferFactory,
 ) : MobileConnectionsRepository {
 
-    private var demoCommandJob: Job? = null
+    private var mobileDemoCommandJob: Job? = null
+    private var wifiDemoCommandJob: Job? = null
 
-    private var connectionRepoCache = mutableMapOf<Int, DemoMobileConnectionRepository>()
+    private var carrierMergedSubId: Int? = null
+
+    private var connectionRepoCache = mutableMapOf<Int, CacheContainer>()
     private val subscriptionInfoCache = mutableMapOf<Int, SubscriptionModel>()
     val demoModeFinishedEvent = MutableSharedFlow<Unit>(extraBufferCapacity = 1)
 
@@ -111,6 +121,9 @@
                 subscriptions.value.firstOrNull()?.subscriptionId ?: INVALID_SUBSCRIPTION_ID
             )
 
+    // TODO(b/261029387): consider adding a demo command for this
+    override val activeSubChangedInGroupEvent: Flow<Unit> = flowOf()
+
     /** Demo mode doesn't currently support modifications to the mobile mappings */
     override val defaultDataSubRatConfig =
         MutableStateFlow(MobileMappings.Config.readConfig(context))
@@ -140,80 +153,131 @@
     private fun <K, V> Map<K, V>.reverse() = entries.associateBy({ it.value }) { it.key }
 
     // TODO(b/261029387): add a command for this value
-    override val defaultDataSubId =
-        activeMobileDataSubscriptionId.stateIn(
-            scope,
-            SharingStarted.WhileSubscribed(),
-            INVALID_SUBSCRIPTION_ID
-        )
+    override val defaultDataSubId = MutableStateFlow(INVALID_SUBSCRIPTION_ID)
 
     // TODO(b/261029387): not yet supported
-    override val defaultMobileNetworkConnectivity = MutableStateFlow(MobileConnectivityModel())
+    override val defaultMobileNetworkConnectivity =
+        MutableStateFlow(MobileConnectivityModel(isConnected = true, isValidated = true))
 
     override fun getRepoForSubId(subId: Int): DemoMobileConnectionRepository {
-        return connectionRepoCache[subId]
-            ?: createDemoMobileConnectionRepo(subId).also { connectionRepoCache[subId] = it }
+        val current = connectionRepoCache[subId]?.repo
+        if (current != null) {
+            return current
+        }
+
+        val new = createDemoMobileConnectionRepo(subId)
+        connectionRepoCache[subId] = new
+        return new.repo
     }
 
-    private fun createDemoMobileConnectionRepo(subId: Int): DemoMobileConnectionRepository {
-        val tableLogBuffer = logFactory.create("DemoMobileConnectionLog [$subId]", 100)
+    private fun createDemoMobileConnectionRepo(subId: Int): CacheContainer {
+        val tableLogBuffer =
+            logFactory.getOrCreate(
+                "DemoMobileConnectionLog [$subId]",
+                MOBILE_CONNECTION_BUFFER_SIZE,
+            )
 
-        return DemoMobileConnectionRepository(
-            subId,
-            tableLogBuffer,
-        )
+        val repo =
+            DemoMobileConnectionRepository(
+                subId,
+                tableLogBuffer,
+            )
+        return CacheContainer(repo, lastMobileState = null)
     }
 
     override val globalMobileDataSettingChangedEvent = MutableStateFlow(Unit)
 
     fun startProcessingCommands() {
-        demoCommandJob =
+        mobileDemoCommandJob =
             scope.launch {
-                dataSource.mobileEvents.filterNotNull().collect { event -> processEvent(event) }
+                mobileDataSource.mobileEvents.filterNotNull().collect { event ->
+                    processMobileEvent(event)
+                }
+            }
+        wifiDemoCommandJob =
+            scope.launch {
+                wifiDataSource.wifiEvents.filterNotNull().collect { event ->
+                    processWifiEvent(event)
+                }
             }
     }
 
     fun stopProcessingCommands() {
-        demoCommandJob?.cancel()
+        mobileDemoCommandJob?.cancel()
+        wifiDemoCommandJob?.cancel()
         _subscriptions.value = listOf()
         connectionRepoCache.clear()
         subscriptionInfoCache.clear()
     }
 
-    private fun processEvent(event: FakeNetworkEventModel) {
+    private fun processMobileEvent(event: FakeNetworkEventModel) {
         when (event) {
             is Mobile -> {
                 processEnabledMobileState(event)
             }
             is MobileDisabled -> {
-                processDisabledMobileState(event)
+                maybeRemoveSubscription(event.subId)
             }
         }
     }
 
+    private fun processWifiEvent(event: FakeWifiEventModel) {
+        when (event) {
+            is FakeWifiEventModel.WifiDisabled -> disableCarrierMerged()
+            is FakeWifiEventModel.Wifi -> disableCarrierMerged()
+            is FakeWifiEventModel.CarrierMerged -> processCarrierMergedWifiState(event)
+        }
+    }
+
     private fun processEnabledMobileState(state: Mobile) {
         // get or create the connection repo, and set its values
         val subId = state.subId ?: DEFAULT_SUB_ID
         maybeCreateSubscription(subId)
 
         val connection = getRepoForSubId(subId)
+        connectionRepoCache[subId]?.lastMobileState = state
+
+        // TODO(b/261029387): until we have a command, use the most recent subId
+        defaultDataSubId.value = subId
+
         // This is always true here, because we split out disabled states at the data-source level
         connection.dataEnabled.value = true
-        connection.isDefaultDataSubscription.value = state.dataType != null
         connection.networkName.value = NetworkNameModel.Derived(state.name)
 
         connection.cdmaRoaming.value = state.roaming
         connection.connectionInfo.value = state.toMobileConnectionModel()
     }
 
-    private fun processDisabledMobileState(state: MobileDisabled) {
+    private fun processCarrierMergedWifiState(event: FakeWifiEventModel.CarrierMerged) {
+        // The new carrier merged connection is for a different sub ID, so disable carrier merged
+        // for the current (now old) sub
+        if (carrierMergedSubId != event.subscriptionId) {
+            disableCarrierMerged()
+        }
+
+        // get or create the connection repo, and set its values
+        val subId = event.subscriptionId
+        maybeCreateSubscription(subId)
+        carrierMergedSubId = subId
+
+        val connection = getRepoForSubId(subId)
+        // This is always true here, because we split out disabled states at the data-source level
+        connection.dataEnabled.value = true
+        connection.networkName.value = NetworkNameModel.Derived(CARRIER_MERGED_NAME)
+        connection.numberOfLevels.value = event.numberOfLevels
+        connection.cdmaRoaming.value = false
+        connection.connectionInfo.value = event.toMobileConnectionModel()
+        Log.e("CCS", "output connection info = ${connection.connectionInfo.value}")
+    }
+
+    private fun maybeRemoveSubscription(subId: Int?) {
         if (_subscriptions.value.isEmpty()) {
             // Nothing to do here
             return
         }
 
-        val subId =
-            state.subId
+        val finalSubId =
+            subId
                 ?: run {
                     // For sake of usability, we can allow for no subId arg if there is only one
                     // subscription
@@ -231,7 +295,21 @@
                     _subscriptions.value[0].subscriptionId
                 }
 
-        removeSubscription(subId)
+        removeSubscription(finalSubId)
+    }
+
+    private fun disableCarrierMerged() {
+        val currentCarrierMergedSubId = carrierMergedSubId ?: return
+
+        // If this sub ID was previously not carrier merged, we should reset it to its previous
+        // connection.
+        val lastMobileState = connectionRepoCache[carrierMergedSubId]?.lastMobileState
+        if (lastMobileState != null) {
+            processEnabledMobileState(lastMobileState)
+        } else {
+            // Otherwise, just remove the subscription entirely
+            removeSubscription(currentCarrierMergedSubId)
+        }
     }
 
     private fun removeSubscription(subId: Int) {
@@ -247,6 +325,7 @@
         return MobileConnectionModel(
             isEmergencyOnly = false, // TODO(b/261029387): not yet supported
             isRoaming = roaming,
+            isInService = (level ?: 0) > 0,
             isGsm = false, // TODO(b/261029387): not yet supported
             cdmaLevel = level ?: 0,
             primaryLevel = level ?: 0,
@@ -258,9 +337,13 @@
         )
     }
 
+    private fun FakeWifiEventModel.CarrierMerged.toMobileConnectionModel(): MobileConnectionModel {
+        return createCarrierMergedConnectionModel(this.level)
+    }
+
     private fun SignalIcon.MobileIconGroup?.toResolvedNetworkType(): ResolvedNetworkType {
         val key = mobileMappingsReverseLookup.value[this] ?: "dis"
-        return DefaultNetworkType(DEMO_NET_TYPE, key)
+        return DefaultNetworkType(key)
     }
 
     companion object {
@@ -268,19 +351,25 @@
 
         private const val DEFAULT_SUB_ID = 1
 
-        private const val DEMO_NET_TYPE = 1234
+        private const val CARRIER_MERGED_NAME = "Carrier Merged Network"
     }
 }
 
+class CacheContainer(
+    var repo: DemoMobileConnectionRepository,
+    /** The last received [Mobile] event. Used when switching from carrier merged back to mobile. */
+    var lastMobileState: Mobile?,
+)
+
 class DemoMobileConnectionRepository(
     override val subId: Int,
     override val tableLogBuffer: TableLogBuffer,
 ) : MobileConnectionRepository {
     override val connectionInfo = MutableStateFlow(MobileConnectionModel())
 
-    override val dataEnabled = MutableStateFlow(true)
+    override val numberOfLevels = MutableStateFlow(DEFAULT_NUM_LEVELS)
 
-    override val isDefaultDataSubscription = MutableStateFlow(true)
+    override val dataEnabled = MutableStateFlow(true)
 
     override val cdmaRoaming = MutableStateFlow(false)
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepository.kt
new file mode 100644
index 0000000..c783b12
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepository.kt
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.mobile.data.repository.prod
+
+import android.util.Log
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
+import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel
+import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
+import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
+import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
+import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
+
+/**
+ * A repository implementation for a carrier merged (aka VCN) network. A carrier merged network is
+ * delivered to SysUI as a wifi network (see [WifiNetworkModel.CarrierMerged], but is visually
+ * displayed as a mobile network triangle.
+ *
+ * See [android.net.wifi.WifiInfo.isCarrierMerged] for more information.
+ *
+ * See [MobileConnectionRepositoryImpl] for a repository implementation of a typical mobile
+ * connection.
+ */
+class CarrierMergedConnectionRepository(
+    override val subId: Int,
+    override val tableLogBuffer: TableLogBuffer,
+    defaultNetworkName: NetworkNameModel,
+    @Application private val scope: CoroutineScope,
+    val wifiRepository: WifiRepository,
+) : MobileConnectionRepository {
+
+    /**
+     * Outputs the carrier merged network to use, or null if we don't have a valid carrier merged
+     * network.
+     */
+    private val network: Flow<WifiNetworkModel.CarrierMerged?> =
+        combine(
+            wifiRepository.isWifiEnabled,
+            wifiRepository.isWifiDefault,
+            wifiRepository.wifiNetwork,
+        ) { isEnabled, isDefault, network ->
+            when {
+                !isEnabled -> null
+                !isDefault -> null
+                network !is WifiNetworkModel.CarrierMerged -> null
+                network.subscriptionId != subId -> {
+                    Log.w(
+                        TAG,
+                        "Connection repo subId=$subId " +
+                            "does not equal wifi repo subId=${network.subscriptionId}; " +
+                            "not showing carrier merged"
+                    )
+                    null
+                }
+                else -> network
+            }
+        }
+
+    override val connectionInfo: StateFlow<MobileConnectionModel> =
+        network
+            .map { it.toMobileConnectionModel() }
+            .stateIn(scope, SharingStarted.WhileSubscribed(), MobileConnectionModel())
+
+    // TODO(b/238425913): Add logging to this class.
+    // TODO(b/238425913): Make sure SignalStrength.getEmptyState is used when appropriate.
+
+    // Carrier merged is never roaming.
+    override val cdmaRoaming: StateFlow<Boolean> = MutableStateFlow(false).asStateFlow()
+
+    // TODO(b/238425913): Fetch the carrier merged network name.
+    override val networkName: StateFlow<NetworkNameModel> =
+        flowOf(defaultNetworkName)
+            .stateIn(scope, SharingStarted.WhileSubscribed(), defaultNetworkName)
+
+    override val numberOfLevels: StateFlow<Int> =
+        wifiRepository.wifiNetwork
+            .map {
+                if (it is WifiNetworkModel.CarrierMerged) {
+                    it.numberOfLevels
+                } else {
+                    DEFAULT_NUM_LEVELS
+                }
+            }
+            .stateIn(scope, SharingStarted.WhileSubscribed(), DEFAULT_NUM_LEVELS)
+
+    override val dataEnabled: StateFlow<Boolean> = wifiRepository.isWifiEnabled
+
+    private fun WifiNetworkModel.CarrierMerged?.toMobileConnectionModel(): MobileConnectionModel {
+        if (this == null) {
+            return MobileConnectionModel()
+        }
+
+        return createCarrierMergedConnectionModel(level)
+    }
+
+    companion object {
+        /**
+         * Creates an instance of [MobileConnectionModel] that represents a carrier merged network
+         * with the given [level].
+         */
+        fun createCarrierMergedConnectionModel(level: Int): MobileConnectionModel {
+            return MobileConnectionModel(
+                primaryLevel = level,
+                cdmaLevel = level,
+                // A [WifiNetworkModel.CarrierMerged] instance is always connected.
+                // (A [WifiNetworkModel.Inactive] represents a disconnected network.)
+                dataConnectionState = DataConnectionState.Connected,
+                // TODO(b/238425913): This should come from [WifiRepository.wifiActivity].
+                dataActivityDirection =
+                    DataActivityModel(
+                        hasActivityIn = false,
+                        hasActivityOut = false,
+                    ),
+                resolvedNetworkType = ResolvedNetworkType.CarrierMergedNetworkType,
+                // Carrier merged is never roaming
+                isRoaming = false,
+
+                // TODO(b/238425913): Verify that these fields never change for carrier merged.
+                isEmergencyOnly = false,
+                operatorAlphaShort = null,
+                isInService = true,
+                isGsm = false,
+                carrierNetworkChangeActive = false,
+            )
+        }
+    }
+
+    @SysUISingleton
+    class Factory
+    @Inject
+    constructor(
+        @Application private val scope: CoroutineScope,
+        private val wifiRepository: WifiRepository,
+    ) {
+        fun build(
+            subId: Int,
+            mobileLogger: TableLogBuffer,
+            defaultNetworkName: NetworkNameModel,
+        ): MobileConnectionRepository {
+            return CarrierMergedConnectionRepository(
+                subId,
+                mobileLogger,
+                defaultNetworkName,
+                scope,
+                wifiRepository,
+            )
+        }
+    }
+}
+
+private const val TAG = "CarrierMergedConnectionRepository"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepository.kt
new file mode 100644
index 0000000..0f30ae2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepository.kt
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.mobile.data.repository.prod
+
+import androidx.annotation.VisibleForTesting
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.log.table.TableLogBufferFactory
+import com.android.systemui.log.table.logDiffsForTable
+import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.mapLatest
+import kotlinx.coroutines.flow.stateIn
+
+/**
+ * A repository that fully implements a mobile connection.
+ *
+ * This connection could either be a typical mobile connection (see [MobileConnectionRepositoryImpl]
+ * or a carrier merged connection (see [CarrierMergedConnectionRepository]). This repository
+ * switches between the two types of connections based on whether the connection is currently
+ * carrier merged (see [setIsCarrierMerged]).
+ */
+@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
+@OptIn(ExperimentalCoroutinesApi::class)
+class FullMobileConnectionRepository(
+    override val subId: Int,
+    startingIsCarrierMerged: Boolean,
+    override val tableLogBuffer: TableLogBuffer,
+    private val defaultNetworkName: NetworkNameModel,
+    private val networkNameSeparator: String,
+    private val globalMobileDataSettingChangedEvent: Flow<Unit>,
+    @Application scope: CoroutineScope,
+    private val mobileRepoFactory: MobileConnectionRepositoryImpl.Factory,
+    private val carrierMergedRepoFactory: CarrierMergedConnectionRepository.Factory,
+) : MobileConnectionRepository {
+    /**
+     * Sets whether this connection is a typical mobile connection or a carrier merged connection.
+     */
+    fun setIsCarrierMerged(isCarrierMerged: Boolean) {
+        _isCarrierMerged.value = isCarrierMerged
+    }
+
+    /**
+     * Returns true if this repo is currently for a carrier merged connection and false otherwise.
+     */
+    @VisibleForTesting fun getIsCarrierMerged() = _isCarrierMerged.value
+
+    private val _isCarrierMerged = MutableStateFlow(startingIsCarrierMerged)
+    private val isCarrierMerged: StateFlow<Boolean> =
+        _isCarrierMerged
+            .logDiffsForTable(
+                tableLogBuffer,
+                columnPrefix = "",
+                columnName = "isCarrierMerged",
+                initialValue = startingIsCarrierMerged,
+            )
+            .stateIn(scope, SharingStarted.WhileSubscribed(), startingIsCarrierMerged)
+
+    private val mobileRepo: MobileConnectionRepository by lazy {
+        mobileRepoFactory.build(
+            subId,
+            tableLogBuffer,
+            defaultNetworkName,
+            networkNameSeparator,
+            globalMobileDataSettingChangedEvent,
+        )
+    }
+
+    private val carrierMergedRepo: MobileConnectionRepository by lazy {
+        carrierMergedRepoFactory.build(subId, tableLogBuffer, defaultNetworkName)
+    }
+
+    @VisibleForTesting
+    internal val activeRepo: StateFlow<MobileConnectionRepository> = run {
+        val initial =
+            if (startingIsCarrierMerged) {
+                carrierMergedRepo
+            } else {
+                mobileRepo
+            }
+
+        this.isCarrierMerged
+            .mapLatest { isCarrierMerged ->
+                if (isCarrierMerged) {
+                    carrierMergedRepo
+                } else {
+                    mobileRepo
+                }
+            }
+            .stateIn(scope, SharingStarted.WhileSubscribed(), initial)
+    }
+
+    override val cdmaRoaming =
+        activeRepo
+            .flatMapLatest { it.cdmaRoaming }
+            .stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.cdmaRoaming.value)
+
+    override val connectionInfo =
+        activeRepo
+            .flatMapLatest { it.connectionInfo }
+            .stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.connectionInfo.value)
+
+    override val dataEnabled =
+        activeRepo
+            .flatMapLatest { it.dataEnabled }
+            .stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.dataEnabled.value)
+
+    override val numberOfLevels =
+        activeRepo
+            .flatMapLatest { it.numberOfLevels }
+            .stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.numberOfLevels.value)
+
+    override val networkName =
+        activeRepo
+            .flatMapLatest { it.networkName }
+            .stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.networkName.value)
+
+    class Factory
+    @Inject
+    constructor(
+        @Application private val scope: CoroutineScope,
+        private val logFactory: TableLogBufferFactory,
+        private val mobileRepoFactory: MobileConnectionRepositoryImpl.Factory,
+        private val carrierMergedRepoFactory: CarrierMergedConnectionRepository.Factory,
+    ) {
+        fun build(
+            subId: Int,
+            startingIsCarrierMerged: Boolean,
+            defaultNetworkName: NetworkNameModel,
+            networkNameSeparator: String,
+            globalMobileDataSettingChangedEvent: Flow<Unit>,
+        ): FullMobileConnectionRepository {
+            val mobileLogger =
+                logFactory.getOrCreate(tableBufferLogName(subId), MOBILE_CONNECTION_BUFFER_SIZE)
+
+            return FullMobileConnectionRepository(
+                subId,
+                startingIsCarrierMerged,
+                mobileLogger,
+                defaultNetworkName,
+                networkNameSeparator,
+                globalMobileDataSettingChangedEvent,
+                scope,
+                mobileRepoFactory,
+                carrierMergedRepoFactory,
+            )
+        }
+
+        companion object {
+            /** The buffer size to use for logging. */
+            const val MOBILE_CONNECTION_BUFFER_SIZE = 100
+
+            /** Returns a log buffer name for a mobile connection with the given [subId]. */
+            fun tableBufferLogName(subId: Int): String = "MobileConnectionLog [$subId]"
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
index 0b9e158..3f2ce40 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
@@ -32,12 +32,12 @@
 import android.telephony.TelephonyManager.ERI_OFF
 import android.telephony.TelephonyManager.EXTRA_SUBSCRIPTION_ID
 import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
+import com.android.settingslib.Utils
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.log.table.TableLogBuffer
-import com.android.systemui.log.table.TableLogBufferFactory
 import com.android.systemui.log.table.logDiffsForTable
 import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
@@ -47,6 +47,7 @@
 import com.android.systemui.statusbar.pipeline.mobile.data.model.toDataConnectionType
 import com.android.systemui.statusbar.pipeline.mobile.data.model.toNetworkNameModel
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
 import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
 import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel
@@ -62,11 +63,16 @@
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.mapLatest
 import kotlinx.coroutines.flow.merge
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.stateIn
 
+/**
+ * A repository implementation for a typical mobile connection (as opposed to a carrier merged
+ * connection -- see [CarrierMergedConnectionRepository]).
+ */
 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
 @OptIn(ExperimentalCoroutinesApi::class)
 class MobileConnectionRepositoryImpl(
@@ -77,7 +83,6 @@
     private val telephonyManager: TelephonyManager,
     private val globalSettings: GlobalSettings,
     broadcastDispatcher: BroadcastDispatcher,
-    defaultDataSubId: StateFlow<Int>,
     globalMobileDataSettingChangedEvent: Flow<Unit>,
     mobileMappingsProxy: MobileMappingsProxy,
     bgDispatcher: CoroutineDispatcher,
@@ -117,6 +122,7 @@
                                     isEmergencyOnly = serviceState.isEmergencyOnly,
                                     isRoaming = serviceState.roaming,
                                     operatorAlphaShort = serviceState.operatorAlphaShort,
+                                    isInService = Utils.isInService(serviceState),
                                 )
                             trySend(state)
                         }
@@ -183,14 +189,12 @@
                                         OVERRIDE_NETWORK_TYPE_NONE
                                 ) {
                                     DefaultNetworkType(
-                                        telephonyDisplayInfo.networkType,
                                         mobileMappingsProxy.toIconKey(
                                             telephonyDisplayInfo.networkType
                                         )
                                     )
                                 } else {
                                     OverrideNetworkType(
-                                        telephonyDisplayInfo.overrideNetworkType,
                                         mobileMappingsProxy.toIconKeyOverride(
                                             telephonyDisplayInfo.overrideNetworkType
                                         )
@@ -212,6 +216,12 @@
             .stateIn(scope, SharingStarted.WhileSubscribed(), state)
     }
 
+    // This will become variable based on [CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL]
+    // once it's wired up inside of [CarrierConfigTracker].
+    override val numberOfLevels: StateFlow<Int> =
+        flowOf(DEFAULT_NUM_LEVELS)
+            .stateIn(scope, SharingStarted.WhileSubscribed(), DEFAULT_NUM_LEVELS)
+
     /** Produces whenever the mobile data setting changes for this subId */
     private val localMobileDataSettingChangedEvent: Flow<Unit> = conflatedCallbackFlow {
         val observer =
@@ -282,20 +292,6 @@
 
     private fun dataConnectionAllowed(): Boolean = telephonyManager.isDataConnectionAllowed
 
-    override val isDefaultDataSubscription: StateFlow<Boolean> = run {
-        val initialValue = defaultDataSubId.value == subId
-        defaultDataSubId
-            .mapLatest { it == subId }
-            .distinctUntilChanged()
-            .logDiffsForTable(
-                mobileLogger,
-                columnPrefix = "",
-                columnName = "isDefaultDataSub",
-                initialValue = initialValue,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), initialValue)
-    }
-
     class Factory
     @Inject
     constructor(
@@ -305,19 +301,16 @@
         private val logger: ConnectivityPipelineLogger,
         private val globalSettings: GlobalSettings,
         private val mobileMappingsProxy: MobileMappingsProxy,
-        private val logFactory: TableLogBufferFactory,
         @Background private val bgDispatcher: CoroutineDispatcher,
         @Application private val scope: CoroutineScope,
     ) {
         fun build(
             subId: Int,
+            mobileLogger: TableLogBuffer,
             defaultNetworkName: NetworkNameModel,
             networkNameSeparator: String,
-            defaultDataSubId: StateFlow<Int>,
             globalMobileDataSettingChangedEvent: Flow<Unit>,
         ): MobileConnectionRepository {
-            val mobileLogger = logFactory.create(tableBufferLogName(subId), 100)
-
             return MobileConnectionRepositoryImpl(
                 context,
                 subId,
@@ -326,7 +319,6 @@
                 telephonyManager.createForSubscriptionId(subId),
                 globalSettings,
                 broadcastDispatcher,
-                defaultDataSubId,
                 globalMobileDataSettingChangedEvent,
                 mobileMappingsProxy,
                 bgDispatcher,
@@ -336,8 +328,4 @@
             )
         }
     }
-
-    companion object {
-        fun tableBufferLogName(subId: Int): String = "MobileConnectionLog [$subId]"
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
index d407abe..510482d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
@@ -47,11 +47,13 @@
 import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
 import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logInputChange
+import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository
+import com.android.systemui.util.kotlin.pairwiseBy
 import com.android.systemui.util.settings.GlobalSettings
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
@@ -64,6 +66,8 @@
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.mapLatest
 import kotlinx.coroutines.flow.merge
@@ -87,9 +91,14 @@
     private val context: Context,
     @Background private val bgDispatcher: CoroutineDispatcher,
     @Application private val scope: CoroutineScope,
-    private val mobileConnectionRepositoryFactory: MobileConnectionRepositoryImpl.Factory
+    // Some "wifi networks" should be rendered as a mobile connection, which is why the wifi
+    // repository is an input to the mobile repository.
+    // See [CarrierMergedConnectionRepository] for details.
+    wifiRepository: WifiRepository,
+    private val fullMobileRepoFactory: FullMobileConnectionRepository.Factory,
 ) : MobileConnectionsRepository {
-    private var subIdRepositoryCache: MutableMap<Int, MobileConnectionRepository> = mutableMapOf()
+    private var subIdRepositoryCache: MutableMap<Int, FullMobileConnectionRepository> =
+        mutableMapOf()
 
     private val defaultNetworkName =
         NetworkNameModel.Default(
@@ -99,30 +108,43 @@
     private val networkNameSeparator: String =
         context.getString(R.string.status_bar_network_name_separator)
 
+    private val carrierMergedSubId: StateFlow<Int?> =
+        wifiRepository.wifiNetwork
+            .mapLatest {
+                if (it is WifiNetworkModel.CarrierMerged) {
+                    it.subscriptionId
+                } else {
+                    null
+                }
+            }
+            .distinctUntilChanged()
+            .stateIn(scope, started = SharingStarted.WhileSubscribed(), null)
+
+    private val mobileSubscriptionsChangeEvent: Flow<Unit> = conflatedCallbackFlow {
+        val callback =
+            object : SubscriptionManager.OnSubscriptionsChangedListener() {
+                override fun onSubscriptionsChanged() {
+                    trySend(Unit)
+                }
+            }
+
+        subscriptionManager.addOnSubscriptionsChangedListener(
+            bgDispatcher.asExecutor(),
+            callback,
+        )
+
+        awaitClose { subscriptionManager.removeOnSubscriptionsChangedListener(callback) }
+    }
+
     /**
      * State flow that emits the set of mobile data subscriptions, each represented by its own
-     * [SubscriptionInfo]. We probably only need the [SubscriptionInfo.getSubscriptionId] of each
-     * info object, but for now we keep track of the infos themselves.
+     * [SubscriptionModel].
      */
     override val subscriptions: StateFlow<List<SubscriptionModel>> =
-        conflatedCallbackFlow {
-                val callback =
-                    object : SubscriptionManager.OnSubscriptionsChangedListener() {
-                        override fun onSubscriptionsChanged() {
-                            trySend(Unit)
-                        }
-                    }
-
-                subscriptionManager.addOnSubscriptionsChangedListener(
-                    bgDispatcher.asExecutor(),
-                    callback,
-                )
-
-                awaitClose { subscriptionManager.removeOnSubscriptionsChangedListener(callback) }
-            }
+        merge(mobileSubscriptionsChangeEvent, carrierMergedSubId)
             .mapLatest { fetchSubscriptionsList().map { it.toSubscriptionModel() } }
             .logInputChange(logger, "onSubscriptionsChanged")
-            .onEach { infos -> dropUnusedReposFromCache(infos) }
+            .onEach { infos -> updateRepos(infos) }
             .stateIn(scope, started = SharingStarted.WhileSubscribed(), listOf())
 
     /** StateFlow that keeps track of the current active mobile data subscription */
@@ -189,7 +211,7 @@
             .distinctUntilChanged()
             .logInputChange(logger, "defaultMobileIconGroup")
 
-    override fun getRepoForSubId(subId: Int): MobileConnectionRepository {
+    override fun getRepoForSubId(subId: Int): FullMobileConnectionRepository {
         if (!isValidSubId(subId)) {
             throw IllegalArgumentException(
                 "subscriptionId $subId is not in the list of valid subscriptions"
@@ -255,6 +277,35 @@
             .logInputChange(logger, "defaultMobileNetworkConnectivity")
             .stateIn(scope, SharingStarted.WhileSubscribed(), MobileConnectivityModel())
 
+    /**
+     * Flow that tracks the active mobile data subscriptions. Emits `true` whenever the active data
+     * subscription Id changes but the subscription group remains the same. In these cases, we want
+     * to retain the previous subscription's validation status for up to 2s to avoid flickering the
+     * icon.
+     *
+     * TODO(b/265164432): we should probably expose all change events, not just same group
+     */
+    @SuppressLint("MissingPermission")
+    override val activeSubChangedInGroupEvent =
+        flow {
+                activeMobileDataSubscriptionId.pairwiseBy { prevVal: Int, newVal: Int ->
+                    if (!defaultMobileNetworkConnectivity.value.isValidated) {
+                        return@pairwiseBy
+                    }
+                    val prevSub = subscriptionManager.getActiveSubscriptionInfo(prevVal)
+                    val nextSub = subscriptionManager.getActiveSubscriptionInfo(newVal)
+
+                    if (prevSub == null || nextSub == null) {
+                        return@pairwiseBy
+                    }
+
+                    if (prevSub.groupUuid != null && prevSub.groupUuid == nextSub.groupUuid) {
+                        emit(Unit)
+                    }
+                }
+            }
+            .flowOn(bgDispatcher)
+
     private fun isValidSubId(subId: Int): Boolean {
         subscriptions.value.forEach {
             if (it.subscriptionId == subId) {
@@ -267,16 +318,27 @@
 
     @VisibleForTesting fun getSubIdRepoCache() = subIdRepositoryCache
 
-    private fun createRepositoryForSubId(subId: Int): MobileConnectionRepository {
-        return mobileConnectionRepositoryFactory.build(
+    private fun createRepositoryForSubId(subId: Int): FullMobileConnectionRepository {
+        return fullMobileRepoFactory.build(
             subId,
+            isCarrierMerged(subId),
             defaultNetworkName,
             networkNameSeparator,
-            defaultDataSubId,
             globalMobileDataSettingChangedEvent,
         )
     }
 
+    private fun updateRepos(newInfos: List<SubscriptionModel>) {
+        dropUnusedReposFromCache(newInfos)
+        subIdRepositoryCache.forEach { (subId, repo) ->
+            repo.setIsCarrierMerged(isCarrierMerged(subId))
+        }
+    }
+
+    private fun isCarrierMerged(subId: Int): Boolean {
+        return subId == carrierMergedSubId.value
+    }
+
     private fun dropUnusedReposFromCache(newInfos: List<SubscriptionModel>) {
         // Remove any connection repository from the cache that isn't in the new set of IDs. They
         // will get garbage collected once their subscribers go away
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
index e6686dc..9cdff96 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
@@ -18,17 +18,18 @@
 
 import android.telephony.CarrierConfigManager
 import com.android.settingslib.SignalIcon.MobileIconGroup
+import com.android.settingslib.mobile.TelephonyIcons.NOT_DEFAULT_DATA
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState.Connected
+import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
+import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
 import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
-import com.android.systemui.util.CarrierConfigTracker
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.combine
@@ -42,11 +43,31 @@
     /** The current mobile data activity */
     val activity: Flow<DataActivityModel>
 
+    /**
+     * This bit is meant to be `true` if and only if the default network capabilities (see
+     * [android.net.ConnectivityManager.registerDefaultNetworkCallback]) result in a network that
+     * has the [android.net.NetworkCapabilities.TRANSPORT_CELLULAR] represented.
+     *
+     * Note that this differs from [isDataConnected], which is tracked by telephony and has to do
+     * with the state of using this mobile connection for data as opposed to just voice. It is
+     * possible for a mobile subscription to be connected but not be in a connected data state, and
+     * thus we wouldn't want to show the network type icon.
+     */
+    val isConnected: Flow<Boolean>
+
+    /**
+     * True when telephony tells us that the data state is CONNECTED. See
+     * [android.telephony.TelephonyCallback.DataConnectionStateListener] for more details. We
+     * consider this connection to be serving data, and thus want to show a network type icon, when
+     * data is connected. Other data connection states would typically cause us not to show the icon
+     */
+    val isDataConnected: StateFlow<Boolean>
+
     /** Only true if mobile is the default transport but is not validated, otherwise false */
     val isDefaultConnectionFailed: StateFlow<Boolean>
 
-    /** True when telephony tells us that the data state is CONNECTED */
-    val isDataConnected: StateFlow<Boolean>
+    /** True if we consider this connection to be in service, i.e. can make calls */
+    val isInService: StateFlow<Boolean>
 
     // TODO(b/256839546): clarify naming of default vs active
     /** True if we want to consider the data connection enabled */
@@ -58,6 +79,9 @@
     /** True if the RAT icon should always be displayed and false otherwise. */
     val alwaysShowDataRatIcon: StateFlow<Boolean>
 
+    /** True if the CDMA level should be preferred over the primary level. */
+    val alwaysUseCdmaLevel: StateFlow<Boolean>
+
     /** Observable for RAT type (network type) indicator */
     val networkTypeIconGroup: StateFlow<MobileIconGroup>
 
@@ -94,8 +118,11 @@
     @Application scope: CoroutineScope,
     defaultSubscriptionHasDataEnabled: StateFlow<Boolean>,
     override val alwaysShowDataRatIcon: StateFlow<Boolean>,
+    override val alwaysUseCdmaLevel: StateFlow<Boolean>,
+    defaultMobileConnectivity: StateFlow<MobileConnectivityModel>,
     defaultMobileIconMapping: StateFlow<Map<String, MobileIconGroup>>,
     defaultMobileIconGroup: StateFlow<MobileIconGroup>,
+    defaultDataSubId: StateFlow<Int>,
     override val isDefaultConnectionFailed: StateFlow<Boolean>,
     connectionRepository: MobileConnectionRepository,
 ) : MobileIconInteractor {
@@ -105,8 +132,19 @@
 
     override val activity = connectionInfo.mapLatest { it.dataActivityDirection }
 
+    override val isConnected: Flow<Boolean> = defaultMobileConnectivity.mapLatest { it.isConnected }
+
     override val isDataEnabled: StateFlow<Boolean> = connectionRepository.dataEnabled
 
+    private val isDefault =
+        defaultDataSubId
+            .mapLatest { connectionRepository.subId == it }
+            .stateIn(
+                scope,
+                SharingStarted.WhileSubscribed(),
+                connectionRepository.subId == defaultDataSubId.value
+            )
+
     override val isDefaultDataEnabled = defaultSubscriptionHasDataEnabled
 
     override val networkName =
@@ -131,8 +169,17 @@
                 connectionInfo,
                 defaultMobileIconMapping,
                 defaultMobileIconGroup,
-            ) { info, mapping, defaultGroup ->
-                mapping[info.resolvedNetworkType.lookupKey] ?: defaultGroup
+                isDefault,
+            ) { info, mapping, defaultGroup, isDefault ->
+                if (!isDefault) {
+                    return@combine NOT_DEFAULT_DATA
+                }
+
+                when (info.resolvedNetworkType) {
+                    is ResolvedNetworkType.CarrierMergedNetworkType ->
+                        info.resolvedNetworkType.iconGroupOverride
+                    else -> mapping[info.resolvedNetworkType.lookupKey] ?: defaultGroup
+                }
             }
             .stateIn(scope, SharingStarted.WhileSubscribed(), defaultMobileIconGroup.value)
 
@@ -154,25 +201,30 @@
             .stateIn(scope, SharingStarted.WhileSubscribed(), false)
 
     override val level: StateFlow<Int> =
-        connectionInfo
-            .mapLatest { connection ->
-                // TODO: incorporate [MobileMappings.Config.alwaysShowCdmaRssi]
-                if (connection.isGsm) {
-                    connection.primaryLevel
-                } else {
-                    connection.cdmaLevel
+        combine(connectionInfo, alwaysUseCdmaLevel) { connection, alwaysUseCdmaLevel ->
+                when {
+                    // GSM connections should never use the CDMA level
+                    connection.isGsm -> connection.primaryLevel
+                    alwaysUseCdmaLevel -> connection.cdmaLevel
+                    else -> connection.primaryLevel
                 }
             }
             .stateIn(scope, SharingStarted.WhileSubscribed(), 0)
 
-    /**
-     * This will become variable based on [CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL]
-     * once it's wired up inside of [CarrierConfigTracker]
-     */
-    override val numberOfLevels: StateFlow<Int> = MutableStateFlow(4)
+    override val numberOfLevels: StateFlow<Int> =
+        connectionRepository.numberOfLevels.stateIn(
+            scope,
+            SharingStarted.WhileSubscribed(),
+            connectionRepository.numberOfLevels.value,
+        )
 
     override val isDataConnected: StateFlow<Boolean> =
         connectionInfo
             .mapLatest { connection -> connection.dataConnectionState == Connected }
             .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+
+    override val isInService =
+        connectionRepository.connectionInfo
+            .mapLatest { it.isInService }
+            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt
index 21f6d8e..9ae38e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt
@@ -23,6 +23,7 @@
 import com.android.settingslib.mobile.TelephonyIcons
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
@@ -31,14 +32,17 @@
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.mapLatest
 import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.flow.transformLatest
 
 /**
  * Business layer logic for the set of mobile subscription icons.
@@ -55,8 +59,24 @@
     val filteredSubscriptions: Flow<List<SubscriptionModel>>
     /** True if the active mobile data subscription has data enabled */
     val activeDataConnectionHasDataEnabled: StateFlow<Boolean>
+
     /** True if the RAT icon should always be displayed and false otherwise. */
     val alwaysShowDataRatIcon: StateFlow<Boolean>
+
+    /** True if the CDMA level should be preferred over the primary level. */
+    val alwaysUseCdmaLevel: StateFlow<Boolean>
+
+    /** Tracks the subscriptionId set as the default for data connections */
+    val defaultDataSubId: StateFlow<Int>
+
+    /**
+     * The connectivity of the default mobile network. Note that this can differ from what is
+     * reported from [MobileConnectionsRepository] in some cases. E.g., when the active subscription
+     * changes but the groupUuid remains the same, we keep the old validation information for 2
+     * seconds to avoid icon flickering.
+     */
+    val defaultMobileNetworkConnectivity: StateFlow<MobileConnectivityModel>
+
     /** The icon mapping from network type to [MobileIconGroup] for the default subscription */
     val defaultMobileIconMapping: StateFlow<Map<String, MobileIconGroup>>
     /** Fallback [MobileIconGroup] in the case where there is no icon in the mapping */
@@ -149,6 +169,48 @@
             }
         }
 
+    override val defaultDataSubId = mobileConnectionsRepo.defaultDataSubId
+
+    /**
+     * Copied from the old pipeline. We maintain a 2s period of time where we will keep the
+     * validated bit from the old active network (A) while data is changing to the new one (B).
+     *
+     * This condition only applies if
+     * 1. A and B are in the same subscription group (e.c. for CBRS data switching) and
+     * 2. A was validated before the switch
+     *
+     * The goal of this is to minimize the flickering in the UI of the cellular indicator
+     */
+    private val forcingCellularValidation =
+        mobileConnectionsRepo.activeSubChangedInGroupEvent
+            .filter { mobileConnectionsRepo.defaultMobileNetworkConnectivity.value.isValidated }
+            .transformLatest {
+                emit(true)
+                delay(2000)
+                emit(false)
+            }
+            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+
+    override val defaultMobileNetworkConnectivity: StateFlow<MobileConnectivityModel> =
+        combine(
+                mobileConnectionsRepo.defaultMobileNetworkConnectivity,
+                forcingCellularValidation,
+            ) { networkConnectivity, forceValidation ->
+                return@combine if (forceValidation) {
+                    MobileConnectivityModel(
+                        isValidated = true,
+                        isConnected = networkConnectivity.isConnected
+                    )
+                } else {
+                    networkConnectivity
+                }
+            }
+            .stateIn(
+                scope,
+                SharingStarted.WhileSubscribed(),
+                mobileConnectionsRepo.defaultMobileNetworkConnectivity.value
+            )
+
     /**
      * Mapping from network type to [MobileIconGroup] using the config generated for the default
      * subscription Id. This mapping is the same for every subscription.
@@ -165,6 +227,11 @@
             .mapLatest { it.alwaysShowDataRatIcon }
             .stateIn(scope, SharingStarted.WhileSubscribed(), false)
 
+    override val alwaysUseCdmaLevel: StateFlow<Boolean> =
+        mobileConnectionsRepo.defaultDataSubRatConfig
+            .mapLatest { it.alwaysShowCdmaRssi }
+            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+
     /** If there is no mapping in [defaultMobileIconMapping], then use this default icon group */
     override val defaultMobileIconGroup: StateFlow<MobileIconGroup> =
         mobileConnectionsRepo.defaultMobileIconGroup.stateIn(
@@ -196,8 +263,11 @@
             scope,
             activeDataConnectionHasDataEnabled,
             alwaysShowDataRatIcon,
+            alwaysUseCdmaLevel,
+            defaultMobileNetworkConnectivity,
             defaultMobileIconMapping,
             defaultMobileIconGroup,
+            defaultDataSubId,
             isDefaultConnectionFailed,
             mobileConnectionsRepo.getRepoForSubId(subId),
         )
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
index ab442b5..3e81c7c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
@@ -19,6 +19,7 @@
 import android.content.res.ColorStateList
 import android.view.View
 import android.view.View.GONE
+import android.view.View.INVISIBLE
 import android.view.View.VISIBLE
 import android.view.ViewGroup
 import android.widget.ImageView
@@ -30,7 +31,13 @@
 import com.android.systemui.R
 import com.android.systemui.common.ui.binder.IconViewBinder
 import com.android.systemui.lifecycle.repeatWhenAttached
+import com.android.systemui.statusbar.StatusBarIconView
+import com.android.systemui.statusbar.StatusBarIconView.STATE_DOT
+import com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN
+import com.android.systemui.statusbar.StatusBarIconView.STATE_ICON
 import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.LocationBasedMobileViewModel
+import com.android.systemui.statusbar.pipeline.shared.ui.binder.ModernStatusBarViewBinding
+import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.launch
 
@@ -40,7 +47,8 @@
     fun bind(
         view: ViewGroup,
         viewModel: LocationBasedMobileViewModel,
-    ) {
+    ): ModernStatusBarViewBinding {
+        val mobileGroupView = view.requireViewById<ViewGroup>(R.id.mobile_group)
         val activityContainer = view.requireViewById<View>(R.id.inout_container)
         val activityIn = view.requireViewById<ImageView>(R.id.mobile_in)
         val activityOut = view.requireViewById<ImageView>(R.id.mobile_out)
@@ -49,12 +57,39 @@
         val mobileDrawable = SignalDrawable(view.context).also { iconView.setImageDrawable(it) }
         val roamingView = view.requireViewById<ImageView>(R.id.mobile_roaming)
         val roamingSpace = view.requireViewById<Space>(R.id.mobile_roaming_space)
+        val dotView = view.requireViewById<StatusBarIconView>(R.id.status_bar_dot)
 
         view.isVisible = true
         iconView.isVisible = true
 
+        // TODO(b/238425913): We should log this visibility state.
+        @StatusBarIconView.VisibleState
+        val visibilityState: MutableStateFlow<Int> = MutableStateFlow(STATE_HIDDEN)
+
+        val iconTint: MutableStateFlow<Int> = MutableStateFlow(viewModel.defaultColor)
+        val decorTint: MutableStateFlow<Int> = MutableStateFlow(viewModel.defaultColor)
+
         view.repeatWhenAttached {
             repeatOnLifecycle(Lifecycle.State.STARTED) {
+                launch {
+                    visibilityState.collect { state ->
+                        when (state) {
+                            STATE_ICON -> {
+                                mobileGroupView.visibility = VISIBLE
+                                dotView.visibility = GONE
+                            }
+                            STATE_DOT -> {
+                                mobileGroupView.visibility = INVISIBLE
+                                dotView.visibility = VISIBLE
+                            }
+                            STATE_HIDDEN -> {
+                                mobileGroupView.visibility = INVISIBLE
+                                dotView.visibility = INVISIBLE
+                            }
+                        }
+                    }
+                }
+
                 // Set the icon for the triangle
                 launch {
                     viewModel.iconId.distinctUntilChanged().collect { iconId ->
@@ -89,15 +124,43 @@
 
                 // Set the tint
                 launch {
-                    viewModel.tint.collect { tint ->
+                    iconTint.collect { tint ->
                         val tintList = ColorStateList.valueOf(tint)
                         iconView.imageTintList = tintList
                         networkTypeView.imageTintList = tintList
                         roamingView.imageTintList = tintList
                         activityIn.imageTintList = tintList
                         activityOut.imageTintList = tintList
+                        dotView.setDecorColor(tint)
                     }
                 }
+
+                launch { decorTint.collect { tint -> dotView.setDecorColor(tint) } }
+            }
+        }
+
+        return object : ModernStatusBarViewBinding {
+            override fun getShouldIconBeVisible(): Boolean {
+                // If this view model exists, then the icon should be visible.
+                return true
+            }
+
+            override fun onVisibilityStateChanged(@StatusBarIconView.VisibleState state: Int) {
+                visibilityState.value = state
+            }
+
+            override fun onIconTintChanged(newTint: Int) {
+                if (viewModel.useDebugColoring) {
+                    return
+                }
+                iconTint.value = newTint
+            }
+
+            override fun onDecorTintChanged(newTint: Int) {
+                if (viewModel.useDebugColoring) {
+                    return
+                }
+                decorTint.value = newTint
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt
index e86fee2..ed9a188 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt
@@ -17,50 +17,20 @@
 package com.android.systemui.statusbar.pipeline.mobile.ui.view
 
 import android.content.Context
-import android.graphics.Rect
 import android.util.AttributeSet
 import android.view.LayoutInflater
 import com.android.systemui.R
-import com.android.systemui.statusbar.BaseStatusBarFrameLayout
-import com.android.systemui.statusbar.StatusBarIconView.STATE_ICON
 import com.android.systemui.statusbar.pipeline.mobile.ui.binder.MobileIconBinder
 import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.LocationBasedMobileViewModel
-import java.util.ArrayList
+import com.android.systemui.statusbar.pipeline.shared.ui.view.ModernStatusBarView
 
 class ModernStatusBarMobileView(
     context: Context,
     attrs: AttributeSet?,
-) : BaseStatusBarFrameLayout(context, attrs) {
+) : ModernStatusBarView(context, attrs) {
 
     var subId: Int = -1
 
-    private lateinit var slot: String
-    override fun getSlot() = slot
-
-    override fun onDarkChanged(areas: ArrayList<Rect>?, darkIntensity: Float, tint: Int) {
-        // TODO
-    }
-
-    override fun setStaticDrawableColor(color: Int) {
-        // TODO
-    }
-
-    override fun setDecorColor(color: Int) {
-        // TODO
-    }
-
-    override fun setVisibleState(state: Int, animate: Boolean) {
-        // TODO
-    }
-
-    override fun getVisibleState(): Int {
-        return STATE_ICON
-    }
-
-    override fun isIconVisible(): Boolean {
-        return true
-    }
-
     companion object {
 
         /**
@@ -77,9 +47,8 @@
                     .inflate(R.layout.status_bar_mobile_signal_group_new, null)
                     as ModernStatusBarMobileView)
                 .also {
-                    it.slot = slot
                     it.subId = viewModel.subscriptionId
-                    MobileIconBinder.bind(it, viewModel)
+                    it.initView(slot) { MobileIconBinder.bind(it, viewModel) }
                 }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModel.kt
index b0dc41f..24cd930 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModel.kt
@@ -18,11 +18,7 @@
 
 import android.graphics.Color
 import com.android.systemui.statusbar.phone.StatusBarLocation
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logOutputChange
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.flowOf
+import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
 
 /**
  * A view model for an individual mobile icon that embeds the notion of a [StatusBarLocation]. This
@@ -33,50 +29,51 @@
  */
 abstract class LocationBasedMobileViewModel(
     val commonImpl: MobileIconViewModelCommon,
-    val logger: ConnectivityPipelineLogger,
+    statusBarPipelineFlags: StatusBarPipelineFlags,
+    debugTint: Int,
 ) : MobileIconViewModelCommon by commonImpl {
-    abstract val tint: Flow<Int>
+    val useDebugColoring: Boolean = statusBarPipelineFlags.useDebugColoring()
+
+    val defaultColor: Int =
+        if (useDebugColoring) {
+            debugTint
+        } else {
+            Color.WHITE
+        }
 
     companion object {
         fun viewModelForLocation(
             commonImpl: MobileIconViewModelCommon,
-            logger: ConnectivityPipelineLogger,
+            statusBarPipelineFlags: StatusBarPipelineFlags,
             loc: StatusBarLocation,
         ): LocationBasedMobileViewModel =
             when (loc) {
-                StatusBarLocation.HOME -> HomeMobileIconViewModel(commonImpl, logger)
-                StatusBarLocation.KEYGUARD -> KeyguardMobileIconViewModel(commonImpl, logger)
-                StatusBarLocation.QS -> QsMobileIconViewModel(commonImpl, logger)
+                StatusBarLocation.HOME ->
+                    HomeMobileIconViewModel(commonImpl, statusBarPipelineFlags)
+                StatusBarLocation.KEYGUARD ->
+                    KeyguardMobileIconViewModel(commonImpl, statusBarPipelineFlags)
+                StatusBarLocation.QS -> QsMobileIconViewModel(commonImpl, statusBarPipelineFlags)
             }
     }
 }
 
 class HomeMobileIconViewModel(
     commonImpl: MobileIconViewModelCommon,
-    logger: ConnectivityPipelineLogger,
-) : MobileIconViewModelCommon, LocationBasedMobileViewModel(commonImpl, logger) {
-    override val tint: Flow<Int> =
-        flowOf(Color.CYAN)
-            .distinctUntilChanged()
-            .logOutputChange(logger, "HOME tint(${commonImpl.subscriptionId})")
-}
+    statusBarPipelineFlags: StatusBarPipelineFlags,
+) :
+    MobileIconViewModelCommon,
+    LocationBasedMobileViewModel(commonImpl, statusBarPipelineFlags, debugTint = Color.CYAN)
 
 class QsMobileIconViewModel(
     commonImpl: MobileIconViewModelCommon,
-    logger: ConnectivityPipelineLogger,
-) : MobileIconViewModelCommon, LocationBasedMobileViewModel(commonImpl, logger) {
-    override val tint: Flow<Int> =
-        flowOf(Color.GREEN)
-            .distinctUntilChanged()
-            .logOutputChange(logger, "QS tint(${commonImpl.subscriptionId})")
-}
+    statusBarPipelineFlags: StatusBarPipelineFlags,
+) :
+    MobileIconViewModelCommon,
+    LocationBasedMobileViewModel(commonImpl, statusBarPipelineFlags, debugTint = Color.GREEN)
 
 class KeyguardMobileIconViewModel(
     commonImpl: MobileIconViewModelCommon,
-    logger: ConnectivityPipelineLogger,
-) : MobileIconViewModelCommon, LocationBasedMobileViewModel(commonImpl, logger) {
-    override val tint: Flow<Int> =
-        flowOf(Color.MAGENTA)
-            .distinctUntilChanged()
-            .logOutputChange(logger, "KEYGUARD tint(${commonImpl.subscriptionId})")
-}
+    statusBarPipelineFlags: StatusBarPipelineFlags,
+) :
+    MobileIconViewModelCommon,
+    LocationBasedMobileViewModel(commonImpl, statusBarPipelineFlags, debugTint = Color.MAGENTA)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt
index 2d6ac4e..5e935616 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt
@@ -80,11 +80,17 @@
 
     override val iconId: Flow<Int> = run {
         val initial = SignalDrawable.getEmptyState(iconInteractor.numberOfLevels.value)
-        combine(iconInteractor.level, iconInteractor.numberOfLevels, showExclamationMark) {
-                level,
-                numberOfLevels,
-                showExclamationMark ->
-                SignalDrawable.getState(level, numberOfLevels, showExclamationMark)
+        combine(
+                iconInteractor.level,
+                iconInteractor.numberOfLevels,
+                showExclamationMark,
+                iconInteractor.isInService,
+            ) { level, numberOfLevels, showExclamationMark, isInService ->
+                if (!isInService) {
+                    SignalDrawable.getEmptyState(numberOfLevels)
+                } else {
+                    SignalDrawable.getState(level, numberOfLevels, showExclamationMark)
+                }
             }
             .distinctUntilChanged()
             .logDiffsForTable(
@@ -96,24 +102,29 @@
             .stateIn(scope, SharingStarted.WhileSubscribed(), initial)
     }
 
+    private val showNetworkTypeIcon: Flow<Boolean> =
+        combine(
+            iconInteractor.isDataConnected,
+            iconInteractor.isDataEnabled,
+            iconInteractor.isDefaultConnectionFailed,
+            iconInteractor.alwaysShowDataRatIcon,
+            iconInteractor.isConnected,
+        ) { dataConnected, dataEnabled, failedConnection, alwaysShow, connected ->
+            alwaysShow || (dataConnected && dataEnabled && !failedConnection && connected)
+        }
+
     override val networkTypeIcon: Flow<Icon?> =
         combine(
                 iconInteractor.networkTypeIconGroup,
-                iconInteractor.isDataConnected,
-                iconInteractor.isDataEnabled,
-                iconInteractor.isDefaultConnectionFailed,
-                iconInteractor.alwaysShowDataRatIcon,
-            ) { networkTypeIconGroup, dataConnected, dataEnabled, failedConnection, alwaysShow ->
+                showNetworkTypeIcon,
+            ) { networkTypeIconGroup, shouldShow ->
                 val desc =
                     if (networkTypeIconGroup.dataContentDescription != 0)
                         ContentDescription.Resource(networkTypeIconGroup.dataContentDescription)
                     else null
                 val icon = Icon.Resource(networkTypeIconGroup.dataType, desc)
                 return@combine when {
-                    alwaysShow -> icon
-                    !dataConnected -> null
-                    !dataEnabled -> null
-                    failedConnection -> null
+                    !shouldShow -> null
                     else -> icon
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt
index b9318b1..24370d2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt
@@ -19,6 +19,7 @@
 import androidx.annotation.VisibleForTesting
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.statusbar.phone.StatusBarLocation
+import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
 import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
 import com.android.systemui.statusbar.pipeline.mobile.ui.view.ModernStatusBarMobileView
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
@@ -41,6 +42,7 @@
     private val logger: ConnectivityPipelineLogger,
     private val constants: ConnectivityConstants,
     @Application private val scope: CoroutineScope,
+    private val statusBarPipelineFlags: StatusBarPipelineFlags,
 ) {
     @VisibleForTesting val mobileIconSubIdCache = mutableMapOf<Int, MobileIconViewModel>()
 
@@ -60,7 +62,11 @@
                     )
                     .also { mobileIconSubIdCache[subId] = it }
 
-        return LocationBasedMobileViewModel.viewModelForLocation(common, logger, location)
+        return LocationBasedMobileViewModel.viewModelForLocation(
+            common,
+            statusBarPipelineFlags,
+            location,
+        )
     }
 
     private fun removeInvalidModelsFromCache(subIds: List<Int>) {
@@ -75,6 +81,7 @@
         private val logger: ConnectivityPipelineLogger,
         private val constants: ConnectivityConstants,
         @Application private val scope: CoroutineScope,
+        private val statusBarPipelineFlags: StatusBarPipelineFlags,
     ) {
         fun create(subscriptionIdsFlow: StateFlow<List<Int>>): MobileIconsViewModel {
             return MobileIconsViewModel(
@@ -83,6 +90,7 @@
                 logger,
                 constants,
                 scope,
+                statusBarPipelineFlags,
             )
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/ModernStatusBarViewBinding.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/ModernStatusBarViewBinding.kt
new file mode 100644
index 0000000..f67876b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/ModernStatusBarViewBinding.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.shared.ui.binder
+
+import com.android.systemui.statusbar.StatusBarIconView
+
+/**
+ * Defines interface for an object that acts as the binding between a modern status bar view and its
+ * view-model.
+ *
+ * Users of the view binder classes in the modern status bar pipeline should use this to control the
+ * binder after it is bound.
+ */
+interface ModernStatusBarViewBinding {
+    /** Returns true if the icon should be visible and false otherwise. */
+    fun getShouldIconBeVisible(): Boolean
+
+    /** Notifies that the visibility state has changed. */
+    fun onVisibilityStateChanged(@StatusBarIconView.VisibleState state: Int)
+
+    /** Notifies that the icon tint has been updated. */
+    fun onIconTintChanged(newTint: Int)
+
+    /** Notifies that the decor tint has been updated (used only for the dot). */
+    fun onDecorTintChanged(newTint: Int)
+}
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
new file mode 100644
index 0000000..cc0ec54
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.shared.ui.view
+
+import android.content.Context
+import android.graphics.Rect
+import android.util.AttributeSet
+import android.view.Gravity
+import com.android.systemui.R
+import com.android.systemui.plugins.DarkIconDispatcher
+import com.android.systemui.statusbar.BaseStatusBarFrameLayout
+import com.android.systemui.statusbar.StatusBarIconView
+import com.android.systemui.statusbar.StatusBarIconView.STATE_DOT
+import com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN
+import com.android.systemui.statusbar.pipeline.shared.ui.binder.ModernStatusBarViewBinding
+
+/**
+ * A new and more modern implementation of [BaseStatusBarFrameLayout] that gets updated by view
+ * binders communicating via [ModernStatusBarViewBinding].
+ */
+open class ModernStatusBarView(context: Context, attrs: AttributeSet?) :
+    BaseStatusBarFrameLayout(context, attrs) {
+
+    private lateinit var slot: String
+    private lateinit var binding: ModernStatusBarViewBinding
+
+    @StatusBarIconView.VisibleState
+    private var iconVisibleState: Int = STATE_HIDDEN
+        set(value) {
+            if (field == value) {
+                return
+            }
+            field = value
+            binding.onVisibilityStateChanged(value)
+        }
+
+    override fun getSlot() = slot
+
+    override fun onDarkChanged(areas: ArrayList<Rect>?, darkIntensity: Float, tint: Int) {
+        val newTint = DarkIconDispatcher.getTint(areas, this, tint)
+        binding.onIconTintChanged(newTint)
+        binding.onDecorTintChanged(newTint)
+    }
+
+    override fun setStaticDrawableColor(color: Int) {
+        binding.onIconTintChanged(color)
+    }
+
+    override fun setDecorColor(color: Int) {
+        binding.onDecorTintChanged(color)
+    }
+
+    override fun setVisibleState(@StatusBarIconView.VisibleState state: Int, animate: Boolean) {
+        iconVisibleState = state
+    }
+
+    @StatusBarIconView.VisibleState
+    override fun getVisibleState(): Int {
+        return iconVisibleState
+    }
+
+    override fun isIconVisible(): Boolean {
+        return binding.getShouldIconBeVisible()
+    }
+
+    /**
+     * Initializes this view.
+     *
+     * Creates a dot view, and uses [bindingCreator] to get and set the binding.
+     */
+    fun initView(slot: String, bindingCreator: () -> ModernStatusBarViewBinding) {
+        // The dot view requires [slot] to be set, and the [binding] may require an instantiated dot
+        // view. So, this is the required order.
+        this.slot = slot
+        initDotView()
+        this.binding = bindingCreator.invoke()
+    }
+
+    /**
+     * Creates a [StatusBarIconView] that is always in DOT mode and adds it to this view.
+     *
+     * Mostly duplicated from [com.android.systemui.statusbar.StatusBarWifiView] and
+     * [com.android.systemui.statusbar.StatusBarMobileView].
+     */
+    private fun initDotView() {
+        // TODO(b/238425913): Could we just have this dot view be part of the layout with a dot
+        //  drawable so we don't need to inflate it manually? Would that not work with animations?
+        val dotView =
+            StatusBarIconView(mContext, slot, null).also {
+                it.id = R.id.status_bar_dot
+                // Hard-code this view to always be in the DOT state so that whenever it's visible
+                // it will show a dot
+                it.visibleState = STATE_DOT
+            }
+
+        val width = mContext.resources.getDimensionPixelSize(R.dimen.status_bar_icon_size)
+        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/model/WifiNetworkModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt
index a682a57..da2daf2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt
@@ -16,13 +16,80 @@
 
 package com.android.systemui.statusbar.pipeline.wifi.data.model
 
+import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
 import androidx.annotation.VisibleForTesting
 import com.android.systemui.log.table.TableRowLogger
 import com.android.systemui.log.table.Diffable
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
 
 /** Provides information about the current wifi network. */
 sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
 
+    // TODO(b/238425913): Have a better, more unified strategy for diff-logging instead of
+    //   copy-pasting the column names for each sub-object.
+
+    /**
+     * A model representing that we couldn't fetch any wifi information.
+     *
+     * This is only used with [DisabledWifiRepository], where [WifiManager] is null.
+     */
+    object Unavailable : WifiNetworkModel() {
+        override fun toString() = "WifiNetwork.Unavailable"
+        override fun logDiffs(prevVal: WifiNetworkModel, row: TableRowLogger) {
+            if (prevVal is Unavailable) {
+                return
+            }
+
+            logFull(row)
+        }
+
+        override fun logFull(row: TableRowLogger) {
+            row.logChange(COL_NETWORK_TYPE, TYPE_UNAVAILABLE)
+            row.logChange(COL_NETWORK_ID, NETWORK_ID_DEFAULT)
+            row.logChange(COL_SUB_ID, SUB_ID_DEFAULT)
+            row.logChange(COL_VALIDATED, false)
+            row.logChange(COL_LEVEL, LEVEL_DEFAULT)
+            row.logChange(COL_NUM_LEVELS, NUM_LEVELS_DEFAULT)
+            row.logChange(COL_SSID, null)
+            row.logChange(COL_PASSPOINT_ACCESS_POINT, false)
+            row.logChange(COL_ONLINE_SIGN_UP, false)
+            row.logChange(COL_PASSPOINT_NAME, null)
+        }
+    }
+
+    /**
+     * A model representing that the wifi information we received was invalid in some way.
+     */
+    data class Invalid(
+        /** A description of why the wifi information was invalid. */
+        val invalidReason: String,
+    ) : WifiNetworkModel() {
+        override fun toString() = "WifiNetwork.Invalid[$invalidReason]"
+        override fun logDiffs(prevVal: WifiNetworkModel, row: TableRowLogger) {
+            if (prevVal !is Invalid) {
+                logFull(row)
+                return
+            }
+
+            if (invalidReason != prevVal.invalidReason) {
+                row.logChange(COL_NETWORK_TYPE, "$TYPE_UNAVAILABLE $invalidReason")
+            }
+        }
+
+        override fun logFull(row: TableRowLogger) {
+            row.logChange(COL_NETWORK_TYPE, "$TYPE_UNAVAILABLE $invalidReason")
+            row.logChange(COL_NETWORK_ID, NETWORK_ID_DEFAULT)
+            row.logChange(COL_SUB_ID, SUB_ID_DEFAULT)
+            row.logChange(COL_VALIDATED, false)
+            row.logChange(COL_LEVEL, LEVEL_DEFAULT)
+            row.logChange(COL_NUM_LEVELS, NUM_LEVELS_DEFAULT)
+            row.logChange(COL_SSID, null)
+            row.logChange(COL_PASSPOINT_ACCESS_POINT, false)
+            row.logChange(COL_ONLINE_SIGN_UP, false)
+            row.logChange(COL_PASSPOINT_NAME, null)
+        }
+    }
+
     /** A model representing that we have no active wifi network. */
     object Inactive : WifiNetworkModel() {
         override fun toString() = "WifiNetwork.Inactive"
@@ -32,18 +99,21 @@
                 return
             }
 
-            if (prevVal is CarrierMerged) {
-                // The only difference between CarrierMerged and Inactive is the type
-                row.logChange(COL_NETWORK_TYPE, TYPE_INACTIVE)
-                return
-            }
-
-            // When changing from Active to Inactive, we need to log diffs to all the fields.
-            logFullNonActiveNetwork(TYPE_INACTIVE, row)
+            // When changing to Inactive, we need to log diffs to all the fields.
+            logFull(row)
         }
 
         override fun logFull(row: TableRowLogger) {
-            logFullNonActiveNetwork(TYPE_INACTIVE, row)
+            row.logChange(COL_NETWORK_TYPE, TYPE_INACTIVE)
+            row.logChange(COL_NETWORK_ID, NETWORK_ID_DEFAULT)
+            row.logChange(COL_SUB_ID, SUB_ID_DEFAULT)
+            row.logChange(COL_VALIDATED, false)
+            row.logChange(COL_LEVEL, LEVEL_DEFAULT)
+            row.logChange(COL_NUM_LEVELS, NUM_LEVELS_DEFAULT)
+            row.logChange(COL_SSID, null)
+            row.logChange(COL_PASSPOINT_ACCESS_POINT, false)
+            row.logChange(COL_ONLINE_SIGN_UP, false)
+            row.logChange(COL_PASSPOINT_NAME, null)
         }
     }
 
@@ -53,22 +123,75 @@
      *
      * See [android.net.wifi.WifiInfo.isCarrierMerged] for more information.
      */
-    object CarrierMerged : WifiNetworkModel() {
-        override fun toString() = "WifiNetwork.CarrierMerged"
+    data class CarrierMerged(
+        /**
+         * The [android.net.Network.netId] we received from
+         * [android.net.ConnectivityManager.NetworkCallback] in association with this wifi network.
+         *
+         * Importantly, **not** [android.net.wifi.WifiInfo.getNetworkId].
+         */
+        val networkId: Int,
+
+        /**
+         * The subscription ID that this connection represents.
+         *
+         * Comes from [android.net.wifi.WifiInfo.getSubscriptionId].
+         *
+         * Per that method, this value must not be [INVALID_SUBSCRIPTION_ID] (if it was invalid,
+         * then this is *not* a carrier merged network).
+         */
+        val subscriptionId: Int,
+
+        /**
+         * The signal level, guaranteed to be 0 <= level <= numberOfLevels.
+         */
+        val level: Int,
+
+        /**
+         * The maximum possible level.
+         */
+        val numberOfLevels: Int = DEFAULT_NUM_LEVELS,
+    ) : WifiNetworkModel() {
+        init {
+            require(level in MIN_VALID_LEVEL..numberOfLevels) {
+                "0 <= wifi level <= $numberOfLevels required; level was $level"
+            }
+            require(subscriptionId != INVALID_SUBSCRIPTION_ID) {
+                "subscription ID cannot be invalid"
+            }
+        }
 
         override fun logDiffs(prevVal: WifiNetworkModel, row: TableRowLogger) {
-            if (prevVal is CarrierMerged) {
+            if (prevVal !is CarrierMerged) {
+                logFull(row)
                 return
             }
 
-            if (prevVal is Inactive) {
-                // The only difference between CarrierMerged and Inactive is the type.
-                row.logChange(COL_NETWORK_TYPE, TYPE_CARRIER_MERGED)
-                return
+            if (prevVal.networkId != networkId) {
+                row.logChange(COL_NETWORK_ID, networkId)
             }
+            if (prevVal.subscriptionId != subscriptionId) {
+                row.logChange(COL_SUB_ID, subscriptionId)
+            }
+            if (prevVal.level != level) {
+                row.logChange(COL_LEVEL, level)
+            }
+            if (prevVal.numberOfLevels != numberOfLevels) {
+                row.logChange(COL_NUM_LEVELS, numberOfLevels)
+            }
+        }
 
-            // When changing from Active to CarrierMerged, we need to log diffs to all the fields.
-            logFullNonActiveNetwork(TYPE_CARRIER_MERGED, row)
+        override fun logFull(row: TableRowLogger) {
+            row.logChange(COL_NETWORK_TYPE, TYPE_CARRIER_MERGED)
+            row.logChange(COL_NETWORK_ID, networkId)
+            row.logChange(COL_SUB_ID, subscriptionId)
+            row.logChange(COL_VALIDATED, true)
+            row.logChange(COL_LEVEL, level)
+            row.logChange(COL_NUM_LEVELS, numberOfLevels)
+            row.logChange(COL_SSID, null)
+            row.logChange(COL_PASSPOINT_ACCESS_POINT, false)
+            row.logChange(COL_ONLINE_SIGN_UP, false)
+            row.logChange(COL_PASSPOINT_NAME, null)
         }
     }
 
@@ -87,13 +210,8 @@
 
         /**
          * The wifi signal level, guaranteed to be 0 <= level <= 4.
-         *
-         * Null if we couldn't fetch the level for some reason.
-         *
-         * TODO(b/238425913): The level will only be null if we have a null WifiManager. Is there a
-         *   way we can guarantee a non-null WifiManager?
          */
-        val level: Int? = null,
+        val level: Int,
 
         /** See [android.net.wifi.WifiInfo.ssid]. */
         val ssid: String? = null,
@@ -108,49 +226,57 @@
         val passpointProviderFriendlyName: String? = null,
     ) : WifiNetworkModel() {
         init {
-            require(level == null || level in MIN_VALID_LEVEL..MAX_VALID_LEVEL) {
+            require(level in MIN_VALID_LEVEL..MAX_VALID_LEVEL) {
                 "0 <= wifi level <= 4 required; level was $level"
             }
         }
 
         override fun logDiffs(prevVal: WifiNetworkModel, row: TableRowLogger) {
             if (prevVal !is Active) {
-                row.logChange(COL_NETWORK_TYPE, TYPE_ACTIVE)
+                logFull(row)
+                return
             }
 
-            if (prevVal !is Active || prevVal.networkId != networkId) {
+            if (prevVal.networkId != networkId) {
                 row.logChange(COL_NETWORK_ID, networkId)
             }
-            if (prevVal !is Active || prevVal.isValidated != isValidated) {
+            if (prevVal.isValidated != isValidated) {
                 row.logChange(COL_VALIDATED, isValidated)
             }
-            if (prevVal !is Active || prevVal.level != level) {
-                if (level != null) {
-                    row.logChange(COL_LEVEL, level)
-                } else {
-                    row.logChange(COL_LEVEL, LEVEL_DEFAULT)
-                }
+            if (prevVal.level != level) {
+                row.logChange(COL_LEVEL, level)
             }
-            if (prevVal !is Active || prevVal.ssid != ssid) {
+            if (prevVal.ssid != ssid) {
                 row.logChange(COL_SSID, ssid)
             }
 
             // TODO(b/238425913): The passpoint-related values are frequently never used, so it
             //   would be great to not log them when they're not used.
-            if (prevVal !is Active || prevVal.isPasspointAccessPoint != isPasspointAccessPoint) {
+            if (prevVal.isPasspointAccessPoint != isPasspointAccessPoint) {
                 row.logChange(COL_PASSPOINT_ACCESS_POINT, isPasspointAccessPoint)
             }
-            if (prevVal !is Active ||
-                prevVal.isOnlineSignUpForPasspointAccessPoint !=
+            if (prevVal.isOnlineSignUpForPasspointAccessPoint !=
                 isOnlineSignUpForPasspointAccessPoint) {
                 row.logChange(COL_ONLINE_SIGN_UP, isOnlineSignUpForPasspointAccessPoint)
             }
-            if (prevVal !is Active ||
-                prevVal.passpointProviderFriendlyName != passpointProviderFriendlyName) {
+            if (prevVal.passpointProviderFriendlyName != passpointProviderFriendlyName) {
                 row.logChange(COL_PASSPOINT_NAME, passpointProviderFriendlyName)
             }
         }
 
+        override fun logFull(row: TableRowLogger) {
+            row.logChange(COL_NETWORK_TYPE, TYPE_ACTIVE)
+            row.logChange(COL_NETWORK_ID, networkId)
+            row.logChange(COL_SUB_ID, null)
+            row.logChange(COL_VALIDATED, isValidated)
+            row.logChange(COL_LEVEL, level)
+            row.logChange(COL_NUM_LEVELS, null)
+            row.logChange(COL_SSID, ssid)
+            row.logChange(COL_PASSPOINT_ACCESS_POINT, isPasspointAccessPoint)
+            row.logChange(COL_ONLINE_SIGN_UP, isOnlineSignUpForPasspointAccessPoint)
+            row.logChange(COL_PASSPOINT_NAME, passpointProviderFriendlyName)
+        }
+
         override fun toString(): String {
             // Only include the passpoint-related values in the string if we have them. (Most
             // networks won't have them so they'll be mostly clutter.)
@@ -171,36 +297,33 @@
 
         companion object {
             @VisibleForTesting
-            internal const val MIN_VALID_LEVEL = 0
-            @VisibleForTesting
             internal const val MAX_VALID_LEVEL = 4
         }
     }
 
-    internal fun logFullNonActiveNetwork(type: String, row: TableRowLogger) {
-        row.logChange(COL_NETWORK_TYPE, type)
-        row.logChange(COL_NETWORK_ID, NETWORK_ID_DEFAULT)
-        row.logChange(COL_VALIDATED, false)
-        row.logChange(COL_LEVEL, LEVEL_DEFAULT)
-        row.logChange(COL_SSID, null)
-        row.logChange(COL_PASSPOINT_ACCESS_POINT, false)
-        row.logChange(COL_ONLINE_SIGN_UP, false)
-        row.logChange(COL_PASSPOINT_NAME, null)
+    companion object {
+        @VisibleForTesting
+        internal const val MIN_VALID_LEVEL = 0
     }
 }
 
 const val TYPE_CARRIER_MERGED = "CarrierMerged"
+const val TYPE_UNAVAILABLE = "Unavailable"
 const val TYPE_INACTIVE = "Inactive"
 const val TYPE_ACTIVE = "Active"
 
 const val COL_NETWORK_TYPE = "type"
 const val COL_NETWORK_ID = "networkId"
+const val COL_SUB_ID = "subscriptionId"
 const val COL_VALIDATED = "isValidated"
 const val COL_LEVEL = "level"
+const val COL_NUM_LEVELS = "maxLevel"
 const val COL_SSID = "ssid"
 const val COL_PASSPOINT_ACCESS_POINT = "isPasspointAccessPoint"
 const val COL_ONLINE_SIGN_UP = "isOnlineSignUpForPasspointAccessPoint"
 const val COL_PASSPOINT_NAME = "passpointProviderFriendlyName"
 
 val LEVEL_DEFAULT: String? = null
+val NUM_LEVELS_DEFAULT: String? = null
 val NETWORK_ID_DEFAULT: String? = null
+val SUB_ID_DEFAULT: String? = null
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
index 5ccd6f4..ac4d55c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
@@ -16,51 +16,9 @@
 
 package com.android.systemui.statusbar.pipeline.wifi.data.repository
 
-import android.annotation.SuppressLint
-import android.content.IntentFilter
-import android.net.ConnectivityManager
-import android.net.Network
-import android.net.NetworkCapabilities
-import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN
-import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
-import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
-import android.net.NetworkCapabilities.TRANSPORT_WIFI
-import android.net.NetworkRequest
-import android.net.wifi.WifiInfo
-import android.net.wifi.WifiManager
-import android.net.wifi.WifiManager.TrafficStateCallback
-import android.util.Log
-import com.android.settingslib.Utils
-import com.android.systemui.broadcast.BroadcastDispatcher
-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.Main
-import com.android.systemui.log.table.TableLogBuffer
-import com.android.systemui.log.table.logDiffsForTable
-import com.android.systemui.statusbar.pipeline.dagger.WifiTableLog
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.SB_LOGGING_TAG
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logInputChange
 import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
-import com.android.systemui.statusbar.pipeline.shared.data.model.toWifiDataActivityModel
 import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
-import java.util.concurrent.Executor
-import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.channels.awaitClose
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableSharedFlow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.asStateFlow
-import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.mapLatest
-import kotlinx.coroutines.flow.merge
-import kotlinx.coroutines.flow.stateIn
 
 /** Provides data related to the wifi state. */
 interface WifiRepository {
@@ -77,249 +35,12 @@
     val wifiActivity: StateFlow<DataActivityModel>
 }
 
-/** Real implementation of [WifiRepository]. */
-@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
-@OptIn(ExperimentalCoroutinesApi::class)
-@SysUISingleton
-@SuppressLint("MissingPermission")
-class WifiRepositoryImpl @Inject constructor(
-    broadcastDispatcher: BroadcastDispatcher,
-    connectivityManager: ConnectivityManager,
-    logger: ConnectivityPipelineLogger,
-    @WifiTableLog wifiTableLogBuffer: TableLogBuffer,
-    @Main mainExecutor: Executor,
-    @Application scope: CoroutineScope,
-    wifiManager: WifiManager?,
-) : WifiRepository {
-
-    private val wifiStateChangeEvents: Flow<Unit> = broadcastDispatcher.broadcastFlow(
-        IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION)
-    )
-        .logInputChange(logger, "WIFI_STATE_CHANGED_ACTION intent")
-
-    private val wifiNetworkChangeEvents: MutableSharedFlow<Unit> =
-        MutableSharedFlow(extraBufferCapacity = 1)
-
-    override val isWifiEnabled: StateFlow<Boolean> =
-        if (wifiManager == null) {
-            MutableStateFlow(false).asStateFlow()
-        } else {
-            // Because [WifiManager] doesn't expose a wifi enabled change listener, we do it
-            // internally by fetching [WifiManager.isWifiEnabled] whenever we think the state may
-            // have changed.
-            merge(wifiNetworkChangeEvents, wifiStateChangeEvents)
-                .mapLatest { wifiManager.isWifiEnabled }
-                .distinctUntilChanged()
-                .logDiffsForTable(
-                    wifiTableLogBuffer,
-                    columnPrefix = "",
-                    columnName = "isWifiEnabled",
-                    initialValue = wifiManager.isWifiEnabled,
-                )
-                .stateIn(
-                    scope = scope,
-                    started = SharingStarted.WhileSubscribed(),
-                    initialValue = wifiManager.isWifiEnabled
-                )
-        }
-
-    override val isWifiDefault: StateFlow<Boolean> = conflatedCallbackFlow {
-        // Note: This callback doesn't do any logging because we already log every network change
-        // in the [wifiNetwork] callback.
-        val callback = object : ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) {
-            override fun onCapabilitiesChanged(
-                network: Network,
-                networkCapabilities: NetworkCapabilities
-            ) {
-                // This method will always be called immediately after the network becomes the
-                // default, in addition to any time the capabilities change while the network is
-                // the default.
-                // If this network contains valid wifi info, then wifi is the default network.
-                val wifiInfo = networkCapabilitiesToWifiInfo(networkCapabilities)
-                trySend(wifiInfo != null)
-            }
-
-            override fun onLost(network: Network) {
-                // The system no longer has a default network, so wifi is definitely not default.
-                trySend(false)
-            }
-        }
-
-        connectivityManager.registerDefaultNetworkCallback(callback)
-        awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
-    }
-        .distinctUntilChanged()
-        .logDiffsForTable(
-            wifiTableLogBuffer,
-            columnPrefix = "",
-            columnName = "isWifiDefault",
-            initialValue = false,
-        )
-        .stateIn(
-            scope,
-            started = SharingStarted.WhileSubscribed(),
-            initialValue = false
-        )
-
-    override val wifiNetwork: StateFlow<WifiNetworkModel> = conflatedCallbackFlow {
-        var currentWifi: WifiNetworkModel = WIFI_NETWORK_DEFAULT
-
-        val callback = object : ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) {
-            override fun onCapabilitiesChanged(
-                network: Network,
-                networkCapabilities: NetworkCapabilities
-            ) {
-                logger.logOnCapabilitiesChanged(network, networkCapabilities)
-
-                wifiNetworkChangeEvents.tryEmit(Unit)
-
-                val wifiInfo = networkCapabilitiesToWifiInfo(networkCapabilities)
-                if (wifiInfo?.isPrimary == true) {
-                    val wifiNetworkModel = createWifiNetworkModel(
-                        wifiInfo,
-                        network,
-                        networkCapabilities,
-                        wifiManager,
-                    )
-                    logger.logTransformation(
-                        WIFI_NETWORK_CALLBACK_NAME,
-                        oldValue = currentWifi,
-                        newValue = wifiNetworkModel
-                    )
-                    currentWifi = wifiNetworkModel
-                    trySend(wifiNetworkModel)
-                }
-            }
-
-            override fun onLost(network: Network) {
-                logger.logOnLost(network)
-
-                wifiNetworkChangeEvents.tryEmit(Unit)
-
-                val wifi = currentWifi
-                if (wifi is WifiNetworkModel.Active && wifi.networkId == network.getNetId()) {
-                    val newNetworkModel = WifiNetworkModel.Inactive
-                    logger.logTransformation(
-                        WIFI_NETWORK_CALLBACK_NAME,
-                        oldValue = wifi,
-                        newValue = newNetworkModel
-                    )
-                    currentWifi = newNetworkModel
-                    trySend(newNetworkModel)
-                }
-            }
-        }
-
-        connectivityManager.registerNetworkCallback(WIFI_NETWORK_CALLBACK_REQUEST, callback)
-
-        awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
-    }
-        .distinctUntilChanged()
-        .logDiffsForTable(
-            wifiTableLogBuffer,
-            columnPrefix = "wifiNetwork",
-            initialValue = WIFI_NETWORK_DEFAULT,
-        )
-        // There will be multiple wifi icons in different places that will frequently
-        // subscribe/unsubscribe to flows as the views attach/detach. Using [stateIn] ensures that
-        // new subscribes will get the latest value immediately upon subscription. Otherwise, the
-        // views could show stale data. See b/244173280.
-        .stateIn(
-            scope,
-            started = SharingStarted.WhileSubscribed(),
-            initialValue = WIFI_NETWORK_DEFAULT
-        )
-
-    override val wifiActivity: StateFlow<DataActivityModel> =
-            if (wifiManager == null) {
-                Log.w(SB_LOGGING_TAG, "Null WifiManager; skipping activity callback")
-                flowOf(ACTIVITY_DEFAULT)
-            } else {
-                conflatedCallbackFlow {
-                    val callback = TrafficStateCallback { state ->
-                        logger.logInputChange("onTrafficStateChange", prettyPrintActivity(state))
-                        trySend(state.toWifiDataActivityModel())
-                    }
-                    wifiManager.registerTrafficStateCallback(mainExecutor, callback)
-                    awaitClose { wifiManager.unregisterTrafficStateCallback(callback) }
-                }
-            }
-                .logDiffsForTable(
-                    wifiTableLogBuffer,
-                    columnPrefix = ACTIVITY_PREFIX,
-                    initialValue = ACTIVITY_DEFAULT,
-                )
-                .stateIn(
-                    scope,
-                    started = SharingStarted.WhileSubscribed(),
-                    initialValue = ACTIVITY_DEFAULT
-                )
-
-    companion object {
-        private const val ACTIVITY_PREFIX = "wifiActivity"
-
-        val ACTIVITY_DEFAULT = DataActivityModel(hasActivityIn = false, hasActivityOut = false)
-        // Start out with no known wifi network.
-        // Note: [WifiStatusTracker] (the old implementation of connectivity logic) does do an
-        // initial fetch to get a starting wifi network. But, it uses a deprecated API
-        // [WifiManager.getConnectionInfo()], and the deprecation doc indicates to just use
-        // [ConnectivityManager.NetworkCallback] results instead. So, for now we'll just rely on the
-        // NetworkCallback inside [wifiNetwork] for our wifi network information.
-        val WIFI_NETWORK_DEFAULT = WifiNetworkModel.Inactive
-
-        private fun networkCapabilitiesToWifiInfo(
-            networkCapabilities: NetworkCapabilities
-        ): WifiInfo? {
-            return when {
-                networkCapabilities.hasTransport(TRANSPORT_WIFI) ->
-                    networkCapabilities.transportInfo as WifiInfo?
-                networkCapabilities.hasTransport(TRANSPORT_CELLULAR) ->
-                    // Sometimes, cellular networks can act as wifi networks (known as VCN --
-                    // virtual carrier network). So, see if this cellular network has wifi info.
-                    Utils.tryGetWifiInfoForVcn(networkCapabilities)
-                else -> null
-            }
-        }
-
-        private fun createWifiNetworkModel(
-            wifiInfo: WifiInfo,
-            network: Network,
-            networkCapabilities: NetworkCapabilities,
-            wifiManager: WifiManager?,
-        ): WifiNetworkModel {
-            return if (wifiInfo.isCarrierMerged) {
-                WifiNetworkModel.CarrierMerged
-            } else {
-                WifiNetworkModel.Active(
-                        network.getNetId(),
-                        isValidated = networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED),
-                        level = wifiManager?.calculateSignalLevel(wifiInfo.rssi),
-                        wifiInfo.ssid,
-                        wifiInfo.isPasspointAp,
-                        wifiInfo.isOsuAp,
-                        wifiInfo.passpointProviderFriendlyName
-                )
-            }
-        }
-
-        private fun prettyPrintActivity(activity: Int): String {
-            return when (activity) {
-                TrafficStateCallback.DATA_ACTIVITY_NONE -> "NONE"
-                TrafficStateCallback.DATA_ACTIVITY_IN -> "IN"
-                TrafficStateCallback.DATA_ACTIVITY_OUT -> "OUT"
-                TrafficStateCallback.DATA_ACTIVITY_INOUT -> "INOUT"
-                else -> "INVALID"
-            }
-        }
-
-        private val WIFI_NETWORK_CALLBACK_REQUEST: NetworkRequest =
-            NetworkRequest.Builder()
-                .clearCapabilities()
-                .addCapability(NET_CAPABILITY_NOT_VPN)
-                .addTransportType(TRANSPORT_WIFI)
-                .addTransportType(TRANSPORT_CELLULAR)
-                .build()
-
-        private const val WIFI_NETWORK_CALLBACK_NAME = "wifiNetworkModel"
-    }
-}
+/**
+ * A no-op interface used for Dagger bindings.
+ *
+ * [WifiRepositorySwitcher] needs to inject the "real" wifi repository, which could either be the
+ * full [WifiRepositoryImpl] or just [DisabledWifiRepository]. Having this interface lets us bind
+ * [RealWifiRepository], and then [WifiRepositorySwitcher] will automatically get the correct real
+ * repository.
+ */
+interface RealWifiRepository : WifiRepository
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcher.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcher.kt
index 73bcdfd..2cb81c8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcher.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcher.kt
@@ -25,6 +25,7 @@
 import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
 import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
 import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.DemoWifiRepository
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -57,7 +58,7 @@
 class WifiRepositorySwitcher
 @Inject
 constructor(
-    private val realImpl: WifiRepositoryImpl,
+    private val realImpl: RealWifiRepository,
     private val demoImpl: DemoWifiRepository,
     private val demoModeController: DemoModeController,
     @Application scope: CoroutineScope,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoModeWifiDataSource.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoModeWifiDataSource.kt
index c588945..caac8fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoModeWifiDataSource.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoModeWifiDataSource.kt
@@ -22,6 +22,7 @@
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.demomode.DemoMode.COMMAND_NETWORK
 import com.android.systemui.demomode.DemoModeController
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
 import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.model.FakeWifiEventModel
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
@@ -43,10 +44,10 @@
 
     private fun Bundle.toWifiEvent(): FakeWifiEventModel? {
         val wifi = getString("wifi") ?: return null
-        return if (wifi == "show") {
-            activeWifiEvent()
-        } else {
-            FakeWifiEventModel.WifiDisabled
+        return when (wifi) {
+            "show" -> activeWifiEvent()
+            "carriermerged" -> carrierMergedWifiEvent()
+            else -> FakeWifiEventModel.WifiDisabled
         }
     }
 
@@ -64,6 +65,14 @@
         )
     }
 
+    private fun Bundle.carrierMergedWifiEvent(): FakeWifiEventModel.CarrierMerged {
+        val subId = getString("slot")?.toInt() ?: DEFAULT_CARRIER_MERGED_SUB_ID
+        val level = getString("level")?.toInt() ?: 0
+        val numberOfLevels = getString("numlevels")?.toInt() ?: DEFAULT_NUM_LEVELS
+
+        return FakeWifiEventModel.CarrierMerged(subId, level, numberOfLevels)
+    }
+
     private fun String.toActivity(): Int =
         when (this) {
             "inout" -> WifiManager.TrafficStateCallback.DATA_ACTIVITY_INOUT
@@ -71,4 +80,8 @@
             "out" -> WifiManager.TrafficStateCallback.DATA_ACTIVITY_OUT
             else -> WifiManager.TrafficStateCallback.DATA_ACTIVITY_NONE
         }
+
+    companion object {
+        const val DEFAULT_CARRIER_MERGED_SUB_ID = 10
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt
index 7890074..e161b3e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt
@@ -66,6 +66,7 @@
     private fun processEvent(event: FakeWifiEventModel) =
         when (event) {
             is FakeWifiEventModel.Wifi -> processEnabledWifiState(event)
+            is FakeWifiEventModel.CarrierMerged -> processCarrierMergedWifiState(event)
             is FakeWifiEventModel.WifiDisabled -> processDisabledWifiState()
         }
 
@@ -85,11 +86,19 @@
         _wifiNetwork.value = event.toWifiNetworkModel()
     }
 
+    private fun processCarrierMergedWifiState(event: FakeWifiEventModel.CarrierMerged) {
+        _isWifiEnabled.value = true
+        _isWifiDefault.value = true
+        // TODO(b/238425913): Support activity in demo mode.
+        _wifiActivity.value = DataActivityModel(hasActivityIn = false, hasActivityOut = false)
+        _wifiNetwork.value = event.toCarrierMergedModel()
+    }
+
     private fun FakeWifiEventModel.Wifi.toWifiNetworkModel(): WifiNetworkModel =
         WifiNetworkModel.Active(
             networkId = DEMO_NET_ID,
             isValidated = validated ?: true,
-            level = level,
+            level = level ?: 0,
             ssid = ssid,
 
             // These fields below aren't supported in demo mode, since they aren't needed to satisfy
@@ -99,6 +108,14 @@
             passpointProviderFriendlyName = null,
         )
 
+    private fun FakeWifiEventModel.CarrierMerged.toCarrierMergedModel(): WifiNetworkModel =
+        WifiNetworkModel.CarrierMerged(
+            networkId = DEMO_NET_ID,
+            subscriptionId = subscriptionId,
+            level = level,
+            numberOfLevels = numberOfLevels,
+        )
+
     companion object {
         private const val DEMO_NET_ID = 1234
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/model/FakeWifiEventModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/model/FakeWifiEventModel.kt
index 2353fb8..518f8ce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/model/FakeWifiEventModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/model/FakeWifiEventModel.kt
@@ -29,5 +29,11 @@
         val validated: Boolean?,
     ) : FakeWifiEventModel
 
+    data class CarrierMerged(
+        val subscriptionId: Int,
+        val level: Int,
+        val numberOfLevels: Int,
+    ) : FakeWifiEventModel
+
     object WifiDisabled : FakeWifiEventModel
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepository.kt
new file mode 100644
index 0000000..5d4a666
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepository.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.wifi.data.repository.prod
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
+import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.RealWifiRepository
+import javax.inject.Inject
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+
+/**
+ * Implementation of wifi repository used when wifi is permanently disabled on the device.
+ *
+ * This repo should only exist when [WifiManager] is null, which means that we can never fetch any
+ * wifi information.
+ */
+@SysUISingleton
+class DisabledWifiRepository @Inject constructor() : RealWifiRepository {
+    override val isWifiEnabled: StateFlow<Boolean> = MutableStateFlow(false).asStateFlow()
+
+    override val isWifiDefault: StateFlow<Boolean> = MutableStateFlow(false).asStateFlow()
+
+    override val wifiNetwork: StateFlow<WifiNetworkModel> = MutableStateFlow(NETWORK).asStateFlow()
+
+    override val wifiActivity: StateFlow<DataActivityModel> =
+        MutableStateFlow(ACTIVITY).asStateFlow()
+
+    companion object {
+        private val NETWORK = WifiNetworkModel.Unavailable
+        private val ACTIVITY = DataActivityModel(hasActivityIn = false, hasActivityOut = false)
+    }
+}
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
new file mode 100644
index 0000000..d26499c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.wifi.data.repository.prod
+
+import android.annotation.SuppressLint
+import android.content.IntentFilter
+import android.net.ConnectivityManager
+import android.net.Network
+import android.net.NetworkCapabilities
+import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN
+import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
+import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
+import android.net.NetworkCapabilities.TRANSPORT_WIFI
+import android.net.NetworkRequest
+import android.net.wifi.WifiInfo
+import android.net.wifi.WifiManager
+import android.net.wifi.WifiManager.TrafficStateCallback
+import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
+import com.android.settingslib.Utils
+import com.android.systemui.broadcast.BroadcastDispatcher
+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.Main
+import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.log.table.logDiffsForTable
+import com.android.systemui.statusbar.pipeline.dagger.WifiTableLog
+import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
+import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logInputChange
+import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
+import com.android.systemui.statusbar.pipeline.shared.data.model.toWifiDataActivityModel
+import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.RealWifiRepository
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository
+import java.util.concurrent.Executor
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.mapLatest
+import kotlinx.coroutines.flow.merge
+import kotlinx.coroutines.flow.stateIn
+
+/** Real implementation of [WifiRepository]. */
+@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
+@OptIn(ExperimentalCoroutinesApi::class)
+@SysUISingleton
+@SuppressLint("MissingPermission")
+class WifiRepositoryImpl
+@Inject
+constructor(
+    broadcastDispatcher: BroadcastDispatcher,
+    connectivityManager: ConnectivityManager,
+    logger: ConnectivityPipelineLogger,
+    @WifiTableLog wifiTableLogBuffer: TableLogBuffer,
+    @Main mainExecutor: Executor,
+    @Application scope: CoroutineScope,
+    wifiManager: WifiManager,
+) : RealWifiRepository {
+
+    private val wifiStateChangeEvents: Flow<Unit> =
+        broadcastDispatcher
+            .broadcastFlow(IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION))
+            .logInputChange(logger, "WIFI_STATE_CHANGED_ACTION intent")
+
+    private val wifiNetworkChangeEvents: MutableSharedFlow<Unit> =
+        MutableSharedFlow(extraBufferCapacity = 1)
+
+    // Because [WifiManager] doesn't expose a wifi enabled change listener, we do it
+    // internally by fetching [WifiManager.isWifiEnabled] whenever we think the state may
+    // have changed.
+    override val isWifiEnabled: StateFlow<Boolean> =
+        merge(wifiNetworkChangeEvents, wifiStateChangeEvents)
+            .mapLatest { wifiManager.isWifiEnabled }
+            .distinctUntilChanged()
+            .logDiffsForTable(
+                wifiTableLogBuffer,
+                columnPrefix = "",
+                columnName = "isWifiEnabled",
+                initialValue = wifiManager.isWifiEnabled,
+            )
+            .stateIn(
+                scope = scope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue = wifiManager.isWifiEnabled,
+            )
+
+    override val isWifiDefault: StateFlow<Boolean> =
+        conflatedCallbackFlow {
+                // Note: This callback doesn't do any logging because we already log every network
+                // change in the [wifiNetwork] callback.
+                val callback =
+                    object : ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) {
+                        override fun onCapabilitiesChanged(
+                            network: Network,
+                            networkCapabilities: NetworkCapabilities
+                        ) {
+                            // This method will always be called immediately after the network
+                            // becomes the default, in addition to any time the capabilities change
+                            // while the network is the default.
+                            // If this network contains valid wifi info, then wifi is the default
+                            // network.
+                            val wifiInfo = networkCapabilitiesToWifiInfo(networkCapabilities)
+                            trySend(wifiInfo != null)
+                        }
+
+                        override fun onLost(network: Network) {
+                            // The system no longer has a default network, so wifi is definitely not
+                            // default.
+                            trySend(false)
+                        }
+                    }
+
+                connectivityManager.registerDefaultNetworkCallback(callback)
+                awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
+            }
+            .distinctUntilChanged()
+            .logDiffsForTable(
+                wifiTableLogBuffer,
+                columnPrefix = "",
+                columnName = "isWifiDefault",
+                initialValue = false,
+            )
+            .stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = false)
+
+    override val wifiNetwork: StateFlow<WifiNetworkModel> =
+        conflatedCallbackFlow {
+                var currentWifi: WifiNetworkModel = WIFI_NETWORK_DEFAULT
+
+                val callback =
+                    object : ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) {
+                        override fun onCapabilitiesChanged(
+                            network: Network,
+                            networkCapabilities: NetworkCapabilities
+                        ) {
+                            logger.logOnCapabilitiesChanged(network, networkCapabilities)
+
+                            wifiNetworkChangeEvents.tryEmit(Unit)
+
+                            val wifiInfo = networkCapabilitiesToWifiInfo(networkCapabilities)
+                            if (wifiInfo?.isPrimary == true) {
+                                val wifiNetworkModel =
+                                    createWifiNetworkModel(
+                                        wifiInfo,
+                                        network,
+                                        networkCapabilities,
+                                        wifiManager,
+                                    )
+                                logger.logTransformation(
+                                    WIFI_NETWORK_CALLBACK_NAME,
+                                    oldValue = currentWifi,
+                                    newValue = wifiNetworkModel,
+                                )
+                                currentWifi = wifiNetworkModel
+                                trySend(wifiNetworkModel)
+                            }
+                        }
+
+                        override fun onLost(network: Network) {
+                            logger.logOnLost(network)
+
+                            wifiNetworkChangeEvents.tryEmit(Unit)
+
+                            val wifi = currentWifi
+                            if (
+                                wifi is WifiNetworkModel.Active &&
+                                    wifi.networkId == network.getNetId()
+                            ) {
+                                val newNetworkModel = WifiNetworkModel.Inactive
+                                logger.logTransformation(
+                                    WIFI_NETWORK_CALLBACK_NAME,
+                                    oldValue = wifi,
+                                    newValue = newNetworkModel,
+                                )
+                                currentWifi = newNetworkModel
+                                trySend(newNetworkModel)
+                            }
+                        }
+                    }
+
+                connectivityManager.registerNetworkCallback(WIFI_NETWORK_CALLBACK_REQUEST, callback)
+
+                awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
+            }
+            .distinctUntilChanged()
+            .logDiffsForTable(
+                wifiTableLogBuffer,
+                columnPrefix = "wifiNetwork",
+                initialValue = WIFI_NETWORK_DEFAULT,
+            )
+            // There will be multiple wifi icons in different places that will frequently
+            // subscribe/unsubscribe to flows as the views attach/detach. Using [stateIn] ensures
+            // that new subscribes will get the latest value immediately upon subscription.
+            // Otherwise, the views could show stale data. See b/244173280.
+            .stateIn(
+                scope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue = WIFI_NETWORK_DEFAULT,
+            )
+
+    override val wifiActivity: StateFlow<DataActivityModel> =
+        conflatedCallbackFlow {
+                val callback = TrafficStateCallback { state ->
+                    logger.logInputChange("onTrafficStateChange", prettyPrintActivity(state))
+                    trySend(state.toWifiDataActivityModel())
+                }
+                wifiManager.registerTrafficStateCallback(mainExecutor, callback)
+                awaitClose { wifiManager.unregisterTrafficStateCallback(callback) }
+            }
+            .logDiffsForTable(
+                wifiTableLogBuffer,
+                columnPrefix = ACTIVITY_PREFIX,
+                initialValue = ACTIVITY_DEFAULT,
+            )
+            .stateIn(
+                scope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue = ACTIVITY_DEFAULT,
+            )
+
+    companion object {
+        private const val ACTIVITY_PREFIX = "wifiActivity"
+
+        val ACTIVITY_DEFAULT = DataActivityModel(hasActivityIn = false, hasActivityOut = false)
+        // Start out with no known wifi network.
+        // Note: [WifiStatusTracker] (the old implementation of connectivity logic) does do an
+        // initial fetch to get a starting wifi network. But, it uses a deprecated API
+        // [WifiManager.getConnectionInfo()], and the deprecation doc indicates to just use
+        // [ConnectivityManager.NetworkCallback] results instead. So, for now we'll just rely on the
+        // NetworkCallback inside [wifiNetwork] for our wifi network information.
+        val WIFI_NETWORK_DEFAULT = WifiNetworkModel.Inactive
+
+        private fun networkCapabilitiesToWifiInfo(
+            networkCapabilities: NetworkCapabilities
+        ): WifiInfo? {
+            return when {
+                networkCapabilities.hasTransport(TRANSPORT_WIFI) ->
+                    networkCapabilities.transportInfo as WifiInfo?
+                networkCapabilities.hasTransport(TRANSPORT_CELLULAR) ->
+                    // Sometimes, cellular networks can act as wifi networks (known as VCN --
+                    // virtual carrier network). So, see if this cellular network has wifi info.
+                    Utils.tryGetWifiInfoForVcn(networkCapabilities)
+                else -> null
+            }
+        }
+
+        private fun createWifiNetworkModel(
+            wifiInfo: WifiInfo,
+            network: Network,
+            networkCapabilities: NetworkCapabilities,
+            wifiManager: WifiManager,
+        ): WifiNetworkModel {
+            return if (wifiInfo.isCarrierMerged) {
+                if (wifiInfo.subscriptionId == INVALID_SUBSCRIPTION_ID) {
+                    WifiNetworkModel.Invalid(CARRIER_MERGED_INVALID_SUB_ID_REASON)
+                } else {
+                    WifiNetworkModel.CarrierMerged(
+                        networkId = network.getNetId(),
+                        subscriptionId = wifiInfo.subscriptionId,
+                        level = wifiManager.calculateSignalLevel(wifiInfo.rssi),
+                        // The WiFi signal level returned by WifiManager#calculateSignalLevel start
+                        // from 0, so WifiManager#getMaxSignalLevel + 1 represents the total level
+                        // buckets count.
+                        numberOfLevels = wifiManager.maxSignalLevel + 1,
+                    )
+                }
+            } else {
+                WifiNetworkModel.Active(
+                    network.getNetId(),
+                    isValidated = networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED),
+                    level = wifiManager.calculateSignalLevel(wifiInfo.rssi),
+                    wifiInfo.ssid,
+                    wifiInfo.isPasspointAp,
+                    wifiInfo.isOsuAp,
+                    wifiInfo.passpointProviderFriendlyName
+                )
+            }
+        }
+
+        private fun prettyPrintActivity(activity: Int): String {
+            return when (activity) {
+                TrafficStateCallback.DATA_ACTIVITY_NONE -> "NONE"
+                TrafficStateCallback.DATA_ACTIVITY_IN -> "IN"
+                TrafficStateCallback.DATA_ACTIVITY_OUT -> "OUT"
+                TrafficStateCallback.DATA_ACTIVITY_INOUT -> "INOUT"
+                else -> "INVALID"
+            }
+        }
+
+        private val WIFI_NETWORK_CALLBACK_REQUEST: NetworkRequest =
+            NetworkRequest.Builder()
+                .clearCapabilities()
+                .addCapability(NET_CAPABILITY_NOT_VPN)
+                .addTransportType(TRANSPORT_WIFI)
+                .addTransportType(TRANSPORT_CELLULAR)
+                .build()
+
+        private const val WIFI_NETWORK_CALLBACK_NAME = "wifiNetworkModel"
+
+        private const val CARRIER_MERGED_INVALID_SUB_ID_REASON =
+            "Wifi network was carrier merged but had invalid sub ID"
+    }
+
+    @SysUISingleton
+    class Factory
+    @Inject
+    constructor(
+        private val broadcastDispatcher: BroadcastDispatcher,
+        private val connectivityManager: ConnectivityManager,
+        private val logger: ConnectivityPipelineLogger,
+        @WifiTableLog private val wifiTableLogBuffer: TableLogBuffer,
+        @Main private val mainExecutor: Executor,
+        @Application private val scope: CoroutineScope,
+    ) {
+        fun create(wifiManager: WifiManager): WifiRepositoryImpl {
+            return WifiRepositoryImpl(
+                broadcastDispatcher,
+                connectivityManager,
+                logger,
+                wifiTableLogBuffer,
+                mainExecutor,
+                scope,
+                wifiManager,
+            )
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt
index 93041ce..86dcd18 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt
@@ -65,6 +65,8 @@
 
     override val ssid: Flow<String?> = wifiRepository.wifiNetwork.map { info ->
         when (info) {
+            is WifiNetworkModel.Unavailable -> null
+            is WifiNetworkModel.Invalid -> null
             is WifiNetworkModel.Inactive -> null
             is WifiNetworkModel.CarrierMerged -> null
             is WifiNetworkModel.Active -> when {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt
index cc67c84..2aff12c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt
@@ -30,6 +30,7 @@
 import com.android.systemui.statusbar.StatusBarIconView.STATE_DOT
 import com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN
 import com.android.systemui.statusbar.StatusBarIconView.STATE_ICON
+import com.android.systemui.statusbar.pipeline.shared.ui.binder.ModernStatusBarViewBinding
 import com.android.systemui.statusbar.pipeline.wifi.ui.model.WifiIcon
 import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.LocationBasedWifiViewModel
 import kotlinx.coroutines.InternalCoroutinesApi
@@ -49,31 +50,12 @@
 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
 object WifiViewBinder {
 
-    /**
-     * Defines interface for an object that acts as the binding between the view and its view-model.
-     *
-     * Users of the [WifiViewBinder] class should use this to control the binder after it is bound.
-     */
-    interface Binding {
-        /** Returns true if the wifi icon should be visible and false otherwise. */
-        fun getShouldIconBeVisible(): Boolean
-
-        /** Notifies that the visibility state has changed. */
-        fun onVisibilityStateChanged(@StatusBarIconView.VisibleState state: Int)
-
-        /** Notifies that the icon tint has been updated. */
-        fun onIconTintChanged(newTint: Int)
-
-        /** Notifies that the decor tint has been updated (used only for the dot). */
-        fun onDecorTintChanged(newTint: Int)
-    }
-
     /** Binds the view to the view-model, continuing to update the former based on the latter. */
     @JvmStatic
     fun bind(
         view: ViewGroup,
         viewModel: LocationBasedWifiViewModel,
-    ): Binding {
+    ): ModernStatusBarViewBinding {
         val groupView = view.requireViewById<ViewGroup>(R.id.wifi_group)
         val iconView = view.requireViewById<ImageView>(R.id.wifi_signal)
         val dotView = view.requireViewById<StatusBarIconView>(R.id.status_bar_dot)
@@ -148,7 +130,7 @@
             }
         }
 
-        return object : Binding {
+        return object : ModernStatusBarViewBinding {
             override fun getShouldIconBeVisible(): Boolean {
                 return viewModel.wifiIcon.value is WifiIcon.Visible
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt
index be7782c..7a73486 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt
@@ -16,17 +16,12 @@
 
 package com.android.systemui.statusbar.pipeline.wifi.ui.view
 
+import android.annotation.SuppressLint
 import android.content.Context
-import android.graphics.Rect
 import android.util.AttributeSet
-import android.view.Gravity
 import android.view.LayoutInflater
 import com.android.systemui.R
-import com.android.systemui.plugins.DarkIconDispatcher
-import com.android.systemui.statusbar.BaseStatusBarFrameLayout
-import com.android.systemui.statusbar.StatusBarIconView
-import com.android.systemui.statusbar.StatusBarIconView.STATE_DOT
-import com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN
+import com.android.systemui.statusbar.pipeline.shared.ui.view.ModernStatusBarView
 import com.android.systemui.statusbar.pipeline.wifi.ui.binder.WifiViewBinder
 import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.LocationBasedWifiViewModel
 
@@ -36,83 +31,14 @@
  */
 class ModernStatusBarWifiView(
     context: Context,
-    attrs: AttributeSet?
-) : BaseStatusBarFrameLayout(context, attrs) {
-
-    private lateinit var slot: String
-    private lateinit var binding: WifiViewBinder.Binding
-
-    @StatusBarIconView.VisibleState
-    private var iconVisibleState: Int = STATE_HIDDEN
-        set(value) {
-            if (field == value) {
-                return
-            }
-            field = value
-            binding.onVisibilityStateChanged(value)
-        }
-
-    override fun getSlot() = slot
-
-    override fun onDarkChanged(areas: ArrayList<Rect>?, darkIntensity: Float, tint: Int) {
-        val newTint = DarkIconDispatcher.getTint(areas, this, tint)
-        binding.onIconTintChanged(newTint)
-        binding.onDecorTintChanged(newTint)
-    }
-
-    override fun setStaticDrawableColor(color: Int) {
-        binding.onIconTintChanged(color)
-    }
-
-    override fun setDecorColor(color: Int) {
-        binding.onDecorTintChanged(color)
-    }
-
-    override fun setVisibleState(@StatusBarIconView.VisibleState state: Int, animate: Boolean) {
-        iconVisibleState = state
-    }
-
-    @StatusBarIconView.VisibleState
-    override fun getVisibleState(): Int {
-        return iconVisibleState
-    }
-
-    override fun isIconVisible(): Boolean {
-        return binding.getShouldIconBeVisible()
-    }
-
-    private fun initView(
-        slotName: String,
-        wifiViewModel: LocationBasedWifiViewModel,
-    ) {
-        slot = slotName
-        initDotView()
-        binding = WifiViewBinder.bind(this, wifiViewModel)
-    }
-
-    // Mostly duplicated from [com.android.systemui.statusbar.StatusBarWifiView].
-    private fun initDotView() {
-        // TODO(b/238425913): Could we just have this dot view be part of
-        //   R.layout.new_status_bar_wifi_group with a dot drawable so we don't need to inflate it
-        //   manually? Would that not work with animations?
-        val dotView = StatusBarIconView(mContext, slot, null).also {
-            it.id = R.id.status_bar_dot
-            // Hard-code this view to always be in the DOT state so that whenever it's visible it
-            // will show a dot
-            it.visibleState = STATE_DOT
-        }
-
-        val width = mContext.resources.getDimensionPixelSize(R.dimen.status_bar_icon_size)
-        val lp = LayoutParams(width, width)
-        lp.gravity = Gravity.CENTER_VERTICAL or Gravity.START
-        addView(dotView, lp)
-    }
-
+    attrs: AttributeSet?,
+) : ModernStatusBarView(context, attrs) {
     companion object {
         /**
          * Inflates a new instance of [ModernStatusBarWifiView], binds it to a view model, and
          * returns it.
          */
+        @SuppressLint("InflateParams")
         @JvmStatic
         fun constructAndBind(
             context: Context,
@@ -123,7 +49,7 @@
                 LayoutInflater.from(context).inflate(R.layout.new_status_bar_wifi_group, null)
                     as ModernStatusBarWifiView
                 ).also {
-                    it.initView(slot, wifiViewModel)
+                    it.initView(slot) { WifiViewBinder.bind(it, wifiViewModel) }
                 }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/LocationBasedWifiViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/LocationBasedWifiViewModel.kt
index a4615cc..02c3a65 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/LocationBasedWifiViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/LocationBasedWifiViewModel.kt
@@ -47,7 +47,7 @@
     /** True if the airplane spacer view should be visible. */
     val isAirplaneSpacerVisible: Flow<Boolean>,
 ) {
-    val useDebugColoring: Boolean = statusBarPipelineFlags.useWifiDebugColoring()
+    val useDebugColoring: Boolean = statusBarPipelineFlags.useDebugColoring()
 
     val defaultColor: Int =
         if (useDebugColoring) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt
index ab464cc..95431af 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt
@@ -82,6 +82,8 @@
     /** Returns the icon to use based on the given network. */
     private fun WifiNetworkModel.icon(): WifiIcon {
         return when (this) {
+            is WifiNetworkModel.Unavailable -> WifiIcon.Hidden
+            is WifiNetworkModel.Invalid -> WifiIcon.Hidden
             is WifiNetworkModel.CarrierMerged -> WifiIcon.Hidden
             is WifiNetworkModel.Inactive -> WifiIcon.Visible(
                 res = WIFI_NO_NETWORK,
@@ -89,27 +91,23 @@
                     "${context.getString(WIFI_NO_CONNECTION)},${context.getString(NO_INTERNET)}"
                 )
             )
-            is WifiNetworkModel.Active ->
-                when (this.level) {
-                    null -> WifiIcon.Hidden
-                    else -> {
-                        val levelDesc = context.getString(WIFI_CONNECTION_STRENGTH[this.level])
-                        when {
-                            this.isValidated ->
-                                WifiIcon.Visible(
-                                    WIFI_FULL_ICONS[this.level],
-                                    ContentDescription.Loaded(levelDesc)
-                                )
-                            else ->
-                                WifiIcon.Visible(
-                                    WIFI_NO_INTERNET_ICONS[this.level],
-                                    ContentDescription.Loaded(
-                                        "$levelDesc,${context.getString(NO_INTERNET)}"
-                                    )
-                                )
-                        }
-                    }
+            is WifiNetworkModel.Active -> {
+                val levelDesc = context.getString(WIFI_CONNECTION_STRENGTH[this.level])
+                when {
+                    this.isValidated ->
+                        WifiIcon.Visible(
+                            WIFI_FULL_ICONS[this.level],
+                            ContentDescription.Loaded(levelDesc),
+                        )
+                    else ->
+                        WifiIcon.Visible(
+                            WIFI_NO_INTERNET_ICONS[this.level],
+                            ContentDescription.Loaded(
+                                "$levelDesc,${context.getString(NO_INTERNET)}"
+                            ),
+                        )
                 }
+            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseUserSwitcherAdapter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseUserSwitcherAdapter.kt
index 68d30d3..2b4f51c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseUserSwitcherAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseUserSwitcherAdapter.kt
@@ -60,7 +60,7 @@
      * animation to and from the parent dialog.
      */
     @JvmOverloads
-    open fun onUserListItemClicked(
+    fun onUserListItemClicked(
         record: UserRecord,
         dialogShower: DialogShower? = null,
     ) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EmergencyCryptkeeperText.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EmergencyCryptkeeperText.java
deleted file mode 100644
index 21a8300..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EmergencyCryptkeeperText.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.statusbar.policy;
-
-import android.annotation.Nullable;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.provider.Settings;
-import android.telephony.SubscriptionInfo;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.widget.TextView;
-
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.systemui.Dependency;
-
-import java.util.List;
-
-public class EmergencyCryptkeeperText extends TextView {
-
-    private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
-    private final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
-        @Override
-        public void onPhoneStateChanged(int phoneState) {
-            update();
-        }
-
-        @Override
-        public void onRefreshCarrierInfo() {
-            update();
-        }
-    };
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(intent.getAction())) {
-                update();
-            }
-        }
-    };
-
-    public EmergencyCryptkeeperText(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-        setVisibility(GONE);
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
-        mKeyguardUpdateMonitor.registerCallback(mCallback);
-        getContext().registerReceiver(mReceiver,
-                new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));
-        update();
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        if (mKeyguardUpdateMonitor != null) {
-            mKeyguardUpdateMonitor.removeCallback(mCallback);
-        }
-        getContext().unregisterReceiver(mReceiver);
-    }
-
-    private boolean iccCardExist(int simState) {
-        return ((simState == TelephonyManager.SIM_STATE_PIN_REQUIRED)
-                || (simState == TelephonyManager.SIM_STATE_PUK_REQUIRED)
-                || (simState == TelephonyManager.SIM_STATE_NETWORK_LOCKED)
-                || (simState == TelephonyManager.SIM_STATE_READY)
-                || (simState == TelephonyManager.SIM_STATE_NOT_READY)
-                || (simState == TelephonyManager.SIM_STATE_PERM_DISABLED)
-                || (simState == TelephonyManager.SIM_STATE_CARD_IO_ERROR)
-                || (simState == TelephonyManager.SIM_STATE_CARD_RESTRICTED)
-                || (simState == TelephonyManager.SIM_STATE_LOADED));
-    }
-
-    public void update() {
-        boolean hasMobile = mContext.getSystemService(TelephonyManager.class).isDataCapable();
-        boolean airplaneMode = (Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.AIRPLANE_MODE_ON, 0) == 1);
-
-        if (!hasMobile || airplaneMode) {
-            setText(null);
-            setVisibility(GONE);
-            return;
-        }
-
-        boolean allSimsMissing = true;
-        CharSequence displayText = null;
-
-        List<SubscriptionInfo> subs = mKeyguardUpdateMonitor.getFilteredSubscriptionInfo();
-        final int N = subs.size();
-        for (int i = 0; i < N; i++) {
-            int subId = subs.get(i).getSubscriptionId();
-            int simState = mKeyguardUpdateMonitor.getSimState(subId);
-            CharSequence carrierName = subs.get(i).getCarrierName();
-            if (iccCardExist(simState) && !TextUtils.isEmpty(carrierName)) {
-                allSimsMissing = false;
-                displayText = carrierName;
-            }
-        }
-        if (allSimsMissing) {
-            if (N != 0) {
-                // Shows "Emergency calls only" on devices that are voice-capable.
-                // This depends on mPlmn containing the text "Emergency calls only" when the radio
-                // has some connectivity. Otherwise it should show "No service"
-                // Grab the first subscription, because they all should contain the emergency text,
-                // described above.
-                displayText = subs.get(0).getCarrierName();
-            } else {
-                // We don't have a SubscriptionInfo to get the emergency calls only from.
-                // Grab it from the old sticky broadcast if possible instead. We can use it
-                // here because no subscriptions are active, so we don't have
-                // to worry about MSIM clashing.
-                displayText = getContext().getText(
-                        com.android.internal.R.string.emergency_calls_only);
-                Intent i = getContext().registerReceiver(null,
-                        new IntentFilter(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED));
-                if (i != null) {
-                    displayText = i.getStringExtra(TelephonyManager.EXTRA_PLMN);
-                }
-            }
-        }
-
-        setText(displayText);
-        setVisibility(TextUtils.isEmpty(displayText) ? GONE : VISIBLE);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EncryptionHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EncryptionHelper.java
deleted file mode 100644
index 9c099f9..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EncryptionHelper.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.statusbar.policy;
-
-import android.sysprop.VoldProperties;
-
-/**
- * Helper for determining whether the phone is decrypted yet.
- */
-public class EncryptionHelper {
-
-    public static final boolean IS_DATA_ENCRYPTED = isDataEncrypted();
-
-    private static boolean isDataEncrypted() {
-        String voldState = VoldProperties.decrypt().orElse("");
-        return "1".equals(voldState) || "trigger_restart_min_framework".equals(voldState);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
index f63d652..c8ee647 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
@@ -160,7 +160,7 @@
         mStatusBarStateController = statusBarStateController;
         mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView,
                 keyguardStateController, dozeParameters,
-                screenOffAnimationController,  /* animateYPos= */ false);
+                screenOffAnimationController,  /* animateYPos= */ false, /* logBuffer= */ null);
         mUserSwitchDialogController = userSwitchDialogController;
         mUiEventLogger = uiEventLogger;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java
index c150654..e9f0dcb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java
@@ -173,7 +173,7 @@
                 mUserSwitcherController, this);
         mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView,
                 keyguardStateController, dozeParameters,
-                screenOffAnimationController, /* animateYPos= */ false);
+                screenOffAnimationController, /* animateYPos= */ false, /* logBuffer= */ null);
         mBackground = new KeyguardUserSwitcherScrim(context);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index c9ed0cb..4866f73 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -109,6 +109,8 @@
     private static final long FOCUS_ANIMATION_FADE_IN_DELAY = 33;
     private static final long FOCUS_ANIMATION_FADE_IN_DURATION = 83;
     private static final float FOCUS_ANIMATION_MIN_SCALE = 0.5f;
+    private static final long DEFOCUS_ANIMATION_FADE_OUT_DELAY = 120;
+    private static final long DEFOCUS_ANIMATION_CROSSFADE_DELAY = 180;
 
     public final Object mToken = new Object();
 
@@ -301,7 +303,8 @@
                     mEntry.mRemoteEditImeVisible = editTextRootWindowInsets != null
                             && editTextRootWindowInsets.isVisible(WindowInsets.Type.ime());
                     if (!mEntry.mRemoteEditImeVisible && !mEditText.mShowImeOnInputConnection) {
-                        mController.removeRemoteInput(mEntry, mToken);
+                        // Pass null to ensure all inputs are cleared for this entry b/227115380
+                        mController.removeRemoteInput(mEntry, null);
                     }
                 }
             }
@@ -421,7 +424,7 @@
     }
 
     @VisibleForTesting
-    void onDefocus(boolean animate, boolean logClose) {
+    void onDefocus(boolean animate, boolean logClose, @Nullable Runnable doAfterDefocus) {
         mController.removeRemoteInput(mEntry, mToken);
         mEntry.remoteInputText = mEditText.getText();
 
@@ -431,18 +434,20 @@
             ViewGroup parent = (ViewGroup) getParent();
             if (animate && parent != null && mIsFocusAnimationFlagActive) {
 
-
                 ViewGroup grandParent = (ViewGroup) parent.getParent();
                 ViewGroupOverlay overlay = parent.getOverlay();
+                View actionsContainer = getActionsContainerLayout();
+                int actionsContainerHeight =
+                        actionsContainer != null ? actionsContainer.getHeight() : 0;
 
                 // After adding this RemoteInputView to the overlay of the parent (and thus removing
                 // it from the parent itself), the parent will shrink in height. This causes the
                 // overlay to be moved. To correct the position of the overlay we need to offset it.
-                int overlayOffsetY = getMaxSiblingHeight() - getHeight();
+                int overlayOffsetY = actionsContainerHeight - getHeight();
                 overlay.add(this);
                 if (grandParent != null) grandParent.setClipChildren(false);
 
-                Animator animator = getDefocusAnimator(overlayOffsetY);
+                Animator animator = getDefocusAnimator(actionsContainer, overlayOffsetY);
                 View self = this;
                 animator.addListener(new AnimatorListenerAdapter() {
                     @Override
@@ -454,8 +459,12 @@
                         if (mWrapper != null) {
                             mWrapper.setRemoteInputVisible(false);
                         }
+                        if (doAfterDefocus != null) {
+                            doAfterDefocus.run();
+                        }
                     }
                 });
+                if (actionsContainer != null) actionsContainer.setAlpha(0f);
                 animator.start();
 
             } else if (animate && mRevealParams != null && mRevealParams.radius > 0) {
@@ -474,6 +483,7 @@
                 reveal.start();
             } else {
                 setVisibility(GONE);
+                if (doAfterDefocus != null) doAfterDefocus.run();
                 if (mWrapper != null) {
                     mWrapper.setRemoteInputVisible(false);
                 }
@@ -596,10 +606,8 @@
 
     /**
      * Focuses the RemoteInputView and animates its appearance
-     *
-     * @param crossFadeView view that will be crossfaded during the appearance animation
      */
-    public void focusAnimated(View crossFadeView) {
+    public void focusAnimated() {
         if (!mIsFocusAnimationFlagActive && getVisibility() != VISIBLE
                 && mRevealParams != null) {
             android.animation.Animator animator = mRevealParams.createCircularRevealAnimator(this);
@@ -609,7 +617,7 @@
         } else if (mIsFocusAnimationFlagActive && getVisibility() != VISIBLE) {
             mIsAnimatingAppearance = true;
             setAlpha(0f);
-            Animator focusAnimator = getFocusAnimator(crossFadeView);
+            Animator focusAnimator = getFocusAnimator(getActionsContainerLayout());
             focusAnimator.addListener(new AnimatorListenerAdapter() {
                 @Override
                 public void onAnimationEnd(Animator animation, boolean isReverse) {
@@ -661,6 +669,23 @@
     }
 
     private void reset() {
+        if (mIsFocusAnimationFlagActive) {
+            mProgressBar.setVisibility(INVISIBLE);
+            mResetting = true;
+            mSending = false;
+            onDefocus(true /* animate */, false /* logClose */, () -> {
+                mEntry.remoteInputTextWhenReset = SpannedString.valueOf(mEditText.getText());
+                mEditText.getText().clear();
+                mEditText.setEnabled(isAggregatedVisible());
+                mSendButton.setVisibility(VISIBLE);
+                mController.removeSpinning(mEntry.getKey(), mToken);
+                updateSendButton();
+                setAttachment(null);
+                mResetting = false;
+            });
+            return;
+        }
+
         mResetting = true;
         mSending = false;
         mEntry.remoteInputTextWhenReset = SpannedString.valueOf(mEditText.getText());
@@ -671,7 +696,7 @@
         mProgressBar.setVisibility(INVISIBLE);
         mController.removeSpinning(mEntry.getKey(), mToken);
         updateSendButton();
-        onDefocus(false /* animate */, false /* logClose */);
+        onDefocus(false /* animate */, false /* logClose */, null /* doAfterDefocus */);
         setAttachment(null);
 
         mResetting = false;
@@ -825,23 +850,22 @@
     }
 
     /**
-     * @return max sibling height (0 in case of no siblings)
+     * @return action button container view (i.e. ViewGroup containing Reply button etc.)
      */
-    public int getMaxSiblingHeight() {
+    public View getActionsContainerLayout() {
         ViewGroup parentView = (ViewGroup) getParent();
-        int maxHeight = 0;
-        if (parentView == null) return 0;
-        for (int i = 0; i < parentView.getChildCount(); i++) {
-            View siblingView = parentView.getChildAt(i);
-            if (siblingView != this) maxHeight = Math.max(maxHeight, siblingView.getHeight());
-        }
-        return maxHeight;
+        if (parentView == null) return null;
+        return parentView.findViewById(com.android.internal.R.id.actions_container_layout);
     }
 
     /**
      * Creates an animator for the focus animation.
+     *
+     * @param fadeOutView View that will be faded out during the focus animation.
      */
-    private Animator getFocusAnimator(View crossFadeView) {
+    private Animator getFocusAnimator(@Nullable View fadeOutView) {
+        final AnimatorSet animatorSet = new AnimatorSet();
+
         final Animator alphaAnimator = ObjectAnimator.ofFloat(this, View.ALPHA, 0f, 1f);
         alphaAnimator.setStartDelay(FOCUS_ANIMATION_FADE_IN_DELAY);
         alphaAnimator.setDuration(FOCUS_ANIMATION_FADE_IN_DURATION);
@@ -854,30 +878,36 @@
         scaleAnimator.setDuration(FOCUS_ANIMATION_TOTAL_DURATION);
         scaleAnimator.setInterpolator(InterpolatorsAndroidX.FAST_OUT_SLOW_IN);
 
-        final Animator crossFadeViewAlphaAnimator =
-                ObjectAnimator.ofFloat(crossFadeView, View.ALPHA, 1f, 0f);
-        crossFadeViewAlphaAnimator.setDuration(FOCUS_ANIMATION_CROSSFADE_DURATION);
-        crossFadeViewAlphaAnimator.setInterpolator(InterpolatorsAndroidX.LINEAR);
-        alphaAnimator.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation, boolean isReverse) {
-                crossFadeView.setAlpha(1f);
-            }
-        });
-
-        final AnimatorSet animatorSet = new AnimatorSet();
-        animatorSet.playTogether(alphaAnimator, scaleAnimator, crossFadeViewAlphaAnimator);
+        if (fadeOutView == null) {
+            animatorSet.playTogether(alphaAnimator, scaleAnimator);
+        } else {
+            final Animator fadeOutViewAlphaAnimator =
+                    ObjectAnimator.ofFloat(fadeOutView, View.ALPHA, 1f, 0f);
+            fadeOutViewAlphaAnimator.setDuration(FOCUS_ANIMATION_CROSSFADE_DURATION);
+            fadeOutViewAlphaAnimator.setInterpolator(InterpolatorsAndroidX.LINEAR);
+            animatorSet.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation, boolean isReverse) {
+                    fadeOutView.setAlpha(1f);
+                }
+            });
+            animatorSet.playTogether(alphaAnimator, scaleAnimator, fadeOutViewAlphaAnimator);
+        }
         return animatorSet;
     }
 
     /**
      * Creates an animator for the defocus animation.
      *
-     * @param offsetY The RemoteInputView will be offset by offsetY during the animation
+     * @param fadeInView View that will be faded in during the defocus animation.
+     * @param offsetY    The RemoteInputView will be offset by offsetY during the animation
      */
-    private Animator getDefocusAnimator(int offsetY) {
+    private Animator getDefocusAnimator(@Nullable View fadeInView, int offsetY) {
+        final AnimatorSet animatorSet = new AnimatorSet();
+
         final Animator alphaAnimator = ObjectAnimator.ofFloat(this, View.ALPHA, 1f, 0f);
-        alphaAnimator.setDuration(FOCUS_ANIMATION_CROSSFADE_DURATION);
+        alphaAnimator.setDuration(FOCUS_ANIMATION_FADE_IN_DURATION);
+        alphaAnimator.setStartDelay(DEFOCUS_ANIMATION_FADE_OUT_DELAY);
         alphaAnimator.setInterpolator(InterpolatorsAndroidX.LINEAR);
 
         ValueAnimator scaleAnimator = ValueAnimator.ofFloat(1f, FOCUS_ANIMATION_MIN_SCALE);
@@ -893,8 +923,17 @@
             }
         });
 
-        final AnimatorSet animatorSet = new AnimatorSet();
-        animatorSet.playTogether(alphaAnimator, scaleAnimator);
+        if (fadeInView == null) {
+            animatorSet.playTogether(alphaAnimator, scaleAnimator);
+        } else {
+            fadeInView.forceHasOverlappingRendering(false);
+            Animator fadeInViewAlphaAnimator =
+                    ObjectAnimator.ofFloat(fadeInView, View.ALPHA, 0f, 1f);
+            fadeInViewAlphaAnimator.setDuration(FOCUS_ANIMATION_FADE_IN_DURATION);
+            fadeInViewAlphaAnimator.setInterpolator(InterpolatorsAndroidX.LINEAR);
+            fadeInViewAlphaAnimator.setStartDelay(DEFOCUS_ANIMATION_CROSSFADE_DELAY);
+            animatorSet.playTogether(alphaAnimator, scaleAnimator, fadeInViewAlphaAnimator);
+        }
         return animatorSet;
     }
 
@@ -1011,7 +1050,8 @@
             if (isFocusable() && isEnabled()) {
                 setInnerFocusable(false);
                 if (mRemoteInputView != null) {
-                    mRemoteInputView.onDefocus(animate, true /* logClose */);
+                    mRemoteInputView
+                            .onDefocus(animate, true /* logClose */, null /* doAfterDefocus */);
                 }
                 mShowImeOnInputConnection = false;
             }
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusFirstUsageListener.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusFirstUsageListener.kt
deleted file mode 100644
index 154c6e2..0000000
--- a/packages/SystemUI/src/com/android/systemui/stylus/StylusFirstUsageListener.kt
+++ /dev/null
@@ -1,136 +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.stylus
-
-import android.content.Context
-import android.hardware.BatteryState
-import android.hardware.input.InputManager
-import android.os.Handler
-import android.util.Log
-import android.view.InputDevice
-import androidx.annotation.VisibleForTesting
-import com.android.systemui.CoreStartable
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
-import java.util.concurrent.Executor
-import javax.inject.Inject
-
-/**
- * A listener that detects when a stylus has first been used, by detecting 1) the presence of an
- * internal SOURCE_STYLUS with a battery, or 2) any added SOURCE_STYLUS device with a bluetooth
- * address.
- */
-@SysUISingleton
-class StylusFirstUsageListener
-@Inject
-constructor(
-    private val context: Context,
-    private val inputManager: InputManager,
-    private val stylusManager: StylusManager,
-    private val featureFlags: FeatureFlags,
-    @Background private val executor: Executor,
-    @Background private val handler: Handler,
-) : CoreStartable, StylusManager.StylusCallback, InputManager.InputDeviceBatteryListener {
-
-    // Set must be only accessed from the background handler, which is the same handler that
-    // runs the StylusManager callbacks.
-    private val internalStylusDeviceIds: MutableSet<Int> = mutableSetOf()
-    @VisibleForTesting var hasStarted = false
-
-    override fun start() {
-        if (true) return // TODO(b/261826950): remove on main
-        if (hasStarted) return
-        if (!featureFlags.isEnabled(Flags.TRACK_STYLUS_EVER_USED)) return
-        if (inputManager.isStylusEverUsed(context)) return
-        if (!hostDeviceSupportsStylusInput()) return
-
-        hasStarted = true
-        inputManager.inputDeviceIds.forEach(this::onStylusAdded)
-        stylusManager.registerCallback(this)
-        stylusManager.startListener()
-    }
-
-    override fun onStylusAdded(deviceId: Int) {
-        if (!hasStarted) return
-
-        val device = inputManager.getInputDevice(deviceId) ?: return
-        if (device.isExternal || !device.supportsSource(InputDevice.SOURCE_STYLUS)) return
-
-        try {
-            inputManager.addInputDeviceBatteryListener(deviceId, executor, this)
-            internalStylusDeviceIds += deviceId
-        } catch (e: SecurityException) {
-            Log.e(TAG, "$e: Failed to register battery listener for $deviceId ${device.name}.")
-        }
-    }
-
-    override fun onStylusRemoved(deviceId: Int) {
-        if (!hasStarted) return
-
-        if (!internalStylusDeviceIds.contains(deviceId)) return
-        try {
-            inputManager.removeInputDeviceBatteryListener(deviceId, this)
-            internalStylusDeviceIds.remove(deviceId)
-        } catch (e: SecurityException) {
-            Log.e(TAG, "$e: Failed to remove registered battery listener for $deviceId.")
-        }
-    }
-
-    override fun onStylusBluetoothConnected(deviceId: Int, btAddress: String) {
-        if (!hasStarted) return
-
-        onRemoteDeviceFound()
-    }
-
-    override fun onBatteryStateChanged(
-        deviceId: Int,
-        eventTimeMillis: Long,
-        batteryState: BatteryState
-    ) {
-        if (!hasStarted) return
-
-        if (batteryState.isPresent) {
-            onRemoteDeviceFound()
-        }
-    }
-
-    private fun onRemoteDeviceFound() {
-        inputManager.setStylusEverUsed(context, true)
-        cleanupListeners()
-    }
-
-    private fun cleanupListeners() {
-        stylusManager.unregisterCallback(this)
-        handler.post {
-            internalStylusDeviceIds.forEach {
-                inputManager.removeInputDeviceBatteryListener(it, this)
-            }
-        }
-    }
-
-    private fun hostDeviceSupportsStylusInput(): Boolean {
-        return inputManager.inputDeviceIds
-            .asSequence()
-            .mapNotNull { inputManager.getInputDevice(it) }
-            .any { it.supportsSource(InputDevice.SOURCE_STYLUS) && !it.isExternal }
-    }
-
-    companion object {
-        private val TAG = StylusFirstUsageListener::class.simpleName.orEmpty()
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt
index 3e111e6..235495cf 100644
--- a/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt
@@ -18,6 +18,8 @@
 
 import android.bluetooth.BluetoothAdapter
 import android.bluetooth.BluetoothDevice
+import android.content.Context
+import android.hardware.BatteryState
 import android.hardware.input.InputManager
 import android.os.Handler
 import android.util.ArrayMap
@@ -25,6 +27,8 @@
 import android.view.InputDevice
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
 import java.util.concurrent.CopyOnWriteArrayList
 import java.util.concurrent.Executor
 import javax.inject.Inject
@@ -37,25 +41,37 @@
 class StylusManager
 @Inject
 constructor(
+    private val context: Context,
     private val inputManager: InputManager,
-    private val bluetoothAdapter: BluetoothAdapter,
+    private val bluetoothAdapter: BluetoothAdapter?,
     @Background private val handler: Handler,
     @Background private val executor: Executor,
-) : InputManager.InputDeviceListener, BluetoothAdapter.OnMetadataChangedListener {
+    private val featureFlags: FeatureFlags,
+) :
+    InputManager.InputDeviceListener,
+    InputManager.InputDeviceBatteryListener,
+    BluetoothAdapter.OnMetadataChangedListener {
 
     private val stylusCallbacks: CopyOnWriteArrayList<StylusCallback> = CopyOnWriteArrayList()
     private val stylusBatteryCallbacks: CopyOnWriteArrayList<StylusBatteryCallback> =
         CopyOnWriteArrayList()
     // This map should only be accessed on the handler
     private val inputDeviceAddressMap: MutableMap<Int, String?> = ArrayMap()
+    // This variable should only be accessed on the handler
+    private var hasStarted: Boolean = false
 
     /**
      * Starts listening to InputManager InputDevice events. Will also load the InputManager snapshot
      * at time of starting.
      */
     fun startListener() {
-        addExistingStylusToMap()
-        inputManager.registerInputDeviceListener(this, handler)
+        handler.post {
+            if (hasStarted) return@post
+            hasStarted = true
+            addExistingStylusToMap()
+
+            inputManager.registerInputDeviceListener(this, handler)
+        }
     }
 
     /** Registers a StylusCallback to listen to stylus events. */
@@ -77,21 +93,30 @@
     }
 
     override fun onInputDeviceAdded(deviceId: Int) {
+        if (!hasStarted) return
+
         val device: InputDevice = inputManager.getInputDevice(deviceId) ?: return
         if (!device.supportsSource(InputDevice.SOURCE_STYLUS)) return
 
+        if (!device.isExternal) {
+            registerBatteryListener(deviceId)
+        }
+
         // TODO(b/257936830): get address once input api available
         val btAddress: String? = null
         inputDeviceAddressMap[deviceId] = btAddress
         executeStylusCallbacks { cb -> cb.onStylusAdded(deviceId) }
 
         if (btAddress != null) {
+            onStylusUsed()
             onStylusBluetoothConnected(btAddress)
             executeStylusCallbacks { cb -> cb.onStylusBluetoothConnected(deviceId, btAddress) }
         }
     }
 
     override fun onInputDeviceChanged(deviceId: Int) {
+        if (!hasStarted) return
+
         val device: InputDevice = inputManager.getInputDevice(deviceId) ?: return
         if (!device.supportsSource(InputDevice.SOURCE_STYLUS)) return
 
@@ -112,7 +137,10 @@
     }
 
     override fun onInputDeviceRemoved(deviceId: Int) {
+        if (!hasStarted) return
+
         if (!inputDeviceAddressMap.contains(deviceId)) return
+        unregisterBatteryListener(deviceId)
 
         val btAddress: String? = inputDeviceAddressMap[deviceId]
         inputDeviceAddressMap.remove(deviceId)
@@ -124,13 +152,14 @@
     }
 
     override fun onMetadataChanged(device: BluetoothDevice, key: Int, value: ByteArray?) {
-        handler.post executeMetadataChanged@{
-            if (key != BluetoothDevice.METADATA_MAIN_CHARGING || value == null)
-                return@executeMetadataChanged
+        handler.post {
+            if (!hasStarted) return@post
+
+            if (key != BluetoothDevice.METADATA_MAIN_CHARGING || value == null) return@post
 
             val inputDeviceId: Int =
                 inputDeviceAddressMap.filterValues { it == device.address }.keys.firstOrNull()
-                    ?: return@executeMetadataChanged
+                    ?: return@post
 
             val isCharging = String(value) == "true"
 
@@ -140,8 +169,26 @@
         }
     }
 
+    override fun onBatteryStateChanged(
+        deviceId: Int,
+        eventTimeMillis: Long,
+        batteryState: BatteryState
+    ) {
+        handler.post {
+            if (!hasStarted) return@post
+
+            if (batteryState.isPresent) {
+                onStylusUsed()
+            }
+
+            executeStylusBatteryCallbacks { cb ->
+                cb.onStylusUsiBatteryStateChanged(deviceId, eventTimeMillis, batteryState)
+            }
+        }
+    }
+
     private fun onStylusBluetoothConnected(btAddress: String) {
-        val device: BluetoothDevice = bluetoothAdapter.getRemoteDevice(btAddress) ?: return
+        val device: BluetoothDevice = bluetoothAdapter?.getRemoteDevice(btAddress) ?: return
         try {
             bluetoothAdapter.addOnMetadataChangedListener(device, executor, this)
         } catch (e: IllegalArgumentException) {
@@ -150,7 +197,7 @@
     }
 
     private fun onStylusBluetoothDisconnected(btAddress: String) {
-        val device: BluetoothDevice = bluetoothAdapter.getRemoteDevice(btAddress) ?: return
+        val device: BluetoothDevice = bluetoothAdapter?.getRemoteDevice(btAddress) ?: return
         try {
             bluetoothAdapter.removeOnMetadataChangedListener(device, this)
         } catch (e: IllegalArgumentException) {
@@ -158,6 +205,21 @@
         }
     }
 
+    /**
+     * An InputDevice that supports [InputDevice.SOURCE_STYLUS] may still be present even when a
+     * physical stylus device has never been used. This method is run when 1) a USI stylus battery
+     * event happens, or 2) a bluetooth stylus is connected, as they are both indicators that a
+     * physical stylus device has actually been used.
+     */
+    private fun onStylusUsed() {
+        if (true) return // TODO(b/261826950): remove on main
+        if (!featureFlags.isEnabled(Flags.TRACK_STYLUS_EVER_USED)) return
+        if (inputManager.isStylusEverUsed(context)) return
+
+        inputManager.setStylusEverUsed(context, true)
+        executeStylusCallbacks { cb -> cb.onStylusFirstUsed() }
+    }
+
     private fun executeStylusCallbacks(run: (cb: StylusCallback) -> Unit) {
         stylusCallbacks.forEach(run)
     }
@@ -166,31 +228,69 @@
         stylusBatteryCallbacks.forEach(run)
     }
 
+    private fun registerBatteryListener(deviceId: Int) {
+        try {
+            inputManager.addInputDeviceBatteryListener(deviceId, executor, this)
+        } catch (e: SecurityException) {
+            Log.e(TAG, "$e: Failed to register battery listener for $deviceId.")
+        }
+    }
+
+    private fun unregisterBatteryListener(deviceId: Int) {
+        // If deviceId wasn't registered, the result is a no-op, so an "is registered"
+        // check is not needed.
+        try {
+            inputManager.removeInputDeviceBatteryListener(deviceId, this)
+        } catch (e: SecurityException) {
+            Log.e(TAG, "$e: Failed to remove registered battery listener for $deviceId.")
+        }
+    }
+
     private fun addExistingStylusToMap() {
         for (deviceId: Int in inputManager.inputDeviceIds) {
             val device: InputDevice = inputManager.getInputDevice(deviceId) ?: continue
             if (device.supportsSource(InputDevice.SOURCE_STYLUS)) {
                 // TODO(b/257936830): get address once input api available
                 inputDeviceAddressMap[deviceId] = null
+
+                if (!device.isExternal) { // TODO(b/263556967): add supportsUsi check once available
+                    // For most devices, an active (non-bluetooth) stylus is represented by an
+                    // internal InputDevice. This InputDevice will be present in InputManager
+                    // before CoreStartables run, and will not be removed.
+                    // In many cases, it reports the battery level of the stylus.
+                    registerBatteryListener(deviceId)
+                }
             }
         }
     }
 
-    /** Callback interface to receive events from the StylusManager. */
+    /**
+     * Callback interface to receive events from the StylusManager. All callbacks are run on the
+     * same background handler.
+     */
     interface StylusCallback {
         fun onStylusAdded(deviceId: Int) {}
         fun onStylusRemoved(deviceId: Int) {}
         fun onStylusBluetoothConnected(deviceId: Int, btAddress: String) {}
         fun onStylusBluetoothDisconnected(deviceId: Int, btAddress: String) {}
+        fun onStylusFirstUsed() {}
     }
 
-    /** Callback interface to receive stylus battery events from the StylusManager. */
+    /**
+     * Callback interface to receive stylus battery events from the StylusManager. All callbacks are
+     * runs on the same background handler.
+     */
     interface StylusBatteryCallback {
         fun onStylusBluetoothChargingStateChanged(
             inputDeviceId: Int,
             btDevice: BluetoothDevice,
             isCharging: Boolean
         ) {}
+        fun onStylusUsiBatteryStateChanged(
+            deviceId: Int,
+            eventTimeMillis: Long,
+            batteryState: BatteryState,
+        ) {}
     }
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerStartable.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerStartable.kt
index 11233dd..5a8850a 100644
--- a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerStartable.kt
@@ -18,14 +18,11 @@
 
 import android.hardware.BatteryState
 import android.hardware.input.InputManager
-import android.util.Log
 import android.view.InputDevice
 import com.android.systemui.CoreStartable
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
-import java.util.concurrent.Executor
 import javax.inject.Inject
 
 /**
@@ -40,16 +37,7 @@
     private val inputManager: InputManager,
     private val stylusUsiPowerUi: StylusUsiPowerUI,
     private val featureFlags: FeatureFlags,
-    @Background private val executor: Executor,
-) : CoreStartable, StylusManager.StylusCallback, InputManager.InputDeviceBatteryListener {
-
-    override fun onStylusAdded(deviceId: Int) {
-        val device = inputManager.getInputDevice(deviceId) ?: return
-
-        if (!device.isExternal) {
-            registerBatteryListener(deviceId)
-        }
-    }
+) : CoreStartable, StylusManager.StylusCallback, StylusManager.StylusBatteryCallback {
 
     override fun onStylusBluetoothConnected(deviceId: Int, btAddress: String) {
         stylusUsiPowerUi.refresh()
@@ -59,57 +47,30 @@
         stylusUsiPowerUi.refresh()
     }
 
-    override fun onStylusRemoved(deviceId: Int) {
-        val device = inputManager.getInputDevice(deviceId) ?: return
-
-        if (!device.isExternal) {
-            unregisterBatteryListener(deviceId)
-        }
-    }
-
-    override fun onBatteryStateChanged(
+    override fun onStylusUsiBatteryStateChanged(
         deviceId: Int,
         eventTimeMillis: Long,
         batteryState: BatteryState
     ) {
-        if (batteryState.isPresent) {
-            stylusUsiPowerUi.updateBatteryState(batteryState)
-        }
-    }
-
-    private fun registerBatteryListener(deviceId: Int) {
-        try {
-            inputManager.addInputDeviceBatteryListener(deviceId, executor, this)
-        } catch (e: SecurityException) {
-            Log.e(TAG, "$e: Failed to register battery listener for $deviceId.")
-        }
-    }
-
-    private fun unregisterBatteryListener(deviceId: Int) {
-        try {
-            inputManager.removeInputDeviceBatteryListener(deviceId, this)
-        } catch (e: SecurityException) {
-            Log.e(TAG, "$e: Failed to unregister battery listener for $deviceId.")
+        if (batteryState.isPresent && batteryState.capacity > 0f) {
+            stylusUsiPowerUi.updateBatteryState(deviceId, batteryState)
         }
     }
 
     override fun start() {
         if (!featureFlags.isEnabled(Flags.ENABLE_USI_BATTERY_NOTIFICATIONS)) return
-        addBatteryListenerForInternalStyluses()
+        if (!hostDeviceSupportsStylusInput()) return
 
+        stylusUsiPowerUi.init()
         stylusManager.registerCallback(this)
         stylusManager.startListener()
     }
 
-    private fun addBatteryListenerForInternalStyluses() {
-        // For most devices, an active stylus is represented by an internal InputDevice.
-        // This InputDevice will be present in InputManager before CoreStartables run,
-        // and will not be removed. In many cases, it reports the battery level of the stylus.
-        inputManager.inputDeviceIds
+    private fun hostDeviceSupportsStylusInput(): Boolean {
+        return inputManager.inputDeviceIds
             .asSequence()
             .mapNotNull { inputManager.getInputDevice(it) }
-            .filter { it.supportsSource(InputDevice.SOURCE_STYLUS) }
-            .forEach { onStylusAdded(it.id) }
+            .any { it.supportsSource(InputDevice.SOURCE_STYLUS) && !it.isExternal }
     }
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
index 70a5b36..8d5e01c 100644
--- a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
+++ b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
@@ -18,17 +18,21 @@
 
 import android.Manifest
 import android.app.PendingIntent
+import android.content.ActivityNotFoundException
 import android.content.BroadcastReceiver
 import android.content.Context
 import android.content.Intent
 import android.content.IntentFilter
 import android.hardware.BatteryState
 import android.hardware.input.InputManager
+import android.os.Bundle
 import android.os.Handler
 import android.os.UserHandle
+import android.util.Log
 import android.view.InputDevice
 import androidx.core.app.NotificationCompat
 import androidx.core.app.NotificationManagerCompat
+import com.android.internal.annotations.VisibleForTesting
 import com.android.systemui.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
@@ -53,6 +57,7 @@
     // These values must only be accessed on the handler.
     private var batteryCapacity = 1.0f
     private var suppressed = false
+    private var inputDeviceId: Int? = null
 
     fun init() {
         val filter =
@@ -87,10 +92,12 @@
         }
     }
 
-    fun updateBatteryState(batteryState: BatteryState) {
+    fun updateBatteryState(deviceId: Int, batteryState: BatteryState) {
         handler.post updateBattery@{
-            if (batteryState.capacity == batteryCapacity) return@updateBattery
+            if (batteryState.capacity == batteryCapacity || batteryState.capacity <= 0f)
+                return@updateBattery
 
+            inputDeviceId = deviceId
             batteryCapacity = batteryState.capacity
             refresh()
         }
@@ -123,13 +130,13 @@
                 .setSmallIcon(R.drawable.ic_power_low)
                 .setDeleteIntent(getPendingBroadcast(ACTION_DISMISSED_LOW_BATTERY))
                 .setContentIntent(getPendingBroadcast(ACTION_CLICKED_LOW_BATTERY))
-                .setContentTitle(context.getString(R.string.stylus_battery_low))
-                .setContentText(
+                .setContentTitle(
                     context.getString(
-                        R.string.battery_low_percent_format,
+                        R.string.stylus_battery_low_percentage,
                         NumberFormat.getPercentInstance().format(batteryCapacity)
                     )
                 )
+                .setContentText(context.getString(R.string.stylus_battery_low_subtitle))
                 .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                 .setLocalOnly(true)
                 .setAutoCancel(true)
@@ -150,23 +157,41 @@
     }
 
     private fun getPendingBroadcast(action: String): PendingIntent? {
-        return PendingIntent.getBroadcastAsUser(
+        return PendingIntent.getBroadcast(
             context,
             0,
-            Intent(action),
+            Intent(action).setPackage(context.packageName),
             PendingIntent.FLAG_IMMUTABLE,
-            UserHandle.CURRENT
         )
     }
 
-    private val receiver: BroadcastReceiver =
+    @VisibleForTesting
+    internal val receiver: BroadcastReceiver =
         object : BroadcastReceiver() {
             override fun onReceive(context: Context, intent: Intent) {
                 when (intent.action) {
                     ACTION_DISMISSED_LOW_BATTERY -> updateSuppression(true)
                     ACTION_CLICKED_LOW_BATTERY -> {
                         updateSuppression(true)
-                        // TODO(b/261584943): open USI device details page
+                        if (inputDeviceId == null) return
+
+                        val args = Bundle()
+                        args.putInt(KEY_DEVICE_INPUT_ID, inputDeviceId!!)
+                        try {
+                            context.startActivity(
+                                Intent(ACTION_STYLUS_USI_DETAILS)
+                                    .putExtra(KEY_SETTINGS_FRAGMENT_ARGS, args)
+                                    .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
+                                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+                            )
+                        } catch (e: ActivityNotFoundException) {
+                            // In the rare scenario where the Settings app manifest doesn't contain
+                            // the USI details activity, ignore the intent.
+                            Log.e(
+                                StylusUsiPowerUI::class.java.simpleName,
+                                "Cannot open USI details page."
+                            )
+                        }
                     }
                 }
             }
@@ -177,9 +202,13 @@
         // https://source.chromium.org/chromium/chromium/src/+/main:ash/system/power/peripheral_battery_notifier.cc;l=41
         private const val LOW_BATTERY_THRESHOLD = 0.16f
 
-        private val USI_NOTIFICATION_ID = R.string.stylus_battery_low
+        private val USI_NOTIFICATION_ID = R.string.stylus_battery_low_percentage
 
-        private const val ACTION_DISMISSED_LOW_BATTERY = "StylusUsiPowerUI.dismiss"
-        private const val ACTION_CLICKED_LOW_BATTERY = "StylusUsiPowerUI.click"
+        @VisibleForTesting const val ACTION_DISMISSED_LOW_BATTERY = "StylusUsiPowerUI.dismiss"
+        @VisibleForTesting const val ACTION_CLICKED_LOW_BATTERY = "StylusUsiPowerUI.click"
+        @VisibleForTesting
+        const val ACTION_STYLUS_USI_DETAILS = "com.android.settings.STYLUS_USI_DETAILS_SETTINGS"
+        @VisibleForTesting const val KEY_DEVICE_INPUT_ID = "device_input_id"
+        @VisibleForTesting const val KEY_SETTINGS_FRAGMENT_ARGS = ":settings:show_fragment_args"
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/telephony/ui/activity/SwitchToManagedProfileForCallActivity.kt b/packages/SystemUI/src/com/android/systemui/telephony/ui/activity/SwitchToManagedProfileForCallActivity.kt
new file mode 100644
index 0000000..e092f01
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/telephony/ui/activity/SwitchToManagedProfileForCallActivity.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.systemui.telephony.ui.activity
+
+import android.app.ActivityOptions
+import android.content.DialogInterface
+import android.content.Intent
+import android.net.Uri
+import android.os.Bundle
+import android.os.UserHandle
+import android.util.Log
+import android.view.WindowManager
+import com.android.internal.app.AlertActivity
+import com.android.systemui.R
+
+/** Dialog shown to the user to switch to managed profile for making a call using work SIM. */
+class SwitchToManagedProfileForCallActivity : AlertActivity(), DialogInterface.OnClickListener {
+    private lateinit var phoneNumber: Uri
+    private var managedProfileUserId = UserHandle.USER_NULL
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        window.addSystemFlags(
+            WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS
+        )
+        super.onCreate(savedInstanceState)
+
+        phoneNumber = intent.getData()
+        managedProfileUserId =
+            intent.getIntExtra(
+                "android.telecom.extra.MANAGED_PROFILE_USER_ID",
+                UserHandle.USER_NULL
+            )
+
+        mAlertParams.apply {
+            mTitle = getString(R.string.call_from_work_profile_title)
+            mMessage = getString(R.string.call_from_work_profile_text)
+            mPositiveButtonText = getString(R.string.call_from_work_profile_action)
+            mNegativeButtonText = getString(R.string.call_from_work_profile_close)
+            mPositiveButtonListener = this@SwitchToManagedProfileForCallActivity
+            mNegativeButtonListener = this@SwitchToManagedProfileForCallActivity
+        }
+        setupAlert()
+    }
+
+    override fun onClick(dialog: DialogInterface?, which: Int) {
+        if (which == BUTTON_POSITIVE) {
+            switchToManagedProfile()
+        }
+        finish()
+    }
+
+    private fun switchToManagedProfile() {
+        try {
+            applicationContext.startActivityAsUser(
+                Intent(Intent.ACTION_DIAL, phoneNumber),
+                ActivityOptions.makeOpenCrossProfileAppsAnimation().toBundle(),
+                UserHandle.of(managedProfileUserId)
+            )
+        } catch (e: Exception) {
+            Log.e(TAG, "Failed to launch activity", e)
+        }
+    }
+
+    companion object {
+        private const val TAG = "SwitchToManagedProfileForCallActivity"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt
index ad48e21..df8d161 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt
@@ -31,6 +31,7 @@
 import android.view.accessibility.AccessibilityManager.FLAG_CONTENT_ICONS
 import android.view.accessibility.AccessibilityManager.FLAG_CONTENT_TEXT
 import androidx.annotation.CallSuper
+import androidx.annotation.VisibleForTesting
 import com.android.systemui.CoreStartable
 import com.android.systemui.Dumpable
 import com.android.systemui.dagger.qualifiers.Main
@@ -108,9 +109,10 @@
      * Whenever the current view disappears, the next-priority view will be displayed if it's still
      * valid.
      */
+    @VisibleForTesting
     internal val activeViews: MutableList<DisplayInfo> = mutableListOf()
 
-    private fun getCurrentDisplayInfo(): DisplayInfo? {
+    internal fun getCurrentDisplayInfo(): DisplayInfo? {
         return activeViews.getOrNull(0)
     }
 
@@ -119,15 +121,26 @@
         dumpManager.registerNormalDumpable(this)
     }
 
+    private val listeners: MutableSet<Listener> = mutableSetOf()
+
+    /** Registers a listener. */
+    fun registerListener(listener: Listener) {
+        listeners.add(listener)
+    }
+
+    /** Unregisters a listener. */
+    fun unregisterListener(listener: Listener) {
+        listeners.remove(listener)
+    }
+
     /**
      * Displays the view with the provided [newInfo].
      *
      * This method handles inflating and attaching the view, then delegates to [updateView] to
      * display the correct information in the view.
-     * @param onViewTimeout a runnable that runs after the view timeout.
      */
     @Synchronized
-    fun displayView(newInfo: T, onViewTimeout: Runnable? = null) {
+    fun displayView(newInfo: T) {
         val timeout = accessibilityManager.getRecommendedTimeoutMillis(
             newInfo.timeoutMs,
             // Not all views have controls so FLAG_CONTENT_CONTROLS might be superfluous, but
@@ -146,14 +159,13 @@
             logger.logViewUpdate(newInfo)
             currentDisplayInfo.info = newInfo
             currentDisplayInfo.timeExpirationMillis = timeExpirationMillis
-            updateTimeout(currentDisplayInfo, timeout, onViewTimeout)
+            updateTimeout(currentDisplayInfo, timeout)
             updateView(newInfo, view)
             return
         }
 
         val newDisplayInfo = DisplayInfo(
             info = newInfo,
-            onViewTimeout = onViewTimeout,
             timeExpirationMillis = timeExpirationMillis,
             // Null values will be updated to non-null if/when this view actually gets displayed
             view = null,
@@ -196,7 +208,7 @@
     private fun showNewView(newDisplayInfo: DisplayInfo, timeout: Int) {
         logger.logViewAddition(newDisplayInfo.info)
         createAndAcquireWakeLock(newDisplayInfo)
-        updateTimeout(newDisplayInfo, timeout, newDisplayInfo.onViewTimeout)
+        updateTimeout(newDisplayInfo, timeout)
         inflateAndUpdateView(newDisplayInfo)
     }
 
@@ -227,19 +239,16 @@
     /**
      * Creates a runnable that will remove [displayInfo] in [timeout] ms from now.
      *
-     * @param onViewTimeout an optional runnable that will be run if the view times out.
      * @return a runnable that, when run, will *cancel* the view's timeout.
      */
-    private fun updateTimeout(displayInfo: DisplayInfo, timeout: Int, onViewTimeout: Runnable?) {
+    private fun updateTimeout(displayInfo: DisplayInfo, timeout: Int) {
         val cancelViewTimeout = mainExecutor.executeDelayed(
             {
                 removeView(displayInfo.info.id, REMOVAL_REASON_TIMEOUT)
-                onViewTimeout?.run()
             },
             timeout.toLong()
         )
 
-        displayInfo.onViewTimeout = onViewTimeout
         // Cancel old view timeout and re-set it.
         displayInfo.cancelViewTimeout?.run()
         displayInfo.cancelViewTimeout = cancelViewTimeout
@@ -317,6 +326,9 @@
         // event comes in while this view is animating out, we still display the new view
         // appropriately.
         activeViews.remove(displayInfo)
+        listeners.forEach {
+            it.onInfoPermanentlyRemoved(id)
+        }
 
         // No need to time the view out since it's already gone
         displayInfo.cancelViewTimeout?.run()
@@ -380,6 +392,9 @@
         invalidViews.forEach {
             activeViews.remove(it)
             logger.logViewExpiration(it.info)
+            listeners.forEach { listener ->
+                listener.onInfoPermanentlyRemoved(it.info.id)
+            }
         }
     }
 
@@ -436,6 +451,15 @@
         onAnimationEnd.run()
     }
 
+    /** A listener interface to be notified of various view events. */
+    fun interface Listener {
+        /**
+         * Called whenever a [DisplayInfo] with the given [id] has been removed and will never be
+         * displayed again (unless another call to [updateView] is made).
+         */
+        fun onInfoPermanentlyRemoved(id: String)
+    }
+
     /** A container for all the display-related state objects. */
     inner class DisplayInfo(
         /**
@@ -461,11 +485,6 @@
         var wakeLock: WakeLock?,
 
         /**
-         * See [displayView].
-         */
-        var onViewTimeout: Runnable?,
-
-        /**
          * A runnable that, when run, will cancel this view's timeout.
          *
          * Null if this info isn't currently being displayed.
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
index 52980c3..9e0bbb7 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
@@ -65,26 +65,28 @@
  * in the list of notifications until the user dismisses them.
  *
  * Only one chipbar may be shown at a time.
- * TODO(b/245610654): Should we just display whichever chipbar was most recently requested, or do we
- *   need to maintain a priority ordering?
  */
 @SysUISingleton
-open class ChipbarCoordinator @Inject constructor(
-        context: Context,
-        logger: ChipbarLogger,
-        windowManager: WindowManager,
-        @Main mainExecutor: DelayableExecutor,
-        accessibilityManager: AccessibilityManager,
-        configurationController: ConfigurationController,
-        dumpManager: DumpManager,
-        powerManager: PowerManager,
-        private val falsingManager: FalsingManager,
-        private val falsingCollector: FalsingCollector,
-        private val viewUtil: ViewUtil,
-        private val vibratorHelper: VibratorHelper,
-        wakeLockBuilder: WakeLock.Builder,
-        systemClock: SystemClock,
-) : TemporaryViewDisplayController<ChipbarInfo, ChipbarLogger>(
+open class ChipbarCoordinator
+@Inject
+constructor(
+    context: Context,
+    logger: ChipbarLogger,
+    windowManager: WindowManager,
+    @Main mainExecutor: DelayableExecutor,
+    accessibilityManager: AccessibilityManager,
+    configurationController: ConfigurationController,
+    dumpManager: DumpManager,
+    powerManager: PowerManager,
+    private val falsingManager: FalsingManager,
+    private val falsingCollector: FalsingCollector,
+    private val swipeChipbarAwayGestureHandler: SwipeChipbarAwayGestureHandler?,
+    private val viewUtil: ViewUtil,
+    private val vibratorHelper: VibratorHelper,
+    wakeLockBuilder: WakeLock.Builder,
+    systemClock: SystemClock,
+) :
+    TemporaryViewDisplayController<ChipbarInfo, ChipbarLogger>(
         context,
         logger,
         windowManager,
@@ -96,18 +98,16 @@
         R.layout.chipbar,
         wakeLockBuilder,
         systemClock,
-) {
+    ) {
 
     private lateinit var parent: ChipbarRootView
 
-    override val windowLayoutParams = commonWindowLayoutParams.apply {
-        gravity = Gravity.TOP.or(Gravity.CENTER_HORIZONTAL)
-    }
+    override val windowLayoutParams =
+        commonWindowLayoutParams.apply { gravity = Gravity.TOP.or(Gravity.CENTER_HORIZONTAL) }
 
-    override fun updateView(
-        newInfo: ChipbarInfo,
-        currentView: ViewGroup
-    ) {
+    override fun updateView(newInfo: ChipbarInfo, currentView: ViewGroup) {
+        updateGestureListening()
+
         logger.logViewUpdate(
             newInfo.windowTitle,
             newInfo.text.loadText(context),
@@ -123,12 +123,13 @@
 
         // Detect falsing touches on the chip.
         parent = currentView.requireViewById(R.id.chipbar_root_view)
-        parent.touchHandler = object : Gefingerpoken {
-            override fun onTouchEvent(ev: MotionEvent?): Boolean {
-                falsingCollector.onTouchEvent(ev)
-                return false
+        parent.touchHandler =
+            object : Gefingerpoken {
+                override fun onTouchEvent(ev: MotionEvent?): Boolean {
+                    falsingCollector.onTouchEvent(ev)
+                    return false
+                }
             }
-        }
 
         // ---- Start icon ----
         val iconView = currentView.requireViewById<CachingIconView>(R.id.start_icon)
@@ -155,10 +156,12 @@
         if (newInfo.endItem is ChipbarEndItem.Button) {
             TextViewBinder.bind(buttonView, newInfo.endItem.text)
 
-            val onClickListener = View.OnClickListener { clickedView ->
-                if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return@OnClickListener
-                newInfo.endItem.onClickListener.onClick(clickedView)
-            }
+            val onClickListener =
+                View.OnClickListener { clickedView ->
+                    if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY))
+                        return@OnClickListener
+                    newInfo.endItem.onClickListener.onClick(clickedView)
+                }
 
             buttonView.setOnClickListener(onClickListener)
             buttonView.visibility = View.VISIBLE
@@ -168,21 +171,27 @@
 
         // ---- Overall accessibility ----
         val iconDesc = newInfo.startIcon.icon.contentDescription
-        val loadedIconDesc = if (iconDesc != null) {
-            "${iconDesc.loadContentDescription(context)} "
-        } else {
-            ""
-        }
+        val loadedIconDesc =
+            if (iconDesc != null) {
+                "${iconDesc.loadContentDescription(context)} "
+            } else {
+                ""
+            }
+        val endItemDesc =
+            if (newInfo.endItem is ChipbarEndItem.Loading) {
+                ". ${context.resources.getString(R.string.media_transfer_loading)}."
+            } else {
+                ""
+            }
 
         val chipInnerView = currentView.getInnerView()
-        chipInnerView.contentDescription = "$loadedIconDesc${newInfo.text.loadText(context)}"
+        chipInnerView.contentDescription =
+            "$loadedIconDesc${newInfo.text.loadText(context)}$endItemDesc"
         chipInnerView.accessibilityLiveRegion = ACCESSIBILITY_LIVE_REGION_ASSERTIVE
         maybeGetAccessibilityFocus(newInfo, currentView)
 
         // ---- Haptics ----
-        newInfo.vibrationEffect?.let {
-            vibratorHelper.vibrate(it)
-        }
+        newInfo.vibrationEffect?.let { vibratorHelper.vibrate(it) }
     }
 
     private fun maybeGetAccessibilityFocus(info: ChipbarInfo?, view: ViewGroup) {
@@ -222,6 +231,42 @@
             includeMargins = true,
             onAnimationEnd,
         )
+
+        updateGestureListening()
+    }
+
+    private fun updateGestureListening() {
+        if (swipeChipbarAwayGestureHandler == null) {
+            return
+        }
+
+        val currentDisplayInfo = getCurrentDisplayInfo()
+        if (currentDisplayInfo != null && currentDisplayInfo.info.allowSwipeToDismiss) {
+            swipeChipbarAwayGestureHandler.setViewFetcher { currentDisplayInfo.view }
+            swipeChipbarAwayGestureHandler.addOnGestureDetectedCallback(TAG) {
+                onSwipeUpGestureDetected()
+            }
+        } else {
+            swipeChipbarAwayGestureHandler.resetViewFetcher()
+            swipeChipbarAwayGestureHandler.removeOnGestureDetectedCallback(TAG)
+        }
+    }
+
+    private fun onSwipeUpGestureDetected() {
+        val currentDisplayInfo = getCurrentDisplayInfo()
+        if (currentDisplayInfo == null) {
+            logger.logSwipeGestureError(id = null, errorMsg = "No info is being displayed")
+            return
+        }
+        if (!currentDisplayInfo.info.allowSwipeToDismiss) {
+            logger.logSwipeGestureError(
+                id = currentDisplayInfo.info.id,
+                errorMsg = "This view prohibits swipe-to-dismiss",
+            )
+            return
+        }
+        removeView(currentDisplayInfo.info.id, SWIPE_UP_GESTURE_REASON)
+        updateGestureListening()
     }
 
     private fun ViewGroup.getInnerView(): ViewGroup {
@@ -244,3 +289,5 @@
 private const val ANIMATION_IN_DURATION = 500L
 private const val ANIMATION_OUT_DURATION = 250L
 @IdRes private val INFO_TAG = R.id.tag_chipbar_info
+private const val SWIPE_UP_GESTURE_REASON = "SWIPE_UP_GESTURE_DETECTED"
+private const val TAG = "ChipbarCoordinator"
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
index dd4bd26..fe46318 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
@@ -33,12 +33,14 @@
  * @property endItem an optional end item to display at the end of the chipbar (on the right in LTR
  * locales; on the left in RTL locales).
  * @property vibrationEffect an optional vibration effect when the chipbar is displayed
+ * @property allowSwipeToDismiss true if users are allowed to swipe up to dismiss this chipbar.
  */
 data class ChipbarInfo(
     val startIcon: TintedIcon,
     val text: Text,
     val endItem: ChipbarEndItem?,
     val vibrationEffect: VibrationEffect? = null,
+    val allowSwipeToDismiss: Boolean = false,
     override val windowTitle: String,
     override val wakeReason: String,
     override val timeoutMs: Int,
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarLogger.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarLogger.kt
index fcfbe0a..f239428 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarLogger.kt
@@ -46,4 +46,16 @@
             { "Chipbar updated. window=$str1 text=$str2 endItem=$str3" }
         )
     }
+
+    fun logSwipeGestureError(id: String?, errorMsg: String) {
+        buffer.log(
+            tag,
+            LogLevel.WARNING,
+            {
+                str1 = id
+                str2 = errorMsg
+            },
+            { "Chipbar swipe gesture detected for incorrect state. id=$str1 error=$str2" }
+        )
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/SwipeChipbarAwayGestureHandler.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/SwipeChipbarAwayGestureHandler.kt
new file mode 100644
index 0000000..6e3cb48
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/SwipeChipbarAwayGestureHandler.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.systemui.temporarydisplay.chipbar
+
+import android.content.Context
+import android.view.MotionEvent
+import android.view.View
+import com.android.systemui.statusbar.gesture.SwipeUpGestureHandler
+import com.android.systemui.statusbar.gesture.SwipeUpGestureLogger
+import com.android.systemui.util.boundsOnScreen
+
+/**
+ * A class to detect when a user has swiped the chipbar away.
+ *
+ * Effectively [SysUISingleton]. But, this shouldn't be created if the gesture isn't enabled. See
+ * [TemporaryDisplayModule.provideSwipeChipbarAwayGestureHandler].
+ */
+class SwipeChipbarAwayGestureHandler(
+    context: Context,
+    logger: SwipeUpGestureLogger,
+) : SwipeUpGestureHandler(context, logger, loggerTag = LOGGER_TAG) {
+
+    private var viewFetcher: () -> View? = { null }
+
+    override fun startOfGestureIsWithinBounds(ev: MotionEvent): Boolean {
+        val view = viewFetcher.invoke() ?: return false
+        // Since chipbar is in its own window, we need to use [boundsOnScreen] to get an accurate
+        // bottom. ([view.bottom] would be relative to its window, which would be too small.)
+        val viewBottom = view.boundsOnScreen.bottom
+        // Allow the gesture to start a bit below the chipbar
+        return ev.y <= 1.5 * viewBottom
+    }
+
+    /**
+     * Sets a fetcher that returns the current chipbar view. The fetcher will be invoked whenever a
+     * gesture starts to determine if the gesture is near the chipbar.
+     */
+    fun setViewFetcher(fetcher: () -> View?) {
+        viewFetcher = fetcher
+    }
+
+    /** Removes the current view fetcher. */
+    fun resetViewFetcher() {
+        viewFetcher = { null }
+    }
+}
+
+private const val LOGGER_TAG = "SwipeChipbarAway"
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/dagger/TemporaryDisplayModule.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/dagger/TemporaryDisplayModule.kt
index cf0a183..933c060 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/dagger/TemporaryDisplayModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/dagger/TemporaryDisplayModule.kt
@@ -16,22 +16,38 @@
 
 package com.android.systemui.temporarydisplay.dagger
 
+import android.content.Context
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.log.LogBufferFactory
+import com.android.systemui.media.taptotransfer.MediaTttFlags
 import com.android.systemui.plugins.log.LogBuffer
+import com.android.systemui.statusbar.gesture.SwipeUpGestureLogger
+import com.android.systemui.temporarydisplay.chipbar.SwipeChipbarAwayGestureHandler
 import dagger.Module
 import dagger.Provides
 
 @Module
 interface TemporaryDisplayModule {
-    @Module
     companion object {
-        @JvmStatic
         @Provides
         @SysUISingleton
         @ChipbarLog
         fun provideChipbarLogBuffer(factory: LogBufferFactory): LogBuffer {
             return factory.create("ChipbarLog", 40)
         }
+
+        @Provides
+        @SysUISingleton
+        fun provideSwipeChipbarAwayGestureHandler(
+            mediaTttFlags: MediaTttFlags,
+            context: Context,
+            logger: SwipeUpGestureLogger,
+        ): SwipeChipbarAwayGestureHandler? {
+            return if (mediaTttFlags.isMediaTttDismissGestureEnabled()) {
+                SwipeChipbarAwayGestureHandler(context, logger)
+            } else {
+                null
+            }
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index 3ecb15b..f29ca4d 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -26,7 +26,6 @@
 import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_COLOR_SOURCE;
 import static com.android.systemui.theme.ThemeOverlayApplier.TIMESTAMP_FIELD;
 
-import android.annotation.Nullable;
 import android.app.WallpaperColors;
 import android.app.WallpaperManager;
 import android.app.WallpaperManager.OnColorsChangedListener;
@@ -70,6 +69,7 @@
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.monet.ColorScheme;
 import com.android.systemui.monet.Style;
+import com.android.systemui.monet.TonalPalette;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
@@ -391,7 +391,7 @@
         mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, mMainExecutor,
                 UserHandle.ALL);
         mSecureSettings.registerContentObserverForUser(
-                Settings.Secure.getUriFor(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES),
+                Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
                 false,
                 new ContentObserver(mBgHandler) {
                     @Override
@@ -513,39 +513,42 @@
     /**
      * Given a color candidate, return an overlay definition.
      */
-    protected @Nullable FabricatedOverlay getOverlay(int color, int type, Style style) {
+    protected FabricatedOverlay getOverlay(int color, int type, Style style) {
         boolean nightMode = (mResources.getConfiguration().uiMode
                 & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
 
         mColorScheme = new ColorScheme(color, nightMode, style);
-        List<Integer> colorShades = type == ACCENT
-                ? mColorScheme.getAllAccentColors() : mColorScheme.getAllNeutralColors();
         String name = type == ACCENT ? "accent" : "neutral";
-        int paletteSize = mColorScheme.getAccent1().size();
+
         FabricatedOverlay.Builder overlay =
                 new FabricatedOverlay.Builder("com.android.systemui", name, "android");
-        for (int i = 0; i < colorShades.size(); i++) {
-            int luminosity = i % paletteSize;
-            int paletteIndex = i / paletteSize + 1;
-            String resourceName;
-            switch (luminosity) {
-                case 0:
-                    resourceName = "android:color/system_" + name + paletteIndex + "_10";
-                    break;
-                case 1:
-                    resourceName = "android:color/system_" + name + paletteIndex + "_50";
-                    break;
-                default:
-                    int l = luminosity - 1;
-                    resourceName = "android:color/system_" + name + paletteIndex + "_" + l + "00";
-            }
-            overlay.setResourceValue(resourceName, TypedValue.TYPE_INT_COLOR_ARGB8,
-                    ColorUtils.setAlphaComponent(colorShades.get(i), 0xFF));
+
+        if (type == ACCENT) {
+            assignTonalPaletteToOverlay("accent1", overlay, mColorScheme.getAccent1());
+            assignTonalPaletteToOverlay("accent2", overlay, mColorScheme.getAccent2());
+            assignTonalPaletteToOverlay("accent3", overlay, mColorScheme.getAccent3());
+        } else {
+            assignTonalPaletteToOverlay("neutral1", overlay, mColorScheme.getNeutral1());
+            assignTonalPaletteToOverlay("neutral2", overlay, mColorScheme.getNeutral2());
         }
 
         return overlay.build();
     }
 
+    private void assignTonalPaletteToOverlay(String name,
+            FabricatedOverlay.Builder overlay, TonalPalette tonalPalette) {
+
+        String resourcePrefix = "android:color/system_" + name;
+        int colorDataType = TypedValue.TYPE_INT_COLOR_ARGB8;
+
+        tonalPalette.getAllShadesMapped().forEach((key, value) -> {
+            String resourceName = resourcePrefix + "_" + key;
+            int colorValue = ColorUtils.setAlphaComponent(value, 0xFF);
+            overlay.setResourceValue(resourceName, colorDataType,
+                    colorValue);
+        });
+    }
+
     /**
      * Checks if the color scheme in mColorScheme matches the current system palettes.
      * @param managedProfiles List of managed profiles for this user.
@@ -557,15 +560,15 @@
             Resources res = userHandle.isSystem()
                     ? mResources : mContext.createContextAsUser(userHandle, 0).getResources();
             if (!(res.getColor(android.R.color.system_accent1_500, mContext.getTheme())
-                    == mColorScheme.getAccent1().get(6)
+                    == mColorScheme.getAccent1().getS500()
                     && res.getColor(android.R.color.system_accent2_500, mContext.getTheme())
-                    == mColorScheme.getAccent2().get(6)
+                    == mColorScheme.getAccent2().getS500()
                     && res.getColor(android.R.color.system_accent3_500, mContext.getTheme())
-                    == mColorScheme.getAccent3().get(6)
+                    == mColorScheme.getAccent3().getS500()
                     && res.getColor(android.R.color.system_neutral1_500, mContext.getTheme())
-                    == mColorScheme.getNeutral1().get(6)
+                    == mColorScheme.getNeutral1().getS500()
                     && res.getColor(android.R.color.system_neutral2_500, mContext.getTheme())
-                    == mColorScheme.getNeutral2().get(6))) {
+                    == mColorScheme.getNeutral2().getS500())) {
                 return false;
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt b/packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt
index 209d93f..1482cfc 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt
@@ -20,6 +20,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.shade.NotificationPanelUnfoldAnimationController
 import com.android.systemui.statusbar.phone.StatusBarMoveFromCenterAnimationController
+import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityManager
 import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider
 import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider
 import com.android.systemui.util.kotlin.getOrNull
@@ -95,4 +96,6 @@
     fun getUnfoldHapticsPlayer(): UnfoldHapticsPlayer
 
     fun getUnfoldLightRevealOverlayAnimation(): UnfoldLightRevealOverlayAnimation
+
+    fun getUnfoldKeyguardVisibilityManager(): UnfoldKeyguardVisibilityManager
 }
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldHapticsPlayer.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldHapticsPlayer.kt
index 7726d09..8214822 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldHapticsPlayer.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldHapticsPlayer.kt
@@ -3,26 +3,43 @@
 import android.os.SystemProperties
 import android.os.VibrationEffect
 import android.os.Vibrator
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
+import com.android.systemui.unfold.updates.FoldProvider
+import com.android.systemui.unfold.updates.FoldProvider.FoldCallback
+import java.util.concurrent.Executor
 import javax.inject.Inject
 
-/**
- * Class that plays a haptics effect during unfolding a foldable device
- */
+/** Class that plays a haptics effect during unfolding a foldable device */
 @SysUIUnfoldScope
 class UnfoldHapticsPlayer
 @Inject
 constructor(
     unfoldTransitionProgressProvider: UnfoldTransitionProgressProvider,
+    foldProvider: FoldProvider,
+    @Main private val mainExecutor: Executor,
     private val vibrator: Vibrator?
 ) : TransitionProgressListener {
 
+    private var isFirstAnimationAfterUnfold = false
+
     init {
         if (vibrator != null) {
             // We don't need to remove the callback because we should listen to it
             // the whole time when SystemUI process is alive
             unfoldTransitionProgressProvider.addCallback(this)
         }
+
+        foldProvider.registerCallback(
+            object : FoldCallback {
+                override fun onFoldUpdated(isFolded: Boolean) {
+                    if (isFolded) {
+                        isFirstAnimationAfterUnfold = true
+                    }
+                }
+            },
+            mainExecutor
+        )
     }
 
     private var lastTransitionProgress = TRANSITION_PROGRESS_FULL_OPEN
@@ -36,6 +53,13 @@
     }
 
     override fun onTransitionFinishing() {
+        // Run haptics only when unfolding the device (first animation after unfolding)
+        if (!isFirstAnimationAfterUnfold) {
+            return
+        }
+
+        isFirstAnimationAfterUnfold = false
+
         // Run haptics only if the animation is long enough to notice
         if (lastTransitionProgress < TRANSITION_NOTICEABLE_THRESHOLD) {
             playHaptics()
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldKeyguardVisibilityListener.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldKeyguardVisibilityListener.kt
new file mode 100644
index 0000000..59558ac
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldKeyguardVisibilityListener.kt
@@ -0,0 +1,39 @@
+package com.android.systemui.unfold
+
+import android.util.Log
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityManager
+import com.android.systemui.util.kotlin.getOrNull
+import java.util.Optional
+import javax.inject.Inject
+
+/**
+ * Used to set the keyguard visibility state to [UnfoldKeyguardVisibilityManager].
+ *
+ * It is not possible to directly inject a sysui class (e.g. [KeyguardStateController]) into
+ * [DeviceStateProvider], as it can't depend on google sysui directly. So,
+ * [UnfoldKeyguardVisibilityManager] is provided to clients, that can set the keyguard visibility
+ * accordingly.
+ */
+@SysUISingleton
+class UnfoldKeyguardVisibilityListener
+@Inject
+constructor(
+    keyguardStateController: KeyguardStateController,
+    unfoldComponent: Optional<SysUIUnfoldComponent>,
+) {
+
+    private val unfoldKeyguardVisibilityManager =
+        unfoldComponent.getOrNull()?.getUnfoldKeyguardVisibilityManager()
+
+    private val delegate = { keyguardStateController.isVisible }
+
+    fun init() {
+        unfoldKeyguardVisibilityManager?.setKeyguardVisibleDelegate(delegate).also {
+            Log.d(TAG, "setKeyguardVisibleDelegate set")
+        }
+    }
+}
+
+private const val TAG = "UnfoldKeyguardVisibilityListener"
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
index 523cf68..0069bb5 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
@@ -36,6 +36,8 @@
 import android.view.WindowManager
 import android.view.WindowlessWindowManager
 import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
 import com.android.systemui.statusbar.LightRevealEffect
 import com.android.systemui.statusbar.LightRevealScrim
 import com.android.systemui.statusbar.LinearLightRevealEffect
@@ -57,6 +59,7 @@
 @Inject
 constructor(
     private val context: Context,
+    private val featureFlags: FeatureFlags,
     private val deviceStateManager: DeviceStateManager,
     private val contentResolver: ContentResolver,
     private val displayManager: DisplayManager,
@@ -81,6 +84,7 @@
     private var scrimView: LightRevealScrim? = null
     private var isFolded: Boolean = false
     private var isUnfoldHandled: Boolean = true
+    private var overlayAddReason: AddOverlayReason? = null
 
     private var currentRotation: Int = context.display!!.rotation
 
@@ -158,6 +162,8 @@
         ensureInBackground()
         ensureOverlayRemoved()
 
+        overlayAddReason = reason
+
         val newRoot = SurfaceControlViewHost(context, context.display!!, wwm)
         val params = getLayoutParams()
         val newView =
@@ -170,11 +176,7 @@
                 .apply {
                     revealEffect = createLightRevealEffect()
                     isScrimOpaqueChangedListener = Consumer {}
-                    revealAmount =
-                        when (reason) {
-                            FOLD -> TRANSPARENT
-                            UNFOLD -> BLACK
-                        }
+                    revealAmount = calculateRevealAmount()
                 }
 
         newRoot.setView(newView, params)
@@ -207,6 +209,31 @@
         root = newRoot
     }
 
+    private fun calculateRevealAmount(animationProgress: Float? = null): Float {
+        val overlayAddReason = overlayAddReason ?: UNFOLD
+
+        if (animationProgress == null) {
+            // Animation progress is unknown, calculate the initial value based on the overlay
+            // add reason
+            return when (overlayAddReason) {
+                FOLD -> TRANSPARENT
+                UNFOLD -> BLACK
+            }
+        }
+
+        val showVignetteWhenFolding =
+            featureFlags.isEnabled(Flags.ENABLE_DARK_VIGNETTE_WHEN_FOLDING)
+
+        return if (!showVignetteWhenFolding && overlayAddReason == FOLD) {
+            // Do not darken the content when SHOW_VIGNETTE_WHEN_FOLDING flag is off
+            // and we are folding the device. We still add the overlay to block touches
+            // while the animation is running but the overlay is transparent.
+            TRANSPARENT
+        } else {
+            animationProgress
+        }
+    }
+
     private fun getLayoutParams(): WindowManager.LayoutParams {
         val params: WindowManager.LayoutParams = WindowManager.LayoutParams()
 
@@ -259,7 +286,7 @@
     private inner class TransitionListener : TransitionProgressListener {
 
         override fun onTransitionProgress(progress: Float) {
-            executeInBackground { scrimView?.revealAmount = progress }
+            executeInBackground { scrimView?.revealAmount = calculateRevealAmount(progress) }
         }
 
         override fun onTransitionFinished() {
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
index 59ad24a..2709da3 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
@@ -17,6 +17,9 @@
 package com.android.systemui.unfold
 
 import android.content.Context
+import android.hardware.devicestate.DeviceStateManager
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.keyguard.LifecycleScreenStatusProvider
 import com.android.systemui.unfold.config.UnfoldTransitionConfig
 import com.android.systemui.unfold.system.SystemUnfoldSharedModule
@@ -32,6 +35,7 @@
 import dagger.Module
 import dagger.Provides
 import java.util.Optional
+import java.util.concurrent.Executor
 import javax.inject.Named
 import javax.inject.Singleton
 
@@ -40,6 +44,20 @@
 
     @Provides @UnfoldTransitionATracePrefix fun tracingTagPrefix() = "systemui"
 
+    /** A globally available FoldStateListener that allows one to query the fold state. */
+    @Provides
+    @Singleton
+    fun providesFoldStateListener(
+        deviceStateManager: DeviceStateManager,
+        @Application context: Context,
+        @Main executor: Executor
+    ): DeviceStateManager.FoldStateListener {
+        val listener = DeviceStateManager.FoldStateListener(context)
+        deviceStateManager.registerCallback(executor, listener)
+
+        return listener
+    }
+
     @Provides
     @Singleton
     fun providesFoldStateLoggingProvider(
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 d7b0971..c0ba3cc 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
@@ -115,9 +115,7 @@
     private val callbackMutex = Mutex()
     private val callbacks = mutableSetOf<UserCallback>()
     private val userInfos: Flow<List<UserInfo>> =
-        repository.userInfos.map { userInfos ->
-            userInfos.filter { it.isFull }
-        }
+        repository.userInfos.map { userInfos -> userInfos.filter { it.isFull } }
 
     /** List of current on-device users to select from. */
     val users: Flow<List<UserModel>>
@@ -445,7 +443,8 @@
                     )
                 )
             }
-            UserActionModel.ADD_SUPERVISED_USER ->
+            UserActionModel.ADD_SUPERVISED_USER -> {
+                dismissDialog()
                 activityStarter.startActivity(
                     Intent()
                         .setAction(UserManager.ACTION_CREATE_SUPERVISED_USER)
@@ -453,6 +452,7 @@
                         .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
                     /* dismissShade= */ true,
                 )
+            }
             UserActionModel.NAVIGATE_TO_USER_MANAGEMENT ->
                 activityStarter.startActivity(
                     Intent(Settings.ACTION_USER_SETTINGS),
@@ -493,7 +493,7 @@
 
     fun showUserSwitcher(context: Context, expandable: Expandable) {
         if (!featureFlags.isEnabled(Flags.FULL_SCREEN_USER_SWITCHER)) {
-            showDialog(ShowDialogRequestModel.ShowUserSwitcherDialog)
+            showDialog(ShowDialogRequestModel.ShowUserSwitcherDialog(expandable))
             return
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/user/domain/model/ShowDialogRequestModel.kt b/packages/SystemUI/src/com/android/systemui/user/domain/model/ShowDialogRequestModel.kt
index 85c2964..14cc3e7 100644
--- a/packages/SystemUI/src/com/android/systemui/user/domain/model/ShowDialogRequestModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/domain/model/ShowDialogRequestModel.kt
@@ -18,11 +18,13 @@
 package com.android.systemui.user.domain.model
 
 import android.os.UserHandle
+import com.android.systemui.animation.Expandable
 import com.android.systemui.qs.user.UserSwitchDialogController
 
 /** Encapsulates a request to show a dialog. */
 sealed class ShowDialogRequestModel(
     open val dialogShower: UserSwitchDialogController.DialogShower? = null,
+    open val expandable: Expandable? = null,
 ) {
     data class ShowAddUserDialog(
         val userHandle: UserHandle,
@@ -45,5 +47,7 @@
     ) : ShowDialogRequestModel(dialogShower)
 
     /** Show the user switcher dialog */
-    object ShowUserSwitcherDialog : ShowDialogRequestModel()
+    data class ShowUserSwitcherDialog(
+        override val expandable: Expandable?,
+    ) : ShowDialogRequestModel()
 }
diff --git a/packages/SystemUI/src/com/android/systemui/user/ui/dialog/AddUserDialog.kt b/packages/SystemUI/src/com/android/systemui/user/ui/dialog/AddUserDialog.kt
index a9d66de..5a25a4e 100644
--- a/packages/SystemUI/src/com/android/systemui/user/ui/dialog/AddUserDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/ui/dialog/AddUserDialog.kt
@@ -63,11 +63,10 @@
                 }
 
                 // Use broadcast instead of ShadeController, as this dialog may have started in
-                // another
-                // process where normal dagger bindings are not available.
+                // another process where normal dagger bindings are not available.
                 broadcastSender.sendBroadcastAsUser(
                     Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS),
-                    UserHandle.CURRENT
+                    userHandle
                 )
 
                 context.startActivityAsUser(
diff --git a/packages/SystemUI/src/com/android/systemui/user/ui/dialog/DialogShowerImpl.kt b/packages/SystemUI/src/com/android/systemui/user/ui/dialog/DialogShowerImpl.kt
new file mode 100644
index 0000000..3fe2a7b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/user/ui/dialog/DialogShowerImpl.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.user.ui.dialog
+
+import android.app.Dialog
+import android.content.DialogInterface
+import com.android.systemui.animation.DialogCuj
+import com.android.systemui.animation.DialogLaunchAnimator
+import com.android.systemui.qs.user.UserSwitchDialogController.DialogShower
+
+/** Extracted from [UserSwitchDialogController] */
+class DialogShowerImpl(
+    private val animateFrom: Dialog,
+    private val dialogLaunchAnimator: DialogLaunchAnimator,
+) : DialogInterface by animateFrom, DialogShower {
+    override fun showDialog(dialog: Dialog, cuj: DialogCuj) {
+        dialogLaunchAnimator.showFromDialog(dialog, animateFrom = animateFrom, cuj)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/user/ui/dialog/UserSwitchDialog.kt b/packages/SystemUI/src/com/android/systemui/user/ui/dialog/UserSwitchDialog.kt
index ed25898..b8ae257 100644
--- a/packages/SystemUI/src/com/android/systemui/user/ui/dialog/UserSwitchDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/ui/dialog/UserSwitchDialog.kt
@@ -60,6 +60,7 @@
         setView(gridFrame)
 
         adapter.linkToViewGroup(gridFrame.findViewById(R.id.grid))
+        adapter.injectDialogShower(DialogShowerImpl(this, dialogLaunchAnimator))
     }
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/user/ui/dialog/UserSwitcherDialogCoordinator.kt b/packages/SystemUI/src/com/android/systemui/user/ui/dialog/UserSwitcherDialogCoordinator.kt
index 4141054..79721b3 100644
--- a/packages/SystemUI/src/com/android/systemui/user/ui/dialog/UserSwitcherDialogCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/ui/dialog/UserSwitcherDialogCoordinator.kt
@@ -66,12 +66,6 @@
     private fun startHandlingDialogShowRequests() {
         applicationScope.get().launch {
             interactor.get().dialogShowRequests.filterNotNull().collect { request ->
-                currentDialog?.let {
-                    if (it.isShowing) {
-                        it.cancel()
-                    }
-                }
-
                 val (dialog, dialogCuj) =
                     when (request) {
                         is ShowDialogRequestModel.ShowAddUserDialog ->
@@ -133,7 +127,10 @@
                     }
                 currentDialog = dialog
 
-                if (request.dialogShower != null && dialogCuj != null) {
+                val controller = request.expandable?.dialogLaunchController(dialogCuj)
+                if (controller != null) {
+                    dialogLaunchAnimator.get().show(dialog, controller)
+                } else if (request.dialogShower != null && dialogCuj != null) {
                     request.dialogShower?.showDialog(dialog, dialogCuj)
                 } else {
                     dialog.show()
diff --git a/packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayout.kt b/packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayout.kt
index 46611e0..08ee0af 100644
--- a/packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayout.kt
@@ -59,8 +59,8 @@
      */
     var measureState: TransitionViewState = TransitionViewState()
         set(value) {
-            val newWidth = value.width
-            val newHeight = value.height
+            val newWidth = value.measureWidth
+            val newHeight = value.measureHeight
             if (newWidth != desiredMeasureWidth || newHeight != desiredMeasureHeight) {
                 desiredMeasureWidth = newWidth
                 desiredMeasureHeight = newHeight
@@ -318,8 +318,28 @@
 
 class TransitionViewState {
     var widgetStates: MutableMap<Int, WidgetState> = mutableMapOf()
+
+    /**
+     * The visible width of this ViewState. This may differ from the measuredWidth when e.g.
+     * squishing the view
+     */
     var width: Int = 0
+
+    /**
+     * The visible height of this ViewState. This may differ from the measuredHeight when e.g.
+     * squishing the view
+     */
     var height: Int = 0
+
+    /**
+     * The height that determines the measured dimensions of the view
+     */
+    var measureHeight: Int = 0
+
+    /**
+     * The width that determines the measured dimensions of the view
+     */
+    var measureWidth: Int = 0
     var alpha: Float = 1.0f
     val translation = PointF()
     val contentTranslation = PointF()
@@ -328,6 +348,8 @@
         val copy = reusedState ?: TransitionViewState()
         copy.width = width
         copy.height = height
+        copy.measureHeight = measureHeight
+        copy.measureWidth = measureWidth
         copy.alpha = alpha
         copy.translation.set(translation.x, translation.y)
         copy.contentTranslation.set(contentTranslation.x, contentTranslation.y)
@@ -348,6 +370,8 @@
         }
         width = transitionLayout.measuredWidth
         height = transitionLayout.measuredHeight
+        measureWidth = width
+        measureHeight = height
         translation.set(0.0f, 0.0f)
         contentTranslation.set(0.0f, 0.0f)
         alpha = 1.0f
diff --git a/packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayoutController.kt b/packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayoutController.kt
index 0c9b48e..5d80292 100644
--- a/packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayoutController.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayoutController.kt
@@ -234,6 +234,15 @@
                     progress).toInt()
             height = MathUtils.lerp(startState.height.toFloat(), endState.height.toFloat(),
                     progress).toInt()
+            // If we're at the start, let's measure with the starting dimensions, otherwise always
+            // with the end state
+            if (progress == 0.0f) {
+                measureWidth = startState.measureWidth
+                measureHeight = startState.measureHeight
+            } else {
+                measureWidth = endState.measureWidth
+                measureHeight = endState.measureHeight
+            }
             translation.x = MathUtils.lerp(startState.translation.x, endState.translation.x,
                     progress)
             translation.y = MathUtils.lerp(startState.translation.y, endState.translation.y,
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt
index b61b2e6..47d505e 100644
--- a/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt
@@ -16,14 +16,21 @@
 
 package com.android.systemui.util.kotlin
 
+import com.android.systemui.util.time.SystemClock
+import com.android.systemui.util.time.SystemClockImpl
+import kotlinx.coroutines.CoroutineStart
 import java.util.concurrent.atomic.AtomicReference
 import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
 import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.channelFlow
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.flow
 import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.launch
+import kotlin.math.max
 
 /**
  * Returns a new [Flow] that combines the two most recent emissions from [this] using [transform].
@@ -167,3 +174,89 @@
  * Note that the returned Flow will not emit anything until [other] has emitted at least one value.
  */
 fun <A> Flow<*>.sample(other: Flow<A>): Flow<A> = sample(other) { _, a -> a }
+
+/**
+ * Returns a flow that mirrors the original flow, but delays values following emitted values for the
+ * given [periodMs]. If the original flow emits more than one value during this period, only the
+ * latest value is emitted.
+ *
+ * Example:
+ *
+ * ```kotlin
+ * flow {
+ *     emit(1)     // t=0ms
+ *     delay(90)
+ *     emit(2)     // t=90ms
+ *     delay(90)
+ *     emit(3)     // t=180ms
+ *     delay(1010)
+ *     emit(4)     // t=1190ms
+ *     delay(1010)
+ *     emit(5)     // t=2200ms
+ * }.throttle(1000)
+ * ```
+ *
+ * produces the following emissions at the following times
+ *
+ * ```text
+ * 1 (t=0ms), 3 (t=1000ms), 4 (t=2000ms), 5 (t=3000ms)
+ * ```
+ */
+fun <T> Flow<T>.throttle(periodMs: Long): Flow<T> = this.throttle(periodMs, SystemClockImpl())
+
+/**
+ * Returns a flow that mirrors the original flow, but delays values following emitted values for the
+ * given [periodMs] as reported by the given [clock]. If the original flow emits more than one value
+ * during this period, only The latest value is emitted.
+ *
+ * Example:
+ *
+ * ```kotlin
+ * flow {
+ *     emit(1)     // t=0ms
+ *     delay(90)
+ *     emit(2)     // t=90ms
+ *     delay(90)
+ *     emit(3)     // t=180ms
+ *     delay(1010)
+ *     emit(4)     // t=1190ms
+ *     delay(1010)
+ *     emit(5)     // t=2200ms
+ * }.throttle(1000)
+ * ```
+ *
+ * produces the following emissions at the following times
+ *
+ * ```text
+ * 1 (t=0ms), 3 (t=1000ms), 4 (t=2000ms), 5 (t=3000ms)
+ * ```
+ */
+fun <T> Flow<T>.throttle(periodMs: Long, clock: SystemClock): Flow<T> = channelFlow {
+    coroutineScope {
+        var previousEmitTimeMs = 0L
+        var delayJob: Job? = null
+        var sendJob: Job? = null
+        val outerScope = this
+
+        collect {
+            delayJob?.cancel()
+            sendJob?.join()
+            val currentTimeMs = clock.elapsedRealtime()
+            val timeSinceLastEmit = currentTimeMs - previousEmitTimeMs
+            val timeUntilNextEmit = max(0L, periodMs - timeSinceLastEmit)
+            if (timeUntilNextEmit > 0L) {
+                // We create delayJob to allow cancellation during the delay period
+                delayJob = launch {
+                    delay(timeUntilNextEmit)
+                    sendJob = outerScope.launch(start = CoroutineStart.UNDISPATCHED) {
+                        send(it)
+                        previousEmitTimeMs = clock.elapsedRealtime()
+                    }
+                }
+            } else {
+                send(it)
+                previousEmitTimeMs = currentTimeMs
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java b/packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java
index 4351afe..a0d22f3 100644
--- a/packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java
@@ -29,12 +29,12 @@
 import android.net.Uri;
 import android.os.Debug;
 import android.os.SystemProperties;
-import android.os.UserHandle;
 import android.util.Log;
 
 import androidx.core.content.FileProvider;
 
 import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.settings.UserTracker;
 
 import com.google.android.collect.Lists;
 
@@ -62,13 +62,15 @@
     static final String LEAK_DUMP = "leak.dump";
 
     private final Context mContext;
+    private final UserTracker mUserTracker;
     private final LeakDetector mLeakDetector;
     private final String mLeakReportEmail;
 
     @Inject
-    public LeakReporter(Context context, LeakDetector leakDetector,
+    public LeakReporter(Context context, UserTracker userTracker, LeakDetector leakDetector,
             @Nullable @Named(LEAK_REPORT_EMAIL_NAME) String leakReportEmail) {
         mContext = context;
+        mUserTracker = userTracker;
         mLeakDetector = leakDetector;
         mLeakReportEmail = leakReportEmail;
     }
@@ -111,7 +113,7 @@
                             getIntent(hprofFile, dumpFile),
                             PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE,
                             null,
-                            UserHandle.CURRENT));
+                            mUserTracker.getUserHandle()));
             notiMan.notify(TAG, 0, builder.build());
         } catch (IOException e) {
             Log.e(TAG, "Couldn't dump heap for leak", e);
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/RotationUtils.java b/packages/SystemUI/src/com/android/systemui/util/leak/RotationUtils.java
index 0b2f004..31f35fc 100644
--- a/packages/SystemUI/src/com/android/systemui/util/leak/RotationUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/RotationUtils.java
@@ -1,15 +1,17 @@
 /*
  * Copyright (C) 2017 The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
  *      http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF 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.leak;
@@ -26,7 +28,27 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
-public class RotationUtils {
+/**
+ * Utility class that provides device orientation.
+ *
+ * <p>Consider using {@link Surface.Rotation} or add a function that respects device aspect ratio
+ * and {@code android.internal.R.bool.config_reverseDefaultRotation}.
+ *
+ * <p>If you only care about the rotation, use {@link Surface.Rotation}, as it always gives the
+ * counter clock-wise rotation. (e.g. If you have a device that has a charging port at the bottom,
+ * rotating three times in counter clock direction will give you {@link Surface#ROTATION_270} while
+ * having the charging port on the left side of the device.)
+ *
+ * <p>If you need whether the device is in portrait or landscape (or their opposites), please add a
+ * function here that respects the device aspect ratio and
+ * {@code android.internal.R.bool.config_reverseDefaultRotation} together.
+ *
+ * <p>Note that {@code android.internal.R.bool.config_reverseDefaultRotation} does not change the
+ * winding order. In other words, the rotation order (counter clock-wise) will remain the same. It
+ * only flips the device orientation, such that portrait becomes upside down, landscape becomes
+ * seascape.
+ */
+public final class RotationUtils {
 
     public static final int ROTATION_NONE = 0;
     public static final int ROTATION_LANDSCAPE = 1;
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettingsImpl.java b/packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettingsImpl.java
index 1a30b0a..85fada2 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettingsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettingsImpl.java
@@ -20,14 +20,18 @@
 import android.net.Uri;
 import android.provider.Settings;
 
+import com.android.systemui.settings.UserTracker;
+
 import javax.inject.Inject;
 
 class GlobalSettingsImpl implements GlobalSettings {
     private final ContentResolver mContentResolver;
+    private final UserTracker mUserTracker;
 
     @Inject
-    GlobalSettingsImpl(ContentResolver contentResolver) {
+    GlobalSettingsImpl(ContentResolver contentResolver, UserTracker userTracker) {
         mContentResolver = contentResolver;
+        mUserTracker = userTracker;
     }
 
     @Override
@@ -36,13 +40,19 @@
     }
 
     @Override
+    public UserTracker getUserTracker() {
+        return mUserTracker;
+    }
+
+    @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);
+        return Settings.Global.getStringForUser(mContentResolver, name,
+                getRealUserHandle(userHandle));
     }
 
     @Override
@@ -53,14 +63,16 @@
 
     @Override
     public boolean putStringForUser(String name, String value, int userHandle) {
-        return Settings.Global.putStringForUser(mContentResolver, name, value, userHandle);
+        return Settings.Global.putStringForUser(mContentResolver, name, value,
+                getRealUserHandle(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);
+                mContentResolver, name, value, tag, makeDefault, getRealUserHandle(userHandle),
+                overrideableByRestore);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SecureSettingsImpl.java b/packages/SystemUI/src/com/android/systemui/util/settings/SecureSettingsImpl.java
index 020c234..f995436 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/SecureSettingsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/SecureSettingsImpl.java
@@ -20,14 +20,18 @@
 import android.net.Uri;
 import android.provider.Settings;
 
+import com.android.systemui.settings.UserTracker;
+
 import javax.inject.Inject;
 
 class SecureSettingsImpl implements SecureSettings {
     private final ContentResolver mContentResolver;
+    private final UserTracker mUserTracker;
 
     @Inject
-    SecureSettingsImpl(ContentResolver contentResolver) {
+    SecureSettingsImpl(ContentResolver contentResolver, UserTracker userTracker) {
         mContentResolver = contentResolver;
+        mUserTracker = userTracker;
     }
 
     @Override
@@ -36,13 +40,19 @@
     }
 
     @Override
+    public UserTracker getUserTracker() {
+        return mUserTracker;
+    }
+
+    @Override
     public Uri getUriFor(String name) {
         return Settings.Secure.getUriFor(name);
     }
 
     @Override
     public String getStringForUser(String name, int userHandle) {
-        return Settings.Secure.getStringForUser(mContentResolver, name, userHandle);
+        return Settings.Secure.getStringForUser(mContentResolver, name,
+                getRealUserHandle(userHandle));
     }
 
     @Override
@@ -52,14 +62,16 @@
 
     @Override
     public boolean putStringForUser(String name, String value, int userHandle) {
-        return Settings.Secure.putStringForUser(mContentResolver, name, value, userHandle);
+        return Settings.Secure.putStringForUser(mContentResolver, name, value,
+                getRealUserHandle(userHandle));
     }
 
     @Override
     public boolean putStringForUser(String name, String value, String tag, boolean makeDefault,
             int userHandle, boolean overrideableByRestore) {
         return Settings.Secure.putStringForUser(
-                mContentResolver, name, value, tag, makeDefault, userHandle, overrideableByRestore);
+                mContentResolver, name, value, tag, makeDefault, getRealUserHandle(userHandle),
+                overrideableByRestore);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.java b/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.java
index 1bf5f07..b6846a3 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.java
@@ -22,8 +22,11 @@
 import android.content.ContentResolver;
 import android.database.ContentObserver;
 import android.net.Uri;
+import android.os.UserHandle;
 import android.provider.Settings;
 
+import com.android.systemui.settings.UserTracker;
+
 /**
  * Used to interact with Settings.Secure, Settings.Global, and Settings.System.
  *
@@ -46,6 +49,11 @@
     ContentResolver getContentResolver();
 
     /**
+     * Returns that {@link UserTracker} this instance was constructed with.
+     */
+    UserTracker getUserTracker();
+
+    /**
      * Returns the user id for the associated {@link ContentResolver}.
      */
     default int getUserId() {
@@ -53,6 +61,17 @@
     }
 
     /**
+     * Returns the actual current user handle when querying with the current user. Otherwise,
+     * returns the passed in user id.
+     */
+    default int getRealUserHandle(int userHandle) {
+        if (userHandle != UserHandle.USER_CURRENT) {
+            return userHandle;
+        }
+        return getUserTracker().getUserId();
+    }
+
+    /**
      * 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
@@ -84,18 +103,18 @@
      *
      * Implicitly calls {@link #getUriFor(String)} on the passed in name.
      */
-    default void registerContentObserver(String name, boolean notifyForDescendents,
+    default void registerContentObserver(String name, boolean notifyForDescendants,
             ContentObserver settingsObserver) {
-        registerContentObserver(getUriFor(name), notifyForDescendents, settingsObserver);
+        registerContentObserver(getUriFor(name), notifyForDescendants, settingsObserver);
     }
 
     /**
      * Convenience wrapper around
      * {@link ContentResolver#registerContentObserver(Uri, boolean, ContentObserver)}.'
      */
-    default void registerContentObserver(Uri uri, boolean notifyForDescendents,
+    default void registerContentObserver(Uri uri, boolean notifyForDescendants,
             ContentObserver settingsObserver) {
-        registerContentObserverForUser(uri, notifyForDescendents, settingsObserver, getUserId());
+        registerContentObserverForUser(uri, notifyForDescendants, settingsObserver, getUserId());
     }
 
     /**
@@ -127,10 +146,10 @@
      * Implicitly calls {@link #getUriFor(String)} on the passed in name.
      */
     default void registerContentObserverForUser(
-            String name, boolean notifyForDescendents, ContentObserver settingsObserver,
+            String name, boolean notifyForDescendants, ContentObserver settingsObserver,
             int userHandle) {
         registerContentObserverForUser(
-                getUriFor(name), notifyForDescendents, settingsObserver, userHandle);
+                getUriFor(name), notifyForDescendants, settingsObserver, userHandle);
     }
 
     /**
@@ -138,10 +157,10 @@
      * {@link ContentResolver#registerContentObserver(Uri, boolean, ContentObserver, int)}
      */
     default void registerContentObserverForUser(
-            Uri uri, boolean notifyForDescendents, ContentObserver settingsObserver,
+            Uri uri, boolean notifyForDescendants, ContentObserver settingsObserver,
             int userHandle) {
         getContentResolver().registerContentObserver(
-                uri, notifyForDescendents, settingsObserver, userHandle);
+                uri, notifyForDescendants, settingsObserver, getRealUserHandle(userHandle));
     }
 
     /** See {@link ContentResolver#unregisterContentObserver(ContentObserver)}. */
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxyExt.kt b/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxyExt.kt
index 0b8257d..561495e 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxyExt.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxyExt.kt
@@ -19,7 +19,6 @@
 
 import android.annotation.UserIdInt
 import android.database.ContentObserver
-import android.os.UserHandle
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.flow.Flow
@@ -29,8 +28,8 @@
 
     /** Returns a flow of [Unit] that is invoked each time that content is updated. */
     fun SettingsProxy.observerFlow(
+        @UserIdInt userId: Int,
         vararg names: String,
-        @UserIdInt userId: Int = UserHandle.USER_CURRENT,
     ): Flow<Unit> {
         return conflatedCallbackFlow {
             val observer =
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SystemSettingsImpl.java b/packages/SystemUI/src/com/android/systemui/util/settings/SystemSettingsImpl.java
index 0dbb76f..fba7ddf 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/SystemSettingsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/SystemSettingsImpl.java
@@ -20,14 +20,18 @@
 import android.net.Uri;
 import android.provider.Settings;
 
+import com.android.systemui.settings.UserTracker;
+
 import javax.inject.Inject;
 
 class SystemSettingsImpl implements SystemSettings {
     private final ContentResolver mContentResolver;
+    private final UserTracker mUserTracker;
 
     @Inject
-    SystemSettingsImpl(ContentResolver contentResolver) {
+    SystemSettingsImpl(ContentResolver contentResolver, UserTracker userTracker) {
         mContentResolver = contentResolver;
+        mUserTracker = userTracker;
     }
 
     @Override
@@ -36,13 +40,19 @@
     }
 
     @Override
+    public UserTracker getUserTracker() {
+        return mUserTracker;
+    }
+
+    @Override
     public Uri getUriFor(String name) {
         return Settings.System.getUriFor(name);
     }
 
     @Override
     public String getStringForUser(String name, int userHandle) {
-        return Settings.System.getStringForUser(mContentResolver, name, userHandle);
+        return Settings.System.getStringForUser(mContentResolver, name,
+                getRealUserHandle(userHandle));
     }
 
     @Override
@@ -52,7 +62,8 @@
 
     @Override
     public boolean putStringForUser(String name, String value, int userHandle) {
-        return Settings.System.putStringForUser(mContentResolver, name, value, userHandle);
+        return Settings.System.putStringForUser(mContentResolver, name, value,
+                getRealUserHandle(userHandle));
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
index f71d988..a453726 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
@@ -25,6 +25,7 @@
 import android.provider.Settings;
 import android.view.WindowManager.LayoutParams;
 
+import com.android.internal.R;
 import com.android.settingslib.applications.InterestingConfigChanges;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.demomode.DemoMode;
@@ -55,7 +56,7 @@
     public static final String VOLUME_UP_SILENT = "sysui_volume_up_silent";
     public static final String VOLUME_SILENT_DO_NOT_DISTURB = "sysui_do_not_disturb";
 
-    public static final boolean DEFAULT_VOLUME_DOWN_TO_ENTER_SILENT = false;
+    private final boolean mDefaultVolumeDownToEnterSilent;
     public static final boolean DEFAULT_VOLUME_UP_TO_EXIT_SILENT = false;
     public static final boolean DEFAULT_DO_NOT_DISTURB_WHEN_SILENT = false;
 
@@ -72,12 +73,7 @@
     private final KeyguardViewMediator mKeyguardViewMediator;
     private final ActivityStarter mActivityStarter;
     private VolumeDialog mDialog;
-    private VolumePolicy mVolumePolicy = new VolumePolicy(
-            DEFAULT_VOLUME_DOWN_TO_ENTER_SILENT,  // volumeDownToEnterSilent
-            DEFAULT_VOLUME_UP_TO_EXIT_SILENT,  // volumeUpToExitSilent
-            DEFAULT_DO_NOT_DISTURB_WHEN_SILENT,  // doNotDisturbWhenSilent
-            400    // vibrateToSilentDebounce
-    );
+    private VolumePolicy mVolumePolicy;
 
     @Inject
     public VolumeDialogComponent(
@@ -107,7 +103,20 @@
                     mDialog = dialog;
                     mDialog.init(LayoutParams.TYPE_VOLUME_OVERLAY, mVolumeDialogCallback);
                 }).build();
+
+
+        mDefaultVolumeDownToEnterSilent = mContext.getResources()
+                .getBoolean(R.bool.config_volume_down_to_enter_silent);
+
+        mVolumePolicy = new VolumePolicy(
+                mDefaultVolumeDownToEnterSilent,  // volumeDownToEnterSilent
+                DEFAULT_VOLUME_UP_TO_EXIT_SILENT,  // volumeUpToExitSilent
+                DEFAULT_DO_NOT_DISTURB_WHEN_SILENT,  // doNotDisturbWhenSilent
+                400    // vibrateToSilentDebounce
+        );
+
         applyConfiguration();
+
         tunerService.addTunable(this, VOLUME_DOWN_SILENT, VOLUME_UP_SILENT,
                 VOLUME_SILENT_DO_NOT_DISTURB);
         demoModeController.addCallback(this);
@@ -121,7 +130,7 @@
 
         if (VOLUME_DOWN_SILENT.equals(key)) {
             volumeDownToEnterSilent =
-                TunerService.parseIntegerSwitch(newValue, DEFAULT_VOLUME_DOWN_TO_ENTER_SILENT);
+                TunerService.parseIntegerSwitch(newValue, mDefaultVolumeDownToEnterSilent);
         } else if (VOLUME_UP_SILENT.equals(key)) {
             volumeUpToExitSilent =
                 TunerService.parseIntegerSwitch(newValue, DEFAULT_VOLUME_UP_TO_EXIT_SILENT);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index 98d904e..89b66ee 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -46,7 +46,6 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
-import android.os.UserHandle;
 import android.os.VibrationEffect;
 import android.provider.Settings;
 import android.service.notification.Condition;
@@ -69,6 +68,7 @@
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.plugins.VolumeDialogController;
 import com.android.systemui.qs.tiles.DndTile;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.VibratorHelper;
 import com.android.systemui.util.RingerModeLiveData;
 import com.android.systemui.util.RingerModeTracker;
@@ -133,6 +133,7 @@
     private final CaptioningManager mCaptioningManager;
     private final KeyguardManager mKeyguardManager;
     private final ActivityManager mActivityManager;
+    private final UserTracker mUserTracker;
     protected C mCallbacks = new C();
     private final State mState = new State();
     protected final MediaSessionsCallbacks mMediaSessionsCallbacksW;
@@ -180,6 +181,7 @@
             CaptioningManager captioningManager,
             KeyguardManager keyguardManager,
             ActivityManager activityManager,
+            UserTracker userTracker,
             DumpManager dumpManager
     ) {
         mContext = context.getApplicationContext();
@@ -209,6 +211,7 @@
         mCaptioningManager = captioningManager;
         mKeyguardManager = keyguardManager;
         mActivityManager = activityManager;
+        mUserTracker = userTracker;
         dumpManager.registerDumpable("VolumeDialogControllerImpl", this);
 
         boolean accessibilityVolumeStreamActive = accessibilityManager
@@ -371,7 +374,7 @@
         if (System.currentTimeMillis() - mLastToggledRingerOn < TOUCH_FEEDBACK_TIMEOUT_MS) {
             try {
                 mAudioService.playSoundEffect(AudioManager.FX_KEYPRESS_STANDARD,
-                        UserHandle.USER_CURRENT);
+                        mUserTracker.getUserId());
             } catch (RemoteException e) {
                 // ignore
             }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index db1853d..52eef42 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -1487,6 +1487,7 @@
                 .setDuration(mDialogHideAnimationDurationMs)
                 .setInterpolator(new SystemUIInterpolators.LogAccelerateInterpolator())
                 .withEndAction(() -> mHandler.postDelayed(() -> {
+                    mController.notifyVisible(false);
                     mDialog.dismiss();
                     tryToRemoveCaptionsTooltip();
                     mIsAnimatingDismiss = false;
@@ -1497,7 +1498,6 @@
         animator.setListener(getJankListener(getDialogView(), TYPE_DISMISS,
                 mDialogHideAnimationDurationMs)).start();
         checkODICaptionsTooltip(true);
-        mController.notifyVisible(false);
         synchronized (mSafetyWarningLock) {
             if (mSafetyWarning != null) {
                 if (D.BUG) Log.d(TAG, "SafetyWarning dismissed");
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java b/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java
index 4cbc709..4da5d49 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java
@@ -273,7 +273,7 @@
             };
 
             mSecureSettings.registerContentObserverForUser(
-                    Settings.Secure.getUriFor(Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT),
+                    Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
                     false /* notifyForDescendants */,
                     mDefaultPaymentAppObserver,
                     UserHandle.USER_ALL);
@@ -293,7 +293,7 @@
             };
 
             mSecureSettings.registerContentObserverForUser(
-                    Settings.Secure.getUriFor(QuickAccessWalletClientImpl.SETTING_KEY),
+                    QuickAccessWalletClientImpl.SETTING_KEY,
                     false /* notifyForDescendants */,
                     mWalletPreferenceObserver,
                     UserHandle.USER_ALL);
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/controller/WalletContextualSuggestionsController.kt b/packages/SystemUI/src/com/android/systemui/wallet/controller/WalletContextualSuggestionsController.kt
new file mode 100644
index 0000000..7b8235a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/wallet/controller/WalletContextualSuggestionsController.kt
@@ -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 com.android.systemui.wallet.controller
+
+import android.Manifest
+import android.content.Context
+import android.content.IntentFilter
+import android.service.quickaccesswallet.GetWalletCardsError
+import android.service.quickaccesswallet.GetWalletCardsResponse
+import android.service.quickaccesswallet.QuickAccessWalletClient
+import android.service.quickaccesswallet.WalletCard
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.emptyFlow
+import kotlinx.coroutines.flow.shareIn
+
+@SysUISingleton
+class WalletContextualSuggestionsController
+@Inject
+constructor(
+    @Application private val applicationCoroutineScope: CoroutineScope,
+    private val walletController: QuickAccessWalletController,
+    broadcastDispatcher: BroadcastDispatcher,
+    featureFlags: FeatureFlags
+) {
+    private val allWalletCards: Flow<List<WalletCard>> =
+        if (featureFlags.isEnabled(Flags.ENABLE_WALLET_CONTEXTUAL_LOYALTY_CARDS)) {
+            conflatedCallbackFlow {
+                val callback =
+                    object : QuickAccessWalletClient.OnWalletCardsRetrievedCallback {
+                        override fun onWalletCardsRetrieved(response: GetWalletCardsResponse) {
+                            trySendWithFailureLogging(response.walletCards, TAG)
+                        }
+
+                        override fun onWalletCardRetrievalError(error: GetWalletCardsError) {
+                            trySendWithFailureLogging(emptyList<WalletCard>(), TAG)
+                        }
+                    }
+
+                walletController.setupWalletChangeObservers(
+                    callback,
+                    QuickAccessWalletController.WalletChangeEvent.WALLET_PREFERENCE_CHANGE,
+                    QuickAccessWalletController.WalletChangeEvent.DEFAULT_PAYMENT_APP_CHANGE
+                )
+                walletController.updateWalletPreference()
+                walletController.queryWalletCards(callback)
+
+                awaitClose {
+                    walletController.unregisterWalletChangeObservers(
+                        QuickAccessWalletController.WalletChangeEvent.WALLET_PREFERENCE_CHANGE,
+                        QuickAccessWalletController.WalletChangeEvent.DEFAULT_PAYMENT_APP_CHANGE
+                    )
+                }
+            }
+        } else {
+            emptyFlow()
+        }
+
+    private val contextualSuggestionsCardIds: Flow<Set<String>> =
+        if (featureFlags.isEnabled(Flags.ENABLE_WALLET_CONTEXTUAL_LOYALTY_CARDS)) {
+            broadcastDispatcher.broadcastFlow(
+                filter = IntentFilter(ACTION_UPDATE_WALLET_CONTEXTUAL_SUGGESTIONS),
+                permission = Manifest.permission.BIND_QUICK_ACCESS_WALLET_SERVICE,
+                flags = Context.RECEIVER_EXPORTED
+            ) { intent, _ ->
+                if (intent.hasExtra(UPDATE_CARD_IDS_EXTRA)) {
+                    intent.getStringArrayListExtra(UPDATE_CARD_IDS_EXTRA).toSet()
+                } else {
+                    emptySet()
+                }
+            }
+        } else {
+            emptyFlow()
+        }
+
+    val contextualSuggestionCards: Flow<List<WalletCard>> =
+        combine(allWalletCards, contextualSuggestionsCardIds) { cards, ids ->
+                cards.filter { card -> ids.contains(card.cardId) }
+            }
+            .shareIn(applicationCoroutineScope, replay = 1, started = SharingStarted.Eagerly)
+
+    companion object {
+        private const val ACTION_UPDATE_WALLET_CONTEXTUAL_SUGGESTIONS =
+            "com.android.systemui.wallet.UPDATE_CONTEXTUAL_SUGGESTIONS"
+
+        private const val UPDATE_CARD_IDS_EXTRA = "cardIds"
+
+        private const val TAG = "WalletSuggestions"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java
index 1f1b32c..8b925b7 100644
--- a/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java
@@ -26,7 +26,6 @@
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManager.DisplayListener;
 import android.os.Trace;
-import android.os.UserHandle;
 import android.service.wallpaper.WallpaperService;
 import android.util.Log;
 import android.view.Surface;
@@ -37,6 +36,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.util.concurrency.DelayableExecutor;
 
 import java.io.FileDescriptor;
@@ -58,6 +58,8 @@
     private volatile int mPages = 1;
     private boolean mPagesComputed = false;
 
+    private final UserTracker mUserTracker;
+
     // used for most tasks (call canvas.drawBitmap, load/unload the bitmap)
     @Background
     private final DelayableExecutor mBackgroundExecutor;
@@ -66,9 +68,11 @@
     private static final int DELAY_UNLOAD_BITMAP = 2000;
 
     @Inject
-    public ImageWallpaper(@Background DelayableExecutor backgroundExecutor) {
+    public ImageWallpaper(@Background DelayableExecutor backgroundExecutor,
+            UserTracker userTracker) {
         super();
         mBackgroundExecutor = backgroundExecutor;
+        mUserTracker = userTracker;
     }
 
     @Override
@@ -288,7 +292,7 @@
             boolean loadSuccess = false;
             Bitmap bitmap;
             try {
-                bitmap = mWallpaperManager.getBitmapAsUser(UserHandle.USER_CURRENT, false);
+                bitmap = mWallpaperManager.getBitmapAsUser(mUserTracker.getUserId(), false);
                 if (bitmap != null
                         && bitmap.getByteCount() > RecordingCanvas.MAX_BITMAP_SIZE) {
                     throw new RuntimeException("Wallpaper is too large to draw!");
@@ -300,9 +304,9 @@
                 // default wallpaper can't be loaded.
                 Log.w(TAG, "Unable to load wallpaper!", exception);
                 mWallpaperManager.clearWallpaper(
-                        WallpaperManager.FLAG_SYSTEM, UserHandle.USER_CURRENT);
+                        WallpaperManager.FLAG_SYSTEM, mUserTracker.getUserId());
                 try {
-                    bitmap = mWallpaperManager.getBitmapAsUser(UserHandle.USER_CURRENT, false);
+                    bitmap = mWallpaperManager.getBitmapAsUser(mUserTracker.getUserId(), false);
                 } catch (RuntimeException | OutOfMemoryError e) {
                     Log.w(TAG, "Unable to load default wallpaper!", e);
                     bitmap = null;
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index d8331ab..d4e06bc 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -146,7 +146,7 @@
             tools:replace="android:authorities"
             tools:node="remove" />
 
-        <provider android:name="com.android.systemui.keyguard.KeyguardQuickAffordanceProvider"
+        <provider android:name="com.android.systemui.keyguard.CustomizationProvider"
             android:authorities="com.android.systemui.test.keyguard.quickaffordance.disabled"
             android:enabled="false"
             tools:replace="android:authorities"
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
index e8f8e25..c76b127 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
@@ -15,6 +15,7 @@
  */
 package com.android.keyguard
 
+import com.android.systemui.statusbar.CommandQueue
 import android.content.BroadcastReceiver
 import android.testing.AndroidTestingRunner
 import android.view.View
@@ -81,8 +82,10 @@
     @Mock private lateinit var largeClockEvents: ClockFaceEvents
     @Mock private lateinit var parentView: View
     @Mock private lateinit var transitionRepository: KeyguardTransitionRepository
+    @Mock private lateinit var commandQueue: CommandQueue
     private lateinit var repository: FakeKeyguardRepository
-    @Mock private lateinit var logBuffer: LogBuffer
+    @Mock private lateinit var smallLogBuffer: LogBuffer
+    @Mock private lateinit var largeLogBuffer: LogBuffer
     private lateinit var underTest: ClockEventController
 
     @Before
@@ -99,7 +102,7 @@
         repository = FakeKeyguardRepository()
 
         underTest = ClockEventController(
-            KeyguardInteractor(repository = repository),
+            KeyguardInteractor(repository = repository, commandQueue = commandQueue),
             KeyguardTransitionInteractor(repository = transitionRepository),
             broadcastDispatcher,
             batteryController,
@@ -109,7 +112,8 @@
             context,
             mainExecutor,
             bgExecutor,
-            logBuffer,
+            smallLogBuffer,
+            largeLogBuffer,
             featureFlags
         )
         underTest.clock = clock
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
index c8e7538..a4180fd 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
@@ -29,7 +29,6 @@
 
 import android.content.res.Resources;
 import android.database.ContentObserver;
-import android.net.Uri;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.testing.AndroidTestingRunner;
@@ -48,6 +47,7 @@
 import com.android.systemui.plugins.ClockController;
 import com.android.systemui.plugins.ClockEvents;
 import com.android.systemui.plugins.ClockFaceController;
+import com.android.systemui.plugins.log.LogBuffer;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shared.clocks.AnimatableClockView;
 import com.android.systemui.shared.clocks.ClockRegistry;
@@ -115,6 +115,8 @@
     private FrameLayout mLargeClockFrame;
     @Mock
     private SecureSettings mSecureSettings;
+    @Mock
+    private LogBuffer mLogBuffer;
 
     private final View mFakeSmartspaceView = new View(mContext);
 
@@ -156,7 +158,8 @@
                 mSecureSettings,
                 mExecutor,
                 mDumpManager,
-                mClockEventController
+                mClockEventController,
+                mLogBuffer
         );
 
         when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
@@ -271,7 +274,7 @@
         ArgumentCaptor<ContentObserver> observerCaptor =
                 ArgumentCaptor.forClass(ContentObserver.class);
         mController.init();
-        verify(mSecureSettings).registerContentObserverForUser(any(Uri.class),
+        verify(mSecureSettings).registerContentObserverForUser(any(String.class),
                 anyBoolean(), observerCaptor.capture(), eq(UserHandle.USER_ALL));
         ContentObserver observer = observerCaptor.getValue();
         mExecutor.runAllReady();
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
index 254f953..8dc1e8f 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
@@ -16,6 +16,7 @@
 
 package com.android.keyguard;
 
+import static android.view.View.INVISIBLE;
 import static android.view.View.VISIBLE;
 
 import static com.android.keyguard.KeyguardClockSwitch.LARGE;
@@ -189,6 +190,7 @@
         assertThat(mLargeClockFrame.getAlpha()).isEqualTo(1);
         assertThat(mLargeClockFrame.getVisibility()).isEqualTo(VISIBLE);
         assertThat(mSmallClockFrame.getAlpha()).isEqualTo(0);
+        assertThat(mSmallClockFrame.getVisibility()).isEqualTo(INVISIBLE);
     }
 
     @Test
@@ -198,6 +200,7 @@
         assertThat(mLargeClockFrame.getAlpha()).isEqualTo(1);
         assertThat(mLargeClockFrame.getVisibility()).isEqualTo(VISIBLE);
         assertThat(mSmallClockFrame.getAlpha()).isEqualTo(0);
+        assertThat(mSmallClockFrame.getVisibility()).isEqualTo(INVISIBLE);
     }
 
     @Test
@@ -212,6 +215,7 @@
         // only big clock is removed at switch
         assertThat(mLargeClockFrame.getParent()).isNull();
         assertThat(mLargeClockFrame.getAlpha()).isEqualTo(0);
+        assertThat(mLargeClockFrame.getVisibility()).isEqualTo(INVISIBLE);
     }
 
     @Test
@@ -223,6 +227,7 @@
         // only big clock is removed at switch
         assertThat(mLargeClockFrame.getParent()).isNull();
         assertThat(mLargeClockFrame.getAlpha()).isEqualTo(0);
+        assertThat(mLargeClockFrame.getVisibility()).isEqualTo(INVISIBLE);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
index 84f6d91..075ef9d 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
@@ -405,6 +405,13 @@
     }
 
     @Test
+    public void onBouncerVisibilityChanged_resetsScale() {
+        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.INVISIBLE);
+
+        verify(mView).resetScale();
+    }
+
+    @Test
     public void onStartingToHide_sideFpsHintShown_sideFpsHintHidden() {
         setupGetSecurityView();
         setupConditionsToEnableSideFpsHint();
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
index 36ed669..1bbc199 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
@@ -49,6 +49,8 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowInsets;
+import android.window.BackEvent;
+import android.window.OnBackAnimationCallback;
 
 import androidx.constraintlayout.widget.ConstraintSet;
 import androidx.test.filters.SmallTest;
@@ -357,6 +359,27 @@
         assertThat(viewFlipperConstraint.layout.leftToLeft).isEqualTo(PARENT_ID);
     }
 
+    @Test
+    public void testPlayBackAnimation() {
+        OnBackAnimationCallback backCallback = mKeyguardSecurityContainer.getBackCallback();
+        backCallback.onBackStarted(createBackEvent(0, 0));
+        mKeyguardSecurityContainer.getBackCallback().onBackProgressed(
+                createBackEvent(0, 1));
+        assertThat(mKeyguardSecurityContainer.getScaleX()).isEqualTo(
+                KeyguardSecurityContainer.MIN_BACK_SCALE);
+        assertThat(mKeyguardSecurityContainer.getScaleY()).isEqualTo(
+                KeyguardSecurityContainer.MIN_BACK_SCALE);
+
+        // reset scale
+        mKeyguardSecurityContainer.resetScale();
+        assertThat(mKeyguardSecurityContainer.getScaleX()).isEqualTo(1);
+        assertThat(mKeyguardSecurityContainer.getScaleY()).isEqualTo(1);
+    }
+
+    private BackEvent createBackEvent(float touchX, float progress) {
+        return new BackEvent(0, 0, progress, BackEvent.EDGE_LEFT);
+    }
+
     private Configuration configuration(@Configuration.Orientation int orientation) {
         Configuration config = new Configuration();
         config.orientation = orientation;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
index be4bbdf..dfad15d 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
@@ -24,6 +24,7 @@
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 
+import com.android.keyguard.logging.KeyguardLogger;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.plugins.ClockAnimations;
@@ -65,6 +66,8 @@
     ScreenOffAnimationController mScreenOffAnimationController;
     @Captor
     private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallbackCaptor;
+    @Mock
+    KeyguardLogger mKeyguardLogger;
 
     private KeyguardStatusViewController mController;
 
@@ -81,7 +84,8 @@
                 mConfigurationController,
                 mDozeParameters,
                 mFeatureFlags,
-                mScreenOffAnimationController);
+                mScreenOffAnimationController,
+                mKeyguardLogger);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 13cd328..df6752a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -32,6 +32,9 @@
 import static com.android.keyguard.KeyguardUpdateMonitor.DEFAULT_CANCEL_SIGNAL_TIMEOUT;
 import static com.android.keyguard.KeyguardUpdateMonitor.HAL_POWER_PRESS_TIMEOUT;
 import static com.android.keyguard.KeyguardUpdateMonitor.getCurrentUser;
+import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_CLOSED;
+import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_OPENED;
+import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_UNKNOWN;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -92,6 +95,7 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.provider.Settings;
 import android.service.dreams.IDreamManager;
 import android.service.trust.TrustAgentService;
 import android.telephony.ServiceState;
@@ -116,6 +120,7 @@
 import com.android.keyguard.logging.KeyguardUpdateMonitorLogger;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.biometrics.AuthController;
+import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.log.SessionTracker;
@@ -123,6 +128,7 @@
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.policy.DevicePostureController;
 import com.android.systemui.telephony.TelephonyListenerManager;
 import com.android.systemui.util.settings.GlobalSettings;
 import com.android.systemui.util.settings.SecureSettings;
@@ -142,6 +148,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Optional;
 import java.util.concurrent.Executor;
 import java.util.concurrent.atomic.AtomicBoolean;
 
@@ -191,6 +198,8 @@
     @Mock
     private DevicePolicyManager mDevicePolicyManager;
     @Mock
+    private DevicePostureController mDevicePostureController;
+    @Mock
     private IDreamManager mDreamManager;
     @Mock
     private KeyguardBypassController mKeyguardBypassController;
@@ -233,6 +242,8 @@
     @Mock
     private GlobalSettings mGlobalSettings;
     private FaceWakeUpTriggersConfig mFaceWakeUpTriggersConfig;
+    @Mock
+    private FingerprintInteractiveToAuthProvider mInteractiveToAuthProvider;
 
 
     private final int mCurrentUserId = 100;
@@ -296,6 +307,7 @@
                 .thenReturn(new ServiceState());
         when(mLockPatternUtils.getLockSettings()).thenReturn(mLockSettings);
         when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(false);
+        when(mDevicePostureController.getDevicePosture()).thenReturn(DEVICE_POSTURE_UNKNOWN);
 
         mMockitoSession = ExtendedMockito.mockitoSession()
                 .spyStatic(SubscriptionManager.class)
@@ -307,6 +319,9 @@
         when(mUserTracker.getUserId()).thenReturn(mCurrentUserId);
         ExtendedMockito.doReturn(mActivityService).when(ActivityManager::getService);
 
+        mContext.getOrCreateTestableResources().addOverride(
+                com.android.systemui.R.integer.config_face_auth_supported_posture,
+                DEVICE_POSTURE_UNKNOWN);
         mFaceWakeUpTriggersConfig = new FaceWakeUpTriggersConfig(
                 mContext.getResources(),
                 mGlobalSettings,
@@ -1250,7 +1265,7 @@
     }
 
     @Test
-    public void testStartsListeningForSfps_whenKeyguardIsVisible_ifRequireScreenOnToAuthEnabled()
+    public void startsListeningForSfps_whenKeyguardIsVisible_ifRequireInteractiveToAuthEnabled()
             throws RemoteException {
         // SFPS supported and enrolled
         final ArrayList<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
@@ -1258,12 +1273,8 @@
         when(mAuthController.getSfpsProps()).thenReturn(props);
         when(mAuthController.isSfpsEnrolled(anyInt())).thenReturn(true);
 
-        // WHEN require screen on to auth is disabled, and keyguard is not awake
-        when(mSecureSettings.getIntForUser(anyString(), anyInt(), anyInt())).thenReturn(0);
-        mKeyguardUpdateMonitor.updateSfpsRequireScreenOnToAuthPref();
-
-        mContext.getOrCreateTestableResources().addOverride(
-                com.android.internal.R.bool.config_requireScreenOnToAuthEnabled, true);
+        // WHEN require interactive to auth is disabled, and keyguard is not awake
+        when(mInteractiveToAuthProvider.isEnabled(anyInt())).thenReturn(false);
 
         // Preconditions for sfps auth to run
         keyguardNotGoingAway();
@@ -1279,9 +1290,8 @@
         // THEN we should listen for sfps when screen off, because require screen on is disabled
         assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isTrue();
 
-        // WHEN require screen on to auth is enabled, and keyguard is not awake
-        when(mSecureSettings.getIntForUser(anyString(), anyInt(), anyInt())).thenReturn(1);
-        mKeyguardUpdateMonitor.updateSfpsRequireScreenOnToAuthPref();
+        // WHEN require interactive to auth is enabled, and keyguard is not awake
+        when(mInteractiveToAuthProvider.isEnabled(anyInt())).thenReturn(true);
 
         // THEN we shouldn't listen for sfps when screen off, because require screen on is enabled
         assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isFalse();
@@ -1295,6 +1305,61 @@
         assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isTrue();
     }
 
+    @Test
+    public void notListeningForSfps_whenGoingToSleep_ifRequireInteractiveToAuthEnabled()
+            throws RemoteException {
+        // GIVEN SFPS supported and enrolled
+        final ArrayList<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
+        props.add(newFingerprintSensorPropertiesInternal(TYPE_POWER_BUTTON));
+        when(mAuthController.getSfpsProps()).thenReturn(props);
+        when(mAuthController.isSfpsEnrolled(anyInt())).thenReturn(true);
+
+        // GIVEN Preconditions for sfps auth to run
+        keyguardNotGoingAway();
+        currentUserIsPrimary();
+        currentUserDoesNotHaveTrust();
+        biometricsNotDisabledThroughDevicePolicyManager();
+        biometricsEnabledForCurrentUser();
+        userNotCurrentlySwitching();
+        statusBarShadeIsLocked();
+
+        // WHEN require interactive to auth is enabled & keyguard is going to sleep
+        when(mInteractiveToAuthProvider.isEnabled(anyInt())).thenReturn(true);
+        deviceGoingToSleep();
+
+        mTestableLooper.processAllMessages();
+
+        // THEN we should NOT listen for sfps because device is going to sleep
+        assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isFalse();
+    }
+
+    @Test
+    public void listeningForSfps_whenGoingToSleep_ifRequireInteractiveToAuthDisabled()
+            throws RemoteException {
+        // GIVEN SFPS supported and enrolled
+        final ArrayList<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
+        props.add(newFingerprintSensorPropertiesInternal(TYPE_POWER_BUTTON));
+        when(mAuthController.getSfpsProps()).thenReturn(props);
+        when(mAuthController.isSfpsEnrolled(anyInt())).thenReturn(true);
+
+        // GIVEN Preconditions for sfps auth to run
+        keyguardNotGoingAway();
+        currentUserIsPrimary();
+        currentUserDoesNotHaveTrust();
+        biometricsNotDisabledThroughDevicePolicyManager();
+        biometricsEnabledForCurrentUser();
+        userNotCurrentlySwitching();
+        statusBarShadeIsLocked();
+
+        // WHEN require interactive to auth is disabled & keyguard is going to sleep
+        when(mInteractiveToAuthProvider.isEnabled(anyInt())).thenReturn(false);
+        deviceGoingToSleep();
+
+        mTestableLooper.processAllMessages();
+
+        // THEN we should listen for sfps because screen on to auth is  disabled
+        assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isTrue();
+    }
 
     private FingerprintSensorPropertiesInternal newFingerprintSensorPropertiesInternal(
             @FingerprintSensorProperties.SensorType int sensorType) {
@@ -2187,6 +2252,54 @@
                 eq(true));
     }
 
+    @Test
+    public void testShouldListenForFace_withAuthSupportPostureConfig_returnsTrue()
+            throws RemoteException {
+        mKeyguardUpdateMonitor.mConfigFaceAuthSupportedPosture = DEVICE_POSTURE_CLOSED;
+        keyguardNotGoingAway();
+        bouncerFullyVisibleAndNotGoingToSleep();
+        currentUserIsPrimary();
+        currentUserDoesNotHaveTrust();
+        biometricsNotDisabledThroughDevicePolicyManager();
+        biometricsEnabledForCurrentUser();
+        userNotCurrentlySwitching();
+        supportsFaceDetection();
+
+        deviceInPostureStateOpened();
+        mTestableLooper.processAllMessages();
+        // Should not listen for face when posture state in DEVICE_POSTURE_OPENED
+        assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isFalse();
+
+        deviceInPostureStateClosed();
+        mTestableLooper.processAllMessages();
+        // Should listen for face when posture state in DEVICE_POSTURE_CLOSED
+        assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isTrue();
+    }
+
+    @Test
+    public void testShouldListenForFace_withoutAuthSupportPostureConfig_returnsTrue()
+            throws RemoteException {
+        mKeyguardUpdateMonitor.mConfigFaceAuthSupportedPosture = DEVICE_POSTURE_UNKNOWN;
+        keyguardNotGoingAway();
+        bouncerFullyVisibleAndNotGoingToSleep();
+        currentUserIsPrimary();
+        currentUserDoesNotHaveTrust();
+        biometricsNotDisabledThroughDevicePolicyManager();
+        biometricsEnabledForCurrentUser();
+        userNotCurrentlySwitching();
+        supportsFaceDetection();
+
+        deviceInPostureStateClosed();
+        mTestableLooper.processAllMessages();
+        // Whether device in any posture state, always listen for face
+        assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isTrue();
+
+        deviceInPostureStateOpened();
+        mTestableLooper.processAllMessages();
+        // Whether device in any posture state, always listen for face
+        assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isTrue();
+    }
+
     private void userDeviceLockDown() {
         when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(false);
         when(mStrongAuthTracker.getStrongAuthForUser(mCurrentUserId))
@@ -2266,6 +2379,14 @@
                 .onAuthenticationAcquired(FINGERPRINT_ACQUIRED_START);
     }
 
+    private void deviceInPostureStateOpened() {
+        mKeyguardUpdateMonitor.mPostureCallback.onPostureChanged(DEVICE_POSTURE_OPENED);
+    }
+
+    private void deviceInPostureStateClosed() {
+        mKeyguardUpdateMonitor.mPostureCallback.onPostureChanged(DEVICE_POSTURE_CLOSED);
+    }
+
     private void successfulFingerprintAuth() {
         mKeyguardUpdateMonitor.mFingerprintAuthenticationCallback
                 .onAuthenticationSucceeded(
@@ -2407,7 +2528,8 @@
                     mPowerManager, mTrustManager, mSubscriptionManager, mUserManager,
                     mDreamManager, mDevicePolicyManager, mSensorPrivacyManager, mTelephonyManager,
                     mPackageManager, mFaceManager, mFingerprintManager, mBiometricManager,
-                    mFaceWakeUpTriggersConfig);
+                    mFaceWakeUpTriggersConfig, mDevicePostureController,
+                    Optional.of(mInteractiveToAuthProvider));
             setStrongAuthTracker(KeyguardUpdateMonitorTest.this.mStrongAuthTracker);
         }
 
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
index ae8f419..05bd1e4 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
@@ -49,6 +49,7 @@
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.VibratorHelper;
 import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -68,6 +69,7 @@
 
 public class LockIconViewControllerBaseTest extends SysuiTestCase {
     protected static final String UNLOCKED_LABEL = "unlocked";
+    protected static final String LOCKED_LABEL = "locked";
     protected static final int PADDING = 10;
 
     protected MockitoSession mStaticMockSession;
@@ -90,6 +92,7 @@
     protected @Mock AuthRippleController mAuthRippleController;
     protected @Mock FeatureFlags mFeatureFlags;
     protected @Mock KeyguardTransitionRepository mTransitionRepository;
+    protected @Mock CommandQueue mCommandQueue;
     protected FakeExecutor mDelayableExecutor = new FakeExecutor(new FakeSystemClock());
 
     protected LockIconViewController mUnderTest;
@@ -130,6 +133,7 @@
         Rect windowBounds = new Rect(0, 0, 800, 1200);
         when(mWindowManager.getCurrentWindowMetrics().getBounds()).thenReturn(windowBounds);
         when(mResources.getString(R.string.accessibility_unlock_button)).thenReturn(UNLOCKED_LABEL);
+        when(mResources.getString(R.string.accessibility_lock_icon)).thenReturn(LOCKED_LABEL);
         when(mResources.getDrawable(anyInt(), any())).thenReturn(mIconDrawable);
         when(mResources.getDimensionPixelSize(R.dimen.lock_icon_padding)).thenReturn(PADDING);
         when(mAuthController.getScaleFactor()).thenReturn(1f);
@@ -155,7 +159,7 @@
                 mAuthRippleController,
                 mResources,
                 new KeyguardTransitionInteractor(mTransitionRepository),
-                new KeyguardInteractor(new FakeKeyguardRepository()),
+                new KeyguardInteractor(new FakeKeyguardRepository(), mCommandQueue),
                 mFeatureFlags
         );
     }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java
index da40595..b69491e 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java
@@ -262,6 +262,26 @@
         // THEN the view is updated to NO translation (no burn-in offsets anymore)
         verify(mLockIconView).setTranslationY(0);
         verify(mLockIconView).setTranslationX(0);
+    }
 
+    @Test
+    public void lockIconShows_afterBiometricsCleared() {
+        // GIVEN lock icon controller is initialized and view is attached
+        init(/* useMigrationFlag= */false);
+        captureKeyguardUpdateMonitorCallback();
+
+        // GIVEN user has unlocked with a biometric auth (ie: face auth)
+        // and biometric running state changes
+        when(mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(anyInt())).thenReturn(true);
+        mKeyguardUpdateMonitorCallback.onBiometricRunningStateChanged(false,
+                BiometricSourceType.FACE);
+        reset(mLockIconView);
+
+        // WHEN biometrics are cleared
+        when(mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(anyInt())).thenReturn(false);
+        mKeyguardUpdateMonitorCallback.onBiometricsCleared();
+
+        // THEN the lock icon is shown
+        verify(mLockIconView).setContentDescription(LOCKED_LABEL);
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt
index 34e78eb..e9a2789 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt
@@ -16,29 +16,25 @@
 
 package com.android.keyguard.mediator
 
+import android.os.Handler
+import android.os.Looper
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
-
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.keyguard.ScreenLifecycle
 import com.android.systemui.unfold.FoldAodAnimationController
 import com.android.systemui.unfold.SysUIUnfoldComponent
 import com.android.systemui.unfold.UnfoldLightRevealOverlayAnimation
-import com.android.systemui.util.concurrency.FakeExecution
 import com.android.systemui.util.mockito.capture
-
-import java.util.Optional
-
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-
 import org.mockito.ArgumentCaptor
 import org.mockito.Captor
 import org.mockito.Mock
 import org.mockito.Mockito.`when`
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
+import java.util.Optional
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
@@ -55,6 +51,8 @@
     @Captor
     private lateinit var readyCaptor: ArgumentCaptor<Runnable>
 
+    private val testHandler = Handler(Looper.getMainLooper())
+
     private lateinit var screenOnCoordinator: ScreenOnCoordinator
 
     @Before
@@ -68,6 +66,7 @@
 
         screenOnCoordinator = ScreenOnCoordinator(
             Optional.of(unfoldComponent),
+            testHandler
         )
     }
 
@@ -77,6 +76,7 @@
 
         onUnfoldOverlayReady()
         onFoldAodReady()
+        waitHandlerIdle(testHandler)
 
         // Should be called when both unfold overlay and keyguard drawn ready
         verify(runnable).run()
@@ -87,8 +87,10 @@
         // Recreate with empty unfoldComponent
         screenOnCoordinator = ScreenOnCoordinator(
             Optional.empty(),
+            testHandler
         )
         screenOnCoordinator.onScreenTurningOn(runnable)
+        waitHandlerIdle(testHandler)
 
         // Should be called when only keyguard drawn
         verify(runnable).run()
@@ -103,4 +105,8 @@
         verify(foldAodAnimationController).onScreenTurningOn(capture(readyCaptor))
         readyCaptor.value.run()
     }
+
+    private fun waitHandlerIdle(handler: Handler) {
+        handler.runWithScissors({},  /* timeout= */ 0)
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/AccessibilityButtonModeObserverTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/AccessibilityButtonModeObserverTest.java
index 7aa4763..4a5c1be 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/AccessibilityButtonModeObserverTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/AccessibilityButtonModeObserverTest.java
@@ -22,14 +22,16 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
-import android.os.UserHandle;
+import android.app.ActivityManager;
 import android.provider.Settings;
 import android.testing.AndroidTestingRunner;
 
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.settings.UserTracker;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -42,11 +44,14 @@
 @RunWith(AndroidTestingRunner.class)
 @SmallTest
 public class AccessibilityButtonModeObserverTest extends SysuiTestCase {
+    private static final int MY_USER_ID = ActivityManager.getCurrentUser();
 
     @Rule
     public MockitoRule mockito = MockitoJUnit.rule();
 
     @Mock
+    private UserTracker mUserTracker;
+    @Mock
     private AccessibilityButtonModeObserver.ModeChangedListener mListener;
 
     private AccessibilityButtonModeObserver mAccessibilityButtonModeObserver;
@@ -56,10 +61,12 @@
 
     @Before
     public void setUp() {
+        when(mUserTracker.getUserId()).thenReturn(MY_USER_ID);
         Settings.Secure.putIntForUser(mContext.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
-                Settings.Secure.ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR, UserHandle.USER_CURRENT);
-        mAccessibilityButtonModeObserver = new AccessibilityButtonModeObserver(mContext);
+                Settings.Secure.ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR, MY_USER_ID);
+        mAccessibilityButtonModeObserver = new AccessibilityButtonModeObserver(mContext,
+                mUserTracker);
     }
 
     @Test
@@ -67,7 +74,7 @@
         mAccessibilityButtonModeObserver.addListener(mListener);
         Settings.Secure.putIntForUser(mContext.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_MODE, TEST_A11Y_BTN_MODE_VALUE,
-                UserHandle.USER_CURRENT);
+                MY_USER_ID);
 
         mAccessibilityButtonModeObserver.mContentObserver.onChange(false);
 
@@ -80,7 +87,7 @@
         mAccessibilityButtonModeObserver.removeListener(mListener);
         Settings.Secure.putIntForUser(mContext.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_MODE, TEST_A11Y_BTN_MODE_VALUE,
-                UserHandle.USER_CURRENT);
+                MY_USER_ID);
 
         mAccessibilityButtonModeObserver.mContentObserver.onChange(false);
 
@@ -91,7 +98,7 @@
     public void getCurrentAccessibilityButtonMode_expectedValue() {
         Settings.Secure.putIntForUser(mContext.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_MODE, TEST_A11Y_BTN_MODE_VALUE,
-                UserHandle.USER_CURRENT);
+                MY_USER_ID);
 
         final int actualValue =
                 mAccessibilityButtonModeObserver.getCurrentAccessibilityButtonMode();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/AccessibilityButtonTargetsObserverTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/AccessibilityButtonTargetsObserverTest.java
index 4145437..a5a7a4a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/AccessibilityButtonTargetsObserverTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/AccessibilityButtonTargetsObserverTest.java
@@ -21,14 +21,16 @@
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
-import android.os.UserHandle;
+import android.app.ActivityManager;
 import android.provider.Settings;
 import android.testing.AndroidTestingRunner;
 
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.settings.UserTracker;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -42,11 +44,14 @@
 @RunWith(AndroidTestingRunner.class)
 @SmallTest
 public class AccessibilityButtonTargetsObserverTest extends SysuiTestCase {
+    private static final int MY_USER_ID = ActivityManager.getCurrentUser();
 
     @Rule
     public MockitoRule mockito = MockitoJUnit.rule();
 
     @Mock
+    private UserTracker mUserTracker;
+    @Mock
     private AccessibilityButtonTargetsObserver.TargetsChangedListener mListener;
 
     private AccessibilityButtonTargetsObserver mAccessibilityButtonTargetsObserver;
@@ -55,7 +60,9 @@
 
     @Before
     public void setUp() {
-        mAccessibilityButtonTargetsObserver = new AccessibilityButtonTargetsObserver(mContext);
+        when(mUserTracker.getUserId()).thenReturn(MY_USER_ID);
+        mAccessibilityButtonTargetsObserver = new AccessibilityButtonTargetsObserver(mContext,
+                mUserTracker);
     }
 
     @Test
@@ -63,7 +70,7 @@
         mAccessibilityButtonTargetsObserver.addListener(mListener);
         Settings.Secure.putStringForUser(mContext.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, TEST_A11Y_BTN_TARGETS,
-                UserHandle.USER_CURRENT);
+                MY_USER_ID);
 
         mAccessibilityButtonTargetsObserver.mContentObserver.onChange(false);
 
@@ -76,7 +83,7 @@
         mAccessibilityButtonTargetsObserver.removeListener(mListener);
         Settings.Secure.putStringForUser(mContext.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, TEST_A11Y_BTN_TARGETS,
-                UserHandle.USER_CURRENT);
+                MY_USER_ID);
 
         mAccessibilityButtonTargetsObserver.mContentObserver.onChange(false);
 
@@ -87,7 +94,7 @@
     public void getCurrentAccessibilityButtonTargets_expectedValue() {
         Settings.Secure.putStringForUser(mContext.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, TEST_A11Y_BTN_TARGETS,
-                UserHandle.USER_CURRENT);
+                MY_USER_ID);
 
         final String actualValue =
                 mAccessibilityButtonTargetsObserver.getCurrentAccessibilityButtonTargets();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/SecureSettingsContentObserverTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/SecureSettingsContentObserverTest.java
index 41fd2b3..9c601a8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/SecureSettingsContentObserverTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/SecureSettingsContentObserverTest.java
@@ -18,18 +18,20 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import android.app.ActivityManager;
 import android.content.Context;
-import android.os.UserHandle;
 import android.provider.Settings;
 import android.testing.AndroidTestingRunner;
 
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.settings.UserTracker;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mockito;
 
 /** Test for {@link SecureSettingsContentObserver}. */
 @RunWith(AndroidTestingRunner.class)
@@ -40,7 +42,9 @@
 
     @Before
     public void setUpObserver() {
-        mTestObserver = new FakeSecureSettingsContentObserver(mContext,
+        UserTracker userTracker = Mockito.mock(UserTracker.class);
+        Mockito.when(userTracker.getUserId()).thenReturn(ActivityManager.getCurrentUser());
+        mTestObserver = new FakeSecureSettingsContentObserver(mContext, userTracker,
                 Settings.Secure.ACCESSIBILITY_BUTTON_MODE);
     }
 
@@ -57,7 +61,7 @@
     @Test
     public void checkValue() {
         Settings.Secure.putIntForUser(mContext.getContentResolver(),
-                Settings.Secure.ACCESSIBILITY_BUTTON_MODE, 1, UserHandle.USER_CURRENT);
+                Settings.Secure.ACCESSIBILITY_BUTTON_MODE, 1, ActivityManager.getCurrentUser());
 
         assertThat(mTestObserver.getSettingsValue()).isEqualTo("1");
     }
@@ -66,9 +70,9 @@
     private static class FakeSecureSettingsContentObserver extends
             SecureSettingsContentObserver<Object> {
 
-        protected FakeSecureSettingsContentObserver(Context context,
+        protected FakeSecureSettingsContentObserver(Context context, UserTracker userTracker,
                 String secureSettingsKey) {
-            super(context, secureSettingsKey);
+            super(context, userTracker, secureSettingsKey);
         }
 
         @Override
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 b7d3459..cdf3f65 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
@@ -32,8 +32,11 @@
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.mockito.AdditionalAnswers.returnsSecondArg;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.atLeastOnce;
@@ -76,6 +79,7 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.util.leak.ReferenceTestUtils;
+import com.android.systemui.util.settings.SecureSettings;
 import com.android.systemui.utils.os.FakeHandler;
 
 import org.junit.After;
@@ -111,6 +115,8 @@
     IRemoteMagnificationAnimationCallback mAnimationCallback;
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();
+    @Mock
+    private SecureSettings mSecureSettings;
 
     private Handler mHandler;
     private TestableWindowManager mWindowManager;
@@ -138,6 +144,10 @@
         }).when(mSfVsyncFrameProvider).postFrameCallback(
                 any(FrameCallback.class));
         mSysUiState.addCallback(Mockito.mock(SysUiState.SysUiStateCallback.class));
+        when(mSecureSettings.getIntForUser(anyString(), anyInt(), anyInt())).then(
+                returnsSecondArg());
+        when(mSecureSettings.getFloatForUser(anyString(), anyFloat(), anyInt())).then(
+                returnsSecondArg());
 
         mResources = getContext().getOrCreateTestableResources().getResources();
         mWindowMagnificationAnimationController = new WindowMagnificationAnimationController(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java
index 8ca17b9..f34a36f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java
@@ -25,6 +25,7 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
+import android.app.ActivityManager;
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.os.UserHandle;
@@ -40,6 +41,7 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.accessibility.AccessibilityButtonModeObserver;
 import com.android.systemui.accessibility.AccessibilityButtonTargetsObserver;
+import com.android.systemui.util.settings.SecureSettings;
 
 import org.junit.After;
 import org.junit.Before;
@@ -48,6 +50,8 @@
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
@@ -71,8 +75,12 @@
     private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardCallbackCaptor;
     private KeyguardUpdateMonitorCallback mKeyguardCallback;
 
+    @Mock
+    private SecureSettings mSecureSettings;
+
     @Before
     public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
         mContextWrapper = new ContextWrapper(mContext) {
             @Override
             public Context createContextAsUser(UserHandle user, int flags) {
@@ -128,7 +136,7 @@
     public void onKeyguardVisibilityChanged_showing_destroyWidget() {
         enableAccessibilityFloatingMenuConfig();
         mController = setUpController();
-        mController.mFloatingMenu = new AccessibilityFloatingMenu(mContextWrapper);
+        mController.mFloatingMenu = new AccessibilityFloatingMenu(mContextWrapper, mSecureSettings);
         captureKeyguardUpdateMonitorCallback();
         mKeyguardCallback.onUserUnlocked();
 
@@ -154,7 +162,7 @@
         final int fakeUserId = 1;
         enableAccessibilityFloatingMenuConfig();
         mController = setUpController();
-        mController.mFloatingMenu = new AccessibilityFloatingMenu(mContextWrapper);
+        mController.mFloatingMenu = new AccessibilityFloatingMenu(mContextWrapper, mSecureSettings);
         captureKeyguardUpdateMonitorCallback();
 
         mKeyguardCallback.onUserSwitching(fakeUserId);
@@ -167,7 +175,7 @@
         final int fakeUserId = 1;
         enableAccessibilityFloatingMenuConfig();
         mController = setUpController();
-        mController.mFloatingMenu = new AccessibilityFloatingMenu(mContextWrapper);
+        mController.mFloatingMenu = new AccessibilityFloatingMenu(mContextWrapper, mSecureSettings);
         captureKeyguardUpdateMonitorCallback();
         mKeyguardCallback.onUserUnlocked();
         mKeyguardCallback.onKeyguardVisibilityChanged(true);
@@ -197,7 +205,7 @@
     public void onAccessibilityButtonModeChanged_floatingModeAndHasButtonTargets_showWidget() {
         Settings.Secure.putStringForUser(mContextWrapper.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, TEST_A11Y_BTN_TARGETS,
-                UserHandle.USER_CURRENT);
+                ActivityManager.getCurrentUser());
         mController = setUpController();
 
         mController.onAccessibilityButtonModeChanged(ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU);
@@ -208,7 +216,7 @@
     @Test
     public void onAccessibilityButtonModeChanged_floatingModeAndNoButtonTargets_destroyWidget() {
         Settings.Secure.putStringForUser(mContextWrapper.getContentResolver(),
-                Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, "", UserHandle.USER_CURRENT);
+                Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, "", ActivityManager.getCurrentUser());
         mController = setUpController();
 
         mController.onAccessibilityButtonModeChanged(ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU);
@@ -220,7 +228,7 @@
     public void onAccessibilityButtonModeChanged_navBarModeAndHasButtonTargets_destroyWidget() {
         Settings.Secure.putStringForUser(mContextWrapper.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, TEST_A11Y_BTN_TARGETS,
-                UserHandle.USER_CURRENT);
+                ActivityManager.getCurrentUser());
         mController = setUpController();
 
         mController.onAccessibilityButtonModeChanged(ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR);
@@ -231,7 +239,7 @@
     @Test
     public void onAccessibilityButtonModeChanged_navBarModeAndNoButtonTargets_destroyWidget() {
         Settings.Secure.putStringForUser(mContextWrapper.getContentResolver(),
-                Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, "", UserHandle.USER_CURRENT);
+                Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, "", ActivityManager.getCurrentUser());
         mController = setUpController();
 
         mController.onAccessibilityButtonModeChanged(ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR);
@@ -243,7 +251,7 @@
     public void onAccessibilityButtonTargetsChanged_floatingModeAndHasButtonTargets_showWidget() {
         Settings.Secure.putIntForUser(mContextWrapper.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_MODE, ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU,
-                UserHandle.USER_CURRENT);
+                ActivityManager.getCurrentUser());
         mController = setUpController();
 
         mController.onAccessibilityButtonTargetsChanged(TEST_A11Y_BTN_TARGETS);
@@ -255,7 +263,7 @@
     public void onAccessibilityButtonTargetsChanged_floatingModeAndNoButtonTargets_destroyWidget() {
         Settings.Secure.putIntForUser(mContextWrapper.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_MODE, ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU,
-                UserHandle.USER_CURRENT);
+                ActivityManager.getCurrentUser());
         mController = setUpController();
 
         mController.onAccessibilityButtonTargetsChanged("");
@@ -267,7 +275,7 @@
     public void onAccessibilityButtonTargetsChanged_navBarModeAndHasButtonTargets_destroyWidget() {
         Settings.Secure.putIntForUser(mContextWrapper.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
-                ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR, UserHandle.USER_CURRENT);
+                ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR, ActivityManager.getCurrentUser());
         mController = setUpController();
 
         mController.onAccessibilityButtonTargetsChanged(TEST_A11Y_BTN_TARGETS);
@@ -279,7 +287,7 @@
     public void onAccessibilityButtonTargetsChanged_navBarModeAndNoButtonTargets_destroyWidget() {
         Settings.Secure.putIntForUser(mContextWrapper.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
-                ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR, UserHandle.USER_CURRENT);
+                ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR, ActivityManager.getCurrentUser());
         mController = setUpController();
 
         mController.onAccessibilityButtonTargetsChanged("");
@@ -293,7 +301,7 @@
         mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
         final AccessibilityFloatingMenuController controller =
                 new AccessibilityFloatingMenuController(mContextWrapper, mTargetsObserver,
-                        mModeObserver, mKeyguardUpdateMonitor);
+                        mModeObserver, mKeyguardUpdateMonitor, mSecureSettings);
         controller.init();
 
         return controller;
@@ -302,10 +310,10 @@
     private void enableAccessibilityFloatingMenuConfig() {
         Settings.Secure.putIntForUser(mContextWrapper.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_MODE, ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU,
-                UserHandle.USER_CURRENT);
+                ActivityManager.getCurrentUser());
         Settings.Secure.putStringForUser(mContextWrapper.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, TEST_A11Y_BTN_TARGETS,
-                UserHandle.USER_CURRENT);
+                ActivityManager.getCurrentUser());
     }
 
     private void captureKeyguardUpdateMonitorCallback() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuTest.java
index 558261b..04345fd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuTest.java
@@ -31,6 +31,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.util.settings.SecureSettings;
 
 import org.junit.After;
 import org.junit.Before;
@@ -55,6 +56,8 @@
 
     @Mock
     private AccessibilityManager mAccessibilityManager;
+    @Mock
+    private SecureSettings mSecureSettings;
 
     private AccessibilityFloatingMenuView mMenuView;
     private AccessibilityFloatingMenu mMenu;
@@ -69,7 +72,7 @@
 
         final Position position = new Position(0, 0);
         mMenuView = new AccessibilityFloatingMenuView(mContext, position);
-        mMenu = new AccessibilityFloatingMenu(mContext, mMenuView);
+        mMenu = new AccessibilityFloatingMenu(mContext, mSecureSettings, mMenuView);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt
index 7c1e384..cac4a0e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt
@@ -12,11 +12,13 @@
 import android.view.ViewGroup
 import android.view.ViewGroup.LayoutParams.MATCH_PARENT
 import android.view.WindowManager
+import android.widget.FrameLayout
 import android.widget.LinearLayout
 import androidx.test.filters.SmallTest
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.policy.DecorView
 import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
 import junit.framework.Assert.assertEquals
 import junit.framework.Assert.assertFalse
 import junit.framework.Assert.assertNotNull
@@ -205,25 +207,74 @@
         verify(interactionJankMonitor).end(InteractionJankMonitor.CUJ_USER_DIALOG_OPEN)
     }
 
+    @Test
+    fun testAnimationDoesNotChangeLaunchableViewVisibility_viewVisible() {
+        val touchSurface = createTouchSurface()
+
+        // View is VISIBLE when starting the animation.
+        runOnMainThreadAndWaitForIdleSync { touchSurface.visibility = View.VISIBLE }
+
+        // View is invisible while the dialog is shown.
+        val dialog = showDialogFromView(touchSurface)
+        assertThat(touchSurface.visibility).isEqualTo(View.INVISIBLE)
+
+        // View is visible again when the dialog is dismissed.
+        runOnMainThreadAndWaitForIdleSync { dialog.dismiss() }
+        assertThat(touchSurface.visibility).isEqualTo(View.VISIBLE)
+    }
+
+    @Test
+    fun testAnimationDoesNotChangeLaunchableViewVisibility_viewInvisible() {
+        val touchSurface = createTouchSurface()
+
+        // View is INVISIBLE when starting the animation.
+        runOnMainThreadAndWaitForIdleSync { touchSurface.visibility = View.INVISIBLE }
+
+        // View is INVISIBLE while the dialog is shown.
+        val dialog = showDialogFromView(touchSurface)
+        assertThat(touchSurface.visibility).isEqualTo(View.INVISIBLE)
+
+        // View is invisible like it was before showing the dialog.
+        runOnMainThreadAndWaitForIdleSync { dialog.dismiss() }
+        assertThat(touchSurface.visibility).isEqualTo(View.INVISIBLE)
+    }
+
+    @Test
+    fun testAnimationDoesNotChangeLaunchableViewVisibility_viewVisibleThenGone() {
+        val touchSurface = createTouchSurface()
+
+        // View is VISIBLE when starting the animation.
+        runOnMainThreadAndWaitForIdleSync { touchSurface.visibility = View.VISIBLE }
+
+        // View is INVISIBLE while the dialog is shown.
+        val dialog = showDialogFromView(touchSurface)
+        assertThat(touchSurface.visibility).isEqualTo(View.INVISIBLE)
+
+        // Some external call makes the View GONE. It remains INVISIBLE while the dialog is shown,
+        // as all visibility changes should be blocked.
+        runOnMainThreadAndWaitForIdleSync { touchSurface.visibility = View.GONE }
+        assertThat(touchSurface.visibility).isEqualTo(View.INVISIBLE)
+
+        // View is restored to GONE once the dialog is dismissed.
+        runOnMainThreadAndWaitForIdleSync { dialog.dismiss() }
+        assertThat(touchSurface.visibility).isEqualTo(View.GONE)
+    }
+
     private fun createAndShowDialog(
         animator: DialogLaunchAnimator = dialogLaunchAnimator,
     ): TestDialog {
         val touchSurface = createTouchSurface()
-        return runOnMainThreadAndWaitForIdleSync {
-            val dialog = TestDialog(context)
-            animator.showFromView(dialog, touchSurface)
-            dialog
-        }
+        return showDialogFromView(touchSurface, animator)
     }
 
     private fun createTouchSurface(): View {
         return runOnMainThreadAndWaitForIdleSync {
             val touchSurfaceRoot = LinearLayout(context)
-            val touchSurface = View(context)
+            val touchSurface = TouchSurfaceView(context)
             touchSurfaceRoot.addView(touchSurface)
 
             // We need to attach the root to the window manager otherwise the exit animation will
-            // be skipped
+            // be skipped.
             ViewUtils.attachView(touchSurfaceRoot)
             attachedViews.add(touchSurfaceRoot)
 
@@ -231,6 +282,17 @@
         }
     }
 
+    private fun showDialogFromView(
+        touchSurface: View,
+        animator: DialogLaunchAnimator = dialogLaunchAnimator,
+    ): TestDialog {
+        return runOnMainThreadAndWaitForIdleSync {
+            val dialog = TestDialog(context)
+            animator.showFromView(dialog, touchSurface)
+            dialog
+        }
+    }
+
     private fun createDialogAndShowFromDialog(animateFrom: Dialog): TestDialog {
         return runOnMainThreadAndWaitForIdleSync {
             val dialog = TestDialog(context)
@@ -248,6 +310,22 @@
         return result
     }
 
+    private class TouchSurfaceView(context: Context) : FrameLayout(context), LaunchableView {
+        private val delegate =
+            LaunchableViewDelegate(
+                this,
+                superSetVisibility = { super.setVisibility(it) },
+            )
+
+        override fun setShouldBlockVisibilityChanges(block: Boolean) {
+            delegate.setShouldBlockVisibilityChanges(block)
+        }
+
+        override fun setVisibility(visibility: Int) {
+            delegate.setVisibility(visibility)
+        }
+    }
+
     private class TestDialog(context: Context) : Dialog(context) {
         companion object {
             const val DIALOG_WIDTH = 100
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 83bf183..ace0ccb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -739,7 +739,7 @@
     public void testForwardsDozeEvents() throws RemoteException {
         when(mStatusBarStateController.isDozing()).thenReturn(true);
         when(mWakefulnessLifecycle.getWakefulness()).thenReturn(WAKEFULNESS_AWAKE);
-        mAuthController.setBiometicContextListener(mContextListener);
+        mAuthController.setBiometricContextListener(mContextListener);
 
         mStatusBarStateListenerCaptor.getValue().onDozingChanged(true);
         mStatusBarStateListenerCaptor.getValue().onDozingChanged(false);
@@ -754,7 +754,7 @@
     public void testForwardsWakeEvents() throws RemoteException {
         when(mStatusBarStateController.isDozing()).thenReturn(false);
         when(mWakefulnessLifecycle.getWakefulness()).thenReturn(WAKEFULNESS_AWAKE);
-        mAuthController.setBiometicContextListener(mContextListener);
+        mAuthController.setBiometricContextListener(mContextListener);
 
         mWakefullnessObserverCaptor.getValue().onStartedGoingToSleep();
         mWakefullnessObserverCaptor.getValue().onFinishedGoingToSleep();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
index 3c40835..b92c5d0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
@@ -53,6 +53,7 @@
 import com.airbnb.lottie.LottieAnimationView
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.SysuiTestableContext
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.recents.OverviewProxyService
 import com.android.systemui.util.concurrency.FakeExecutor
@@ -106,8 +107,7 @@
 
     enum class DeviceConfig {
         X_ALIGNED,
-        Y_ALIGNED_UNFOLDED,
-        Y_ALIGNED_FOLDED
+        Y_ALIGNED,
     }
 
     private lateinit var deviceConfig: DeviceConfig
@@ -143,6 +143,7 @@
 
     private fun testWithDisplay(
         deviceConfig: DeviceConfig = DeviceConfig.X_ALIGNED,
+        isReverseDefaultRotation: Boolean = false,
         initInfo: DisplayInfo.() -> Unit = {},
         windowInsets: WindowInsets = insetsForSmallNavbar(),
         block: () -> Unit
@@ -151,27 +152,21 @@
 
         when (deviceConfig) {
             DeviceConfig.X_ALIGNED -> {
-                displayWidth = 2560
-                displayHeight = 1600
-                sensorLocation = SensorLocationInternal("", 2325, 0, 0)
-                boundsWidth = 160
-                boundsHeight = 84
+                displayWidth = 3000
+                displayHeight = 1500
+                sensorLocation = SensorLocationInternal("", 2500, 0, 0)
+                boundsWidth = 200
+                boundsHeight = 100
             }
-            DeviceConfig.Y_ALIGNED_UNFOLDED -> {
-                displayWidth = 2208
-                displayHeight = 1840
-                sensorLocation = SensorLocationInternal("", 0, 510, 0)
-                boundsWidth = 110
-                boundsHeight = 210
-            }
-            DeviceConfig.Y_ALIGNED_FOLDED -> {
-                displayWidth = 1080
-                displayHeight = 2100
-                sensorLocation = SensorLocationInternal("", 0, 590, 0)
-                boundsWidth = 110
-                boundsHeight = 210
+            DeviceConfig.Y_ALIGNED -> {
+                displayWidth = 2500
+                displayHeight = 2000
+                sensorLocation = SensorLocationInternal("", 0, 300, 0)
+                boundsWidth = 100
+                boundsHeight = 200
             }
         }
+
         indicatorBounds = Rect(0, 0, boundsWidth, boundsHeight)
         displayBounds = Rect(0, 0, displayWidth, displayHeight)
         var locations = listOf(sensorLocation)
@@ -194,8 +189,10 @@
 
         val displayInfo = DisplayInfo()
         displayInfo.initInfo()
+
         val dmGlobal = mock(DisplayManagerGlobal::class.java)
         val display = Display(dmGlobal, DISPLAY_ID, displayInfo, DEFAULT_DISPLAY_ADJUSTMENTS)
+
         whenEver(dmGlobal.getDisplayInfo(eq(DISPLAY_ID))).thenReturn(displayInfo)
         whenEver(windowManager.defaultDisplay).thenReturn(display)
         whenEver(windowManager.maximumWindowMetrics)
@@ -203,9 +200,15 @@
         whenEver(windowManager.currentWindowMetrics)
             .thenReturn(WindowMetrics(displayBounds, windowInsets))
 
+        val sideFpsControllerContext = context.createDisplayContext(display) as SysuiTestableContext
+        sideFpsControllerContext.orCreateTestableResources.addOverride(
+            com.android.internal.R.bool.config_reverseDefaultRotation,
+            isReverseDefaultRotation
+        )
+
         sideFpsController =
             SideFpsController(
-                context.createDisplayContext(display),
+                sideFpsControllerContext,
                 layoutInflater,
                 fingerprintManager,
                 windowManager,
@@ -299,108 +302,316 @@
     }
 
     @Test
-    fun showsWithTaskbar() =
-        testWithDisplay(deviceConfig = DeviceConfig.X_ALIGNED, { rotation = Surface.ROTATION_0 }) {
-            hidesWithTaskbar(visible = true)
-        }
-
-    @Test
-    fun showsWithTaskbarOnY() =
+    fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_0() =
         testWithDisplay(
-            deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED,
+            deviceConfig = DeviceConfig.X_ALIGNED,
+            isReverseDefaultRotation = false,
             { rotation = Surface.ROTATION_0 }
-        ) { hidesWithTaskbar(visible = true) }
+        ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
 
     @Test
-    fun showsWithTaskbar90() =
-        testWithDisplay(deviceConfig = DeviceConfig.X_ALIGNED, { rotation = Surface.ROTATION_90 }) {
-            hidesWithTaskbar(visible = true)
+    fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_90() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.X_ALIGNED,
+            isReverseDefaultRotation = false,
+            { rotation = Surface.ROTATION_90 }
+        ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+
+    @Test
+    fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_180() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.X_ALIGNED,
+            isReverseDefaultRotation = false,
+            { rotation = Surface.ROTATION_180 }
+        ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+
+    @Test
+    fun showsSfpsIndicatorWithTaskbarCollapsedDownForXAlignedSensor_180() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.X_ALIGNED,
+            isReverseDefaultRotation = false,
+            { rotation = Surface.ROTATION_180 },
+            windowInsets = insetsForSmallNavbar()
+        ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+
+    @Test
+    fun hidesSfpsIndicatorWhenOccludingTaskbarForXAlignedSensor_180() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.X_ALIGNED,
+            isReverseDefaultRotation = false,
+            { rotation = Surface.ROTATION_180 },
+            windowInsets = insetsForLargeNavbar()
+        ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = false) }
+
+    @Test
+    fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_270() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.X_ALIGNED,
+            isReverseDefaultRotation = false,
+            { rotation = Surface.ROTATION_270 }
+        ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+
+    @Test
+    fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_InReverseDefaultRotation_0() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.X_ALIGNED,
+            isReverseDefaultRotation = true,
+            { rotation = Surface.ROTATION_0 }
+        ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+
+    @Test
+    fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_InReverseDefaultRotation_90() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.X_ALIGNED,
+            isReverseDefaultRotation = true,
+            { rotation = Surface.ROTATION_90 }
+        ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+
+    @Test
+    fun showsSfpsIndicatorWithTaskbarCollapsedDownForXAlignedSensor_InReverseDefaultRotation_90() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.X_ALIGNED,
+            isReverseDefaultRotation = true,
+            { rotation = Surface.ROTATION_90 },
+            windowInsets = insetsForSmallNavbar()
+        ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+
+    @Test
+    fun hidesSfpsIndicatorWhenOccludingTaskbarForXAlignedSensor_InReverseDefaultRotation_90() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.X_ALIGNED,
+            isReverseDefaultRotation = true,
+            { rotation = Surface.ROTATION_90 },
+            windowInsets = insetsForLargeNavbar()
+        ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = false) }
+
+    @Test
+    fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_InReverseDefaultRotation_180() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.X_ALIGNED,
+            isReverseDefaultRotation = true,
+            { rotation = Surface.ROTATION_180 }
+        ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+
+    @Test
+    fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_InReverseDefaultRotation_270() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.X_ALIGNED,
+            isReverseDefaultRotation = true,
+            { rotation = Surface.ROTATION_270 }
+        ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+
+    @Test
+    fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_0() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.Y_ALIGNED,
+            isReverseDefaultRotation = false,
+            { rotation = Surface.ROTATION_0 }
+        ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+
+    @Test
+    fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_90() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.Y_ALIGNED,
+            isReverseDefaultRotation = false,
+            { rotation = Surface.ROTATION_90 }
+        ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+
+    @Test
+    fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_180() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.Y_ALIGNED,
+            isReverseDefaultRotation = false,
+            { rotation = Surface.ROTATION_180 },
+        ) {
+            verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
         }
 
     @Test
-    fun showsWithTaskbar90OnY() =
+    fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_270() =
         testWithDisplay(
-            deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED,
-            { rotation = Surface.ROTATION_90 }
-        ) { hidesWithTaskbar(visible = true) }
-
-    @Test
-    fun showsWithTaskbar180() =
-        testWithDisplay(
-            deviceConfig = DeviceConfig.X_ALIGNED,
-            { rotation = Surface.ROTATION_180 }
-        ) { hidesWithTaskbar(visible = true) }
-
-    @Test
-    fun showsWithTaskbar270OnY() =
-        testWithDisplay(
-            deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED,
+            deviceConfig = DeviceConfig.Y_ALIGNED,
+            isReverseDefaultRotation = false,
             { rotation = Surface.ROTATION_270 }
-        ) { hidesWithTaskbar(visible = true) }
+        ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
 
     @Test
-    fun showsWithTaskbarCollapsedDown() =
+    fun showsSfpsIndicatorWithTaskbarCollapsedDownForYAlignedSensor_270() =
         testWithDisplay(
-            deviceConfig = DeviceConfig.X_ALIGNED,
+            deviceConfig = DeviceConfig.Y_ALIGNED,
+            isReverseDefaultRotation = false,
             { rotation = Surface.ROTATION_270 },
             windowInsets = insetsForSmallNavbar()
-        ) { hidesWithTaskbar(visible = true) }
+        ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
 
     @Test
-    fun showsWithTaskbarCollapsedDownOnY() =
+    fun hidesSfpsIndicatorWhenOccludingTaskbarForYAlignedSensor_270() =
         testWithDisplay(
-            deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED,
-            { rotation = Surface.ROTATION_180 },
-            windowInsets = insetsForSmallNavbar()
-        ) { hidesWithTaskbar(visible = true) }
-
-    @Test
-    fun hidesWithTaskbarDown() =
-        testWithDisplay(
-            deviceConfig = DeviceConfig.X_ALIGNED,
-            { rotation = Surface.ROTATION_180 },
-            windowInsets = insetsForLargeNavbar()
-        ) { hidesWithTaskbar(visible = false) }
-
-    @Test
-    fun hidesWithTaskbarDownOnY() =
-        testWithDisplay(
-            deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED,
+            deviceConfig = DeviceConfig.Y_ALIGNED,
+            isReverseDefaultRotation = false,
             { rotation = Surface.ROTATION_270 },
             windowInsets = insetsForLargeNavbar()
-        ) { hidesWithTaskbar(visible = true) }
+        ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = false) }
 
-    private fun hidesWithTaskbar(visible: Boolean) {
+    @Test
+    fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_InReverseDefaultRotation_0() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.Y_ALIGNED,
+            isReverseDefaultRotation = true,
+            { rotation = Surface.ROTATION_0 }
+        ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+
+    @Test
+    fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_InReverseDefaultRotation_90() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.Y_ALIGNED,
+            isReverseDefaultRotation = true,
+            { rotation = Surface.ROTATION_90 },
+        ) {
+            verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
+        }
+
+    @Test
+    fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_InReverseDefaultRotation_180() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.Y_ALIGNED,
+            isReverseDefaultRotation = true,
+            { rotation = Surface.ROTATION_180 }
+        ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+
+    @Test
+    fun showsSfpsIndicatorWithTaskbarCollapsedDownForYAlignedSensor_InReverseDefaultRotation_180() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.Y_ALIGNED,
+            isReverseDefaultRotation = true,
+            { rotation = Surface.ROTATION_180 },
+            windowInsets = insetsForSmallNavbar()
+        ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+
+    @Test
+    fun hidesSfpsIndicatorWhenOccludingTaskbarForYAlignedSensor_InReverseDefaultRotation_180() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.Y_ALIGNED,
+            isReverseDefaultRotation = true,
+            { rotation = Surface.ROTATION_180 },
+            windowInsets = insetsForLargeNavbar()
+        ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = false) }
+
+    @Test
+    fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_InReverseDefaultRotation_270() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.Y_ALIGNED,
+            isReverseDefaultRotation = true,
+            { rotation = Surface.ROTATION_270 }
+        ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+
+    private fun verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible: Boolean) {
+        sideFpsController.overlayOffsets = sensorLocation
         overlayController.show(SENSOR_ID, REASON_UNKNOWN)
         executor.runAllReady()
 
-        sideFpsController.overviewProxyListener.onTaskbarStatusUpdated(visible, false)
+        sideFpsController.overviewProxyListener.onTaskbarStatusUpdated(true, false)
         executor.runAllReady()
 
         verify(windowManager).addView(any(), any())
         verify(windowManager, never()).removeView(any())
-        verify(sideFpsView).visibility = if (visible) View.VISIBLE else View.GONE
+        verify(sideFpsView).visibility = if (sfpsViewVisible) View.VISIBLE else View.GONE
     }
 
+    /**
+     * {@link SideFpsController#updateOverlayParams} calculates indicator placement for ROTATION_0,
+     * and uses RotateUtils.rotateBounds to map to the correct indicator location given the device
+     * rotation. Assuming RotationUtils.rotateBounds works correctly, tests for indicator placement
+     * in other rotations have been omitted.
+     */
     @Test
-    fun testIndicatorPlacementForXAlignedSensor() =
-        testWithDisplay(deviceConfig = DeviceConfig.X_ALIGNED) {
-            overlayController.show(SENSOR_ID, REASON_UNKNOWN)
+    fun verifiesIndicatorPlacementForXAlignedSensor_0() {
+        testWithDisplay(
+            deviceConfig = DeviceConfig.X_ALIGNED,
+            isReverseDefaultRotation = false,
+            { rotation = Surface.ROTATION_0 }
+        ) {
             sideFpsController.overlayOffsets = sensorLocation
+
             sideFpsController.updateOverlayParams(windowManager.defaultDisplay, indicatorBounds)
+
+            overlayController.show(SENSOR_ID, REASON_UNKNOWN)
             executor.runAllReady()
 
             verify(windowManager).updateViewLayout(any(), overlayViewParamsCaptor.capture())
-
             assertThat(overlayViewParamsCaptor.value.x).isEqualTo(sensorLocation.sensorLocationX)
             assertThat(overlayViewParamsCaptor.value.y).isEqualTo(0)
         }
+    }
 
+    /**
+     * {@link SideFpsController#updateOverlayParams} calculates indicator placement for ROTATION_270
+     * in reverse default rotation. It then uses RotateUtils.rotateBounds to map to the correct
+     * indicator location given the device rotation. Assuming RotationUtils.rotateBounds works
+     * correctly, tests for indicator placement in other rotations have been omitted.
+     */
     @Test
-    fun testIndicatorPlacementForYAlignedSensor() =
-        testWithDisplay(deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED) {
+    fun verifiesIndicatorPlacementForXAlignedSensor_InReverseDefaultRotation_270() {
+        testWithDisplay(
+            deviceConfig = DeviceConfig.X_ALIGNED,
+            isReverseDefaultRotation = true,
+            { rotation = Surface.ROTATION_270 }
+        ) {
             sideFpsController.overlayOffsets = sensorLocation
+
             sideFpsController.updateOverlayParams(windowManager.defaultDisplay, indicatorBounds)
+
+            overlayController.show(SENSOR_ID, REASON_UNKNOWN)
+            executor.runAllReady()
+
+            verify(windowManager).updateViewLayout(any(), overlayViewParamsCaptor.capture())
+            assertThat(overlayViewParamsCaptor.value.x).isEqualTo(sensorLocation.sensorLocationX)
+            assertThat(overlayViewParamsCaptor.value.y).isEqualTo(0)
+        }
+    }
+
+    /**
+     * {@link SideFpsController#updateOverlayParams} calculates indicator placement for ROTATION_0,
+     * and uses RotateUtils.rotateBounds to map to the correct indicator location given the device
+     * rotation. Assuming RotationUtils.rotateBounds works correctly, tests for indicator placement
+     * in other rotations have been omitted.
+     */
+    @Test
+    fun verifiesIndicatorPlacementForYAlignedSensor_0() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.Y_ALIGNED,
+            isReverseDefaultRotation = false,
+            { rotation = Surface.ROTATION_0 }
+        ) {
+            sideFpsController.overlayOffsets = sensorLocation
+
+            sideFpsController.updateOverlayParams(windowManager.defaultDisplay, indicatorBounds)
+
+            overlayController.show(SENSOR_ID, REASON_UNKNOWN)
+            executor.runAllReady()
+
+            verify(windowManager).updateViewLayout(any(), overlayViewParamsCaptor.capture())
+            assertThat(overlayViewParamsCaptor.value.x).isEqualTo(displayWidth - boundsWidth)
+            assertThat(overlayViewParamsCaptor.value.y).isEqualTo(sensorLocation.sensorLocationY)
+        }
+
+    /**
+     * {@link SideFpsController#updateOverlayParams} calculates indicator placement for ROTATION_270
+     * in reverse default rotation. It then uses RotateUtils.rotateBounds to map to the correct
+     * indicator location given the device rotation. Assuming RotationUtils.rotateBounds works
+     * correctly, tests for indicator placement in other rotations have been omitted.
+     */
+    @Test
+    fun verifiesIndicatorPlacementForYAlignedSensor_InReverseDefaultRotation_270() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.Y_ALIGNED,
+            isReverseDefaultRotation = true,
+            { rotation = Surface.ROTATION_270 }
+        ) {
+            sideFpsController.overlayOffsets = sensorLocation
+
+            sideFpsController.updateOverlayParams(windowManager.defaultDisplay, indicatorBounds)
+
             overlayController.show(SENSOR_ID, REASON_UNKNOWN)
             executor.runAllReady()
 
@@ -412,7 +623,6 @@
     @Test
     fun hasSideFpsSensor_withSensorProps_returnsTrue() = testWithDisplay {
         // By default all those tests assume the side fps sensor is available.
-
         assertThat(fingerprintManager.hasSideFpsSensor()).isTrue()
     }
 
@@ -425,7 +635,7 @@
 
     @Test
     fun testLayoutParams_isKeyguardDialogType() =
-        testWithDisplay(deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED) {
+        testWithDisplay(deviceConfig = DeviceConfig.Y_ALIGNED) {
             sideFpsController.overlayOffsets = sensorLocation
             sideFpsController.updateOverlayParams(windowManager.defaultDisplay, indicatorBounds)
             overlayController.show(SENSOR_ID, REASON_UNKNOWN)
@@ -440,7 +650,7 @@
 
     @Test
     fun testLayoutParams_hasNoMoveAnimationWindowFlag() =
-        testWithDisplay(deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED) {
+        testWithDisplay(deviceConfig = DeviceConfig.Y_ALIGNED) {
             sideFpsController.overlayOffsets = sensorLocation
             sideFpsController.updateOverlayParams(windowManager.defaultDisplay, indicatorBounds)
             overlayController.show(SENSOR_ID, REASON_UNKNOWN)
@@ -455,7 +665,7 @@
 
     @Test
     fun testLayoutParams_hasTrustedOverlayWindowFlag() =
-        testWithDisplay(deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED) {
+        testWithDisplay(deviceConfig = DeviceConfig.Y_ALIGNED) {
             sideFpsController.overlayOffsets = sensorLocation
             sideFpsController.updateOverlayParams(windowManager.defaultDisplay, indicatorBounds)
             overlayController.show(SENSOR_ID, REASON_UNKNOWN)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
index 53bc2c2..0690d1b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
@@ -43,6 +43,7 @@
 import com.android.systemui.animation.ActivityLaunchAnimator
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.shade.ShadeExpansionStateManager
@@ -52,7 +53,7 @@
 import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.policy.KeyguardStateController
-import com.android.systemui.util.time.SystemClock
+import com.android.systemui.util.settings.SecureSettings
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Rule
@@ -95,18 +96,19 @@
     @Mock private lateinit var dumpManager: DumpManager
     @Mock private lateinit var transitionController: LockscreenShadeTransitionController
     @Mock private lateinit var configurationController: ConfigurationController
-    @Mock private lateinit var systemClock: SystemClock
     @Mock private lateinit var keyguardStateController: KeyguardStateController
     @Mock private lateinit var unlockedScreenOffAnimationController:
             UnlockedScreenOffAnimationController
     @Mock private lateinit var udfpsDisplayMode: UdfpsDisplayModeProvider
+    @Mock private lateinit var secureSettings: SecureSettings
     @Mock private lateinit var controllerCallback: IUdfpsOverlayControllerCallback
     @Mock private lateinit var udfpsController: UdfpsController
     @Mock private lateinit var udfpsView: UdfpsView
     @Mock private lateinit var udfpsEnrollView: UdfpsEnrollView
     @Mock private lateinit var activityLaunchAnimator: ActivityLaunchAnimator
     @Mock private lateinit var featureFlags: FeatureFlags
-    @Mock private lateinit var mPrimaryBouncerInteractor: PrimaryBouncerInteractor
+    @Mock private lateinit var primaryBouncerInteractor: PrimaryBouncerInteractor
+    @Mock private lateinit var alternateBouncerInteractor: AlternateBouncerInteractor
     @Captor private lateinit var layoutParamsCaptor: ArgumentCaptor<WindowManager.LayoutParams>
 
     private val onTouch = { _: View, _: MotionEvent, _: Boolean -> true }
@@ -138,10 +140,10 @@
             context, fingerprintManager, inflater, windowManager, accessibilityManager,
             statusBarStateController, shadeExpansionStateManager, statusBarKeyguardViewManager,
             keyguardUpdateMonitor, dialogManager, dumpManager, transitionController,
-            configurationController, systemClock, keyguardStateController,
-            unlockedScreenOffAnimationController, udfpsDisplayMode, REQUEST_ID, reason,
-            controllerCallback, onTouch, activityLaunchAnimator, featureFlags,
-            mPrimaryBouncerInteractor, isDebuggable
+            configurationController, keyguardStateController,
+            unlockedScreenOffAnimationController, udfpsDisplayMode, secureSettings, REQUEST_ID,
+            reason, controllerCallback, onTouch, activityLaunchAnimator, featureFlags,
+            primaryBouncerInteractor, alternateBouncerInteractor, isDebuggable,
         )
         block()
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index b061eb3..232daad 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -81,6 +81,7 @@
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
 import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -95,6 +96,7 @@
 import com.android.systemui.util.concurrency.Execution;
 import com.android.systemui.util.concurrency.FakeExecution;
 import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.settings.SecureSettings;
 import com.android.systemui.util.time.FakeSystemClock;
 import com.android.systemui.util.time.SystemClock;
 
@@ -202,6 +204,10 @@
     private PrimaryBouncerInteractor mPrimaryBouncerInteractor;
     @Mock
     private SinglePointerTouchProcessor mSinglePointerTouchProcessor;
+    @Mock
+    private AlternateBouncerInteractor mAlternateBouncerInteractor;
+    @Mock
+    private SecureSettings mSecureSettings;
 
     // Capture listeners so that they can be used to send events
     @Captor
@@ -292,7 +298,8 @@
                 mDisplayManager, mHandler, mConfigurationController, mSystemClock,
                 mUnlockedScreenOffAnimationController, mSystemUIDialogManager, mLatencyTracker,
                 mActivityLaunchAnimator, alternateTouchProvider, mBiometricExecutor,
-                mPrimaryBouncerInteractor, mSinglePointerTouchProcessor);
+                mPrimaryBouncerInteractor, mSinglePointerTouchProcessor,
+                mAlternateBouncerInteractor, mSecureSettings);
         verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture());
         mOverlayController = mOverlayCaptor.getValue();
         verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture());
@@ -406,7 +413,7 @@
         // GIVEN overlay was showing and the udfps bouncer is showing
         mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId,
                 BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
-        when(mStatusBarKeyguardViewManager.isShowingAlternateBouncer()).thenReturn(true);
+        when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
 
         // WHEN the overlay is hidden
         mOverlayController.hideUdfpsOverlay(mOpticalProps.sensorId);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerBaseTest.java
index 3c61382..9c32c38 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerBaseTest.java
@@ -30,6 +30,7 @@
 import com.android.systemui.flags.FakeFeatureFlags;
 import com.android.systemui.flags.Flags;
 import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shade.ShadeExpansionChangeEvent;
@@ -43,7 +44,6 @@
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.concurrency.DelayableExecutor;
-import com.android.systemui.util.time.FakeSystemClock;
 
 import org.junit.Before;
 import org.mockito.ArgumentCaptor;
@@ -73,9 +73,9 @@
     protected @Mock ActivityLaunchAnimator mActivityLaunchAnimator;
     protected @Mock KeyguardBouncer mBouncer;
     protected @Mock PrimaryBouncerInteractor mPrimaryBouncerInteractor;
+    protected @Mock AlternateBouncerInteractor mAlternateBouncerInteractor;
 
     protected FakeFeatureFlags mFeatureFlags = new FakeFeatureFlags();
-    protected FakeSystemClock mSystemClock = new FakeSystemClock();
 
     protected UdfpsKeyguardViewController mController;
 
@@ -86,10 +86,6 @@
     private @Captor ArgumentCaptor<ShadeExpansionListener> mExpansionListenerCaptor;
     protected List<ShadeExpansionListener> mExpansionListeners;
 
-    private @Captor ArgumentCaptor<StatusBarKeyguardViewManager.AlternateBouncer>
-            mAlternateBouncerCaptor;
-    protected StatusBarKeyguardViewManager.AlternateBouncer mAlternateBouncer;
-
     private @Captor ArgumentCaptor<KeyguardStateController.Callback>
             mKeyguardStateControllerCallbackCaptor;
     protected KeyguardStateController.Callback mKeyguardStateControllerCallback;
@@ -135,12 +131,6 @@
         }
     }
 
-    protected void captureAltAuthInterceptor() {
-        verify(mStatusBarKeyguardViewManager).setAlternateBouncer(
-                mAlternateBouncerCaptor.capture());
-        mAlternateBouncer = mAlternateBouncerCaptor.getValue();
-    }
-
     protected void captureKeyguardStateControllerCallback() {
         verify(mKeyguardStateController).addCallback(
                 mKeyguardStateControllerCallbackCaptor.capture());
@@ -160,6 +150,7 @@
     protected UdfpsKeyguardViewController createUdfpsKeyguardViewController(
             boolean useModernBouncer, boolean useExpandedOverlay) {
         mFeatureFlags.set(Flags.MODERN_BOUNCER, useModernBouncer);
+        mFeatureFlags.set(Flags.MODERN_ALTERNATE_BOUNCER, useModernBouncer);
         mFeatureFlags.set(Flags.UDFPS_NEW_TOUCH_DETECTION, useExpandedOverlay);
         when(mStatusBarKeyguardViewManager.getPrimaryBouncer()).thenReturn(
                 useModernBouncer ? null : mBouncer);
@@ -172,14 +163,14 @@
                 mDumpManager,
                 mLockscreenShadeTransitionController,
                 mConfigurationController,
-                mSystemClock,
                 mKeyguardStateController,
                 mUnlockedScreenOffAnimationController,
                 mDialogManager,
                 mUdfpsController,
                 mActivityLaunchAnimator,
                 mFeatureFlags,
-                mPrimaryBouncerInteractor);
+                mPrimaryBouncerInteractor,
+                mAlternateBouncerInteractor);
         return controller;
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
index babe533..7715f7f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
@@ -19,25 +19,22 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper.RunWithLooper;
+import android.testing.TestableLooper;
 import android.view.MotionEvent;
 
 import androidx.test.filters.SmallTest;
 
+import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback;
 import com.android.systemui.shade.ShadeExpansionListener;
 import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.phone.KeyguardBouncer;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -46,11 +43,12 @@
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
-@RunWithLooper
+
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
 public class UdfpsKeyguardViewControllerTest extends UdfpsKeyguardViewControllerBaseTest {
-    private @Captor ArgumentCaptor<KeyguardBouncer.PrimaryBouncerExpansionCallback>
+    private @Captor ArgumentCaptor<PrimaryBouncerExpansionCallback>
             mBouncerExpansionCallbackCaptor;
-    private KeyguardBouncer.PrimaryBouncerExpansionCallback mBouncerExpansionCallback;
+    private PrimaryBouncerExpansionCallback mBouncerExpansionCallback;
 
     @Override
     public UdfpsKeyguardViewController createUdfpsKeyguardViewController() {
@@ -72,8 +70,6 @@
         assertTrue(mController.shouldPauseAuth());
     }
 
-
-
     @Test
     public void testRegistersExpansionChangedListenerOnAttached() {
         mController.onViewAttached();
@@ -237,85 +233,9 @@
     public void testOverrideShouldPauseAuthOnShadeLocked() {
         mController.onViewAttached();
         captureStatusBarStateListeners();
-        captureAltAuthInterceptor();
 
         sendStatusBarStateChanged(StatusBarState.SHADE_LOCKED);
         assertTrue(mController.shouldPauseAuth());
-
-        mAlternateBouncer.showAlternateBouncer(); // force show
-        assertFalse(mController.shouldPauseAuth());
-        assertTrue(mAlternateBouncer.isShowingAlternateBouncer());
-
-        mAlternateBouncer.hideAlternateBouncer(); // stop force show
-        assertTrue(mController.shouldPauseAuth());
-        assertFalse(mAlternateBouncer.isShowingAlternateBouncer());
-    }
-
-    @Test
-    public void testOnDetachedStateReset() {
-        // GIVEN view is attached
-        mController.onViewAttached();
-        captureAltAuthInterceptor();
-
-        // WHEN view is detached
-        mController.onViewDetached();
-
-        // THEN remove alternate auth interceptor
-        verify(mStatusBarKeyguardViewManager).removeAlternateAuthInterceptor(mAlternateBouncer);
-    }
-
-    @Test
-    public void testHiddenUdfpsBouncerOnTouchOutside_nothingHappens() {
-        // GIVEN view is attached
-        mController.onViewAttached();
-        captureAltAuthInterceptor();
-
-        // GIVEN udfps bouncer isn't showing
-        mAlternateBouncer.hideAlternateBouncer();
-
-        // WHEN touch is observed outside the view
-        mController.onTouchOutsideView();
-
-        // THEN bouncer / alt auth methods are never called
-        verify(mStatusBarKeyguardViewManager, never()).showPrimaryBouncer(anyBoolean());
-        verify(mStatusBarKeyguardViewManager, never()).showBouncer(anyBoolean());
-        verify(mStatusBarKeyguardViewManager, never()).hideAlternateBouncer(anyBoolean());
-    }
-
-    @Test
-    public void testShowingUdfpsBouncerOnTouchOutsideWithinThreshold_nothingHappens() {
-        // GIVEN view is attached
-        mController.onViewAttached();
-        captureAltAuthInterceptor();
-
-        // GIVEN udfps bouncer is showing
-        mAlternateBouncer.showAlternateBouncer();
-
-        // WHEN touch is observed outside the view 200ms later (just within threshold)
-        mSystemClock.advanceTime(200);
-        mController.onTouchOutsideView();
-
-        // THEN bouncer / alt auth methods are never called because not enough time has passed
-        verify(mStatusBarKeyguardViewManager, never()).showPrimaryBouncer(anyBoolean());
-        verify(mStatusBarKeyguardViewManager, never()).showBouncer(anyBoolean());
-        verify(mStatusBarKeyguardViewManager, never()).hideAlternateBouncer(anyBoolean());
-    }
-
-    @Test
-    public void testShowingUdfpsBouncerOnTouchOutsideAboveThreshold_showPrimaryBouncer() {
-        // GIVEN view is attached
-        mController.onViewAttached();
-        captureAltAuthInterceptor();
-
-        // GIVEN udfps bouncer is showing
-        mAlternateBouncer.showAlternateBouncer();
-
-        // WHEN touch is observed outside the view 205ms later
-        mSystemClock.advanceTime(205);
-        mController.onTouchOutsideView();
-
-        // THEN show the bouncer
-        verify(mStatusBarKeyguardViewManager).showPrimaryBouncer(eq(true));
     }
 
     @Test
@@ -334,25 +254,6 @@
     }
 
     @Test
-    public void testShowUdfpsBouncer() {
-        // GIVEN view is attached and status bar expansion is 0
-        mController.onViewAttached();
-        captureStatusBarExpansionListeners();
-        captureKeyguardStateControllerCallback();
-        captureAltAuthInterceptor();
-        updateStatusBarExpansion(0, true);
-        reset(mView);
-        when(mView.getContext()).thenReturn(mResourceContext);
-        when(mResourceContext.getString(anyInt())).thenReturn("test string");
-
-        // WHEN status bar expansion is 0 but udfps bouncer is requested
-        mAlternateBouncer.showAlternateBouncer();
-
-        // THEN alpha is 255
-        verify(mView).setUnpausedAlpha(255);
-    }
-
-    @Test
     public void testTransitionToFullShadeProgress() {
         // GIVEN view is attached and status bar expansion is 1f
         mController.onViewAttached();
@@ -370,24 +271,6 @@
     }
 
     @Test
-    public void testShowUdfpsBouncer_transitionToFullShadeProgress() {
-        // GIVEN view is attached and status bar expansion is 1f
-        mController.onViewAttached();
-        captureStatusBarExpansionListeners();
-        captureKeyguardStateControllerCallback();
-        captureAltAuthInterceptor();
-        updateStatusBarExpansion(1f, true);
-        mAlternateBouncer.showAlternateBouncer();
-        reset(mView);
-
-        // WHEN we're transitioning to the full shade
-        mController.setTransitionToFullShadeProgress(1.0f);
-
-        // THEN alpha is 255 (b/c udfps bouncer is requested)
-        verify(mView).setUnpausedAlpha(255);
-    }
-
-    @Test
     public void testUpdatePanelExpansion_pauseAuth() {
         // GIVEN view is attached + on the keyguard
         mController.onViewAttached();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerWithCoroutinesTest.kt
index 2d412dc..9060922 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerWithCoroutinesTest.kt
@@ -21,26 +21,35 @@
 import android.testing.TestableLooper
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardSecurityModel
+import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.classifier.FalsingCollector
+import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.keyguard.DismissCallbackRegistry
 import com.android.systemui.keyguard.data.BouncerView
+import com.android.systemui.keyguard.data.repository.BiometricRepository
 import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepository
+import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor
+import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants
 import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.statusbar.StatusBarState
-import com.android.systemui.statusbar.phone.KeyguardBouncer
 import com.android.systemui.statusbar.phone.KeyguardBypassController
+import com.android.systemui.util.time.FakeSystemClock
+import com.android.systemui.util.time.SystemClock
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.test.TestCoroutineScope
 import kotlinx.coroutines.yield
+import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.any
 import org.mockito.Mock
 import org.mockito.Mockito.mock
+import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
 @RunWith(AndroidTestingRunner::class)
@@ -57,6 +66,7 @@
         keyguardBouncerRepository =
             KeyguardBouncerRepository(
                 mock(com.android.keyguard.ViewMediatorCallback::class.java),
+                FakeSystemClock(),
                 TestCoroutineScope(),
                 bouncerLogger,
             )
@@ -77,15 +87,43 @@
                 mock(KeyguardBypassController::class.java),
                 mKeyguardUpdateMonitor
             )
+        mAlternateBouncerInteractor =
+            AlternateBouncerInteractor(
+                keyguardBouncerRepository,
+                mock(BiometricRepository::class.java),
+                mock(SystemClock::class.java),
+                mock(KeyguardUpdateMonitor::class.java),
+                mock(FeatureFlags::class.java)
+            )
         return createUdfpsKeyguardViewController(
             /* useModernBouncer */ true, /* useExpandedOverlay */
             false
         )
     }
 
-    /** After migration, replaces LockIconViewControllerTest version */
     @Test
-    fun testShouldPauseAuthBouncerShowing() =
+    fun shadeLocked_showAlternateBouncer_unpauseAuth() =
+        runBlocking(IMMEDIATE) {
+            // GIVEN view is attached + on the SHADE_LOCKED (udfps view not showing)
+            mController.onViewAttached()
+            captureStatusBarStateListeners()
+            sendStatusBarStateChanged(StatusBarState.SHADE_LOCKED)
+
+            // WHEN alternate bouncer is requested
+            val job = mController.listenForAlternateBouncerVisibility(this)
+            keyguardBouncerRepository.setAlternateVisible(true)
+            yield()
+
+            // THEN udfps view will animate in & pause auth is updated to NOT pause
+            verify(mView).animateInUdfpsBouncer(any())
+            assertFalse(mController.shouldPauseAuth())
+
+            job.cancel()
+        }
+
+    /** After migration to MODERN_BOUNCER, replaces UdfpsKeyguardViewControllerTest version */
+    @Test
+    fun shouldPauseAuthBouncerShowing() =
         runBlocking(IMMEDIATE) {
             // GIVEN view attached and we're on the keyguard
             mController.onViewAttached()
@@ -95,7 +133,7 @@
             // WHEN the bouncer expansion is VISIBLE
             val job = mController.listenForBouncerExpansion(this)
             keyguardBouncerRepository.setPrimaryVisible(true)
-            keyguardBouncerRepository.setPanelExpansion(KeyguardBouncer.EXPANSION_VISIBLE)
+            keyguardBouncerRepository.setPanelExpansion(KeyguardBouncerConstants.EXPANSION_VISIBLE)
             yield()
 
             // THEN UDFPS shouldPauseAuth == true
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
index d550b92..8255a14 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
@@ -80,15 +80,6 @@
     }
 
     @Test
-    fun forwardsEvents() {
-        view.dozeTimeTick()
-        verify(animationViewController).dozeTimeTick()
-
-        view.onTouchOutsideView()
-        verify(animationViewController).onTouchOutsideView()
-    }
-
-    @Test
     fun layoutSizeFitsSensor() {
         val params = withArgCaptor<RectF> {
             verify(animationViewController).onSensorRectUpdated(capture())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetectorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetectorTest.kt
new file mode 100644
index 0000000..af46d9b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetectorTest.kt
@@ -0,0 +1,131 @@
+/*
+ * 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.biometrics.udfps
+
+import android.graphics.Point
+import android.graphics.Rect
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import org.junit.runners.Parameterized.Parameters
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.`when` as whenEver
+
+@SmallTest
+@RunWith(Parameterized::class)
+class EllipseOverlapDetectorTest(val testCase: TestCase) : SysuiTestCase() {
+    val underTest = spy(EllipseOverlapDetector(neededPoints = 1))
+
+    @Before
+    fun setUp() {
+        // Use one single center point for testing, required or total number of points may change
+        whenEver(underTest.calculateSensorPoints(SENSOR))
+            .thenReturn(listOf(Point(SENSOR.centerX(), SENSOR.centerY())))
+    }
+
+    @Test
+    fun isGoodOverlap() {
+        val touchData =
+            TOUCH_DATA.copy(
+                x = testCase.x.toFloat(),
+                y = testCase.y.toFloat(),
+                minor = testCase.minor,
+                major = testCase.major
+            )
+        val actual = underTest.isGoodOverlap(touchData, SENSOR)
+
+        assertThat(actual).isEqualTo(testCase.expected)
+    }
+
+    data class TestCase(
+        val x: Int,
+        val y: Int,
+        val minor: Float,
+        val major: Float,
+        val expected: Boolean
+    )
+
+    companion object {
+        @Parameters(name = "{0}")
+        @JvmStatic
+        fun data(): List<TestCase> =
+            listOf(
+                    genTestCases(
+                        innerXs = listOf(SENSOR.left, SENSOR.right, SENSOR.centerX()),
+                        innerYs = listOf(SENSOR.top, SENSOR.bottom, SENSOR.centerY()),
+                        outerXs = listOf(SENSOR.left - 1, SENSOR.right + 1),
+                        outerYs = listOf(SENSOR.top - 1, SENSOR.bottom + 1),
+                        minor = 300f,
+                        major = 300f,
+                        expected = true
+                    ),
+                    genTestCases(
+                        innerXs = listOf(SENSOR.left, SENSOR.right),
+                        innerYs = listOf(SENSOR.top, SENSOR.bottom),
+                        outerXs = listOf(SENSOR.left - 1, SENSOR.right + 1),
+                        outerYs = listOf(SENSOR.top - 1, SENSOR.bottom + 1),
+                        minor = 100f,
+                        major = 100f,
+                        expected = false
+                    )
+                )
+                .flatten()
+    }
+}
+
+/* Placeholder touch parameters. */
+private const val POINTER_ID = 42
+private const val NATIVE_MINOR = 2.71828f
+private const val NATIVE_MAJOR = 3.14f
+private const val ORIENTATION = 0f // used for perfect circles
+private const val TIME = 12345699L
+private const val GESTURE_START = 12345600L
+
+/* Template [NormalizedTouchData]. */
+private val TOUCH_DATA =
+    NormalizedTouchData(
+        POINTER_ID,
+        x = 0f,
+        y = 0f,
+        NATIVE_MINOR,
+        NATIVE_MAJOR,
+        ORIENTATION,
+        TIME,
+        GESTURE_START
+    )
+
+private val SENSOR = Rect(100 /* left */, 200 /* top */, 300 /* right */, 400 /* bottom */)
+
+private fun genTestCases(
+    innerXs: List<Int>,
+    innerYs: List<Int>,
+    outerXs: List<Int>,
+    outerYs: List<Int>,
+    minor: Float,
+    major: Float,
+    expected: Boolean
+): List<EllipseOverlapDetectorTest.TestCase> {
+    return (innerXs + outerXs).flatMap { x ->
+        (innerYs + outerYs).map { y ->
+            EllipseOverlapDetectorTest.TestCase(x, y, minor, major, expected)
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt
index 95c53b4..34ddf79 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt
@@ -39,7 +39,8 @@
 
     @Test
     fun processTouch() {
-        overlapDetector.shouldReturn = testCase.isGoodOverlap
+        overlapDetector.shouldReturn =
+            testCase.currentPointers.associate { pointer -> pointer.id to pointer.onSensor }
 
         val actual =
             underTest.processTouch(
@@ -56,7 +57,7 @@
 
     data class TestCase(
         val event: MotionEvent,
-        val isGoodOverlap: Boolean,
+        val currentPointers: List<TestPointer>,
         val previousPointerOnSensorId: Int,
         val overlayParams: UdfpsOverlayParams,
         val expected: TouchProcessorResult,
@@ -91,28 +92,21 @@
                     genPositiveTestCases(
                         motionEventAction = MotionEvent.ACTION_DOWN,
                         previousPointerOnSensorId = INVALID_POINTER_ID,
-                        isGoodOverlap = true,
+                        currentPointers = listOf(TestPointer(id = POINTER_ID_1, onSensor = true)),
                         expectedInteractionEvent = InteractionEvent.DOWN,
-                        expectedPointerOnSensorId = POINTER_ID,
-                    ),
-                    genPositiveTestCases(
-                        motionEventAction = MotionEvent.ACTION_DOWN,
-                        previousPointerOnSensorId = POINTER_ID,
-                        isGoodOverlap = true,
-                        expectedInteractionEvent = InteractionEvent.DOWN,
-                        expectedPointerOnSensorId = POINTER_ID,
+                        expectedPointerOnSensorId = POINTER_ID_1,
                     ),
                     genPositiveTestCases(
                         motionEventAction = MotionEvent.ACTION_DOWN,
                         previousPointerOnSensorId = INVALID_POINTER_ID,
-                        isGoodOverlap = false,
+                        currentPointers = listOf(TestPointer(id = POINTER_ID_1, onSensor = false)),
                         expectedInteractionEvent = InteractionEvent.UNCHANGED,
                         expectedPointerOnSensorId = INVALID_POINTER_ID,
                     ),
                     genPositiveTestCases(
                         motionEventAction = MotionEvent.ACTION_DOWN,
-                        previousPointerOnSensorId = POINTER_ID,
-                        isGoodOverlap = false,
+                        previousPointerOnSensorId = POINTER_ID_1,
+                        currentPointers = listOf(TestPointer(id = POINTER_ID_1, onSensor = false)),
                         expectedInteractionEvent = InteractionEvent.UP,
                         expectedPointerOnSensorId = INVALID_POINTER_ID,
                     ),
@@ -120,107 +114,232 @@
                     genPositiveTestCases(
                         motionEventAction = MotionEvent.ACTION_MOVE,
                         previousPointerOnSensorId = INVALID_POINTER_ID,
-                        isGoodOverlap = true,
+                        currentPointers = listOf(TestPointer(id = POINTER_ID_1, onSensor = true)),
                         expectedInteractionEvent = InteractionEvent.DOWN,
-                        expectedPointerOnSensorId = POINTER_ID,
+                        expectedPointerOnSensorId = POINTER_ID_1,
                     ),
                     genPositiveTestCases(
                         motionEventAction = MotionEvent.ACTION_MOVE,
-                        previousPointerOnSensorId = POINTER_ID,
-                        isGoodOverlap = true,
+                        previousPointerOnSensorId = POINTER_ID_1,
+                        currentPointers = listOf(TestPointer(id = POINTER_ID_1, onSensor = true)),
                         expectedInteractionEvent = InteractionEvent.UNCHANGED,
-                        expectedPointerOnSensorId = POINTER_ID,
+                        expectedPointerOnSensorId = POINTER_ID_1,
                     ),
                     genPositiveTestCases(
                         motionEventAction = MotionEvent.ACTION_MOVE,
                         previousPointerOnSensorId = INVALID_POINTER_ID,
-                        isGoodOverlap = false,
+                        currentPointers = listOf(TestPointer(id = POINTER_ID_1, onSensor = false)),
                         expectedInteractionEvent = InteractionEvent.UNCHANGED,
                         expectedPointerOnSensorId = INVALID_POINTER_ID,
                     ),
                     genPositiveTestCases(
                         motionEventAction = MotionEvent.ACTION_MOVE,
-                        previousPointerOnSensorId = POINTER_ID,
-                        isGoodOverlap = false,
+                        previousPointerOnSensorId = POINTER_ID_1,
+                        currentPointers = listOf(TestPointer(id = POINTER_ID_1, onSensor = false)),
                         expectedInteractionEvent = InteractionEvent.UP,
                         expectedPointerOnSensorId = INVALID_POINTER_ID,
                     ),
+                    genPositiveTestCases(
+                        motionEventAction = MotionEvent.ACTION_MOVE,
+                        previousPointerOnSensorId = INVALID_POINTER_ID,
+                        currentPointers =
+                            listOf(
+                                TestPointer(id = POINTER_ID_1, onSensor = false),
+                                TestPointer(id = POINTER_ID_2, onSensor = true)
+                            ),
+                        expectedInteractionEvent = InteractionEvent.DOWN,
+                        expectedPointerOnSensorId = POINTER_ID_2,
+                    ),
+                    genPositiveTestCases(
+                        motionEventAction = MotionEvent.ACTION_MOVE,
+                        previousPointerOnSensorId = POINTER_ID_1,
+                        currentPointers =
+                            listOf(
+                                TestPointer(id = POINTER_ID_1, onSensor = false),
+                                TestPointer(id = POINTER_ID_2, onSensor = true)
+                            ),
+                        expectedInteractionEvent = InteractionEvent.UNCHANGED,
+                        expectedPointerOnSensorId = POINTER_ID_2,
+                    ),
                     // MotionEvent.ACTION_UP
                     genPositiveTestCases(
                         motionEventAction = MotionEvent.ACTION_UP,
                         previousPointerOnSensorId = INVALID_POINTER_ID,
-                        isGoodOverlap = true,
+                        currentPointers = listOf(TestPointer(id = POINTER_ID_1, onSensor = true)),
                         expectedInteractionEvent = InteractionEvent.UP,
                         expectedPointerOnSensorId = INVALID_POINTER_ID,
                     ),
                     genPositiveTestCases(
                         motionEventAction = MotionEvent.ACTION_UP,
-                        previousPointerOnSensorId = POINTER_ID,
-                        isGoodOverlap = true,
+                        previousPointerOnSensorId = POINTER_ID_1,
+                        currentPointers = listOf(TestPointer(id = POINTER_ID_1, onSensor = true)),
                         expectedInteractionEvent = InteractionEvent.UP,
                         expectedPointerOnSensorId = INVALID_POINTER_ID,
                     ),
                     genPositiveTestCases(
                         motionEventAction = MotionEvent.ACTION_UP,
                         previousPointerOnSensorId = INVALID_POINTER_ID,
-                        isGoodOverlap = false,
+                        currentPointers = listOf(TestPointer(id = POINTER_ID_1, onSensor = false)),
                         expectedInteractionEvent = InteractionEvent.UNCHANGED,
                         expectedPointerOnSensorId = INVALID_POINTER_ID,
                     ),
-                    genPositiveTestCases(
-                        motionEventAction = MotionEvent.ACTION_UP,
-                        previousPointerOnSensorId = POINTER_ID,
-                        isGoodOverlap = false,
-                        expectedInteractionEvent = InteractionEvent.UP,
-                        expectedPointerOnSensorId = INVALID_POINTER_ID,
-                    ),
                     // MotionEvent.ACTION_CANCEL
                     genPositiveTestCases(
                         motionEventAction = MotionEvent.ACTION_CANCEL,
                         previousPointerOnSensorId = INVALID_POINTER_ID,
-                        isGoodOverlap = true,
+                        currentPointers = listOf(TestPointer(id = POINTER_ID_1, onSensor = true)),
                         expectedInteractionEvent = InteractionEvent.CANCEL,
                         expectedPointerOnSensorId = INVALID_POINTER_ID,
                     ),
                     genPositiveTestCases(
                         motionEventAction = MotionEvent.ACTION_CANCEL,
-                        previousPointerOnSensorId = POINTER_ID,
-                        isGoodOverlap = true,
+                        previousPointerOnSensorId = POINTER_ID_1,
+                        currentPointers = listOf(TestPointer(id = POINTER_ID_1, onSensor = true)),
                         expectedInteractionEvent = InteractionEvent.CANCEL,
                         expectedPointerOnSensorId = INVALID_POINTER_ID,
                     ),
                     genPositiveTestCases(
                         motionEventAction = MotionEvent.ACTION_CANCEL,
                         previousPointerOnSensorId = INVALID_POINTER_ID,
-                        isGoodOverlap = false,
+                        currentPointers = listOf(TestPointer(id = POINTER_ID_1, onSensor = false)),
                         expectedInteractionEvent = InteractionEvent.CANCEL,
                         expectedPointerOnSensorId = INVALID_POINTER_ID,
                     ),
                     genPositiveTestCases(
                         motionEventAction = MotionEvent.ACTION_CANCEL,
-                        previousPointerOnSensorId = POINTER_ID,
-                        isGoodOverlap = false,
+                        previousPointerOnSensorId = POINTER_ID_1,
+                        currentPointers = listOf(TestPointer(id = POINTER_ID_1, onSensor = false)),
                         expectedInteractionEvent = InteractionEvent.CANCEL,
                         expectedPointerOnSensorId = INVALID_POINTER_ID,
                     ),
+                    // MotionEvent.ACTION_POINTER_DOWN
+                    genPositiveTestCases(
+                        motionEventAction =
+                            MotionEvent.ACTION_POINTER_DOWN +
+                                (1 shl MotionEvent.ACTION_POINTER_INDEX_SHIFT),
+                        previousPointerOnSensorId = INVALID_POINTER_ID,
+                        currentPointers =
+                            listOf(
+                                TestPointer(id = POINTER_ID_1, onSensor = true),
+                                TestPointer(id = POINTER_ID_2, onSensor = false)
+                            ),
+                        expectedInteractionEvent = InteractionEvent.DOWN,
+                        expectedPointerOnSensorId = POINTER_ID_1,
+                    ),
+                    genPositiveTestCases(
+                        motionEventAction =
+                            MotionEvent.ACTION_POINTER_DOWN +
+                                (1 shl MotionEvent.ACTION_POINTER_INDEX_SHIFT),
+                        previousPointerOnSensorId = INVALID_POINTER_ID,
+                        currentPointers =
+                            listOf(
+                                TestPointer(id = POINTER_ID_1, onSensor = false),
+                                TestPointer(id = POINTER_ID_2, onSensor = true)
+                            ),
+                        expectedInteractionEvent = InteractionEvent.DOWN,
+                        expectedPointerOnSensorId = POINTER_ID_2
+                    ),
+                    genPositiveTestCases(
+                        motionEventAction =
+                            MotionEvent.ACTION_POINTER_DOWN +
+                                (1 shl MotionEvent.ACTION_POINTER_INDEX_SHIFT),
+                        previousPointerOnSensorId = POINTER_ID_1,
+                        currentPointers =
+                            listOf(
+                                TestPointer(id = POINTER_ID_1, onSensor = true),
+                                TestPointer(id = POINTER_ID_2, onSensor = false)
+                            ),
+                        expectedInteractionEvent = InteractionEvent.UNCHANGED,
+                        expectedPointerOnSensorId = POINTER_ID_1,
+                    ),
+                    // MotionEvent.ACTION_POINTER_UP
+                    genPositiveTestCases(
+                        motionEventAction =
+                            MotionEvent.ACTION_POINTER_UP +
+                                (1 shl MotionEvent.ACTION_POINTER_INDEX_SHIFT),
+                        previousPointerOnSensorId = INVALID_POINTER_ID,
+                        currentPointers =
+                            listOf(
+                                TestPointer(id = POINTER_ID_1, onSensor = false),
+                                TestPointer(id = POINTER_ID_2, onSensor = false)
+                            ),
+                        expectedInteractionEvent = InteractionEvent.UNCHANGED,
+                        expectedPointerOnSensorId = INVALID_POINTER_ID
+                    ),
+                    genPositiveTestCases(
+                        motionEventAction =
+                            MotionEvent.ACTION_POINTER_UP +
+                                (1 shl MotionEvent.ACTION_POINTER_INDEX_SHIFT),
+                        previousPointerOnSensorId = POINTER_ID_2,
+                        currentPointers =
+                            listOf(
+                                TestPointer(id = POINTER_ID_1, onSensor = false),
+                                TestPointer(id = POINTER_ID_2, onSensor = true)
+                            ),
+                        expectedInteractionEvent = InteractionEvent.UP,
+                        expectedPointerOnSensorId = INVALID_POINTER_ID
+                    ),
+                    genPositiveTestCases(
+                        motionEventAction = MotionEvent.ACTION_POINTER_UP,
+                        previousPointerOnSensorId = POINTER_ID_1,
+                        currentPointers =
+                            listOf(
+                                TestPointer(id = POINTER_ID_1, onSensor = true),
+                                TestPointer(id = POINTER_ID_2, onSensor = false)
+                            ),
+                        expectedInteractionEvent = InteractionEvent.UP,
+                        expectedPointerOnSensorId = INVALID_POINTER_ID
+                    ),
+                    genPositiveTestCases(
+                        motionEventAction =
+                            MotionEvent.ACTION_POINTER_UP +
+                                (1 shl MotionEvent.ACTION_POINTER_INDEX_SHIFT),
+                        previousPointerOnSensorId = POINTER_ID_1,
+                        currentPointers =
+                            listOf(
+                                TestPointer(id = POINTER_ID_1, onSensor = true),
+                                TestPointer(id = POINTER_ID_2, onSensor = false)
+                            ),
+                        expectedInteractionEvent = InteractionEvent.UNCHANGED,
+                        expectedPointerOnSensorId = POINTER_ID_1
+                    ),
+                    genPositiveTestCases(
+                        motionEventAction = MotionEvent.ACTION_POINTER_UP,
+                        previousPointerOnSensorId = POINTER_ID_2,
+                        currentPointers =
+                            listOf(
+                                TestPointer(id = POINTER_ID_1, onSensor = false),
+                                TestPointer(id = POINTER_ID_2, onSensor = true)
+                            ),
+                        expectedInteractionEvent = InteractionEvent.UNCHANGED,
+                        expectedPointerOnSensorId = POINTER_ID_2
+                    )
                 )
                 .flatten() +
                 listOf(
-                        // Unsupported MotionEvent actions.
-                        genTestCasesForUnsupportedAction(MotionEvent.ACTION_POINTER_DOWN),
-                        genTestCasesForUnsupportedAction(MotionEvent.ACTION_POINTER_UP),
                         genTestCasesForUnsupportedAction(MotionEvent.ACTION_HOVER_ENTER),
                         genTestCasesForUnsupportedAction(MotionEvent.ACTION_HOVER_MOVE),
-                        genTestCasesForUnsupportedAction(MotionEvent.ACTION_HOVER_EXIT),
+                        genTestCasesForUnsupportedAction(MotionEvent.ACTION_HOVER_EXIT)
                     )
                     .flatten()
     }
 }
 
+data class TestPointer(val id: Int, val onSensor: Boolean)
+
 /* Display dimensions in native resolution and natural orientation. */
 private const val ROTATION_0_NATIVE_DISPLAY_WIDTH = 400
 private const val ROTATION_0_NATIVE_DISPLAY_HEIGHT = 600
 
+/* Placeholder touch parameters. */
+private const val POINTER_ID_1 = 42
+private const val POINTER_ID_2 = 43
+private const val NATIVE_MINOR = 2.71828f
+private const val NATIVE_MAJOR = 3.14f
+private const val ORIENTATION = 1.2345f
+private const val TIME = 12345699L
+private const val GESTURE_START = 12345600L
+
 /*
  * ROTATION_0 map:
  * _ _ _ _
@@ -244,6 +363,7 @@
 private val ROTATION_0_INPUTS =
     OrientationBasedInputs(
         rotation = Surface.ROTATION_0,
+        nativeOrientation = ORIENTATION,
         nativeXWithinSensor = ROTATION_0_NATIVE_SENSOR_BOUNDS.exactCenterX(),
         nativeYWithinSensor = ROTATION_0_NATIVE_SENSOR_BOUNDS.exactCenterY(),
         nativeXOutsideSensor = 250f,
@@ -271,6 +391,7 @@
 private val ROTATION_90_INPUTS =
     OrientationBasedInputs(
         rotation = Surface.ROTATION_90,
+        nativeOrientation = (ORIENTATION - Math.PI.toFloat() / 2),
         nativeXWithinSensor = ROTATION_90_NATIVE_SENSOR_BOUNDS.exactCenterX(),
         nativeYWithinSensor = ROTATION_90_NATIVE_SENSOR_BOUNDS.exactCenterY(),
         nativeXOutsideSensor = 150f,
@@ -304,25 +425,18 @@
 private val ROTATION_270_INPUTS =
     OrientationBasedInputs(
         rotation = Surface.ROTATION_270,
+        nativeOrientation = (ORIENTATION + Math.PI.toFloat() / 2),
         nativeXWithinSensor = ROTATION_270_NATIVE_SENSOR_BOUNDS.exactCenterX(),
         nativeYWithinSensor = ROTATION_270_NATIVE_SENSOR_BOUNDS.exactCenterY(),
         nativeXOutsideSensor = 450f,
         nativeYOutsideSensor = 250f,
     )
 
-/* Placeholder touch parameters. */
-private const val POINTER_ID = 42
-private const val NATIVE_MINOR = 2.71828f
-private const val NATIVE_MAJOR = 3.14f
-private const val ORIENTATION = 1.23f
-private const val TIME = 12345699L
-private const val GESTURE_START = 12345600L
-
 /* Template [MotionEvent]. */
 private val MOTION_EVENT =
     obtainMotionEvent(
         action = 0,
-        pointerId = POINTER_ID,
+        pointerId = POINTER_ID_1,
         x = 0f,
         y = 0f,
         minor = 0f,
@@ -335,7 +449,7 @@
 /* Template [NormalizedTouchData]. */
 private val NORMALIZED_TOUCH_DATA =
     NormalizedTouchData(
-        POINTER_ID,
+        POINTER_ID_1,
         x = 0f,
         y = 0f,
         NATIVE_MINOR,
@@ -352,6 +466,7 @@
  */
 private data class OrientationBasedInputs(
     @Rotation val rotation: Int,
+    val nativeOrientation: Float,
     val nativeXWithinSensor: Float,
     val nativeYWithinSensor: Float,
     val nativeXOutsideSensor: Float,
@@ -380,7 +495,7 @@
 private fun genPositiveTestCases(
     motionEventAction: Int,
     previousPointerOnSensorId: Int,
-    isGoodOverlap: Boolean,
+    currentPointers: List<TestPointer>,
     expectedInteractionEvent: InteractionEvent,
     expectedPointerOnSensorId: Int
 ): List<SinglePointerTouchProcessorTest.TestCase> {
@@ -395,21 +510,47 @@
     return scaleFactors.flatMap { scaleFactor ->
         orientations.map { orientation ->
             val overlayParams = orientation.toOverlayParams(scaleFactor)
-            val nativeX = orientation.getNativeX(isGoodOverlap)
-            val nativeY = orientation.getNativeY(isGoodOverlap)
+
+            val pointerProperties =
+                currentPointers
+                    .map { pointer ->
+                        val pp = MotionEvent.PointerProperties()
+                        pp.id = pointer.id
+                        pp
+                    }
+                    .toList()
+
+            val pointerCoords =
+                currentPointers
+                    .map { pointer ->
+                        val pc = MotionEvent.PointerCoords()
+                        pc.x = orientation.getNativeX(pointer.onSensor) * scaleFactor
+                        pc.y = orientation.getNativeY(pointer.onSensor) * scaleFactor
+                        pc.touchMinor = NATIVE_MINOR * scaleFactor
+                        pc.touchMajor = NATIVE_MAJOR * scaleFactor
+                        pc.orientation = orientation.nativeOrientation
+                        pc
+                    }
+                    .toList()
+
             val event =
                 MOTION_EVENT.copy(
                     action = motionEventAction,
-                    x = nativeX * scaleFactor,
-                    y = nativeY * scaleFactor,
-                    minor = NATIVE_MINOR * scaleFactor,
-                    major = NATIVE_MAJOR * scaleFactor,
+                    pointerProperties = pointerProperties,
+                    pointerCoords = pointerCoords
                 )
+
             val expectedTouchData =
-                NORMALIZED_TOUCH_DATA.copy(
-                    x = ROTATION_0_INPUTS.getNativeX(isGoodOverlap),
-                    y = ROTATION_0_INPUTS.getNativeY(isGoodOverlap),
-                )
+                if (expectedPointerOnSensorId != INVALID_POINTER_ID) {
+                    NORMALIZED_TOUCH_DATA.copy(
+                        pointerId = expectedPointerOnSensorId,
+                        x = ROTATION_0_INPUTS.getNativeX(isWithinSensor = true),
+                        y = ROTATION_0_INPUTS.getNativeY(isWithinSensor = true)
+                    )
+                } else {
+                    NormalizedTouchData()
+                }
+
             val expected =
                 TouchProcessorResult.ProcessedTouch(
                     event = expectedInteractionEvent,
@@ -418,7 +559,7 @@
                 )
             SinglePointerTouchProcessorTest.TestCase(
                 event = event,
-                isGoodOverlap = isGoodOverlap,
+                currentPointers = currentPointers,
                 previousPointerOnSensorId = previousPointerOnSensorId,
                 overlayParams = overlayParams,
                 expected = expected,
@@ -431,7 +572,7 @@
     motionEventAction: Int
 ): List<SinglePointerTouchProcessorTest.TestCase> {
     val isGoodOverlap = true
-    val previousPointerOnSensorIds = listOf(INVALID_POINTER_ID, POINTER_ID)
+    val previousPointerOnSensorIds = listOf(INVALID_POINTER_ID, POINTER_ID_1)
     return previousPointerOnSensorIds.map { previousPointerOnSensorId ->
         val overlayParams = ROTATION_0_INPUTS.toOverlayParams(scaleFactor = 1f)
         val nativeX = ROTATION_0_INPUTS.getNativeX(isGoodOverlap)
@@ -446,7 +587,7 @@
             )
         SinglePointerTouchProcessorTest.TestCase(
             event = event,
-            isGoodOverlap = isGoodOverlap,
+            currentPointers = listOf(TestPointer(id = POINTER_ID_1, onSensor = isGoodOverlap)),
             previousPointerOnSensorId = previousPointerOnSensorId,
             overlayParams = overlayParams,
             expected = TouchProcessorResult.Failure(),
@@ -473,13 +614,23 @@
     pc.touchMinor = minor
     pc.touchMajor = major
     pc.orientation = orientation
+    return obtainMotionEvent(action, arrayOf(pp), arrayOf(pc), time, gestureStart)
+}
+
+private fun obtainMotionEvent(
+    action: Int,
+    pointerProperties: Array<MotionEvent.PointerProperties>,
+    pointerCoords: Array<MotionEvent.PointerCoords>,
+    time: Long,
+    gestureStart: Long,
+): MotionEvent {
     return MotionEvent.obtain(
         gestureStart /* downTime */,
         time /* eventTime */,
         action /* action */,
-        1 /* pointerCount */,
-        arrayOf(pp) /* pointerProperties */,
-        arrayOf(pc) /* pointerCoords */,
+        pointerCoords.size /* pointerCount */,
+        pointerProperties /* pointerProperties */,
+        pointerCoords /* pointerCoords */,
         0 /* metaState */,
         0 /* buttonState */,
         1f /* xPrecision */,
@@ -503,4 +654,19 @@
     gestureStart: Long = this.downTime,
 ) = obtainMotionEvent(action, pointerId, x, y, minor, major, orientation, time, gestureStart)
 
+private fun MotionEvent.copy(
+    action: Int = this.action,
+    pointerProperties: List<MotionEvent.PointerProperties>,
+    pointerCoords: List<MotionEvent.PointerCoords>,
+    time: Long = this.eventTime,
+    gestureStart: Long = this.downTime
+) =
+    obtainMotionEvent(
+        action,
+        pointerProperties.toTypedArray(),
+        pointerCoords.toTypedArray(),
+        time,
+        gestureStart
+    )
+
 private fun Rect.scaled(scaleFactor: Float) = Rect(this).apply { scale(scaleFactor) }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/camera/CameraGestureHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/camera/CameraGestureHelperTest.kt
index 262b4b8..80c3e5e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/camera/CameraGestureHelperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/camera/CameraGestureHelperTest.kt
@@ -28,6 +28,7 @@
 import com.android.systemui.ActivityIntentHelper
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.settings.UserTracker
 import com.android.systemui.statusbar.StatusBarState
 import com.android.systemui.statusbar.phone.CentralSurfaces
 import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -69,6 +70,8 @@
     lateinit var cameraIntents: CameraIntentsWrapper
     @Mock
     lateinit var contentResolver: ContentResolver
+    @Mock
+    lateinit var userTracker: UserTracker
 
     private lateinit var underTest: CameraGestureHelper
 
@@ -96,6 +99,7 @@
             cameraIntents = cameraIntents,
             contentResolver = contentResolver,
             uiExecutor = MoreExecutors.directExecutor(),
+            userTracker = userTracker,
         )
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt
index d159714..d6cafcb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt
@@ -16,18 +16,23 @@
 
 package com.android.systemui.charging
 
+import android.graphics.Rect
 import android.testing.AndroidTestingRunner
+import android.view.Surface
 import android.view.View
 import android.view.WindowManager
+import android.view.WindowMetrics
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.UiEventLogger
+import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
-import com.android.systemui.surfaceeffects.ripple.RippleView
 import com.android.systemui.statusbar.commandline.CommandRegistry
 import com.android.systemui.statusbar.policy.BatteryController
 import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.surfaceeffects.ripple.RippleView
+import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.FakeSystemClock
 import org.junit.Before
 import org.junit.Test
@@ -35,12 +40,12 @@
 import org.mockito.ArgumentCaptor
 import org.mockito.ArgumentMatchers
 import org.mockito.Mock
+import org.mockito.Mockito.`when`
 import org.mockito.Mockito.any
 import org.mockito.Mockito.eq
 import org.mockito.Mockito.never
 import org.mockito.Mockito.reset
 import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
 
 @SmallTest
@@ -54,6 +59,7 @@
     @Mock private lateinit var rippleView: RippleView
     @Mock private lateinit var windowManager: WindowManager
     @Mock private lateinit var uiEventLogger: UiEventLogger
+    @Mock private lateinit var windowMetrics: WindowMetrics
     private val systemClock = FakeSystemClock()
 
     @Before
@@ -66,6 +72,9 @@
         rippleView.setupShader()
         controller.rippleView = rippleView // Replace the real ripple view with a mock instance
         controller.registerCallbacks()
+
+        `when`(windowMetrics.bounds).thenReturn(Rect(0, 0, 100, 100))
+        `when`(windowManager.currentWindowMetrics).thenReturn(windowMetrics)
     }
 
     @Test
@@ -164,4 +173,63 @@
         verify(rippleView, never()).addOnAttachStateChangeListener(attachListenerCaptor.capture())
         verify(windowManager, never()).addView(eq(rippleView), any<WindowManager.LayoutParams>())
     }
+
+    @Test
+    fun testRipple_layoutsCorrectly() {
+        // Sets the correct ripple size.
+        val width = 100
+        val height = 200
+        whenever(windowMetrics.bounds).thenReturn(Rect(0, 0, width, height))
+
+        // Trigger ripple.
+        val captor = ArgumentCaptor
+                .forClass(BatteryController.BatteryStateChangeCallback::class.java)
+        verify(batteryController).addCallback(captor.capture())
+
+        captor.value.onBatteryLevelChanged(
+                /* unusedBatteryLevel= */ 0,
+                /* plugged in= */ true,
+                /* charging= */ false)
+
+        val attachListenerCaptor =
+                ArgumentCaptor.forClass(View.OnAttachStateChangeListener::class.java)
+        verify(rippleView).addOnAttachStateChangeListener(attachListenerCaptor.capture())
+        verify(windowManager).addView(eq(rippleView), any<WindowManager.LayoutParams>())
+
+        val runnableCaptor =
+                ArgumentCaptor.forClass(Runnable::class.java)
+        attachListenerCaptor.value.onViewAttachedToWindow(rippleView)
+        verify(rippleView).startRipple(runnableCaptor.capture())
+
+        // Verify size and center position.
+        val maxSize = 400f // Double the max value between width and height.
+        verify(rippleView).setMaxSize(maxWidth = maxSize, maxHeight = maxSize)
+
+        val normalizedPortPosX =
+                context.resources.getFloat(R.dimen.physical_charger_port_location_normalized_x)
+        val normalizedPortPosY =
+                context.resources.getFloat(R.dimen.physical_charger_port_location_normalized_y)
+        val expectedCenterX: Float
+        val expectedCenterY: Float
+        when (context.display.rotation) {
+            Surface.ROTATION_90 -> {
+                expectedCenterX = width * normalizedPortPosY
+                expectedCenterY = height * (1 - normalizedPortPosX)
+            }
+            Surface.ROTATION_180 -> {
+                expectedCenterX = width * (1 - normalizedPortPosX)
+                expectedCenterY = height * (1 - normalizedPortPosY)
+            }
+            Surface.ROTATION_270 -> {
+                expectedCenterX = width * (1 - normalizedPortPosY)
+                expectedCenterY = height * normalizedPortPosX
+            }
+            else -> { // Surface.ROTATION_0
+                expectedCenterX = width * normalizedPortPosX
+                expectedCenterY = height * normalizedPortPosY
+            }
+        }
+
+        verify(rippleView).setCenter(expectedCenterX, expectedCenterY)
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
index 0fadc13..e4df754 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
@@ -106,6 +106,7 @@
         mClassifiers.add(mClassifierB);
         when(mFalsingDataProvider.getRecentMotionEvents()).thenReturn(mMotionEventList);
         when(mKeyguardStateController.isShowing()).thenReturn(true);
+        when(mFalsingDataProvider.isFolded()).thenReturn(true);
         mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider,
                 mMetricsLogger, mClassifiers, mSingleTapClassfier, mLongTapClassifier,
                 mDoubleTapClassifier, mHistoryTracker, mKeyguardStateController,
@@ -121,6 +122,7 @@
         mGestureFinalizedListener = gestureCompleteListenerCaptor.getValue();
         mFakeFeatureFlags.set(Flags.FALSING_FOR_LONG_TAPS, true);
         mFakeFeatureFlags.set(Flags.MEDIA_FALSING_PENALTY, true);
+        mFakeFeatureFlags.set(Flags.FALSING_OFF_FOR_UNFOLDED, true);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
index 4281ee0..ae38eb6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
@@ -89,25 +89,27 @@
         mClassifiers.add(mClassifierA);
         when(mFalsingDataProvider.getRecentMotionEvents()).thenReturn(mMotionEventList);
         when(mKeyguardStateController.isShowing()).thenReturn(true);
+        when(mFalsingDataProvider.isFolded()).thenReturn(true);
         mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider,
                 mMetricsLogger, mClassifiers, mSingleTapClassifier, mLongTapClassifier,
                 mDoubleTapClassifier, mHistoryTracker, mKeyguardStateController,
                 mAccessibilityManager, false, mFakeFeatureFlags);
         mFakeFeatureFlags.set(Flags.FALSING_FOR_LONG_TAPS, true);
+        mFakeFeatureFlags.set(Flags.FALSING_OFF_FOR_UNFOLDED, true);
     }
 
     @Test
     public void testA11yDisablesGesture() {
-        assertThat(mBrightLineFalsingManager.isFalseTap(1)).isTrue();
+        assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isTrue();
         when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true);
-        assertThat(mBrightLineFalsingManager.isFalseTap(1)).isFalse();
+        assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isFalse();
     }
 
     @Test
     public void testA11yDisablesTap() {
-        assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isTrue();
+        assertThat(mBrightLineFalsingManager.isFalseTap(1)).isTrue();
         when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true);
-        assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isFalse();
+        assertThat(mBrightLineFalsingManager.isFalseTap(1)).isFalse();
     }
 
 
@@ -179,4 +181,11 @@
         when(mFalsingDataProvider.isA11yAction()).thenReturn(true);
         assertThat(mBrightLineFalsingManager.isFalseTap(1)).isFalse();
     }
+
+    @Test
+    public void testSkipUnfolded() {
+        assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isTrue();
+        when(mFalsingDataProvider.isFolded()).thenReturn(false);
+        assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isFalse();
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java
index 5fa7214..94cf384 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.classifier;
 
+import android.hardware.devicestate.DeviceStateManager.FoldStateListener;
 import android.util.DisplayMetrics;
 import android.view.MotionEvent;
 
@@ -38,6 +39,7 @@
     private float mOffsetY = 0;
     @Mock
     private BatteryController mBatteryController;
+    private FoldStateListener mFoldStateListener = new FoldStateListener(mContext);
     private final DockManagerFake mDockManager = new DockManagerFake();
 
     public void setup() {
@@ -47,7 +49,8 @@
         displayMetrics.ydpi = 100;
         displayMetrics.widthPixels = 1000;
         displayMetrics.heightPixels = 1000;
-        mDataProvider = new FalsingDataProvider(displayMetrics, mBatteryController, mDockManager);
+        mDataProvider = new FalsingDataProvider(
+                displayMetrics, mBatteryController, mFoldStateListener, mDockManager);
     }
 
     @After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
index d315c2d..c451a1e7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
@@ -24,6 +24,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.hardware.devicestate.DeviceStateManager.FoldStateListener;
 import android.testing.AndroidTestingRunner;
 import android.util.DisplayMetrics;
 import android.view.MotionEvent;
@@ -50,6 +51,8 @@
     private FalsingDataProvider mDataProvider;
     @Mock
     private BatteryController mBatteryController;
+    @Mock
+    private FoldStateListener mFoldStateListener;
     private final DockManagerFake mDockManager = new DockManagerFake();
 
     @Before
@@ -61,7 +64,8 @@
         displayMetrics.ydpi = 100;
         displayMetrics.widthPixels = 1000;
         displayMetrics.heightPixels = 1000;
-        mDataProvider = new FalsingDataProvider(displayMetrics, mBatteryController, mDockManager);
+        mDataProvider = new FalsingDataProvider(
+                displayMetrics, mBatteryController, mFoldStateListener, mDockManager);
     }
 
     @After
@@ -316,4 +320,16 @@
         mDataProvider.onA11yAction();
         assertThat(mDataProvider.isA11yAction()).isTrue();
     }
+
+    @Test
+    public void test_FoldedState_Folded() {
+        when(mFoldStateListener.getFolded()).thenReturn(true);
+        assertThat(mDataProvider.isFolded()).isTrue();
+    }
+
+    @Test
+    public void test_FoldedState_Unfolded() {
+        when(mFoldStateListener.getFolded()).thenReturn(false);
+        assertThat(mDataProvider.isFolded()).isFalse();
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/compose/ComposeInitializerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/compose/ComposeInitializerTest.kt
new file mode 100644
index 0000000..3e6cc3b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/compose/ComposeInitializerTest.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.compose
+
+import android.content.Context
+import android.testing.AndroidTestingRunner
+import android.testing.ViewUtils
+import android.widget.FrameLayout
+import androidx.compose.ui.platform.ComposeView
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class ComposeInitializerTest : SysuiTestCase() {
+    @Test
+    fun testCanAddComposeViewInInitializedWindow() {
+        if (!ComposeFacade.isComposeAvailable()) {
+            return
+        }
+
+        val root = TestWindowRoot(context)
+        try {
+            runOnMainThreadAndWaitForIdleSync { ViewUtils.attachView(root) }
+            assertThat(root.isAttachedToWindow).isTrue()
+
+            runOnMainThreadAndWaitForIdleSync { root.addView(ComposeView(context)) }
+        } finally {
+            runOnMainThreadAndWaitForIdleSync { ViewUtils.detachView(root) }
+        }
+    }
+
+    private fun runOnMainThreadAndWaitForIdleSync(f: () -> Unit) {
+        mContext.mainExecutor.execute(f)
+        waitForIdleSync()
+    }
+
+    class TestWindowRoot(context: Context) : FrameLayout(context) {
+        override fun onAttachedToWindow() {
+            super.onAttachedToWindow()
+            ComposeFacade.composeInitializer().onAttachedToWindow(this)
+        }
+
+        override fun onDetachedFromWindow() {
+            super.onDetachedFromWindow()
+            ComposeFacade.composeInitializer().onDetachedFromWindow(this)
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsBindingControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsBindingControllerImplTest.kt
index 0a81c38..ebbe096 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsBindingControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsBindingControllerImplTest.kt
@@ -269,6 +269,14 @@
     }
 
     @Test
+    fun testBindServiceForPanel() {
+        controller.bindServiceForPanel(TEST_COMPONENT_NAME_1)
+        executor.runAllReady()
+
+        verify(providers[0]).bindServiceForPanel()
+    }
+
+    @Test
     fun testSubscribe() {
         val controlInfo1 = ControlInfo("id_1", "", "", DeviceTypes.TYPE_UNKNOWN)
         val controlInfo2 = ControlInfo("id_2", "", "", DeviceTypes.TYPE_UNKNOWN)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt
index 1b34706..25f471b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt
@@ -919,6 +919,12 @@
             .getFile(ControlsFavoritePersistenceWrapper.FILE_NAME, context.user.identifier)
         assertThat(userStructure.file).isNotNull()
     }
+
+    @Test
+    fun testBindForPanel() {
+        controller.bindComponentForPanel(TEST_COMPONENT)
+        verify(bindingController).bindServiceForPanel(TEST_COMPONENT)
+    }
 }
 
 private class DidRunRunnable() : Runnable {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt
index af3f24a..da548f7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt
@@ -105,6 +105,22 @@
     }
 
     @Test
+    fun testBindForPanel() {
+        manager.bindServiceForPanel()
+        executor.runAllReady()
+        assertTrue(context.isBound(componentName))
+    }
+
+    @Test
+    fun testUnbindPanelIsUnbound() {
+        manager.bindServiceForPanel()
+        executor.runAllReady()
+        manager.unbindService()
+        executor.runAllReady()
+        assertFalse(context.isBound(componentName))
+    }
+
+    @Test
     fun testNullBinding() {
         val mockContext = mock(Context::class.java)
         lateinit var serviceConnection: ServiceConnection
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
index d172c9a..edc6882 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
@@ -229,6 +229,15 @@
     }
 
     @Test
+    fun testPanelBindsForPanel() {
+        val panel = SelectedItem.PanelItem("App name", ComponentName("pkg", "cls"))
+        setUpPanel(panel)
+
+        underTest.show(parent, {}, context)
+        verify(controlsController).bindComponentForPanel(panel.componentName)
+    }
+
+    @Test
     fun testPanelCallsTaskViewFactoryCreate() {
         mockLayoutInflater()
         val panel = SelectedItem.PanelItem("App name", ComponentName("pkg", "cls"))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java
index 5c2b153..af027e8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java
@@ -26,6 +26,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityManager;
 import android.hardware.display.AmbientDisplayConfiguration;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper.RunWithLooper;
@@ -36,6 +37,7 @@
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.dock.DockManagerFake;
 import com.android.systemui.doze.DozeMachine.State;
+import com.android.systemui.settings.UserTracker;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -48,6 +50,7 @@
 @RunWithLooper
 public class DozeDockHandlerTest extends SysuiTestCase {
     @Mock private DozeMachine mMachine;
+    @Mock private UserTracker mUserTracker;
     private AmbientDisplayConfiguration mConfig;
     private DockManagerFake mDockManagerFake;
     private DozeDockHandler mDockHandler;
@@ -57,9 +60,10 @@
         MockitoAnnotations.initMocks(this);
         mConfig = DozeConfigurationUtil.createMockConfig();
         mDockManagerFake = spy(new DockManagerFake());
-        mDockHandler = new DozeDockHandler(mConfig, mDockManagerFake);
+        mDockHandler = new DozeDockHandler(mConfig, mDockManagerFake, mUserTracker);
         mDockHandler.setDozeMachine(mMachine);
 
+        when(mUserTracker.getUserId()).thenReturn(ActivityManager.getCurrentUser());
         when(mMachine.getState()).thenReturn(State.DOZE_AOD);
         doReturn(true).when(mConfig).alwaysOnEnabled(anyInt());
         mDockHandler.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
index 5bbd810..a636b7f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
@@ -45,6 +45,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityManager;
 import android.content.res.Configuration;
 import android.hardware.display.AmbientDisplayConfiguration;
 import android.testing.AndroidTestingRunner;
@@ -57,6 +58,7 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.util.wakelock.WakeLockFake;
 
@@ -85,6 +87,8 @@
     private DozeMachine.Part mPartMock;
     @Mock
     private DozeMachine.Part mAnotherPartMock;
+    @Mock
+    private UserTracker mUserTracker;
     private DozeServiceFake mServiceFake;
     private WakeLockFake mWakeLockFake;
     private AmbientDisplayConfiguration mAmbientDisplayConfigMock;
@@ -97,6 +101,7 @@
         mAmbientDisplayConfigMock = mock(AmbientDisplayConfiguration.class);
         when(mDockManager.isDocked()).thenReturn(false);
         when(mDockManager.isHidden()).thenReturn(false);
+        when(mUserTracker.getUserId()).thenReturn(ActivityManager.getCurrentUser());
 
         mMachine = new DozeMachine(mServiceFake,
                 mAmbientDisplayConfigMock,
@@ -105,7 +110,8 @@
                 mDozeLog,
                 mDockManager,
                 mHost,
-                new DozeMachine.Part[]{mPartMock, mAnotherPartMock});
+                new DozeMachine.Part[]{mPartMock, mAnotherPartMock},
+                mUserTracker);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
index 03827da..3af444a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
@@ -34,6 +34,7 @@
 import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.reset;
@@ -57,6 +58,7 @@
 import com.android.systemui.util.concurrency.FakeThreadFactory;
 import com.android.systemui.util.sensors.AsyncSensorManager;
 import com.android.systemui.util.sensors.FakeSensorManager;
+import com.android.systemui.util.settings.SystemSettings;
 import com.android.systemui.util.time.FakeSystemClock;
 
 import org.junit.Before;
@@ -94,6 +96,8 @@
     DevicePostureController mDevicePostureController;
     @Mock
     DozeLog mDozeLog;
+    @Mock
+    SystemSettings mSystemSettings;
     private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
     private FakeThreadFactory mFakeThreadFactory = new FakeThreadFactory(mFakeExecutor);
 
@@ -102,9 +106,8 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        Settings.System.putIntForUser(mContext.getContentResolver(),
-                Settings.System.SCREEN_BRIGHTNESS, DEFAULT_BRIGHTNESS,
-                UserHandle.USER_CURRENT);
+        when(mSystemSettings.getIntForUser(eq(Settings.System.SCREEN_BRIGHTNESS), anyInt(),
+                eq(UserHandle.USER_CURRENT))).thenReturn(DEFAULT_BRIGHTNESS);
         doAnswer(invocation -> {
             ((Runnable) invocation.getArgument(0)).run();
             return null;
@@ -131,7 +134,8 @@
                 mWakefulnessLifecycle,
                 mDozeParameters,
                 mDevicePostureController,
-                mDozeLog);
+                mDozeLog,
+                mSystemSettings);
     }
 
     @Test
@@ -157,11 +161,10 @@
     }
 
     @Test
-    public void testAod_usesLightSensorRespectingUserSetting() throws Exception {
+    public void testAod_usesLightSensorRespectingUserSetting() {
         int maxBrightness = 3;
-        Settings.System.putIntForUser(mContext.getContentResolver(),
-                Settings.System.SCREEN_BRIGHTNESS, maxBrightness,
-                UserHandle.USER_CURRENT);
+        when(mSystemSettings.getIntForUser(eq(Settings.System.SCREEN_BRIGHTNESS), anyInt(),
+                eq(UserHandle.USER_CURRENT))).thenReturn(maxBrightness);
 
         mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
         assertEquals(maxBrightness, mServiceFake.screenBrightness);
@@ -238,7 +241,8 @@
                 mWakefulnessLifecycle,
                 mDozeParameters,
                 mDevicePostureController,
-                mDozeLog);
+                mDozeLog,
+                mSystemSettings);
         mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
         mScreen.transitionTo(INITIALIZED, DOZE);
         reset(mDozeHost);
@@ -275,7 +279,8 @@
                 mWakefulnessLifecycle,
                 mDozeParameters,
                 mDevicePostureController,
-                mDozeLog);
+                mDozeLog,
+                mSystemSettings);
 
         mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
         mScreen.transitionTo(INITIALIZED, DOZE_AOD);
@@ -306,7 +311,8 @@
                 mWakefulnessLifecycle,
                 mDozeParameters,
                 mDevicePostureController,
-                mDozeLog);
+                mDozeLog,
+                mSystemSettings);
 
         // GIVEN the device is in AOD
         mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
@@ -344,7 +350,8 @@
                 mWakefulnessLifecycle,
                 mDozeParameters,
                 mDevicePostureController,
-                mDozeLog);
+                mDozeLog,
+                mSystemSettings);
 
         // GIVEN device is in AOD
         mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
@@ -386,7 +393,8 @@
                 mWakefulnessLifecycle,
                 mDozeParameters,
                 mDevicePostureController,
-                mDozeLog);
+                mDozeLog,
+                mSystemSettings);
         verify(mDevicePostureController).addCallback(postureCallbackCaptor.capture());
 
         // GIVEN device is in AOD
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
index d910a27..986d6d5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
@@ -35,11 +35,11 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityManager;
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.hardware.Sensor;
 import android.hardware.display.AmbientDisplayConfiguration;
-import android.os.UserHandle;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
@@ -120,11 +120,13 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mTestableLooper = TestableLooper.get(this);
+        when(mUserTracker.getUserId()).thenReturn(ActivityManager.getCurrentUser());
         when(mAmbientDisplayConfiguration.tapSensorTypeMapping())
                 .thenReturn(new String[]{"tapSensor"});
         when(mAmbientDisplayConfiguration.getWakeLockScreenDebounce()).thenReturn(5000L);
         when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(true);
-        when(mAmbientDisplayConfiguration.enabled(UserHandle.USER_CURRENT)).thenReturn(true);
+        when(mAmbientDisplayConfiguration.enabled(ActivityManager.getCurrentUser())).thenReturn(
+                true);
         doAnswer(invocation -> {
             ((Runnable) invocation.getArgument(0)).run();
             return null;
@@ -144,7 +146,7 @@
 
     @Test
     public void testSensorDebounce() {
-        mDozeSensors.setListening(true, true);
+        mDozeSensors.setListening(true, true, true);
 
         mWakeLockScreenListener.onSensorChanged(mock(SensorManagerPlugin.SensorEvent.class));
         mTestableLooper.processAllMessages();
@@ -162,7 +164,7 @@
     @Test
     public void testSetListening_firstTrue_registerSettingsObserver() {
         verify(mSensorManager, never()).registerListener(any(), any(Sensor.class), anyInt());
-        mDozeSensors.setListening(true, true);
+        mDozeSensors.setListening(true, true, true);
 
         verify(mTriggerSensor).registerSettingsObserver(any(ContentObserver.class));
     }
@@ -170,8 +172,8 @@
     @Test
     public void testSetListening_twiceTrue_onlyRegisterSettingsObserverOnce() {
         verify(mSensorManager, never()).registerListener(any(), any(Sensor.class), anyInt());
-        mDozeSensors.setListening(true, true);
-        mDozeSensors.setListening(true, true);
+        mDozeSensors.setListening(true, true, true);
+        mDozeSensors.setListening(true, true, true);
 
         verify(mTriggerSensor, times(1)).registerSettingsObserver(any(ContentObserver.class));
     }
@@ -196,7 +198,7 @@
         assertFalse(mSensorTap.mRequested);
 
         // WHEN we're now in a low powered state
-        dozeSensors.setListening(true, true, true);
+        dozeSensors.setListeningWithPowerState(true, true, true, true);
 
         // THEN the tap sensor is registered
         assertTrue(mSensorTap.mRequested);
@@ -207,12 +209,12 @@
         // GIVEN doze sensors enabled
         when(mAmbientDisplayConfiguration.enabled(anyInt())).thenReturn(true);
 
-        // GIVEN a trigger sensor
+        // GIVEN a trigger sensor that's enabled by settings
         Sensor mockSensor = mock(Sensor.class);
-        TriggerSensor triggerSensor = mDozeSensors.createDozeSensor(
+        TriggerSensor triggerSensor = mDozeSensors.createDozeSensorWithSettingEnabled(
                 mockSensor,
-                /* settingEnabled */ true,
-                /* requiresTouchScreen */ true);
+                /* settingEnabled */ true
+        );
         when(mSensorManager.requestTriggerSensor(eq(triggerSensor), eq(mockSensor)))
                 .thenReturn(true);
 
@@ -228,12 +230,12 @@
         // GIVEN doze sensors enabled
         when(mAmbientDisplayConfiguration.enabled(anyInt())).thenReturn(true);
 
-        // GIVEN a trigger sensor
+        // GIVEN a trigger sensor that's not enabled by settings
         Sensor mockSensor = mock(Sensor.class);
-        TriggerSensor triggerSensor = mDozeSensors.createDozeSensor(
+        TriggerSensor triggerSensor = mDozeSensors.createDozeSensorWithSettingEnabled(
                 mockSensor,
-                /* settingEnabled*/ false,
-                /* requiresTouchScreen */ true);
+                /* settingEnabled*/ false
+        );
         when(mSensorManager.requestTriggerSensor(eq(triggerSensor), eq(mockSensor)))
                 .thenReturn(true);
 
@@ -249,12 +251,12 @@
         // GIVEN doze sensors enabled
         when(mAmbientDisplayConfiguration.enabled(anyInt())).thenReturn(true);
 
-        // GIVEN a trigger sensor that's
+        // GIVEN a trigger sensor that's not enabled by settings
         Sensor mockSensor = mock(Sensor.class);
-        TriggerSensor triggerSensor = mDozeSensors.createDozeSensor(
+        TriggerSensor triggerSensor = mDozeSensors.createDozeSensorWithSettingEnabled(
                 mockSensor,
-                /* settingEnabled*/ false,
-                /* requiresTouchScreen */ true);
+                /* settingEnabled*/ false
+        );
         when(mSensorManager.requestTriggerSensor(eq(triggerSensor), eq(mockSensor)))
                 .thenReturn(true);
 
@@ -264,7 +266,7 @@
         // WHEN ignoreSetting is called
         triggerSensor.ignoreSetting(true);
 
-        // THEN the sensor is registered
+        // THEN the sensor is still registered since the setting is ignore
         assertTrue(triggerSensor.mRegistered);
     }
 
@@ -275,10 +277,10 @@
 
         // GIVEN a trigger sensor
         Sensor mockSensor = mock(Sensor.class);
-        TriggerSensor triggerSensor = mDozeSensors.createDozeSensor(
+        TriggerSensor triggerSensor = mDozeSensors.createDozeSensorWithSettingEnabled(
                 mockSensor,
-                /* settingEnabled*/ true,
-                /* requiresTouchScreen */ true);
+                /* settingEnabled*/ true
+        );
         when(mSensorManager.requestTriggerSensor(eq(triggerSensor), eq(mockSensor)))
                 .thenReturn(true);
 
@@ -295,7 +297,7 @@
         // GIVEN doze sensor that supports postures
         Sensor closedSensor = createSensor(Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT);
         Sensor openedSensor = createSensor(Sensor.TYPE_PROXIMITY, Sensor.STRING_TYPE_LIGHT);
-        TriggerSensor triggerSensor = mDozeSensors.createDozeSensor(
+        TriggerSensor triggerSensor = mDozeSensors.createDozeSensorForPosture(
                 new Sensor[] {
                         null /* unknown */,
                         closedSensor,
@@ -316,7 +318,7 @@
         // GIVEN doze sensor that supports postures
         Sensor closedSensor = createSensor(Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT);
         Sensor openedSensor = createSensor(Sensor.TYPE_PROXIMITY, Sensor.STRING_TYPE_LIGHT);
-        TriggerSensor triggerSensor = mDozeSensors.createDozeSensor(
+        TriggerSensor triggerSensor = mDozeSensors.createDozeSensorForPosture(
                 new Sensor[] {
                         null /* unknown */,
                         closedSensor,
@@ -345,7 +347,7 @@
         // GIVEN doze sensor that supports postures
         Sensor closedSensor = createSensor(Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT);
         Sensor openedSensor = createSensor(Sensor.TYPE_PROXIMITY, Sensor.STRING_TYPE_LIGHT);
-        TriggerSensor triggerSensor = mDozeSensors.createDozeSensor(
+        TriggerSensor triggerSensor = mDozeSensors.createDozeSensorForPosture(
                 new Sensor[] {
                         null /* unknown */,
                         closedSensor,
@@ -400,7 +402,7 @@
     public void testUdfpsEnrollmentChanged() throws Exception {
         // GIVEN a UDFPS_LONG_PRESS trigger sensor that's not configured
         Sensor mockSensor = mock(Sensor.class);
-        TriggerSensor triggerSensor = mDozeSensors.createDozeSensor(
+        TriggerSensor triggerSensor = mDozeSensors.createDozeSensorForPosture(
                 mockSensor,
                 REASON_SENSOR_UDFPS_LONG_PRESS,
                 /* configured */ false);
@@ -409,7 +411,7 @@
                 .thenReturn(true);
 
         // WHEN listening state is set to TRUE
-        mDozeSensors.setListening(true, true);
+        mDozeSensors.setListening(true, true, true);
 
         // THEN mRegistered is still false b/c !mConfigured
         assertFalse(triggerSensor.mConfigured);
@@ -439,6 +441,35 @@
     }
 
     @Test
+    public void aodOnlySensor_onlyRegisteredWhenAodSensorsIncluded() {
+        // GIVEN doze sensors enabled
+        when(mAmbientDisplayConfiguration.enabled(anyInt())).thenReturn(true);
+
+        // GIVEN a trigger sensor that requires aod
+        Sensor mockSensor = mock(Sensor.class);
+        TriggerSensor aodOnlyTriggerSensor = mDozeSensors.createDozeSensorRequiringAod(mockSensor);
+        when(mSensorManager.requestTriggerSensor(eq(aodOnlyTriggerSensor), eq(mockSensor)))
+                .thenReturn(true);
+        mDozeSensors.addSensor(aodOnlyTriggerSensor);
+
+        // WHEN aod only sensors aren't included
+        mDozeSensors.setListening(/* listen */ true, /* includeTouchScreenSensors */true,
+                /* includeAodOnlySensors */false);
+
+        // THEN the sensor is not registered or requested
+        assertFalse(aodOnlyTriggerSensor.mRequested);
+        assertFalse(aodOnlyTriggerSensor.mRegistered);
+
+        // WHEN aod only sensors ARE included
+        mDozeSensors.setListening(/* listen */ true, /* includeTouchScreenSensors */true,
+                /* includeAodOnlySensors */true);
+
+        // THEN the sensor is registered and requested
+        assertTrue(aodOnlyTriggerSensor.mRequested);
+        assertTrue(aodOnlyTriggerSensor.mRegistered);
+    }
+
+    @Test
     public void liftToWake_defaultSetting_configDefaultFalse() {
         // WHEN the default lift to wake gesture setting is false
         when(mResources.getBoolean(
@@ -494,8 +525,8 @@
             mTriggerSensors = new TriggerSensor[] {mTriggerSensor, mSensorTap};
         }
 
-        public TriggerSensor createDozeSensor(Sensor sensor, boolean settingEnabled,
-                boolean requiresTouchScreen) {
+        public TriggerSensor createDozeSensorWithSettingEnabled(Sensor sensor,
+                boolean settingEnabled) {
             return new TriggerSensor(/* sensor */ sensor,
                     /* setting name */ "test_setting",
                     /* settingDefault */ settingEnabled,
@@ -504,11 +535,13 @@
                     /* reportsTouchCoordinate*/ false,
                     /* requiresTouchscreen */ false,
                     /* ignoresSetting */ false,
-                    requiresTouchScreen,
-                    /* immediatelyReRegister */ true);
+                    /* requiresProx */ false,
+                    /* immediatelyReRegister */ true,
+                    /* requiresAod */false
+            );
         }
 
-        public TriggerSensor createDozeSensor(
+        public TriggerSensor createDozeSensorForPosture(
                 Sensor sensor,
                 int pulseReason,
                 boolean configured
@@ -522,15 +555,35 @@
                     /* requiresTouchscreen */ false,
                     /* ignoresSetting */ false,
                     /* requiresTouchScreen */ false,
-                    /* immediatelyReRegister*/ true);
+                    /* immediatelyReRegister*/ true,
+                    false
+            );
         }
 
         /**
-         * create a doze sensor that supports postures and is enabled
+         * Create a doze sensor that requires Aod
          */
-        public TriggerSensor createDozeSensor(Sensor[] sensors, int posture) {
+        public TriggerSensor createDozeSensorRequiringAod(Sensor sensor) {
+            return new TriggerSensor(/* sensor */ sensor,
+                    /* setting name */ "aod_requiring_sensor",
+                    /* settingDefault */ true,
+                    /* configured */ true,
+                    /* pulseReason*/ 0,
+                    /* reportsTouchCoordinate*/ false,
+                    /* requiresTouchscreen */ false,
+                    /* ignoresSetting */ false,
+                    /* requiresProx */ false,
+                    /* immediatelyReRegister */ true,
+                    /* requiresAoD */ true
+            );
+        }
+
+        /**
+         * Create a doze sensor that supports postures and is enabled
+         */
+        public TriggerSensor createDozeSensorForPosture(Sensor[] sensors, int posture) {
             return new TriggerSensor(/* sensor */ sensors,
-                    /* setting name */ "test_setting",
+                    /* setting name */ "posture_test_setting",
                     /* settingDefault */ true,
                     /* configured */ true,
                     /* pulseReason*/ 0,
@@ -539,7 +592,9 @@
                     /* ignoresSetting */ true,
                     /* requiresProx */ false,
                     /* immediatelyReRegister */ true,
-                    posture);
+                    posture,
+                    /* requiresUi */ false
+            );
         }
 
         public void addSensor(TriggerSensor sensor) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuppressorTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuppressorTest.java
index 32b9945..9064470 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuppressorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuppressorTest.java
@@ -36,6 +36,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityManager;
 import android.hardware.display.AmbientDisplayConfiguration;
 import android.testing.AndroidTestingRunner;
 import android.testing.UiThreadTest;
@@ -43,6 +44,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.phone.BiometricUnlockController;
 
 import org.junit.After;
@@ -73,6 +75,8 @@
     private Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
     @Mock
     private BiometricUnlockController mBiometricUnlockController;
+    @Mock
+    private UserTracker mUserTracker;
 
     @Mock
     private DozeMachine mDozeMachine;
@@ -89,12 +93,14 @@
         when(mBiometricUnlockControllerLazy.get()).thenReturn(mBiometricUnlockController);
         when(mBiometricUnlockController.hasPendingAuthentication()).thenReturn(false);
         when(mDozeHost.isProvisioned()).thenReturn(true);
+        when(mUserTracker.getUserId()).thenReturn(ActivityManager.getCurrentUser());
 
         mDozeSuppressor = new DozeSuppressor(
                 mDozeHost,
                 mConfig,
                 mDozeLog,
-                mBiometricUnlockControllerLazy);
+                mBiometricUnlockControllerLazy,
+                mUserTracker);
 
         mDozeSuppressor.setDozeMachine(mDozeMachine);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
index b66a454..3552399 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -395,6 +395,14 @@
         verify(mAuthController).onAodInterrupt(anyInt(), anyInt(), anyFloat(), anyFloat());
     }
 
+
+    @Test
+    public void udfpsLongPress_dozeState_notRegistered() {
+        // GIVEN device is DOZE_AOD_PAUSED
+        when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE);
+        // beverlyt
+    }
+
     private void waitForSensorManager() {
         mExecutor.runAllReady();
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
index 2799a25..ff883eb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
@@ -37,9 +37,9 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.dreams.complication.ComplicationHostViewController;
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor;
+import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback;
 import com.android.systemui.statusbar.BlurUtils;
 import com.android.systemui.statusbar.phone.KeyguardBouncer;
-import com.android.systemui.statusbar.phone.KeyguardBouncer.PrimaryBouncerExpansionCallback;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
index 4568d1e..3b8bb80 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
@@ -234,6 +234,32 @@
     }
 
     @Test
+    public void testOnEndDream() throws RemoteException {
+        final IBinder proxy = mService.onBind(new Intent());
+        final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy);
+
+        // Inform the overlay service of dream starting.
+        overlay.startDream(mWindowParams, mDreamOverlayCallback,
+                LOW_LIGHT_COMPONENT.flattenToString(), false /*shouldShowComplication*/);
+        mMainExecutor.runAllReady();
+
+        // Verify view added.
+        verify(mWindowManager).addView(mViewCaptor.capture(), any());
+
+        // Service destroyed.
+        mService.onEndDream();
+        mMainExecutor.runAllReady();
+
+        // Verify view removed.
+        verify(mWindowManager).removeView(mViewCaptor.getValue());
+
+        // Verify state correctly set.
+        verify(mStateController).setOverlayActive(false);
+        verify(mStateController).setLowLightActive(false);
+        verify(mStateController).setEntryAnimationsFinished(false);
+    }
+
+    @Test
     public void testDestroy() throws RemoteException {
         final IBinder proxy = mService.onBind(new Intent());
         final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
index 85c2819..596b903 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
@@ -31,6 +31,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityManager;
 import android.app.AlarmManager;
 import android.content.Context;
 import android.content.res.Resources;
@@ -47,6 +48,7 @@
 
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController;
 import com.android.systemui.statusbar.policy.NextAlarmController;
 import com.android.systemui.statusbar.policy.ZenModeController;
@@ -109,6 +111,8 @@
     View mStatusBarItemView;
     @Mock
     DreamOverlayStateController mDreamOverlayStateController;
+    @Mock
+    UserTracker mUserTracker;
 
     @Captor
     private ArgumentCaptor<DreamOverlayStateController.Callback> mCallbackCaptor;
@@ -125,6 +129,7 @@
                 .thenReturn(NOTIFICATION_INDICATOR_FORMATTER_STRING);
         doCallRealMethod().when(mView).setVisibility(anyInt());
         doCallRealMethod().when(mView).getVisibility();
+        when(mUserTracker.getUserId()).thenReturn(ActivityManager.getCurrentUser());
 
         mController = new DreamOverlayStatusBarViewController(
                 mView,
@@ -140,7 +145,8 @@
                 mZenModeController,
                 mStatusBarWindowStateController,
                 mDreamOverlayStatusBarItemsProvider,
-                mDreamOverlayStateController);
+                mDreamOverlayStateController,
+                mUserTracker);
     }
 
     @Test
@@ -282,7 +288,8 @@
                 mZenModeController,
                 mStatusBarWindowStateController,
                 mDreamOverlayStatusBarItemsProvider,
-                mDreamOverlayStateController);
+                mDreamOverlayStateController,
+                mUserTracker);
         controller.onViewAttached();
         verify(mView, never()).showIcon(
                 eq(DreamOverlayStatusBarView.STATUS_ICON_NOTIFICATIONS), eq(true), any());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
index 4bd53c0..f64179d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
@@ -41,11 +41,11 @@
 
 import com.android.internal.logging.UiEventLogger;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants;
 import com.android.systemui.shade.ShadeExpansionChangeEvent;
 import com.android.systemui.shared.system.InputChannelCompat;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
-import com.android.systemui.statusbar.phone.KeyguardBouncer;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.wm.shell.animation.FlingAnimationUtils;
 
@@ -302,12 +302,13 @@
         final float velocityY = -1;
         swipeToPosition(swipeUpPercentage, Direction.UP, velocityY);
 
-        verify(mValueAnimatorCreator).create(eq(expansion), eq(KeyguardBouncer.EXPANSION_HIDDEN));
+        verify(mValueAnimatorCreator).create(eq(expansion),
+                eq(KeyguardBouncerConstants.EXPANSION_HIDDEN));
         verify(mValueAnimator, never()).addListener(any());
 
         verify(mFlingAnimationUtilsClosing).apply(eq(mValueAnimator),
                 eq(SCREEN_HEIGHT_PX * expansion),
-                eq(SCREEN_HEIGHT_PX * KeyguardBouncer.EXPANSION_HIDDEN),
+                eq(SCREEN_HEIGHT_PX * KeyguardBouncerConstants.EXPANSION_HIDDEN),
                 eq(velocityY), eq((float) SCREEN_HEIGHT_PX));
         verify(mValueAnimator).start();
         verify(mUiEventLogger, never()).log(any());
@@ -324,7 +325,8 @@
         final float velocityY = 1;
         swipeToPosition(swipeUpPercentage, Direction.UP, velocityY);
 
-        verify(mValueAnimatorCreator).create(eq(expansion), eq(KeyguardBouncer.EXPANSION_VISIBLE));
+        verify(mValueAnimatorCreator).create(eq(expansion),
+                eq(KeyguardBouncerConstants.EXPANSION_VISIBLE));
 
         ArgumentCaptor<AnimatorListenerAdapter> endAnimationListenerCaptor =
                 ArgumentCaptor.forClass(AnimatorListenerAdapter.class);
@@ -332,7 +334,7 @@
         AnimatorListenerAdapter endAnimationListener = endAnimationListenerCaptor.getValue();
 
         verify(mFlingAnimationUtils).apply(eq(mValueAnimator), eq(SCREEN_HEIGHT_PX * expansion),
-                eq(SCREEN_HEIGHT_PX * KeyguardBouncer.EXPANSION_VISIBLE),
+                eq(SCREEN_HEIGHT_PX * KeyguardBouncerConstants.EXPANSION_VISIBLE),
                 eq(velocityY), eq((float) SCREEN_HEIGHT_PX));
         verify(mValueAnimator).start();
         verify(mUiEventLogger).log(BouncerSwipeTouchHandler.DreamEvent.DREAM_SWIPED);
@@ -355,12 +357,12 @@
         swipeToPosition(swipeDownPercentage, Direction.DOWN, velocityY);
 
         verify(mValueAnimatorCreator).create(eq(swipeDownPercentage),
-                eq(KeyguardBouncer.EXPANSION_VISIBLE));
+                eq(KeyguardBouncerConstants.EXPANSION_VISIBLE));
         verify(mValueAnimator, never()).addListener(any());
 
         verify(mFlingAnimationUtils).apply(eq(mValueAnimator),
                 eq(SCREEN_HEIGHT_PX * swipeDownPercentage),
-                eq(SCREEN_HEIGHT_PX * KeyguardBouncer.EXPANSION_VISIBLE),
+                eq(SCREEN_HEIGHT_PX * KeyguardBouncerConstants.EXPANSION_VISIBLE),
                 eq(velocityY), eq((float) SCREEN_HEIGHT_PX));
         verify(mValueAnimator).start();
         verify(mUiEventLogger, never()).log(any());
@@ -381,12 +383,12 @@
         swipeToPosition(swipeDownPercentage, Direction.DOWN, velocityY);
 
         verify(mValueAnimatorCreator).create(eq(swipeDownPercentage),
-                eq(KeyguardBouncer.EXPANSION_HIDDEN));
+                eq(KeyguardBouncerConstants.EXPANSION_HIDDEN));
         verify(mValueAnimator, never()).addListener(any());
 
         verify(mFlingAnimationUtilsClosing).apply(eq(mValueAnimator),
                 eq(SCREEN_HEIGHT_PX * swipeDownPercentage),
-                eq(SCREEN_HEIGHT_PX * KeyguardBouncer.EXPANSION_HIDDEN),
+                eq(SCREEN_HEIGHT_PX * KeyguardBouncerConstants.EXPANSION_HIDDEN),
                 eq(velocityY), eq((float) SCREEN_HEIGHT_PX));
         verify(mValueAnimator).start();
         verify(mUiEventLogger, never()).log(any());
@@ -405,7 +407,8 @@
         final float velocityY = -1;
         swipeToPosition(swipeUpPercentage, Direction.UP, velocityY);
 
-        verify(mValueAnimatorCreator).create(eq(expansion), eq(KeyguardBouncer.EXPANSION_VISIBLE));
+        verify(mValueAnimatorCreator).create(eq(expansion),
+                eq(KeyguardBouncerConstants.EXPANSION_VISIBLE));
 
         ArgumentCaptor<AnimatorListenerAdapter> endAnimationListenerCaptor =
                 ArgumentCaptor.forClass(AnimatorListenerAdapter.class);
@@ -413,7 +416,7 @@
         AnimatorListenerAdapter endAnimationListener = endAnimationListenerCaptor.getValue();
 
         verify(mFlingAnimationUtils).apply(eq(mValueAnimator), eq(SCREEN_HEIGHT_PX * expansion),
-                eq(SCREEN_HEIGHT_PX * KeyguardBouncer.EXPANSION_VISIBLE),
+                eq(SCREEN_HEIGHT_PX * KeyguardBouncerConstants.EXPANSION_VISIBLE),
                 eq(velocityY), eq((float) SCREEN_HEIGHT_PX));
         verify(mValueAnimator).start();
         verify(mUiEventLogger).log(BouncerSwipeTouchHandler.DreamEvent.DREAM_SWIPED);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
similarity index 81%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProviderTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
index 5e4a43f..c0af0cb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
@@ -49,8 +49,9 @@
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.settings.UserFileManager
 import com.android.systemui.settings.UserTracker
+import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
 import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
-import com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderContract as Contract
+import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.util.FakeSharedPreferences
 import com.android.systemui.util.mockito.any
@@ -75,7 +76,7 @@
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
-class KeyguardQuickAffordanceProviderTest : SysuiTestCase() {
+class CustomizationProviderTest : SysuiTestCase() {
 
     @Mock private lateinit var lockPatternUtils: LockPatternUtils
     @Mock private lateinit var keyguardStateController: KeyguardStateController
@@ -86,9 +87,9 @@
     @Mock private lateinit var backgroundHandler: Handler
     @Mock private lateinit var previewSurfacePackage: SurfaceControlViewHost.SurfacePackage
     @Mock private lateinit var launchAnimator: DialogLaunchAnimator
+    @Mock private lateinit var commandQueue: CommandQueue
 
-    private lateinit var underTest: KeyguardQuickAffordanceProvider
-
+    private lateinit var underTest: CustomizationProvider
     private lateinit var testScope: TestScope
 
     @Before
@@ -98,7 +99,7 @@
         whenever(previewRendererFactory.create(any())).thenReturn(previewRenderer)
         whenever(backgroundHandler.looper).thenReturn(TestableLooper.get(this).looper)
 
-        underTest = KeyguardQuickAffordanceProvider()
+        underTest = CustomizationProvider()
         val testDispatcher = StandardTestDispatcher()
         testScope = TestScope(testDispatcher)
         val localUserSelectionManager =
@@ -160,6 +161,7 @@
                 keyguardInteractor =
                     KeyguardInteractor(
                         repository = FakeKeyguardRepository(),
+                        commandQueue = commandQueue,
                     ),
                 registry = mock(),
                 lockPatternUtils = lockPatternUtils,
@@ -171,6 +173,7 @@
                         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)
                     },
                 repository = { quickAffordanceRepository },
                 launchAnimator = launchAnimator,
@@ -205,19 +208,34 @@
 
     @Test
     fun getType() {
-        assertThat(underTest.getType(Contract.AffordanceTable.URI))
+        assertThat(underTest.getType(Contract.LockScreenQuickAffordances.AffordanceTable.URI))
             .isEqualTo(
                 "vnd.android.cursor.dir/vnd." +
-                    "${Contract.AUTHORITY}.${Contract.AffordanceTable.TABLE_NAME}"
+                    "${Contract.AUTHORITY}." +
+                    Contract.LockScreenQuickAffordances.qualifiedTablePath(
+                        Contract.LockScreenQuickAffordances.AffordanceTable.TABLE_NAME
+                    )
             )
-        assertThat(underTest.getType(Contract.SlotTable.URI))
+        assertThat(underTest.getType(Contract.LockScreenQuickAffordances.SlotTable.URI))
             .isEqualTo(
-                "vnd.android.cursor.dir/vnd.${Contract.AUTHORITY}.${Contract.SlotTable.TABLE_NAME}"
+                "vnd.android.cursor.dir/vnd.${Contract.AUTHORITY}." +
+                    Contract.LockScreenQuickAffordances.qualifiedTablePath(
+                        Contract.LockScreenQuickAffordances.SlotTable.TABLE_NAME
+                    )
             )
-        assertThat(underTest.getType(Contract.SelectionTable.URI))
+        assertThat(underTest.getType(Contract.LockScreenQuickAffordances.SelectionTable.URI))
             .isEqualTo(
                 "vnd.android.cursor.dir/vnd." +
-                    "${Contract.AUTHORITY}.${Contract.SelectionTable.TABLE_NAME}"
+                    "${Contract.AUTHORITY}." +
+                    Contract.LockScreenQuickAffordances.qualifiedTablePath(
+                        Contract.LockScreenQuickAffordances.SelectionTable.TABLE_NAME
+                    )
+            )
+        assertThat(underTest.getType(Contract.FlagsTable.URI))
+            .isEqualTo(
+                "vnd.android.cursor.dir/vnd." +
+                    "${Contract.AUTHORITY}." +
+                    Contract.FlagsTable.TABLE_NAME
             )
     }
 
@@ -296,9 +314,10 @@
             )
 
             context.contentResolver.delete(
-                Contract.SelectionTable.URI,
-                "${Contract.SelectionTable.Columns.SLOT_ID} = ? AND" +
-                    " ${Contract.SelectionTable.Columns.AFFORDANCE_ID} = ?",
+                Contract.LockScreenQuickAffordances.SelectionTable.URI,
+                "${Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID} = ? AND" +
+                    " ${Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_ID}" +
+                    " = ?",
                 arrayOf(
                     KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
                     AFFORDANCE_2,
@@ -330,8 +349,8 @@
             )
 
             context.contentResolver.delete(
-                Contract.SelectionTable.URI,
-                Contract.SelectionTable.Columns.SLOT_ID,
+                Contract.LockScreenQuickAffordances.SelectionTable.URI,
+                Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID,
                 arrayOf(
                     KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
                 ),
@@ -371,10 +390,13 @@
         affordanceId: String,
     ) {
         context.contentResolver.insert(
-            Contract.SelectionTable.URI,
+            Contract.LockScreenQuickAffordances.SelectionTable.URI,
             ContentValues().apply {
-                put(Contract.SelectionTable.Columns.SLOT_ID, slotId)
-                put(Contract.SelectionTable.Columns.AFFORDANCE_ID, affordanceId)
+                put(Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID, slotId)
+                put(
+                    Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_ID,
+                    affordanceId
+                )
             }
         )
     }
@@ -382,7 +404,7 @@
     private fun querySelections(): List<Selection> {
         return context.contentResolver
             .query(
-                Contract.SelectionTable.URI,
+                Contract.LockScreenQuickAffordances.SelectionTable.URI,
                 null,
                 null,
                 null,
@@ -391,11 +413,18 @@
             ?.use { cursor ->
                 buildList {
                     val slotIdColumnIndex =
-                        cursor.getColumnIndex(Contract.SelectionTable.Columns.SLOT_ID)
+                        cursor.getColumnIndex(
+                            Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID
+                        )
                     val affordanceIdColumnIndex =
-                        cursor.getColumnIndex(Contract.SelectionTable.Columns.AFFORDANCE_ID)
+                        cursor.getColumnIndex(
+                            Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_ID
+                        )
                     val affordanceNameColumnIndex =
-                        cursor.getColumnIndex(Contract.SelectionTable.Columns.AFFORDANCE_NAME)
+                        cursor.getColumnIndex(
+                            Contract.LockScreenQuickAffordances.SelectionTable.Columns
+                                .AFFORDANCE_NAME
+                        )
                     if (
                         slotIdColumnIndex == -1 ||
                             affordanceIdColumnIndex == -1 ||
@@ -421,7 +450,7 @@
     private fun querySlots(): List<Slot> {
         return context.contentResolver
             .query(
-                Contract.SlotTable.URI,
+                Contract.LockScreenQuickAffordances.SlotTable.URI,
                 null,
                 null,
                 null,
@@ -429,9 +458,14 @@
             )
             ?.use { cursor ->
                 buildList {
-                    val idColumnIndex = cursor.getColumnIndex(Contract.SlotTable.Columns.ID)
+                    val idColumnIndex =
+                        cursor.getColumnIndex(
+                            Contract.LockScreenQuickAffordances.SlotTable.Columns.ID
+                        )
                     val capacityColumnIndex =
-                        cursor.getColumnIndex(Contract.SlotTable.Columns.CAPACITY)
+                        cursor.getColumnIndex(
+                            Contract.LockScreenQuickAffordances.SlotTable.Columns.CAPACITY
+                        )
                     if (idColumnIndex == -1 || capacityColumnIndex == -1) {
                         return@buildList
                     }
@@ -452,7 +486,7 @@
     private fun queryAffordances(): List<Affordance> {
         return context.contentResolver
             .query(
-                Contract.AffordanceTable.URI,
+                Contract.LockScreenQuickAffordances.AffordanceTable.URI,
                 null,
                 null,
                 null,
@@ -460,11 +494,18 @@
             )
             ?.use { cursor ->
                 buildList {
-                    val idColumnIndex = cursor.getColumnIndex(Contract.AffordanceTable.Columns.ID)
+                    val idColumnIndex =
+                        cursor.getColumnIndex(
+                            Contract.LockScreenQuickAffordances.AffordanceTable.Columns.ID
+                        )
                     val nameColumnIndex =
-                        cursor.getColumnIndex(Contract.AffordanceTable.Columns.NAME)
+                        cursor.getColumnIndex(
+                            Contract.LockScreenQuickAffordances.AffordanceTable.Columns.NAME
+                        )
                     val iconColumnIndex =
-                        cursor.getColumnIndex(Contract.AffordanceTable.Columns.ICON)
+                        cursor.getColumnIndex(
+                            Contract.LockScreenQuickAffordances.AffordanceTable.Columns.ICON
+                        )
                     if (idColumnIndex == -1 || nameColumnIndex == -1 || iconColumnIndex == -1) {
                         return@buildList
                     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
index a78c902..2c81e82 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
@@ -4,6 +4,7 @@
 import android.app.WindowConfiguration
 import android.graphics.Point
 import android.graphics.Rect
+import android.os.PowerManager
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
 import android.view.RemoteAnimationTarget
@@ -19,15 +20,16 @@
 import com.android.systemui.statusbar.SysuiStatusBarStateController
 import com.android.systemui.statusbar.phone.BiometricUnlockController
 import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.util.mockito.whenever
 import junit.framework.Assert.assertEquals
 import junit.framework.Assert.assertFalse
 import junit.framework.Assert.assertTrue
+import org.junit.After
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor.forClass
 import org.mockito.Mock
-import org.mockito.Mockito.`when`
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
@@ -56,6 +58,8 @@
     private lateinit var statusBarStateController: SysuiStatusBarStateController
     @Mock
     private lateinit var notificationShadeWindowController: NotificationShadeWindowController
+    @Mock
+    private lateinit var powerManager: PowerManager
 
     @Mock
     private lateinit var launcherUnlockAnimationController: ILauncherUnlockAnimationController.Stub
@@ -79,12 +83,13 @@
         keyguardUnlockAnimationController = KeyguardUnlockAnimationController(
             context, keyguardStateController, { keyguardViewMediator }, keyguardViewController,
             featureFlags, { biometricUnlockController }, statusBarStateController,
-            notificationShadeWindowController
+            notificationShadeWindowController, powerManager
         )
         keyguardUnlockAnimationController.setLauncherUnlockController(
             launcherUnlockAnimationController)
 
-        `when`(keyguardViewController.viewRootImpl).thenReturn(mock(ViewRootImpl::class.java))
+        whenever(keyguardViewController.viewRootImpl).thenReturn(mock(ViewRootImpl::class.java))
+        whenever(powerManager.isInteractive).thenReturn(true)
 
         // All of these fields are final, so we can't mock them, but are needed so that the surface
         // appear amount setter doesn't short circuit.
@@ -96,6 +101,12 @@
         keyguardUnlockAnimationController.surfaceTransactionApplier = surfaceTransactionApplier
     }
 
+    @After
+    fun tearDown() {
+        keyguardUnlockAnimationController.surfaceBehindEntryAnimator.cancel()
+        keyguardUnlockAnimationController.surfaceBehindAlphaAnimator.cancel()
+    }
+
     /**
      * If we're wake and unlocking, we are animating from the black/AOD screen to the app/launcher
      * underneath. The LightRevealScrim will animate circularly from the fingerprint reader,
@@ -104,7 +115,7 @@
      */
     @Test
     fun noSurfaceAnimation_ifWakeAndUnlocking() {
-        `when`(biometricUnlockController.isWakeAndUnlock).thenReturn(true)
+        whenever(biometricUnlockController.isWakeAndUnlock).thenReturn(true)
 
         keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
             remoteAnimationTargets,
@@ -124,7 +135,7 @@
 
         // Also expect we've immediately asked the keyguard view mediator to finish the remote
         // animation.
-        verify(keyguardViewMediator, times(1)).onKeyguardExitRemoteAnimationFinished(
+        verify(keyguardViewMediator, times(1)).exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
             false /* cancelled */)
 
         verifyNoMoreInteractions(surfaceTransactionApplier)
@@ -135,7 +146,7 @@
      */
     @Test
     fun surfaceAnimation_ifNotWakeAndUnlocking() {
-        `when`(biometricUnlockController.isWakeAndUnlock).thenReturn(false)
+        whenever(biometricUnlockController.isWakeAndUnlock).thenReturn(false)
 
         keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
             remoteAnimationTargets,
@@ -144,7 +155,7 @@
         )
 
         // Since the animation is running, we should not have finished the remote animation.
-        verify(keyguardViewMediator, times(0)).onKeyguardExitRemoteAnimationFinished(
+        verify(keyguardViewMediator, times(0)).exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
             false /* cancelled */)
     }
 
@@ -159,7 +170,7 @@
      */
     @Test
     fun fadeInSurfaceBehind_ifRequestedShowSurface_butNotFlinging() {
-        `when`(keyguardStateController.isFlingingToDismissKeyguard).thenReturn(false)
+        whenever(keyguardStateController.isFlingingToDismissKeyguard).thenReturn(false)
 
         keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
             remoteAnimationTargets,
@@ -181,7 +192,7 @@
      */
     @Test
     fun playCannedUnlockAnimation_ifRequestedShowSurface_andFlinging() {
-        `when`(keyguardStateController.isFlingingToDismissKeyguard).thenReturn(true)
+        whenever(keyguardStateController.isFlingingToDismissKeyguard).thenReturn(true)
 
         keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
             remoteAnimationTargets,
@@ -215,7 +226,7 @@
 
     @Test
     fun doNotPlayCannedUnlockAnimation_ifLaunchingApp() {
-        `when`(notificationShadeWindowController.isLaunchingActivity).thenReturn(true)
+        whenever(notificationShadeWindowController.isLaunchingActivity).thenReturn(true)
 
         keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
             remoteAnimationTargets,
@@ -272,7 +283,53 @@
         assertTrue(remainingTargets.isEmpty())
 
         // Since the animation is running, we should not have finished the remote animation.
-        verify(keyguardViewMediator, times(0)).onKeyguardExitRemoteAnimationFinished(
+        verify(keyguardViewMediator, times(0)).exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
                 false /* cancelled */)
     }
+
+    @Test
+    fun surfaceBehindAlphaOverriddenTo0_ifNotInteractive() {
+        whenever(powerManager.isInteractive).thenReturn(false)
+
+        keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
+                remoteAnimationTargets,
+                0 /* startTime */,
+                false /* requestedShowSurfaceBehindKeyguard */
+        )
+
+        keyguardUnlockAnimationController.setSurfaceBehindAppearAmount(1f)
+
+        val captor = forClass(SyncRtSurfaceTransactionApplier.SurfaceParams::class.java)
+        verify(surfaceTransactionApplier, times(1)).scheduleApply(captor.capture())
+
+        val params = captor.value
+
+        // We expect that we've set the surface behind to alpha = 0f since we're not interactive.
+        assertEquals(params.alpha, 0f)
+        assertTrue(params.matrix.isIdentity)
+
+        verifyNoMoreInteractions(surfaceTransactionApplier)
+    }
+
+    @Test
+    fun surfaceBehindAlphaNotOverriddenTo0_ifInteractive() {
+        whenever(powerManager.isInteractive).thenReturn(true)
+
+        keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
+                remoteAnimationTargets,
+                0 /* startTime */,
+                false /* requestedShowSurfaceBehindKeyguard */
+        )
+
+        keyguardUnlockAnimationController.setSurfaceBehindAppearAmount(1f)
+
+        val captor = forClass(SyncRtSurfaceTransactionApplier.SurfaceParams::class.java)
+        verify(surfaceTransactionApplier, times(1)).scheduleApply(captor.capture())
+
+        val params = captor.value
+        assertEquals(params.alpha, 1f)
+        assertTrue(params.matrix.isIdentity)
+
+        verifyNoMoreInteractions(surfaceTransactionApplier)
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index 804960d..f55b866 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -29,6 +29,7 @@
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -57,6 +58,7 @@
 import com.android.keyguard.KeyguardSecurityView;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.mediator.ScreenOnCoordinator;
+import com.android.systemui.DejankUtils;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.biometrics.AuthController;
@@ -65,11 +67,13 @@
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.dreams.DreamOverlayStateController;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shade.NotificationShadeWindowControllerImpl;
 import com.android.systemui.shade.ShadeController;
 import com.android.systemui.shade.ShadeExpansionStateManager;
+import com.android.systemui.shade.ShadeWindowLogger;
 import com.android.systemui.statusbar.NotificationShadeDepthController;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
@@ -132,6 +136,8 @@
     private @Mock SysuiColorExtractor mColorExtractor;
     private @Mock AuthController mAuthController;
     private @Mock ShadeExpansionStateManager mShadeExpansionStateManager;
+    private @Mock ShadeWindowLogger mShadeWindowLogger;
+    private @Mock FeatureFlags mFeatureFlags;
     private DeviceConfigProxy mDeviceConfig = new DeviceConfigProxyFake();
     private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
 
@@ -155,7 +161,10 @@
                 mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController,
                 mConfigurationController, mViewMediator, mKeyguardBypassController,
                 mColorExtractor, mDumpManager, mKeyguardStateController,
-                mScreenOffAnimationController, mAuthController, mShadeExpansionStateManager);
+                mScreenOffAnimationController, mAuthController, mShadeExpansionStateManager,
+                mShadeWindowLogger);
+
+        DejankUtils.setImmediate(true);
 
         createAndStartViewMediator();
     }
@@ -354,7 +363,67 @@
 
     @Test
     @TestableLooper.RunWithLooper(setAsMainLooper = true)
+    public void testCancelKeyguardExitAnimation_noPendingLock_keyguardWillNotBeShowing() {
+        startMockKeyguardExitAnimation();
+        cancelMockKeyguardExitAnimation();
+
+        // There should not be a pending lock, but try to handle it anyway to ensure one isn't set.
+        mViewMediator.maybeHandlePendingLock();
+        TestableLooper.get(this).processAllMessages();
+
+        assertFalse(mViewMediator.isShowingAndNotOccluded());
+    }
+
+    @Test
+    @TestableLooper.RunWithLooper(setAsMainLooper = true)
+    public void testCancelKeyguardExitAnimationDueToSleep_withPendingLock_keyguardWillBeShowing() {
+        startMockKeyguardExitAnimation();
+
+        mViewMediator.onStartedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON);
+        mViewMediator.onFinishedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, false);
+
+        cancelMockKeyguardExitAnimation();
+
+        mViewMediator.maybeHandlePendingLock();
+        TestableLooper.get(this).processAllMessages();
+
+        assertTrue(mViewMediator.isShowingAndNotOccluded());
+    }
+
+    @Test
+    @TestableLooper.RunWithLooper(setAsMainLooper = true)
+    public void testCancelKeyguardExitAnimationThenSleep_withPendingLock_keyguardWillBeShowing() {
+        startMockKeyguardExitAnimation();
+        cancelMockKeyguardExitAnimation();
+
+        mViewMediator.maybeHandlePendingLock();
+        TestableLooper.get(this).processAllMessages();
+
+        mViewMediator.onStartedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON);
+        mViewMediator.onFinishedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, false);
+
+        mViewMediator.maybeHandlePendingLock();
+        TestableLooper.get(this).processAllMessages();
+
+        assertTrue(mViewMediator.isShowingAndNotOccluded());
+    }
+
+    @Test
+    @TestableLooper.RunWithLooper(setAsMainLooper = true)
     public void testStartKeyguardExitAnimation_expectSurfaceBehindRemoteAnimation() {
+        startMockKeyguardExitAnimation();
+        assertTrue(mViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind());
+    }
+
+    /**
+     * Configures mocks appropriately, then starts the keyguard exit animation.
+     */
+    private void startMockKeyguardExitAnimation() {
+        mViewMediator.onSystemReady();
+        TestableLooper.get(this).processAllMessages();
+
+        mViewMediator.setShowingLocked(true);
+
         RemoteAnimationTarget[] apps = new RemoteAnimationTarget[]{
                 mock(RemoteAnimationTarget.class)
         };
@@ -363,10 +432,90 @@
         };
         IRemoteAnimationFinishedCallback callback = mock(IRemoteAnimationFinishedCallback.class);
 
+        when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(true);
         mViewMediator.startKeyguardExitAnimation(TRANSIT_OLD_KEYGUARD_GOING_AWAY, apps, wallpapers,
                 null, callback);
         TestableLooper.get(this).processAllMessages();
-        assertTrue(mViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind());
+    }
+
+    /**
+     * Configures mocks appropriately, then cancels the keyguard exit animation.
+     */
+    private void cancelMockKeyguardExitAnimation() {
+        when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(false);
+        mViewMediator.cancelKeyguardExitAnimation();
+        TestableLooper.get(this).processAllMessages();
+    }
+
+    @Test
+    @TestableLooper.RunWithLooper(setAsMainLooper = true)
+    public void testKeyguardDelayedOnGoingToSleep_ifScreenOffAnimationWillPlayButIsntPlayingYet() {
+        mViewMediator.onSystemReady();
+        TestableLooper.get(this).processAllMessages();
+
+        mViewMediator.setShowingLocked(false);
+        TestableLooper.get(this).processAllMessages();
+
+        mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_USER);
+        TestableLooper.get(this).processAllMessages();
+
+        when(mScreenOffAnimationController.shouldDelayKeyguardShow()).thenReturn(true);
+        when(mScreenOffAnimationController.isKeyguardShowDelayed()).thenReturn(false);
+        mViewMediator.onFinishedGoingToSleep(OFF_BECAUSE_OF_USER, false);
+        TestableLooper.get(this).processAllMessages();
+
+        assertFalse(mViewMediator.isShowingAndNotOccluded());
+    }
+
+    @Test
+    @TestableLooper.RunWithLooper(setAsMainLooper = true)
+    public void testKeyguardNotDelayedOnGoingToSleep_ifScreenOffAnimationWillNotPlay() {
+        mViewMediator.onSystemReady();
+        TestableLooper.get(this).processAllMessages();
+
+        mViewMediator.setShowingLocked(false);
+        TestableLooper.get(this).processAllMessages();
+
+        mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_USER);
+        TestableLooper.get(this).processAllMessages();
+
+        when(mScreenOffAnimationController.shouldDelayKeyguardShow()).thenReturn(false);
+        mViewMediator.onFinishedGoingToSleep(OFF_BECAUSE_OF_USER, false);
+        TestableLooper.get(this).processAllMessages();
+
+        assertTrue(mViewMediator.isShowingAndNotOccluded());
+    }
+
+    @Test
+    @TestableLooper.RunWithLooper(setAsMainLooper = true)
+    public void testDoKeyguardWhileInteractive_resets() {
+        mViewMediator.setShowingLocked(true);
+        when(mKeyguardStateController.isShowing()).thenReturn(true);
+        TestableLooper.get(this).processAllMessages();
+
+        when(mPowerManager.isInteractive()).thenReturn(true);
+
+        mViewMediator.onSystemReady();
+        TestableLooper.get(this).processAllMessages();
+
+        assertTrue(mViewMediator.isShowingAndNotOccluded());
+        verify(mStatusBarKeyguardViewManager).reset(anyBoolean());
+    }
+
+    @Test
+    @TestableLooper.RunWithLooper(setAsMainLooper = true)
+    public void testDoKeyguardWhileNotInteractive_showsInsteadOfResetting() {
+        mViewMediator.setShowingLocked(true);
+        when(mKeyguardStateController.isShowing()).thenReturn(true);
+        TestableLooper.get(this).processAllMessages();
+
+        when(mPowerManager.isInteractive()).thenReturn(false);
+
+        mViewMediator.onSystemReady();
+        TestableLooper.get(this).processAllMessages();
+
+        assertTrue(mViewMediator.isShowingAndNotOccluded());
+        verify(mStatusBarKeyguardViewManager, never()).reset(anyBoolean());
     }
 
     private void createAndStartViewMediator() {
@@ -396,6 +545,7 @@
                 mScreenOnCoordinator,
                 mInteractionJankMonitor,
                 mDreamOverlayStateController,
+                mFeatureFlags,
                 () -> mShadeController,
                 () -> mNotificationShadeWindowController,
                 () -> mActivityLaunchAnimator,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/WakefulnessLifecycleTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/WakefulnessLifecycleTest.java
index f32d76b..39a453d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/WakefulnessLifecycleTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/WakefulnessLifecycleTest.java
@@ -30,6 +30,7 @@
 
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.util.time.FakeSystemClock;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -51,7 +52,12 @@
     public void setUp() throws Exception {
         mWallpaperManager = mock(IWallpaperManager.class);
         mWakefulness =
-                new WakefulnessLifecycle(mContext, mWallpaperManager, mock(DumpManager.class));
+                new WakefulnessLifecycle(
+                        mContext,
+                        mWallpaperManager,
+                        new FakeSystemClock(),
+                        mock(DumpManager.class)
+                );
         mWakefulnessObserver = mock(WakefulnessLifecycle.Observer.class);
         mWakefulness.addObserver(mWakefulnessObserver);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/WorkLockActivityControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/WorkLockActivityControllerTest.java
index e9db8cc..b9cfc65 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/WorkLockActivityControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/WorkLockActivityControllerTest.java
@@ -23,6 +23,7 @@
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.app.Activity;
 import android.app.ActivityManager;
@@ -35,12 +36,12 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.IBinder;
-import android.os.UserHandle;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.shared.system.TaskStackChangeListeners;
 
@@ -71,6 +72,7 @@
     private @Mock Context mContext;
     private @Mock TaskStackChangeListeners mTaskStackChangeListeners;
     private @Mock IActivityTaskManager mIActivityTaskManager;
+    private @Mock UserTracker mUserTracker;
 
     private WorkLockActivityController mController;
     private TaskStackChangeListener mTaskStackListener;
@@ -81,12 +83,13 @@
 
         // Set a package name to use for checking ComponentName well-formedness in tests.
         doReturn("com.example.test").when(mContext).getPackageName();
+        when(mUserTracker.getUserId()).thenReturn(ActivityManager.getCurrentUser());
 
         // Construct controller. Save the TaskStackListener for injecting events.
         final ArgumentCaptor<TaskStackChangeListener> listenerCaptor =
                 ArgumentCaptor.forClass(TaskStackChangeListener.class);
-        mController = new WorkLockActivityController(mContext, mTaskStackChangeListeners,
-                mIActivityTaskManager);
+        mController = new WorkLockActivityController(mContext, mUserTracker,
+                mTaskStackChangeListeners, mIActivityTaskManager);
 
         verify(mTaskStackChangeListeners).registerTaskStackListener(listenerCaptor.capture());
         mTaskStackListener = listenerCaptor.getValue();
@@ -135,7 +138,7 @@
                 anyInt(),
                 eq((ProfilerInfo) null),
                 argThat(hasOptions(taskId, taskOverlay)),
-                eq(UserHandle.USER_CURRENT));
+                eq(ActivityManager.getCurrentUser()));
     }
 
     private void verifyStartActivity(int taskId, boolean taskOverlay) throws Exception {
@@ -151,7 +154,7 @@
                 anyInt(),
                 eq((ProfilerInfo) null),
                 argThat(hasOptions(taskId, taskOverlay)),
-                eq(UserHandle.USER_CURRENT));
+                eq(ActivityManager.getCurrentUser()));
     }
 
     private static ArgumentMatcher<Intent> hasComponent(final Context context,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt
index 7205f30..8da4eae 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt
@@ -22,15 +22,21 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.camera.CameraGestureHelper
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runTest
 import org.junit.Assert.assertEquals
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
 import org.mockito.Mock
+import org.mockito.Mockito.anyInt
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(JUnit4::class)
 class CameraQuickAffordanceConfigTest : SysuiTestCase() {
@@ -62,4 +68,24 @@
             .launchCamera(StatusBarManager.CAMERA_LAUNCH_SOURCE_QUICK_AFFORDANCE)
         assertEquals(KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled, result)
     }
+
+    @Test
+    fun `getPickerScreenState - default when launchable`() = runTest {
+        setLaunchable(true)
+
+        Truth.assertThat(underTest.getPickerScreenState())
+            .isInstanceOf(KeyguardQuickAffordanceConfig.PickerScreenState.Default::class.java)
+    }
+
+    @Test
+    fun `getPickerScreenState - unavailable when not launchable`() = runTest {
+        setLaunchable(false)
+
+        Truth.assertThat(underTest.getPickerScreenState())
+            .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice)
+    }
+
+    private fun setLaunchable(isLaunchable: Boolean) {
+        whenever(cameraGestureHelper.canCameraGestureBeLaunched(anyInt())).thenReturn(isLaunchable)
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
index 7c10108..15b85de 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
@@ -38,6 +38,7 @@
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.settings.FakeSettings
+import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestDispatcher
@@ -83,169 +84,205 @@
 
         settings = FakeSettings()
 
-        underTest = DoNotDisturbQuickAffordanceConfig(
-            context,
-            zenModeController,
-            settings,
-            userTracker,
-            testDispatcher,
-            conditionUri,
-            enableZenModeDialog,
-        )
+        underTest =
+            DoNotDisturbQuickAffordanceConfig(
+                context,
+                zenModeController,
+                settings,
+                userTracker,
+                testDispatcher,
+                conditionUri,
+                enableZenModeDialog,
+            )
     }
 
     @Test
-    fun `dnd not available - picker state hidden`() = testScope.runTest {
-        //given
-        whenever(zenModeController.isZenAvailable).thenReturn(false)
+    fun `dnd not available - picker state hidden`() =
+        testScope.runTest {
+            // given
+            whenever(zenModeController.isZenAvailable).thenReturn(false)
 
-        //when
-        val result = underTest.getPickerScreenState()
+            // when
+            val result = underTest.getPickerScreenState()
 
-        //then
-        assertEquals(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice, result)
-    }
+            // then
+            assertEquals(
+                KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice,
+                result
+            )
+        }
 
     @Test
-    fun `dnd available - picker state visible`() = testScope.runTest {
-        //given
-        whenever(zenModeController.isZenAvailable).thenReturn(true)
+    fun `dnd available - picker state visible`() =
+        testScope.runTest {
+            // given
+            whenever(zenModeController.isZenAvailable).thenReturn(true)
 
-        //when
-        val result = underTest.getPickerScreenState()
+            // when
+            val result = underTest.getPickerScreenState()
 
-        //then
-        assertEquals(KeyguardQuickAffordanceConfig.PickerScreenState.Default, result)
-    }
+            // then
+            assertThat(result)
+                .isInstanceOf(KeyguardQuickAffordanceConfig.PickerScreenState.Default::class.java)
+            val defaultPickerState =
+                result as KeyguardQuickAffordanceConfig.PickerScreenState.Default
+            assertThat(defaultPickerState.configureIntent).isNotNull()
+            assertThat(defaultPickerState.configureIntent?.action)
+                .isEqualTo(Settings.ACTION_ZEN_MODE_SETTINGS)
+        }
 
     @Test
-    fun `onTriggered - dnd mode is not ZEN_MODE_OFF - set to ZEN_MODE_OFF`() = testScope.runTest {
-        //given
-        whenever(zenModeController.isZenAvailable).thenReturn(true)
-        whenever(zenModeController.zen).thenReturn(-1)
-        settings.putInt(Settings.Secure.ZEN_DURATION, -2)
-        collectLastValue(underTest.lockScreenState)
-        runCurrent()
+    fun `onTriggered - dnd mode is not ZEN_MODE_OFF - set to ZEN_MODE_OFF`() =
+        testScope.runTest {
+            // given
+            whenever(zenModeController.isZenAvailable).thenReturn(true)
+            whenever(zenModeController.zen).thenReturn(-1)
+            settings.putInt(Settings.Secure.ZEN_DURATION, -2)
+            collectLastValue(underTest.lockScreenState)
+            runCurrent()
 
-        //when
-        val result = underTest.onTriggered(null)
-        verify(zenModeController).setZen(spyZenMode.capture(), spyConditionId.capture(), eq(DoNotDisturbQuickAffordanceConfig.TAG))
+            // when
+            val result = underTest.onTriggered(null)
+            verify(zenModeController)
+                .setZen(
+                    spyZenMode.capture(),
+                    spyConditionId.capture(),
+                    eq(DoNotDisturbQuickAffordanceConfig.TAG)
+                )
 
-        //then
-        assertEquals(KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled, result)
-        assertEquals(ZEN_MODE_OFF, spyZenMode.value)
-        assertNull(spyConditionId.value)
-    }
+            // then
+            assertEquals(KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled, result)
+            assertEquals(ZEN_MODE_OFF, spyZenMode.value)
+            assertNull(spyConditionId.value)
+        }
 
     @Test
-    fun `onTriggered - dnd mode is ZEN_MODE_OFF - setting is FOREVER - set zen with no condition`() = testScope.runTest {
-        //given
-        whenever(zenModeController.isZenAvailable).thenReturn(true)
-        whenever(zenModeController.zen).thenReturn(ZEN_MODE_OFF)
-        settings.putInt(Settings.Secure.ZEN_DURATION, ZEN_DURATION_FOREVER)
-        collectLastValue(underTest.lockScreenState)
-        runCurrent()
+    fun `onTriggered - dnd mode is ZEN_MODE_OFF - setting FOREVER - set zen without condition`() =
+        testScope.runTest {
+            // given
+            whenever(zenModeController.isZenAvailable).thenReturn(true)
+            whenever(zenModeController.zen).thenReturn(ZEN_MODE_OFF)
+            settings.putInt(Settings.Secure.ZEN_DURATION, ZEN_DURATION_FOREVER)
+            collectLastValue(underTest.lockScreenState)
+            runCurrent()
 
-        //when
-        val result = underTest.onTriggered(null)
-        verify(zenModeController).setZen(spyZenMode.capture(), spyConditionId.capture(), eq(DoNotDisturbQuickAffordanceConfig.TAG))
+            // when
+            val result = underTest.onTriggered(null)
+            verify(zenModeController)
+                .setZen(
+                    spyZenMode.capture(),
+                    spyConditionId.capture(),
+                    eq(DoNotDisturbQuickAffordanceConfig.TAG)
+                )
 
-        //then
-        assertEquals(KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled, result)
-        assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, spyZenMode.value)
-        assertNull(spyConditionId.value)
-    }
+            // then
+            assertEquals(KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled, result)
+            assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, spyZenMode.value)
+            assertNull(spyConditionId.value)
+        }
 
     @Test
-    fun `onTriggered - dnd mode is ZEN_MODE_OFF - setting is not FOREVER or PROMPT - set zen with condition`() = testScope.runTest {
-        //given
-        whenever(zenModeController.isZenAvailable).thenReturn(true)
-        whenever(zenModeController.zen).thenReturn(ZEN_MODE_OFF)
-        settings.putInt(Settings.Secure.ZEN_DURATION, -900)
-        collectLastValue(underTest.lockScreenState)
-        runCurrent()
+    fun `onTriggered - dnd ZEN_MODE_OFF - setting not FOREVER or PROMPT - zen with condition`() =
+        testScope.runTest {
+            // given
+            whenever(zenModeController.isZenAvailable).thenReturn(true)
+            whenever(zenModeController.zen).thenReturn(ZEN_MODE_OFF)
+            settings.putInt(Settings.Secure.ZEN_DURATION, -900)
+            collectLastValue(underTest.lockScreenState)
+            runCurrent()
 
-        //when
-        val result = underTest.onTriggered(null)
-        verify(zenModeController).setZen(spyZenMode.capture(), spyConditionId.capture(), eq(DoNotDisturbQuickAffordanceConfig.TAG))
+            // when
+            val result = underTest.onTriggered(null)
+            verify(zenModeController)
+                .setZen(
+                    spyZenMode.capture(),
+                    spyConditionId.capture(),
+                    eq(DoNotDisturbQuickAffordanceConfig.TAG)
+                )
 
-        //then
-        assertEquals(KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled, result)
-        assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, spyZenMode.value)
-        assertEquals(conditionUri, spyConditionId.value)
-    }
+            // then
+            assertEquals(KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled, result)
+            assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, spyZenMode.value)
+            assertEquals(conditionUri, spyConditionId.value)
+        }
 
     @Test
-    fun `onTriggered - dnd mode is ZEN_MODE_OFF - setting is PROMPT - show dialog`() = testScope.runTest {
-        //given
-        val expandable: Expandable = mock()
-        whenever(zenModeController.isZenAvailable).thenReturn(true)
-        whenever(zenModeController.zen).thenReturn(ZEN_MODE_OFF)
-        settings.putInt(Settings.Secure.ZEN_DURATION, ZEN_DURATION_PROMPT)
-        whenever(enableZenModeDialog.createDialog()).thenReturn(mock())
-        collectLastValue(underTest.lockScreenState)
-        runCurrent()
+    fun `onTriggered - dnd mode is ZEN_MODE_OFF - setting is PROMPT - show dialog`() =
+        testScope.runTest {
+            // given
+            val expandable: Expandable = mock()
+            whenever(zenModeController.isZenAvailable).thenReturn(true)
+            whenever(zenModeController.zen).thenReturn(ZEN_MODE_OFF)
+            settings.putInt(Settings.Secure.ZEN_DURATION, ZEN_DURATION_PROMPT)
+            whenever(enableZenModeDialog.createDialog()).thenReturn(mock())
+            collectLastValue(underTest.lockScreenState)
+            runCurrent()
 
-        //when
-        val result = underTest.onTriggered(expandable)
+            // when
+            val result = underTest.onTriggered(expandable)
 
-        //then
-        assertTrue(result is KeyguardQuickAffordanceConfig.OnTriggeredResult.ShowDialog)
-        assertEquals(expandable, (result as KeyguardQuickAffordanceConfig.OnTriggeredResult.ShowDialog).expandable)
-    }
+            // then
+            assertTrue(result is KeyguardQuickAffordanceConfig.OnTriggeredResult.ShowDialog)
+            assertEquals(
+                expandable,
+                (result as KeyguardQuickAffordanceConfig.OnTriggeredResult.ShowDialog).expandable
+            )
+        }
 
     @Test
-    fun `lockScreenState - dndAvailable starts as true - changes to false - State moves to Hidden`() = testScope.runTest {
-        //given
-        whenever(zenModeController.isZenAvailable).thenReturn(true)
-        val callbackCaptor: ArgumentCaptor<ZenModeController.Callback> = argumentCaptor()
-        val valueSnapshot = collectLastValue(underTest.lockScreenState)
-        val secondLastValue = valueSnapshot()
-        verify(zenModeController).addCallback(callbackCaptor.capture())
+    fun `lockScreenState - dndAvailable starts as true - change to false - State is Hidden`() =
+        testScope.runTest {
+            // given
+            whenever(zenModeController.isZenAvailable).thenReturn(true)
+            val callbackCaptor: ArgumentCaptor<ZenModeController.Callback> = argumentCaptor()
+            val valueSnapshot = collectLastValue(underTest.lockScreenState)
+            val secondLastValue = valueSnapshot()
+            verify(zenModeController).addCallback(callbackCaptor.capture())
 
-        //when
-        callbackCaptor.value.onZenAvailableChanged(false)
-        val lastValue = valueSnapshot()
+            // when
+            callbackCaptor.value.onZenAvailableChanged(false)
+            val lastValue = valueSnapshot()
 
-        //then
-        assertTrue(secondLastValue is KeyguardQuickAffordanceConfig.LockScreenState.Visible)
-        assertTrue(lastValue is KeyguardQuickAffordanceConfig.LockScreenState.Hidden)
-    }
+            // then
+            assertTrue(secondLastValue is KeyguardQuickAffordanceConfig.LockScreenState.Visible)
+            assertTrue(lastValue is KeyguardQuickAffordanceConfig.LockScreenState.Hidden)
+        }
 
     @Test
-    fun `lockScreenState - dndMode starts as ZEN_MODE_OFF - changes to not OFF - State moves to Visible`() = testScope.runTest {
-        //given
-        whenever(zenModeController.isZenAvailable).thenReturn(true)
-        whenever(zenModeController.zen).thenReturn(ZEN_MODE_OFF)
-        val valueSnapshot = collectLastValue(underTest.lockScreenState)
-        val secondLastValue = valueSnapshot()
-        val callbackCaptor: ArgumentCaptor<ZenModeController.Callback> = argumentCaptor()
-        verify(zenModeController).addCallback(callbackCaptor.capture())
+    fun `lockScreenState - dndMode starts as ZEN_MODE_OFF - change to not OFF - State Visible`() =
+        testScope.runTest {
+            // given
+            whenever(zenModeController.isZenAvailable).thenReturn(true)
+            whenever(zenModeController.zen).thenReturn(ZEN_MODE_OFF)
+            val valueSnapshot = collectLastValue(underTest.lockScreenState)
+            val secondLastValue = valueSnapshot()
+            val callbackCaptor: ArgumentCaptor<ZenModeController.Callback> = argumentCaptor()
+            verify(zenModeController).addCallback(callbackCaptor.capture())
 
-        //when
-        callbackCaptor.value.onZenChanged(ZEN_MODE_IMPORTANT_INTERRUPTIONS)
-        val lastValue = valueSnapshot()
+            // when
+            callbackCaptor.value.onZenChanged(ZEN_MODE_IMPORTANT_INTERRUPTIONS)
+            val lastValue = valueSnapshot()
 
-        //then
-        assertEquals(
-            KeyguardQuickAffordanceConfig.LockScreenState.Visible(
-                Icon.Resource(
-                    R.drawable.qs_dnd_icon_off,
-                    ContentDescription.Resource(R.string.dnd_is_off)
+            // then
+            assertEquals(
+                KeyguardQuickAffordanceConfig.LockScreenState.Visible(
+                    Icon.Resource(
+                        R.drawable.qs_dnd_icon_off,
+                        ContentDescription.Resource(R.string.dnd_is_off)
+                    ),
+                    ActivationState.Inactive
                 ),
-                ActivationState.Inactive
-            ),
-            secondLastValue,
-        )
-        assertEquals(
-            KeyguardQuickAffordanceConfig.LockScreenState.Visible(
-                Icon.Resource(
-                    R.drawable.qs_dnd_icon_on,
-                    ContentDescription.Resource(R.string.dnd_is_on)
+                secondLastValue,
+            )
+            assertEquals(
+                KeyguardQuickAffordanceConfig.LockScreenState.Visible(
+                    Icon.Resource(
+                        R.drawable.qs_dnd_icon_on,
+                        ContentDescription.Resource(R.string.dnd_is_on)
+                    ),
+                    ActivationState.Active
                 ),
-                ActivationState.Active
-            ),
-            lastValue,
-        )
-    }
-}
\ No newline at end of file
+                lastValue,
+            )
+        }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt
index d7e9cf1..b21cec9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt
@@ -22,8 +22,8 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.settings.FakeUserTracker
+import com.android.systemui.shared.customization.data.content.FakeCustomizationProviderClient
 import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
-import com.android.systemui.shared.quickaffordance.data.content.FakeKeyguardQuickAffordanceProviderClient
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -54,16 +54,16 @@
     private lateinit var testScope: TestScope
     private lateinit var testDispatcher: TestDispatcher
     private lateinit var userTracker: FakeUserTracker
-    private lateinit var client1: FakeKeyguardQuickAffordanceProviderClient
-    private lateinit var client2: FakeKeyguardQuickAffordanceProviderClient
+    private lateinit var client1: FakeCustomizationProviderClient
+    private lateinit var client2: FakeCustomizationProviderClient
 
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
         whenever(userHandle.identifier).thenReturn(UserHandle.USER_SYSTEM)
         whenever(userHandle.isSystem).thenReturn(true)
-        client1 = FakeKeyguardQuickAffordanceProviderClient()
-        client2 = FakeKeyguardQuickAffordanceProviderClient()
+        client1 = FakeCustomizationProviderClient()
+        client2 = FakeCustomizationProviderClient()
 
         userTracker = FakeUserTracker()
         userTracker.set(
@@ -122,11 +122,11 @@
 
             client1.insertSelection(
                 slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
-                affordanceId = FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_1,
+                affordanceId = FakeCustomizationProviderClient.AFFORDANCE_1,
             )
             client2.insertSelection(
                 slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
-                affordanceId = FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_2,
+                affordanceId = FakeCustomizationProviderClient.AFFORDANCE_2,
             )
 
             userTracker.set(
@@ -139,7 +139,7 @@
                     mapOf(
                         KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START to
                             listOf(
-                                FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_1,
+                                FakeCustomizationProviderClient.AFFORDANCE_1,
                             ),
                     )
                 )
@@ -154,7 +154,7 @@
                     mapOf(
                         KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END to
                             listOf(
-                                FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_2,
+                                FakeCustomizationProviderClient.AFFORDANCE_2,
                             ),
                     )
                 )
@@ -174,7 +174,7 @@
 
             client1.insertSelection(
                 slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
-                affordanceId = FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_1,
+                affordanceId = FakeCustomizationProviderClient.AFFORDANCE_1,
             )
             userTracker.set(
                 userInfos = userTracker.userProfiles,
@@ -197,7 +197,7 @@
 
             underTest.setSelections(
                 slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
-                affordanceIds = listOf(FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_1),
+                affordanceIds = listOf(FakeCustomizationProviderClient.AFFORDANCE_1),
             )
             runCurrent()
 
@@ -206,7 +206,7 @@
                     mapOf(
                         KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START to
                             listOf(
-                                FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_1,
+                                FakeCustomizationProviderClient.AFFORDANCE_1,
                             ),
                     )
                 )
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
index 6255980..9d2ddff 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
@@ -141,7 +141,7 @@
         whenever(controller.isAbleToOpenCameraApp).thenReturn(true)
 
         assertThat(underTest.getPickerScreenState())
-            .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.Default)
+            .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.Default())
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt
index d875dd9..8f56b95 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt
@@ -114,20 +114,8 @@
     }
 
     @Test
-    fun `affordance - missing icon - model is none`() = runBlockingTest {
-        setUpState(hasWalletIcon = false)
-        var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
-
-        val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
-
-        assertThat(latest).isEqualTo(KeyguardQuickAffordanceConfig.LockScreenState.Hidden)
-
-        job.cancel()
-    }
-
-    @Test
     fun `affordance - no selected card - model is none`() = runBlockingTest {
-        setUpState(hasWalletIcon = false)
+        setUpState(hasSelectedCard = false)
         var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
 
         val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
@@ -159,13 +147,13 @@
         setUpState()
 
         assertThat(underTest.getPickerScreenState())
-            .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.Default)
+            .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.Default())
     }
 
     @Test
     fun `getPickerScreenState - unavailable`() = runTest {
         setUpState(
-            isWalletEnabled = false,
+            isWalletServiceAvailable = false,
         )
 
         assertThat(underTest.getPickerScreenState())
@@ -173,9 +161,9 @@
     }
 
     @Test
-    fun `getPickerScreenState - disabled when there is no icon`() = runTest {
+    fun `getPickerScreenState - disabled when the feature is not enabled`() = runTest {
         setUpState(
-            hasWalletIcon = false,
+            isWalletEnabled = false,
         )
 
         assertThat(underTest.getPickerScreenState())
@@ -194,20 +182,16 @@
 
     private fun setUpState(
         isWalletEnabled: Boolean = true,
+        isWalletServiceAvailable: Boolean = true,
         isWalletQuerySuccessful: Boolean = true,
-        hasWalletIcon: Boolean = true,
         hasSelectedCard: Boolean = true,
     ) {
         whenever(walletController.isWalletEnabled).thenReturn(isWalletEnabled)
 
         val walletClient: QuickAccessWalletClient = mock()
-        val icon: Drawable? =
-            if (hasWalletIcon) {
-                ICON
-            } else {
-                null
-            }
-        whenever(walletClient.tileIcon).thenReturn(icon)
+        whenever(walletClient.tileIcon).thenReturn(ICON)
+        whenever(walletClient.isWalletServiceAvailable).thenReturn(isWalletServiceAvailable)
+
         whenever(walletController.walletClient).thenReturn(walletClient)
 
         whenever(walletController.queryWalletCards(any())).thenAnswer { invocation ->
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt
new file mode 100644
index 0000000..805dcec
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt
@@ -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 com.android.systemui.keyguard.data.quickaffordance
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.ActivityIntentHelper
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.camera.CameraIntentsWrapper
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.settings.FakeUserTracker
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class VideoCameraQuickAffordanceConfigTest : SysuiTestCase() {
+
+    @Mock private lateinit var activityIntentHelper: ActivityIntentHelper
+
+    private lateinit var underTest: VideoCameraQuickAffordanceConfig
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+
+        underTest =
+            VideoCameraQuickAffordanceConfig(
+                context = context,
+                cameraIntents = CameraIntentsWrapper(context),
+                activityIntentHelper = activityIntentHelper,
+                userTracker = FakeUserTracker(),
+            )
+    }
+
+    @Test
+    fun `lockScreenState - visible when launchable`() = runTest {
+        setLaunchable(true)
+
+        val lockScreenState = collectLastValue(underTest.lockScreenState)
+
+        assertThat(lockScreenState())
+            .isInstanceOf(KeyguardQuickAffordanceConfig.LockScreenState.Visible::class.java)
+    }
+
+    @Test
+    fun `lockScreenState - hidden when not launchable`() = runTest {
+        setLaunchable(false)
+
+        val lockScreenState = collectLastValue(underTest.lockScreenState)
+
+        assertThat(lockScreenState())
+            .isEqualTo(KeyguardQuickAffordanceConfig.LockScreenState.Hidden)
+    }
+
+    @Test
+    fun `getPickerScreenState - default when launchable`() = runTest {
+        setLaunchable(true)
+
+        assertThat(underTest.getPickerScreenState())
+            .isInstanceOf(KeyguardQuickAffordanceConfig.PickerScreenState.Default::class.java)
+    }
+
+    @Test
+    fun `getPickerScreenState - unavailable when not launchable`() = runTest {
+        setLaunchable(false)
+
+        assertThat(underTest.getPickerScreenState())
+            .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice)
+    }
+
+    private fun setLaunchable(isLaunchable: Boolean) {
+        whenever(
+                activityIntentHelper.getTargetActivityInfo(
+                    any(),
+                    anyInt(),
+                    anyBoolean(),
+                )
+            )
+            .thenReturn(
+                if (isLaunchable) {
+                    mock()
+                } else {
+                    null
+                }
+            )
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricRepositoryTest.kt
new file mode 100644
index 0000000..a92dd3b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricRepositoryTest.kt
@@ -0,0 +1,176 @@
+/*
+ * 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.data.repository
+
+import android.app.admin.DevicePolicyManager
+import android.content.Intent
+import android.content.pm.UserInfo
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.internal.widget.LockPatternUtils
+import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED
+import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.AuthController
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.user.data.repository.FakeUserRepository
+import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+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
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@RunWith(AndroidTestingRunner::class)
+class BiometricRepositoryTest : SysuiTestCase() {
+    private lateinit var underTest: BiometricRepository
+
+    @Mock private lateinit var authController: AuthController
+    @Mock private lateinit var lockPatternUtils: LockPatternUtils
+    @Mock private lateinit var devicePolicyManager: DevicePolicyManager
+    private lateinit var userRepository: FakeUserRepository
+
+    private lateinit var testDispatcher: TestDispatcher
+    private lateinit var testScope: TestScope
+    private var testableLooper: TestableLooper? = null
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        testableLooper = TestableLooper.get(this)
+        testDispatcher = StandardTestDispatcher()
+        testScope = TestScope(testDispatcher)
+        userRepository = FakeUserRepository()
+    }
+
+    private suspend fun createBiometricRepository() {
+        userRepository.setUserInfos(listOf(PRIMARY_USER))
+        userRepository.setSelectedUserInfo(PRIMARY_USER)
+        underTest =
+            BiometricRepositoryImpl(
+                context = context,
+                lockPatternUtils = lockPatternUtils,
+                broadcastDispatcher = fakeBroadcastDispatcher,
+                authController = authController,
+                userRepository = userRepository,
+                devicePolicyManager = devicePolicyManager,
+                scope = testScope.backgroundScope,
+                backgroundDispatcher = testDispatcher,
+                looper = testableLooper!!.looper,
+            )
+    }
+
+    @Test
+    fun fingerprintEnrollmentChange() =
+        testScope.runTest {
+            createBiometricRepository()
+            val fingerprintEnabledByDevicePolicy = collectLastValue(underTest.isFingerprintEnrolled)
+            runCurrent()
+
+            val captor = argumentCaptor<AuthController.Callback>()
+            verify(authController).addCallback(captor.capture())
+            whenever(authController.isFingerprintEnrolled(anyInt())).thenReturn(true)
+            captor.value.onEnrollmentsChanged(
+                BiometricType.UNDER_DISPLAY_FINGERPRINT,
+                PRIMARY_USER_ID,
+                true
+            )
+            assertThat(fingerprintEnabledByDevicePolicy()).isTrue()
+
+            whenever(authController.isFingerprintEnrolled(anyInt())).thenReturn(false)
+            captor.value.onEnrollmentsChanged(
+                BiometricType.UNDER_DISPLAY_FINGERPRINT,
+                PRIMARY_USER_ID,
+                false
+            )
+            assertThat(fingerprintEnabledByDevicePolicy()).isFalse()
+        }
+
+    @Test
+    fun strongBiometricAllowedChange() =
+        testScope.runTest {
+            createBiometricRepository()
+            val strongBiometricAllowed = collectLastValue(underTest.isStrongBiometricAllowed)
+            runCurrent()
+
+            val captor = argumentCaptor<LockPatternUtils.StrongAuthTracker>()
+            verify(lockPatternUtils).registerStrongAuthTracker(captor.capture())
+
+            captor.value
+                .getStub()
+                .onStrongAuthRequiredChanged(STRONG_AUTH_NOT_REQUIRED, PRIMARY_USER_ID)
+            testableLooper?.processAllMessages() // StrongAuthTracker uses the TestableLooper
+            assertThat(strongBiometricAllowed()).isTrue()
+
+            captor.value
+                .getStub()
+                .onStrongAuthRequiredChanged(STRONG_AUTH_REQUIRED_AFTER_BOOT, PRIMARY_USER_ID)
+            testableLooper?.processAllMessages() // StrongAuthTracker uses the TestableLooper
+            assertThat(strongBiometricAllowed()).isFalse()
+        }
+
+    @Test
+    fun fingerprintDisabledByDpmChange() =
+        testScope.runTest {
+            createBiometricRepository()
+            val fingerprintEnabledByDevicePolicy =
+                collectLastValue(underTest.isFingerprintEnabledByDevicePolicy)
+            runCurrent()
+
+            whenever(devicePolicyManager.getKeyguardDisabledFeatures(any(), anyInt()))
+                .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT)
+            broadcastDPMStateChange()
+            assertThat(fingerprintEnabledByDevicePolicy()).isFalse()
+
+            whenever(devicePolicyManager.getKeyguardDisabledFeatures(any(), anyInt())).thenReturn(0)
+            broadcastDPMStateChange()
+            assertThat(fingerprintEnabledByDevicePolicy()).isTrue()
+        }
+
+    private fun broadcastDPMStateChange() {
+        fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
+            receiver.onReceive(
+                context,
+                Intent(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED)
+            )
+        }
+    }
+
+    companion object {
+        private const val PRIMARY_USER_ID = 0
+        private val PRIMARY_USER =
+            UserInfo(
+                /* id= */ PRIMARY_USER_ID,
+                /* name= */ "primary user",
+                /* flags= */ UserInfo.FLAG_PRIMARY
+            )
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt
new file mode 100644
index 0000000..c4ae2db
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt
@@ -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.systemui.keyguard.data.repository
+
+import android.hardware.biometrics.BiometricSourceType
+import androidx.test.filters.SmallTest
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class DeviceEntryFingerprintAuthRepositoryTest : SysuiTestCase() {
+    @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
+    @Captor private lateinit var callbackCaptor: ArgumentCaptor<KeyguardUpdateMonitorCallback>
+
+    private lateinit var testScope: TestScope
+
+    private lateinit var underTest: DeviceEntryFingerprintAuthRepository
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        testScope = TestScope()
+
+        underTest = DeviceEntryFingerprintAuthRepositoryImpl(keyguardUpdateMonitor)
+    }
+
+    @After
+    fun tearDown() {
+        verify(keyguardUpdateMonitor).removeCallback(callbackCaptor.value)
+    }
+
+    @Test
+    fun isLockedOut_whenFingerprintLockoutStateChanges_emitsNewValue() =
+        testScope.runTest {
+            val isLockedOutValue = collectLastValue(underTest.isLockedOut)
+            runCurrent()
+
+            verify(keyguardUpdateMonitor).registerCallback(callbackCaptor.capture())
+            val callback = callbackCaptor.value
+            whenever(keyguardUpdateMonitor.isFingerprintLockedOut).thenReturn(true)
+
+            callback.onLockedOutStateChanged(BiometricSourceType.FACE)
+            assertThat(isLockedOutValue()).isFalse()
+
+            callback.onLockedOutStateChanged(BiometricSourceType.FINGERPRINT)
+            assertThat(isLockedOutValue()).isTrue()
+
+            whenever(keyguardUpdateMonitor.isFingerprintLockedOut).thenReturn(false)
+            callback.onLockedOutStateChanged(BiometricSourceType.FINGERPRINT)
+            assertThat(isLockedOutValue()).isFalse()
+        }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepositoryTest.kt
index 9970a67..969537d2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepositoryTest.kt
@@ -20,6 +20,7 @@
 import com.android.keyguard.ViewMediatorCallback
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.util.time.SystemClock
 import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.test.TestCoroutineScope
 import org.junit.Before
@@ -34,6 +35,7 @@
 @RunWith(JUnit4::class)
 class KeyguardBouncerRepositoryTest : SysuiTestCase() {
 
+    @Mock private lateinit var systemClock: SystemClock
     @Mock private lateinit var viewMediatorCallback: ViewMediatorCallback
     @Mock private lateinit var bouncerLogger: TableLogBuffer
     lateinit var underTest: KeyguardBouncerRepository
@@ -43,7 +45,12 @@
         MockitoAnnotations.initMocks(this)
         val testCoroutineScope = TestCoroutineScope()
         underTest =
-            KeyguardBouncerRepository(viewMediatorCallback, testCoroutineScope, bouncerLogger)
+            KeyguardBouncerRepository(
+                viewMediatorCallback,
+                systemClock,
+                testCoroutineScope,
+                bouncerLogger,
+            )
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
index c187a3f..b071a02 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
@@ -32,8 +32,8 @@
 import com.android.systemui.keyguard.shared.model.KeyguardSlotPickerRepresentation
 import com.android.systemui.settings.FakeUserTracker
 import com.android.systemui.settings.UserFileManager
+import com.android.systemui.shared.customization.data.content.FakeCustomizationProviderClient
 import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
-import com.android.systemui.shared.quickaffordance.data.content.FakeKeyguardQuickAffordanceProviderClient
 import com.android.systemui.util.FakeSharedPreferences
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
@@ -63,19 +63,13 @@
     private lateinit var config1: FakeKeyguardQuickAffordanceConfig
     private lateinit var config2: FakeKeyguardQuickAffordanceConfig
     private lateinit var userTracker: FakeUserTracker
-    private lateinit var client1: FakeKeyguardQuickAffordanceProviderClient
-    private lateinit var client2: FakeKeyguardQuickAffordanceProviderClient
+    private lateinit var client1: FakeCustomizationProviderClient
+    private lateinit var client2: FakeCustomizationProviderClient
 
     @Before
     fun setUp() {
-        config1 =
-            FakeKeyguardQuickAffordanceConfig(
-                FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_1
-            )
-        config2 =
-            FakeKeyguardQuickAffordanceConfig(
-                FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_2
-            )
+        config1 = FakeKeyguardQuickAffordanceConfig(FakeCustomizationProviderClient.AFFORDANCE_1)
+        config2 = FakeKeyguardQuickAffordanceConfig(FakeCustomizationProviderClient.AFFORDANCE_2)
         val scope = CoroutineScope(IMMEDIATE)
         userTracker = FakeUserTracker()
         val localUserSelectionManager =
@@ -95,8 +89,8 @@
                 userTracker = userTracker,
                 broadcastDispatcher = fakeBroadcastDispatcher,
             )
-        client1 = FakeKeyguardQuickAffordanceProviderClient()
-        client2 = FakeKeyguardQuickAffordanceProviderClient()
+        client1 = FakeCustomizationProviderClient()
+        client2 = FakeCustomizationProviderClient()
         val remoteUserSelectionManager =
             KeyguardQuickAffordanceRemoteUserSelectionManager(
                 scope = scope,
@@ -256,7 +250,7 @@
             )
             client2.insertSelection(
                 slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
-                affordanceId = FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_2,
+                affordanceId = FakeCustomizationProviderClient.AFFORDANCE_2,
             )
             val observed = mutableListOf<Map<String, List<KeyguardQuickAffordanceConfig>>>()
             val job = underTest.selections.onEach { observed.add(it) }.launchIn(this)
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 be712f6..f997d18 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
@@ -24,6 +24,7 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.AuthController
 import com.android.systemui.common.shared.model.Position
+import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.doze.DozeHost
 import com.android.systemui.doze.DozeMachine
 import com.android.systemui.doze.DozeTransitionCallback
@@ -38,14 +39,17 @@
 import com.android.systemui.keyguard.shared.model.WakefulnessState
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.statusbar.phone.BiometricUnlockController
+import com.android.systemui.statusbar.phone.DozeParameters
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.mockito.withArgCaptor
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onCompletion
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
@@ -68,6 +72,7 @@
     @Mock private lateinit var authController: AuthController
     @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
     @Mock private lateinit var dreamOverlayCallbackController: DreamOverlayCallbackController
+    @Mock private lateinit var dozeParameters: DozeParameters
 
     private lateinit var underTest: KeyguardRepositoryImpl
 
@@ -84,6 +89,7 @@
                 keyguardStateController,
                 keyguardUpdateMonitor,
                 dozeTransitionListener,
+                dozeParameters,
                 authController,
                 dreamOverlayCallbackController,
             )
@@ -170,6 +176,26 @@
         }
 
     @Test
+    fun isAodAvailable() = runTest {
+        val flow = underTest.isAodAvailable
+        var isAodAvailable = collectLastValue(flow)
+        runCurrent()
+
+        val callback =
+            withArgCaptor<DozeParameters.Callback> { verify(dozeParameters).addCallback(capture()) }
+
+        whenever(dozeParameters.getAlwaysOn()).thenReturn(false)
+        callback.onAlwaysOnChange()
+        assertThat(isAodAvailable()).isEqualTo(false)
+
+        whenever(dozeParameters.getAlwaysOn()).thenReturn(true)
+        callback.onAlwaysOnChange()
+        assertThat(isAodAvailable()).isEqualTo(true)
+
+        flow.onCompletion { verify(dozeParameters).removeCallback(callback) }
+    }
+
+    @Test
     fun isKeyguardOccluded() =
         runTest(UnconfinedTestDispatcher()) {
             whenever(keyguardStateController.isOccluded).thenReturn(false)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
index 5d2f0eb..32cec09 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
@@ -104,7 +104,7 @@
             val firstTransitionSteps = listWithStep(step = BigDecimal(.1), stop = BigDecimal(.1))
             assertSteps(steps.subList(0, 4), firstTransitionSteps, AOD, LOCKSCREEN)
 
-            val secondTransitionSteps = listWithStep(step = BigDecimal(.1), start = BigDecimal(.9))
+            val secondTransitionSteps = listWithStep(step = BigDecimal(.1), start = BigDecimal(.1))
             assertSteps(steps.subList(4, steps.size), secondTransitionSteps, LOCKSCREEN, AOD)
 
             job.cancel()
@@ -168,6 +168,25 @@
         assertThat(wtfHandler.failed).isTrue()
     }
 
+    @Test
+    fun `Attempt to manually update transition after CANCELED state throws exception`() {
+        val uuid =
+            underTest.startTransition(
+                TransitionInfo(
+                    ownerName = OWNER_NAME,
+                    from = AOD,
+                    to = LOCKSCREEN,
+                    animator = null,
+                )
+            )
+
+        checkNotNull(uuid).let {
+            underTest.updateTransition(it, 0.2f, TransitionState.CANCELED)
+            underTest.updateTransition(it, 0.5f, TransitionState.RUNNING)
+        }
+        assertThat(wtfHandler.failed).isTrue()
+    }
+
     private fun listWithStep(
         step: BigDecimal,
         start: BigDecimal = BigDecimal.ZERO,
@@ -201,7 +220,10 @@
                 )
             )
         fractions.forEachIndexed { index, fraction ->
-            assertThat(steps[index + 1])
+            val step = steps[index + 1]
+            val truncatedValue =
+                BigDecimal(step.value.toDouble()).setScale(2, RoundingMode.HALF_UP).toFloat()
+            assertThat(step.copy(value = truncatedValue))
                 .isEqualTo(
                     TransitionStep(
                         from,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt
new file mode 100644
index 0000000..4b06905
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.data.repository
+
+import android.app.trust.TrustManager
+import android.content.pm.UserInfo
+import androidx.test.filters.SmallTest
+import com.android.keyguard.logging.TrustRepositoryLogger
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.plugins.log.LogBuffer
+import com.android.systemui.plugins.log.LogcatEchoTracker
+import com.android.systemui.user.data.repository.FakeUserRepository
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class TrustRepositoryTest : SysuiTestCase() {
+    @Mock private lateinit var trustManager: TrustManager
+    @Captor private lateinit var listenerCaptor: ArgumentCaptor<TrustManager.TrustListener>
+    private lateinit var userRepository: FakeUserRepository
+    private lateinit var testScope: TestScope
+    private val users = listOf(UserInfo(1, "user 1", 0), UserInfo(2, "user 1", 0))
+
+    private lateinit var underTest: TrustRepository
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        testScope = TestScope()
+        userRepository = FakeUserRepository()
+        userRepository.setUserInfos(users)
+
+        val logger =
+            TrustRepositoryLogger(
+                LogBuffer("TestBuffer", 1, mock(LogcatEchoTracker::class.java), false)
+            )
+        underTest =
+            TrustRepositoryImpl(testScope.backgroundScope, userRepository, trustManager, logger)
+    }
+
+    @Test
+    fun isCurrentUserTrusted_whenTrustChanges_emitsLatestValue() =
+        testScope.runTest {
+            runCurrent()
+            verify(trustManager).registerTrustListener(listenerCaptor.capture())
+            val listener = listenerCaptor.value
+
+            val currentUserId = users[0].id
+            userRepository.setSelectedUserInfo(users[0])
+            val isCurrentUserTrusted = collectLastValue(underTest.isCurrentUserTrusted)
+
+            listener.onTrustChanged(true, false, currentUserId, 0, emptyList())
+            assertThat(isCurrentUserTrusted()).isTrue()
+
+            listener.onTrustChanged(false, false, currentUserId, 0, emptyList())
+
+            assertThat(isCurrentUserTrusted()).isFalse()
+        }
+
+    @Test
+    fun isCurrentUserTrusted_isFalse_byDefault() =
+        testScope.runTest {
+            runCurrent()
+
+            val isCurrentUserTrusted = collectLastValue(underTest.isCurrentUserTrusted)
+
+            assertThat(isCurrentUserTrusted()).isFalse()
+        }
+
+    @Test
+    fun isCurrentUserTrusted_whenTrustChangesForDifferentUser_noop() =
+        testScope.runTest {
+            runCurrent()
+            verify(trustManager).registerTrustListener(listenerCaptor.capture())
+            userRepository.setSelectedUserInfo(users[0])
+            val listener = listenerCaptor.value
+
+            val isCurrentUserTrusted = collectLastValue(underTest.isCurrentUserTrusted)
+            // current user is trusted.
+            listener.onTrustChanged(true, true, users[0].id, 0, emptyList())
+            // some other user is not trusted.
+            listener.onTrustChanged(false, false, users[1].id, 0, emptyList())
+
+            assertThat(isCurrentUserTrusted()).isTrue()
+        }
+
+    @Test
+    fun isCurrentUserTrusted_whenTrustChangesForCurrentUser_emitsNewValue() =
+        testScope.runTest {
+            runCurrent()
+            verify(trustManager).registerTrustListener(listenerCaptor.capture())
+            val listener = listenerCaptor.value
+            userRepository.setSelectedUserInfo(users[0])
+
+            val isCurrentUserTrusted = collectLastValue(underTest.isCurrentUserTrusted)
+            listener.onTrustChanged(true, true, users[0].id, 0, emptyList())
+            assertThat(isCurrentUserTrusted()).isTrue()
+
+            listener.onTrustChanged(false, true, users[0].id, 0, emptyList())
+            assertThat(isCurrentUserTrusted()).isFalse()
+        }
+
+    @Test
+    fun isCurrentUserTrusted_whenUserChangesWithoutRecentTrustChange_defaultsToFalse() =
+        testScope.runTest {
+            runCurrent()
+            verify(trustManager).registerTrustListener(listenerCaptor.capture())
+            val listener = listenerCaptor.value
+            userRepository.setSelectedUserInfo(users[0])
+            listener.onTrustChanged(true, true, users[0].id, 0, emptyList())
+
+            val isCurrentUserTrusted = collectLastValue(underTest.isCurrentUserTrusted)
+            userRepository.setSelectedUserInfo(users[1])
+
+            assertThat(isCurrentUserTrusted()).isFalse()
+        }
+
+    @Test
+    fun isCurrentUserTrusted_trustChangesFirstBeforeUserInfoChanges_emitsCorrectValue() =
+        testScope.runTest {
+            runCurrent()
+            verify(trustManager).registerTrustListener(listenerCaptor.capture())
+            val listener = listenerCaptor.value
+            val isCurrentUserTrusted = collectLastValue(underTest.isCurrentUserTrusted)
+
+            listener.onTrustChanged(true, true, users[0].id, 0, emptyList())
+            assertThat(isCurrentUserTrusted()).isFalse()
+
+            userRepository.setSelectedUserInfo(users[0])
+
+            assertThat(isCurrentUserTrusted()).isTrue()
+        }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt
new file mode 100644
index 0000000..1da7241
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt
@@ -0,0 +1,156 @@
+/*
+ * 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.interactor
+
+import androidx.test.filters.SmallTest
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.ViewMediatorCallback
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.data.repository.FakeBiometricRepository
+import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepository
+import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.util.time.FakeSystemClock
+import com.android.systemui.util.time.SystemClock
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestCoroutineScope
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.Mock
+import org.mockito.Mockito.mock
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class AlternateBouncerInteractorTest : SysuiTestCase() {
+    private lateinit var underTest: AlternateBouncerInteractor
+    private lateinit var bouncerRepository: KeyguardBouncerRepository
+    private lateinit var biometricRepository: FakeBiometricRepository
+    @Mock private lateinit var systemClock: SystemClock
+    @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
+    @Mock private lateinit var bouncerLogger: TableLogBuffer
+    private lateinit var featureFlags: FakeFeatureFlags
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+        bouncerRepository =
+            KeyguardBouncerRepository(
+                mock(ViewMediatorCallback::class.java),
+                FakeSystemClock(),
+                TestCoroutineScope(),
+                bouncerLogger,
+            )
+        biometricRepository = FakeBiometricRepository()
+        featureFlags = FakeFeatureFlags().apply { this.set(Flags.MODERN_ALTERNATE_BOUNCER, true) }
+        underTest =
+            AlternateBouncerInteractor(
+                bouncerRepository,
+                biometricRepository,
+                systemClock,
+                keyguardUpdateMonitor,
+                featureFlags,
+            )
+    }
+
+    @Test
+    fun canShowAlternateBouncerForFingerprint_givenCanShow() {
+        givenCanShowAlternateBouncer()
+        assertTrue(underTest.canShowAlternateBouncerForFingerprint())
+    }
+
+    @Test
+    fun canShowAlternateBouncerForFingerprint_alternateBouncerUIUnavailable() {
+        givenCanShowAlternateBouncer()
+        bouncerRepository.setAlternateBouncerUIAvailable(false)
+
+        assertFalse(underTest.canShowAlternateBouncerForFingerprint())
+    }
+
+    @Test
+    fun canShowAlternateBouncerForFingerprint_noFingerprintsEnrolled() {
+        givenCanShowAlternateBouncer()
+        biometricRepository.setFingerprintEnrolled(false)
+
+        assertFalse(underTest.canShowAlternateBouncerForFingerprint())
+    }
+
+    @Test
+    fun canShowAlternateBouncerForFingerprint_strongBiometricNotAllowed() {
+        givenCanShowAlternateBouncer()
+        biometricRepository.setStrongBiometricAllowed(false)
+
+        assertFalse(underTest.canShowAlternateBouncerForFingerprint())
+    }
+
+    @Test
+    fun canShowAlternateBouncerForFingerprint_devicePolicyDoesNotAllowFingerprint() {
+        givenCanShowAlternateBouncer()
+        biometricRepository.setFingerprintEnabledByDevicePolicy(false)
+
+        assertFalse(underTest.canShowAlternateBouncerForFingerprint())
+    }
+
+    @Test
+    fun show_whenCanShow() {
+        givenCanShowAlternateBouncer()
+
+        assertTrue(underTest.show())
+        assertTrue(bouncerRepository.isAlternateBouncerVisible.value)
+    }
+
+    @Test
+    fun show_whenCannotShow() {
+        givenCannotShowAlternateBouncer()
+
+        assertFalse(underTest.show())
+        assertFalse(bouncerRepository.isAlternateBouncerVisible.value)
+    }
+
+    @Test
+    fun hide_wasPreviouslyShowing() {
+        bouncerRepository.setAlternateVisible(true)
+
+        assertTrue(underTest.hide())
+        assertFalse(bouncerRepository.isAlternateBouncerVisible.value)
+    }
+
+    @Test
+    fun hide_wasNotPreviouslyShowing() {
+        bouncerRepository.setAlternateVisible(false)
+
+        assertFalse(underTest.hide())
+        assertFalse(bouncerRepository.isAlternateBouncerVisible.value)
+    }
+
+    private fun givenCanShowAlternateBouncer() {
+        bouncerRepository.setAlternateBouncerUIAvailable(true)
+        biometricRepository.setFingerprintEnrolled(true)
+        biometricRepository.setStrongBiometricAllowed(true)
+        biometricRepository.setFingerprintEnabledByDevicePolicy(true)
+    }
+
+    private fun givenCannotShowAlternateBouncer() {
+        biometricRepository.setFingerprintEnrolled(false)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
new file mode 100644
index 0000000..68d13d3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
@@ -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.systemui.keyguard.domain.interactor
+
+import android.app.StatusBarManager
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
+import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel
+import com.android.systemui.statusbar.CommandQueue
+import com.android.systemui.statusbar.CommandQueue.Callbacks
+import com.android.systemui.util.mockito.argumentCaptor
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.flow.onCompletion
+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.junit.runners.JUnit4
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(JUnit4::class)
+class KeyguardInteractorTest : SysuiTestCase() {
+    @Mock private lateinit var commandQueue: CommandQueue
+
+    private lateinit var underTest: KeyguardInteractor
+    private lateinit var repository: FakeKeyguardRepository
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+
+        repository = FakeKeyguardRepository()
+        underTest = KeyguardInteractor(repository, commandQueue)
+    }
+
+    @Test
+    fun onCameraLaunchDetected() = runTest {
+        val flow = underTest.onCameraLaunchDetected
+        var cameraLaunchSource = collectLastValue(flow)
+        runCurrent()
+
+        val captor = argumentCaptor<CommandQueue.Callbacks>()
+        verify(commandQueue).addCallback(captor.capture())
+
+        captor.value.onCameraLaunchGestureDetected(StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE)
+        assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.WIGGLE)
+
+        captor.value.onCameraLaunchGestureDetected(
+            StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP
+        )
+        assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.POWER_DOUBLE_TAP)
+
+        captor.value.onCameraLaunchGestureDetected(
+            StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER
+        )
+        assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.LIFT_TRIGGER)
+
+        captor.value.onCameraLaunchGestureDetected(
+            StatusBarManager.CAMERA_LAUNCH_SOURCE_QUICK_AFFORDANCE
+        )
+        assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.QUICK_AFFORDANCE)
+
+        flow.onCompletion { verify(commandQueue).removeCallback(captor.value) }
+    }
+}
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 14b7c31..43287b0 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
@@ -44,6 +44,7 @@
 import com.android.systemui.settings.FakeUserTracker
 import com.android.systemui.settings.UserFileManager
 import com.android.systemui.settings.UserTracker
+import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.util.FakeSharedPreferences
 import com.android.systemui.util.mockito.any
@@ -216,6 +217,7 @@
     @Mock private lateinit var animationController: ActivityLaunchAnimator.Controller
     @Mock private lateinit var expandable: Expandable
     @Mock private lateinit var launchAnimator: DialogLaunchAnimator
+    @Mock private lateinit var commandQueue: CommandQueue
 
     private lateinit var underTest: KeyguardQuickAffordanceInteractor
 
@@ -286,7 +288,11 @@
             )
         underTest =
             KeyguardQuickAffordanceInteractor(
-                keyguardInteractor = KeyguardInteractor(repository = FakeKeyguardRepository()),
+                keyguardInteractor =
+                    KeyguardInteractor(
+                        repository = FakeKeyguardRepository(),
+                        commandQueue = commandQueue
+                    ),
                 registry =
                     FakeKeyguardQuickAffordanceRegistry(
                         mapOf(
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 972919a..b75a15d 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
@@ -46,6 +46,7 @@
 import com.android.systemui.settings.UserFileManager
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
+import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.util.FakeSharedPreferences
 import com.android.systemui.util.mockito.mock
@@ -75,6 +76,7 @@
     @Mock private lateinit var userTracker: UserTracker
     @Mock private lateinit var activityStarter: ActivityStarter
     @Mock private lateinit var launchAnimator: DialogLaunchAnimator
+    @Mock private lateinit var commandQueue: CommandQueue
 
     private lateinit var underTest: KeyguardQuickAffordanceInteractor
 
@@ -152,7 +154,8 @@
 
         underTest =
             KeyguardQuickAffordanceInteractor(
-                keyguardInteractor = KeyguardInteractor(repository = repository),
+                keyguardInteractor =
+                    KeyguardInteractor(repository = repository, commandQueue = commandQueue),
                 registry =
                     FakeKeyguardQuickAffordanceRegistry(
                         mapOf(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
index d2b7838..5a7a3d4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.keyguard.domain.interactor
 
 import android.animation.ValueAnimator
+import androidx.test.filters.FlakyTest
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.Interpolators
@@ -33,10 +34,12 @@
 import com.android.systemui.keyguard.util.KeyguardTransitionRunner
 import com.android.systemui.shade.data.repository.FakeShadeRepository
 import com.android.systemui.shade.data.repository.ShadeRepository
+import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.util.mockito.withArgCaptor
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.cancelChildren
 import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.advanceUntilIdle
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -54,6 +57,7 @@
  */
 @SmallTest
 @RunWith(JUnit4::class)
+@FlakyTest(bugId = 265303901)
 class KeyguardTransitionScenariosTest : SysuiTestCase() {
     private lateinit var testScope: TestScope
 
@@ -66,9 +70,14 @@
 
     // Used to verify transition requests for test output
     @Mock private lateinit var mockTransitionRepository: KeyguardTransitionRepository
+    @Mock private lateinit var commandQueue: CommandQueue
 
     private lateinit var fromLockscreenTransitionInteractor: FromLockscreenTransitionInteractor
     private lateinit var fromDreamingTransitionInteractor: FromDreamingTransitionInteractor
+    private lateinit var fromDozingTransitionInteractor: FromDozingTransitionInteractor
+    private lateinit var fromOccludedTransitionInteractor: FromOccludedTransitionInteractor
+    private lateinit var fromGoneTransitionInteractor: FromGoneTransitionInteractor
+    private lateinit var fromAodTransitionInteractor: FromAodTransitionInteractor
 
     @Before
     fun setUp() {
@@ -85,7 +94,7 @@
         fromLockscreenTransitionInteractor =
             FromLockscreenTransitionInteractor(
                 scope = testScope,
-                keyguardInteractor = KeyguardInteractor(keyguardRepository),
+                keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
                 shadeRepository = shadeRepository,
                 keyguardTransitionRepository = mockTransitionRepository,
                 keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
@@ -95,11 +104,47 @@
         fromDreamingTransitionInteractor =
             FromDreamingTransitionInteractor(
                 scope = testScope,
-                keyguardInteractor = KeyguardInteractor(keyguardRepository),
+                keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
                 keyguardTransitionRepository = mockTransitionRepository,
                 keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
             )
         fromDreamingTransitionInteractor.start()
+
+        fromAodTransitionInteractor =
+            FromAodTransitionInteractor(
+                scope = testScope,
+                keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
+                keyguardTransitionRepository = mockTransitionRepository,
+                keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
+            )
+        fromAodTransitionInteractor.start()
+
+        fromGoneTransitionInteractor =
+            FromGoneTransitionInteractor(
+                scope = testScope,
+                keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
+                keyguardTransitionRepository = mockTransitionRepository,
+                keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
+            )
+        fromGoneTransitionInteractor.start()
+
+        fromDozingTransitionInteractor =
+            FromDozingTransitionInteractor(
+                scope = testScope,
+                keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
+                keyguardTransitionRepository = mockTransitionRepository,
+                keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
+            )
+        fromDozingTransitionInteractor.start()
+
+        fromOccludedTransitionInteractor =
+            FromOccludedTransitionInteractor(
+                scope = testScope,
+                keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
+                keyguardTransitionRepository = mockTransitionRepository,
+                keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
+            )
+        fromOccludedTransitionInteractor.start()
     }
 
     @Test
@@ -135,7 +180,7 @@
             keyguardRepository.setDreamingWithOverlay(false)
             // AND occluded has stopped
             keyguardRepository.setKeyguardOccluded(false)
-            runCurrent()
+            advanceUntilIdle()
 
             val info =
                 withArgCaptor<TransitionInfo> {
@@ -190,6 +235,332 @@
             coroutineContext.cancelChildren()
         }
 
+    @Test
+    fun `OCCLUDED to DOZING`() =
+        testScope.runTest {
+            // GIVEN a device with AOD not available
+            keyguardRepository.setAodAvailable(false)
+            runCurrent()
+
+            // GIVEN a prior transition has run to OCCLUDED
+            runner.startTransition(
+                testScope,
+                TransitionInfo(
+                    ownerName = "",
+                    from = KeyguardState.LOCKSCREEN,
+                    to = KeyguardState.OCCLUDED,
+                    animator =
+                        ValueAnimator().apply {
+                            duration = 10
+                            interpolator = Interpolators.LINEAR
+                        },
+                )
+            )
+            runCurrent()
+            reset(mockTransitionRepository)
+
+            // WHEN the device begins to sleep
+            keyguardRepository.setWakefulnessModel(startingToSleep())
+            runCurrent()
+
+            val info =
+                withArgCaptor<TransitionInfo> {
+                    verify(mockTransitionRepository).startTransition(capture())
+                }
+            // THEN a transition to DOZING should occur
+            assertThat(info.ownerName).isEqualTo("FromOccludedTransitionInteractor")
+            assertThat(info.from).isEqualTo(KeyguardState.OCCLUDED)
+            assertThat(info.to).isEqualTo(KeyguardState.DOZING)
+            assertThat(info.animator).isNotNull()
+
+            coroutineContext.cancelChildren()
+        }
+
+    @Test
+    fun `OCCLUDED to AOD`() =
+        testScope.runTest {
+            // GIVEN a device with AOD available
+            keyguardRepository.setAodAvailable(true)
+            runCurrent()
+
+            // GIVEN a prior transition has run to OCCLUDED
+            runner.startTransition(
+                testScope,
+                TransitionInfo(
+                    ownerName = "",
+                    from = KeyguardState.LOCKSCREEN,
+                    to = KeyguardState.OCCLUDED,
+                    animator =
+                        ValueAnimator().apply {
+                            duration = 10
+                            interpolator = Interpolators.LINEAR
+                        },
+                )
+            )
+            runCurrent()
+            reset(mockTransitionRepository)
+
+            // WHEN the device begins to sleep
+            keyguardRepository.setWakefulnessModel(startingToSleep())
+            runCurrent()
+
+            val info =
+                withArgCaptor<TransitionInfo> {
+                    verify(mockTransitionRepository).startTransition(capture())
+                }
+            // THEN a transition to DOZING should occur
+            assertThat(info.ownerName).isEqualTo("FromOccludedTransitionInteractor")
+            assertThat(info.from).isEqualTo(KeyguardState.OCCLUDED)
+            assertThat(info.to).isEqualTo(KeyguardState.AOD)
+            assertThat(info.animator).isNotNull()
+
+            coroutineContext.cancelChildren()
+        }
+
+    @Test
+    fun `LOCKSCREEN to DOZING`() =
+        testScope.runTest {
+            // GIVEN a device with AOD not available
+            keyguardRepository.setAodAvailable(false)
+            runCurrent()
+
+            // GIVEN a prior transition has run to LOCKSCREEN
+            runner.startTransition(
+                testScope,
+                TransitionInfo(
+                    ownerName = "",
+                    from = KeyguardState.GONE,
+                    to = KeyguardState.LOCKSCREEN,
+                    animator =
+                        ValueAnimator().apply {
+                            duration = 10
+                            interpolator = Interpolators.LINEAR
+                        },
+                )
+            )
+            runCurrent()
+            reset(mockTransitionRepository)
+
+            // WHEN the device begins to sleep
+            keyguardRepository.setWakefulnessModel(startingToSleep())
+            runCurrent()
+
+            val info =
+                withArgCaptor<TransitionInfo> {
+                    verify(mockTransitionRepository).startTransition(capture())
+                }
+            // THEN a transition to DOZING should occur
+            assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor")
+            assertThat(info.from).isEqualTo(KeyguardState.LOCKSCREEN)
+            assertThat(info.to).isEqualTo(KeyguardState.DOZING)
+            assertThat(info.animator).isNotNull()
+
+            coroutineContext.cancelChildren()
+        }
+
+    @Test
+    fun `LOCKSCREEN to AOD`() =
+        testScope.runTest {
+            // GIVEN a device with AOD available
+            keyguardRepository.setAodAvailable(true)
+            runCurrent()
+
+            // GIVEN a prior transition has run to LOCKSCREEN
+            runner.startTransition(
+                testScope,
+                TransitionInfo(
+                    ownerName = "",
+                    from = KeyguardState.GONE,
+                    to = KeyguardState.LOCKSCREEN,
+                    animator =
+                        ValueAnimator().apply {
+                            duration = 10
+                            interpolator = Interpolators.LINEAR
+                        },
+                )
+            )
+            runCurrent()
+            reset(mockTransitionRepository)
+
+            // WHEN the device begins to sleep
+            keyguardRepository.setWakefulnessModel(startingToSleep())
+            runCurrent()
+
+            val info =
+                withArgCaptor<TransitionInfo> {
+                    verify(mockTransitionRepository).startTransition(capture())
+                }
+            // THEN a transition to DOZING should occur
+            assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor")
+            assertThat(info.from).isEqualTo(KeyguardState.LOCKSCREEN)
+            assertThat(info.to).isEqualTo(KeyguardState.AOD)
+            assertThat(info.animator).isNotNull()
+
+            coroutineContext.cancelChildren()
+        }
+
+    @Test
+    fun `DOZING to LOCKSCREEN`() =
+        testScope.runTest {
+            // GIVEN a prior transition has run to DOZING
+            runner.startTransition(
+                testScope,
+                TransitionInfo(
+                    ownerName = "",
+                    from = KeyguardState.LOCKSCREEN,
+                    to = KeyguardState.DOZING,
+                    animator =
+                        ValueAnimator().apply {
+                            duration = 10
+                            interpolator = Interpolators.LINEAR
+                        },
+                )
+            )
+            runCurrent()
+            reset(mockTransitionRepository)
+
+            // WHEN the device begins to wake
+            keyguardRepository.setWakefulnessModel(startingToWake())
+            runCurrent()
+
+            val info =
+                withArgCaptor<TransitionInfo> {
+                    verify(mockTransitionRepository).startTransition(capture())
+                }
+            // THEN a transition to DOZING should occur
+            assertThat(info.ownerName).isEqualTo("FromDozingTransitionInteractor")
+            assertThat(info.from).isEqualTo(KeyguardState.DOZING)
+            assertThat(info.to).isEqualTo(KeyguardState.LOCKSCREEN)
+            assertThat(info.animator).isNotNull()
+
+            coroutineContext.cancelChildren()
+        }
+
+    @Test
+    fun `GONE to DOZING`() =
+        testScope.runTest {
+            // GIVEN a device with AOD not available
+            keyguardRepository.setAodAvailable(false)
+            runCurrent()
+
+            // GIVEN a prior transition has run to GONE
+            runner.startTransition(
+                testScope,
+                TransitionInfo(
+                    ownerName = "",
+                    from = KeyguardState.LOCKSCREEN,
+                    to = KeyguardState.GONE,
+                    animator =
+                        ValueAnimator().apply {
+                            duration = 10
+                            interpolator = Interpolators.LINEAR
+                        },
+                )
+            )
+            runCurrent()
+            reset(mockTransitionRepository)
+
+            // WHEN the device begins to sleep
+            keyguardRepository.setWakefulnessModel(startingToSleep())
+            runCurrent()
+
+            val info =
+                withArgCaptor<TransitionInfo> {
+                    verify(mockTransitionRepository).startTransition(capture())
+                }
+            // THEN a transition to DOZING should occur
+            assertThat(info.ownerName).isEqualTo("FromGoneTransitionInteractor")
+            assertThat(info.from).isEqualTo(KeyguardState.GONE)
+            assertThat(info.to).isEqualTo(KeyguardState.DOZING)
+            assertThat(info.animator).isNotNull()
+
+            coroutineContext.cancelChildren()
+        }
+
+    @Test
+    fun `GONE to AOD`() =
+        testScope.runTest {
+            // GIVEN a device with AOD available
+            keyguardRepository.setAodAvailable(true)
+            runCurrent()
+
+            // GIVEN a prior transition has run to GONE
+            runner.startTransition(
+                testScope,
+                TransitionInfo(
+                    ownerName = "",
+                    from = KeyguardState.LOCKSCREEN,
+                    to = KeyguardState.GONE,
+                    animator =
+                        ValueAnimator().apply {
+                            duration = 10
+                            interpolator = Interpolators.LINEAR
+                        },
+                )
+            )
+            runCurrent()
+            reset(mockTransitionRepository)
+
+            // WHEN the device begins to sleep
+            keyguardRepository.setWakefulnessModel(startingToSleep())
+            runCurrent()
+
+            val info =
+                withArgCaptor<TransitionInfo> {
+                    verify(mockTransitionRepository).startTransition(capture())
+                }
+            // THEN a transition to AOD should occur
+            assertThat(info.ownerName).isEqualTo("FromGoneTransitionInteractor")
+            assertThat(info.from).isEqualTo(KeyguardState.GONE)
+            assertThat(info.to).isEqualTo(KeyguardState.AOD)
+            assertThat(info.animator).isNotNull()
+
+            coroutineContext.cancelChildren()
+        }
+
+    @Test
+    fun `GONE to DREAMING`() =
+        testScope.runTest {
+            // GIVEN a device that is not dreaming or dozing
+            keyguardRepository.setDreamingWithOverlay(false)
+            keyguardRepository.setDozeTransitionModel(
+                DozeTransitionModel(from = DozeStateModel.DOZE, to = DozeStateModel.FINISH)
+            )
+            runCurrent()
+
+            // GIVEN a prior transition has run to GONE
+            runner.startTransition(
+                testScope,
+                TransitionInfo(
+                    ownerName = "",
+                    from = KeyguardState.LOCKSCREEN,
+                    to = KeyguardState.GONE,
+                    animator =
+                        ValueAnimator().apply {
+                            duration = 10
+                            interpolator = Interpolators.LINEAR
+                        },
+                )
+            )
+            reset(mockTransitionRepository)
+
+            // WHEN the device begins to dream
+            keyguardRepository.setDreamingWithOverlay(true)
+            advanceUntilIdle()
+
+            val info =
+                withArgCaptor<TransitionInfo> {
+                    verify(mockTransitionRepository).startTransition(capture())
+                }
+            // THEN a transition to DREAMING should occur
+            assertThat(info.ownerName).isEqualTo("FromGoneTransitionInteractor")
+            assertThat(info.from).isEqualTo(KeyguardState.GONE)
+            assertThat(info.to).isEqualTo(KeyguardState.DREAMING)
+            assertThat(info.animator).isNotNull()
+
+            coroutineContext.cancelChildren()
+        }
+
     private fun startingToWake() =
         WakefulnessModel(
             WakefulnessState.STARTING_TO_WAKE,
@@ -197,4 +568,12 @@
             WakeSleepReason.OTHER,
             WakeSleepReason.OTHER
         )
+
+    private fun startingToSleep() =
+        WakefulnessModel(
+            WakefulnessState.STARTING_TO_SLEEP,
+            true,
+            WakeSleepReason.OTHER,
+            WakeSleepReason.OTHER
+        )
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt
index db9c4e7..fbfeca9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt
@@ -19,7 +19,6 @@
 import android.view.View
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.statusbar.phone.KeyguardBouncer
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -34,8 +33,10 @@
     private val mPrimaryBouncerCallbackInteractor = PrimaryBouncerCallbackInteractor()
     @Mock
     private lateinit var mPrimaryBouncerExpansionCallback:
-        KeyguardBouncer.PrimaryBouncerExpansionCallback
-    @Mock private lateinit var keyguardResetCallback: KeyguardBouncer.KeyguardResetCallback
+        PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback
+    @Mock
+    private lateinit var keyguardResetCallback:
+        PrimaryBouncerCallbackInteractor.KeyguardResetCallback
 
     @Before
     fun setup() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt
index a6fc13b..7f48ea1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt
@@ -30,11 +30,11 @@
 import com.android.systemui.keyguard.data.BouncerView
 import com.android.systemui.keyguard.data.BouncerViewDelegate
 import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepository
+import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_HIDDEN
+import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_VISIBLE
 import com.android.systemui.keyguard.shared.model.BouncerShowMessageModel
 import com.android.systemui.keyguard.shared.model.KeyguardBouncerModel
 import com.android.systemui.plugins.ActivityStarter
-import com.android.systemui.statusbar.phone.KeyguardBouncer.EXPANSION_HIDDEN
-import com.android.systemui.statusbar.phone.KeyguardBouncer.EXPANSION_VISIBLE
 import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.util.mockito.any
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt
new file mode 100644
index 0000000..7fa204b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE
+import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.domain.interactor.FromGoneTransitionInteractor.Companion.TO_DREAMING_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.AnimationParams
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingTransitionViewModel.Companion.LOCKSCREEN_ALPHA
+import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingTransitionViewModel.Companion.LOCKSCREEN_TRANSLATION_Y
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+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.junit.runners.JUnit4
+
+@SmallTest
+@RunWith(JUnit4::class)
+class GoneToDreamingTransitionViewModelTest : SysuiTestCase() {
+    private lateinit var underTest: GoneToDreamingTransitionViewModel
+    private lateinit var repository: FakeKeyguardTransitionRepository
+
+    @Before
+    fun setUp() {
+        repository = FakeKeyguardTransitionRepository()
+        val interactor = KeyguardTransitionInteractor(repository)
+        underTest = GoneToDreamingTransitionViewModel(interactor)
+    }
+
+    @Test
+    fun lockscreenFadeOut() =
+        runTest(UnconfinedTestDispatcher()) {
+            val values = mutableListOf<Float>()
+
+            val job = underTest.lockscreenAlpha.onEach { values.add(it) }.launchIn(this)
+
+            // Should start running here...
+            repository.sendTransitionStep(step(0f))
+            repository.sendTransitionStep(step(0.1f))
+            repository.sendTransitionStep(step(0.2f))
+            // ...up to here
+            repository.sendTransitionStep(step(0.3f))
+            repository.sendTransitionStep(step(1f))
+
+            // Only three values should be present, since the dream overlay runs for a small
+            // fraction
+            // of the overall animation time
+            assertThat(values.size).isEqualTo(3)
+            assertThat(values[0]).isEqualTo(1f - animValue(0f, LOCKSCREEN_ALPHA))
+            assertThat(values[1]).isEqualTo(1f - animValue(0.1f, LOCKSCREEN_ALPHA))
+            assertThat(values[2]).isEqualTo(1f - animValue(0.2f, LOCKSCREEN_ALPHA))
+
+            job.cancel()
+        }
+
+    @Test
+    fun lockscreenTranslationY() =
+        runTest(UnconfinedTestDispatcher()) {
+            val values = mutableListOf<Float>()
+
+            val pixels = 100
+            val job =
+                underTest.lockscreenTranslationY(pixels).onEach { values.add(it) }.launchIn(this)
+
+            // Should start running here...
+            repository.sendTransitionStep(step(0f))
+            repository.sendTransitionStep(step(0.3f))
+            repository.sendTransitionStep(step(0.5f))
+            // ...up to here
+            repository.sendTransitionStep(step(1f))
+            // And a final reset event on CANCEL
+            repository.sendTransitionStep(step(0.8f, TransitionState.CANCELED))
+
+            assertThat(values.size).isEqualTo(4)
+            assertThat(values[0])
+                .isEqualTo(
+                    EMPHASIZED_ACCELERATE.getInterpolation(
+                        animValue(0f, LOCKSCREEN_TRANSLATION_Y)
+                    ) * pixels
+                )
+            assertThat(values[1])
+                .isEqualTo(
+                    EMPHASIZED_ACCELERATE.getInterpolation(
+                        animValue(0.3f, LOCKSCREEN_TRANSLATION_Y)
+                    ) * pixels
+                )
+            assertThat(values[2])
+                .isEqualTo(
+                    EMPHASIZED_ACCELERATE.getInterpolation(
+                        animValue(0.5f, LOCKSCREEN_TRANSLATION_Y)
+                    ) * pixels
+                )
+            assertThat(values[3]).isEqualTo(0f)
+            job.cancel()
+        }
+
+    private fun animValue(stepValue: Float, params: AnimationParams): Float {
+        val totalDuration = TO_DREAMING_DURATION
+        val startValue = (params.startTime / totalDuration).toFloat()
+
+        val multiplier = (totalDuration / params.duration).toFloat()
+        return (stepValue - startValue) * multiplier
+    }
+
+    private fun step(
+        value: Float,
+        state: TransitionState = TransitionState.RUNNING
+    ): TransitionStep {
+        return TransitionStep(
+            from = KeyguardState.GONE,
+            to = KeyguardState.DREAMING,
+            value = value,
+            transitionState = state,
+            ownerName = "GoneToDreamingTransitionViewModelTest"
+        )
+    }
+}
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 a2c2f71..022afdd 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
@@ -47,6 +47,7 @@
 import com.android.systemui.settings.UserFileManager
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
+import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.util.FakeSharedPreferences
 import com.android.systemui.util.mockito.any
@@ -84,6 +85,7 @@
     @Mock private lateinit var userTracker: UserTracker
     @Mock private lateinit var activityStarter: ActivityStarter
     @Mock private lateinit var launchAnimator: DialogLaunchAnimator
+    @Mock private lateinit var commandQueue: CommandQueue
 
     private lateinit var underTest: KeyguardBottomAreaViewModel
 
@@ -124,7 +126,8 @@
             )
         repository = FakeKeyguardRepository()
 
-        val keyguardInteractor = KeyguardInteractor(repository = repository)
+        val keyguardInteractor =
+            KeyguardInteractor(repository = repository, commandQueue = commandQueue)
         whenever(userTracker.userHandle).thenReturn(mock())
         whenever(lockPatternUtils.getStrongAuthForUser(anyInt()))
             .thenReturn(LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt
new file mode 100644
index 0000000..539fc2c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE
+import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor.Companion.TO_DREAMING_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.AnimationParams
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel.Companion.LOCKSCREEN_ALPHA
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel.Companion.LOCKSCREEN_TRANSLATION_Y
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+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.junit.runners.JUnit4
+
+@SmallTest
+@RunWith(JUnit4::class)
+class LockscreenToDreamingTransitionViewModelTest : SysuiTestCase() {
+    private lateinit var underTest: LockscreenToDreamingTransitionViewModel
+    private lateinit var repository: FakeKeyguardTransitionRepository
+
+    @Before
+    fun setUp() {
+        repository = FakeKeyguardTransitionRepository()
+        val interactor = KeyguardTransitionInteractor(repository)
+        underTest = LockscreenToDreamingTransitionViewModel(interactor)
+    }
+
+    @Test
+    fun lockscreenFadeOut() =
+        runTest(UnconfinedTestDispatcher()) {
+            val values = mutableListOf<Float>()
+
+            val job = underTest.lockscreenAlpha.onEach { values.add(it) }.launchIn(this)
+
+            // Should start running here...
+            repository.sendTransitionStep(step(0f))
+            repository.sendTransitionStep(step(0.1f))
+            repository.sendTransitionStep(step(0.2f))
+            // ...up to here
+            repository.sendTransitionStep(step(0.3f))
+            repository.sendTransitionStep(step(1f))
+
+            // Only three values should be present, since the dream overlay runs for a small
+            // fraction of the overall animation time
+            assertThat(values.size).isEqualTo(3)
+            assertThat(values[0]).isEqualTo(1f - animValue(0f, LOCKSCREEN_ALPHA))
+            assertThat(values[1]).isEqualTo(1f - animValue(0.1f, LOCKSCREEN_ALPHA))
+            assertThat(values[2]).isEqualTo(1f - animValue(0.2f, LOCKSCREEN_ALPHA))
+
+            job.cancel()
+        }
+
+    @Test
+    fun lockscreenTranslationY() =
+        runTest(UnconfinedTestDispatcher()) {
+            val values = mutableListOf<Float>()
+
+            val pixels = 100
+            val job =
+                underTest.lockscreenTranslationY(pixels).onEach { values.add(it) }.launchIn(this)
+
+            // Should start running here...
+            repository.sendTransitionStep(step(0f))
+            repository.sendTransitionStep(step(0.3f))
+            repository.sendTransitionStep(step(0.5f))
+            // ...up to here
+            repository.sendTransitionStep(step(1f))
+            // And a final reset event on FINISHED
+            repository.sendTransitionStep(step(1f, TransitionState.FINISHED))
+
+            assertThat(values.size).isEqualTo(4)
+            assertThat(values[0])
+                .isEqualTo(
+                    EMPHASIZED_ACCELERATE.getInterpolation(
+                        animValue(0f, LOCKSCREEN_TRANSLATION_Y)
+                    ) * pixels
+                )
+            assertThat(values[1])
+                .isEqualTo(
+                    EMPHASIZED_ACCELERATE.getInterpolation(
+                        animValue(0.3f, LOCKSCREEN_TRANSLATION_Y)
+                    ) * pixels
+                )
+            assertThat(values[2])
+                .isEqualTo(
+                    EMPHASIZED_ACCELERATE.getInterpolation(
+                        animValue(0.5f, LOCKSCREEN_TRANSLATION_Y)
+                    ) * pixels
+                )
+            assertThat(values[3]).isEqualTo(0f)
+
+            job.cancel()
+        }
+
+    private fun animValue(stepValue: Float, params: AnimationParams): Float {
+        val totalDuration = TO_DREAMING_DURATION
+        val startValue = (params.startTime / totalDuration).toFloat()
+
+        val multiplier = (totalDuration / params.duration).toFloat()
+        return (stepValue - startValue) * multiplier
+    }
+
+    private fun step(
+        value: Float,
+        state: TransitionState = TransitionState.RUNNING
+    ): TransitionStep {
+        return TransitionStep(
+            from = KeyguardState.LOCKSCREEN,
+            to = KeyguardState.DREAMING,
+            value = value,
+            transitionState = state,
+            ownerName = "LockscreenToDreamingTransitionViewModelTest"
+        )
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
new file mode 100644
index 0000000..759345f
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE
+import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor.Companion.TO_OCCLUDED_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.AnimationParams
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenToOccludedTransitionViewModel.Companion.LOCKSCREEN_ALPHA
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenToOccludedTransitionViewModel.Companion.LOCKSCREEN_TRANSLATION_Y
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+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.junit.runners.JUnit4
+
+@SmallTest
+@RunWith(JUnit4::class)
+class LockscreenToOccludedTransitionViewModelTest : SysuiTestCase() {
+    private lateinit var underTest: LockscreenToOccludedTransitionViewModel
+    private lateinit var repository: FakeKeyguardTransitionRepository
+
+    @Before
+    fun setUp() {
+        repository = FakeKeyguardTransitionRepository()
+        val interactor = KeyguardTransitionInteractor(repository)
+        underTest = LockscreenToOccludedTransitionViewModel(interactor)
+    }
+
+    @Test
+    fun lockscreenFadeOut() =
+        runTest(UnconfinedTestDispatcher()) {
+            val values = mutableListOf<Float>()
+
+            val job = underTest.lockscreenAlpha.onEach { values.add(it) }.launchIn(this)
+
+            // Should start running here...
+            repository.sendTransitionStep(step(0f))
+            repository.sendTransitionStep(step(0.1f))
+            repository.sendTransitionStep(step(0.4f))
+            // ...up to here
+            repository.sendTransitionStep(step(0.7f))
+            repository.sendTransitionStep(step(1f))
+
+            // Only 3 values should be present, since the dream overlay runs for a small fraction
+            // of the overall animation time
+            assertThat(values.size).isEqualTo(3)
+            assertThat(values[0]).isEqualTo(1f - animValue(0f, LOCKSCREEN_ALPHA))
+            assertThat(values[1]).isEqualTo(1f - animValue(0.1f, LOCKSCREEN_ALPHA))
+            assertThat(values[2]).isEqualTo(1f - animValue(0.4f, LOCKSCREEN_ALPHA))
+
+            job.cancel()
+        }
+
+    @Test
+    fun lockscreenTranslationY() =
+        runTest(UnconfinedTestDispatcher()) {
+            val values = mutableListOf<Float>()
+
+            val pixels = 100
+            val job =
+                underTest.lockscreenTranslationY(pixels).onEach { values.add(it) }.launchIn(this)
+
+            // Should start running here...
+            repository.sendTransitionStep(step(0f))
+            repository.sendTransitionStep(step(0.3f))
+            repository.sendTransitionStep(step(0.5f))
+            repository.sendTransitionStep(step(1f))
+            // ...up to here
+
+            assertThat(values.size).isEqualTo(4)
+            assertThat(values[0])
+                .isEqualTo(
+                    EMPHASIZED_ACCELERATE.getInterpolation(
+                        animValue(0f, LOCKSCREEN_TRANSLATION_Y)
+                    ) * pixels
+                )
+            assertThat(values[1])
+                .isEqualTo(
+                    EMPHASIZED_ACCELERATE.getInterpolation(
+                        animValue(0.3f, LOCKSCREEN_TRANSLATION_Y)
+                    ) * pixels
+                )
+            assertThat(values[2])
+                .isEqualTo(
+                    EMPHASIZED_ACCELERATE.getInterpolation(
+                        animValue(0.5f, LOCKSCREEN_TRANSLATION_Y)
+                    ) * pixels
+                )
+            assertThat(values[3])
+                .isEqualTo(
+                    EMPHASIZED_ACCELERATE.getInterpolation(
+                        animValue(1f, LOCKSCREEN_TRANSLATION_Y)
+                    ) * pixels
+                )
+            job.cancel()
+        }
+
+    private fun animValue(stepValue: Float, params: AnimationParams): Float {
+        val totalDuration = TO_OCCLUDED_DURATION
+        val startValue = (params.startTime / totalDuration).toFloat()
+
+        val multiplier = (totalDuration / params.duration).toFloat()
+        return (stepValue - startValue) * multiplier
+    }
+
+    private fun step(value: Float): TransitionStep {
+        return TransitionStep(
+            from = KeyguardState.LOCKSCREEN,
+            to = KeyguardState.OCCLUDED,
+            value = value,
+            transitionState = TransitionState.RUNNING,
+            ownerName = "LockscreenToOccludedTransitionViewModelTest"
+        )
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/table/LogDiffsForTableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/log/table/LogDiffsForTableTest.kt
new file mode 100644
index 0000000..3b5e6b9
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/log/table/LogDiffsForTableTest.kt
@@ -0,0 +1,1081 @@
+/*
+ * 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.log.table
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import java.io.PrintWriter
+import java.io.StringWriter
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+
+@SmallTest
+@OptIn(ExperimentalCoroutinesApi::class)
+class LogDiffsForTableTest : SysuiTestCase() {
+
+    private val testScope = TestScope(UnconfinedTestDispatcher())
+
+    private lateinit var systemClock: FakeSystemClock
+    private lateinit var tableLogBuffer: TableLogBuffer
+
+    @Before
+    fun setUp() {
+        systemClock = FakeSystemClock()
+        tableLogBuffer = TableLogBuffer(MAX_SIZE, BUFFER_NAME, systemClock)
+    }
+
+    // ---- Flow<Boolean> tests ----
+
+    @Test
+    fun boolean_doesNotLogWhenNotCollected() {
+        val flow = flowOf(true, true, false)
+
+        flow.logDiffsForTable(
+            tableLogBuffer,
+            COLUMN_PREFIX,
+            COLUMN_NAME,
+            initialValue = false,
+        )
+
+        val logs = dumpLog()
+        assertThat(logs).doesNotContain(COLUMN_PREFIX)
+        assertThat(logs).doesNotContain(COLUMN_NAME)
+        assertThat(logs).doesNotContain("false")
+    }
+
+    @Test
+    fun boolean_logsInitialWhenCollected() =
+        testScope.runTest {
+            val flow = flowOf(true, true, false)
+
+            val flowWithLogging =
+                flow.logDiffsForTable(
+                    tableLogBuffer,
+                    COLUMN_PREFIX,
+                    COLUMN_NAME,
+                    initialValue = false,
+                )
+
+            systemClock.setCurrentTimeMillis(3000L)
+            val job = launch { flowWithLogging.collect() }
+
+            val logs = dumpLog()
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(3000L) +
+                        SEPARATOR +
+                        FULL_NAME +
+                        SEPARATOR +
+                        "false"
+                )
+
+            job.cancel()
+        }
+
+    @Test
+    fun boolean_logsUpdates() =
+        testScope.runTest {
+            systemClock.setCurrentTimeMillis(100L)
+            val flow = flow {
+                for (bool in listOf(true, false, true)) {
+                    systemClock.advanceTime(100L)
+                    emit(bool)
+                }
+            }
+
+            val flowWithLogging =
+                flow.logDiffsForTable(
+                    tableLogBuffer,
+                    COLUMN_PREFIX,
+                    COLUMN_NAME,
+                    initialValue = false,
+                )
+
+            val job = launch { flowWithLogging.collect() }
+
+            val logs = dumpLog()
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(100L) + SEPARATOR + FULL_NAME + SEPARATOR + "false"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(200L) + SEPARATOR + FULL_NAME + SEPARATOR + "true"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(300L) + SEPARATOR + FULL_NAME + SEPARATOR + "false"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(400L) + SEPARATOR + FULL_NAME + SEPARATOR + "true"
+                )
+
+            job.cancel()
+        }
+
+    @Test
+    fun boolean_doesNotLogIfSameValue() =
+        testScope.runTest {
+            systemClock.setCurrentTimeMillis(100L)
+            val flow = flow {
+                for (bool in listOf(true, true, false, false, true)) {
+                    systemClock.advanceTime(100L)
+                    emit(bool)
+                }
+            }
+
+            val flowWithLogging =
+                flow.logDiffsForTable(
+                    tableLogBuffer,
+                    COLUMN_PREFIX,
+                    COLUMN_NAME,
+                    initialValue = true,
+                )
+
+            val job = launch { flowWithLogging.collect() }
+
+            val logs = dumpLog()
+            // Input flow: true@100, true@200, true@300, false@400, false@500, true@600
+            // Output log: true@100, --------, --------, false@400, ---------, true@600
+            val expected1 =
+                TABLE_LOG_DATE_FORMAT.format(100L) + SEPARATOR + FULL_NAME + SEPARATOR + "true"
+            val expected4 =
+                TABLE_LOG_DATE_FORMAT.format(400L) + SEPARATOR + FULL_NAME + SEPARATOR + "false"
+            val expected6 =
+                TABLE_LOG_DATE_FORMAT.format(600L) + SEPARATOR + FULL_NAME + SEPARATOR + "true"
+            assertThat(logs).contains(expected1)
+            assertThat(logs).contains(expected4)
+            assertThat(logs).contains(expected6)
+
+            val unexpected2 =
+                TABLE_LOG_DATE_FORMAT.format(200L) + SEPARATOR + FULL_NAME + SEPARATOR + "true"
+            val unexpected3 =
+                TABLE_LOG_DATE_FORMAT.format(300L) + SEPARATOR + FULL_NAME + SEPARATOR + "true"
+            val unexpected5 =
+                TABLE_LOG_DATE_FORMAT.format(500L) + SEPARATOR + FULL_NAME + SEPARATOR + "false"
+            assertThat(logs).doesNotContain(unexpected2)
+            assertThat(logs).doesNotContain(unexpected3)
+            assertThat(logs).doesNotContain(unexpected5)
+
+            job.cancel()
+        }
+
+    @Test
+    fun boolean_worksForStateFlows() =
+        testScope.runTest {
+            val flow = MutableStateFlow(false)
+
+            val flowWithLogging =
+                flow.logDiffsForTable(
+                    tableLogBuffer,
+                    COLUMN_PREFIX,
+                    COLUMN_NAME,
+                    initialValue = false,
+                )
+
+            systemClock.setCurrentTimeMillis(50L)
+            val job = launch { flowWithLogging.collect() }
+            assertThat(dumpLog())
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(50L) + SEPARATOR + FULL_NAME + SEPARATOR + "false"
+                )
+
+            systemClock.setCurrentTimeMillis(100L)
+            flow.emit(true)
+            assertThat(dumpLog())
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(100L) + SEPARATOR + FULL_NAME + SEPARATOR + "true"
+                )
+
+            systemClock.setCurrentTimeMillis(200L)
+            flow.emit(false)
+            assertThat(dumpLog())
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(200L) + SEPARATOR + FULL_NAME + SEPARATOR + "false"
+                )
+
+            // Doesn't log duplicates
+            systemClock.setCurrentTimeMillis(300L)
+            flow.emit(false)
+            assertThat(dumpLog())
+                .doesNotContain(
+                    TABLE_LOG_DATE_FORMAT.format(300L) + SEPARATOR + FULL_NAME + SEPARATOR + "false"
+                )
+
+            job.cancel()
+        }
+
+    // ---- Flow<Int> tests ----
+
+    @Test
+    fun int_doesNotLogWhenNotCollected() {
+        val flow = flowOf(5, 6, 7)
+
+        flow.logDiffsForTable(
+            tableLogBuffer,
+            COLUMN_PREFIX,
+            COLUMN_NAME,
+            initialValue = 1234,
+        )
+
+        val logs = dumpLog()
+        assertThat(logs).doesNotContain(COLUMN_PREFIX)
+        assertThat(logs).doesNotContain(COLUMN_NAME)
+        assertThat(logs).doesNotContain("1234")
+    }
+
+    @Test
+    fun int_logsInitialWhenCollected() =
+        testScope.runTest {
+            val flow = flowOf(5, 6, 7)
+
+            val flowWithLogging =
+                flow.logDiffsForTable(
+                    tableLogBuffer,
+                    COLUMN_PREFIX,
+                    COLUMN_NAME,
+                    initialValue = 1234,
+                )
+
+            systemClock.setCurrentTimeMillis(3000L)
+            val job = launch { flowWithLogging.collect() }
+
+            val logs = dumpLog()
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(3000L) + SEPARATOR + FULL_NAME + SEPARATOR + "1234"
+                )
+
+            job.cancel()
+        }
+
+    @Test
+    fun int_logsUpdates() =
+        testScope.runTest {
+            systemClock.setCurrentTimeMillis(100L)
+            val flow = flow {
+                for (int in listOf(2, 3, 4)) {
+                    systemClock.advanceTime(100L)
+                    emit(int)
+                }
+            }
+
+            val flowWithLogging =
+                flow.logDiffsForTable(
+                    tableLogBuffer,
+                    COLUMN_PREFIX,
+                    COLUMN_NAME,
+                    initialValue = 1,
+                )
+
+            val job = launch { flowWithLogging.collect() }
+
+            val logs = dumpLog()
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(100L) + SEPARATOR + FULL_NAME + SEPARATOR + "1"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(200L) + SEPARATOR + FULL_NAME + SEPARATOR + "2"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(300L) + SEPARATOR + FULL_NAME + SEPARATOR + "3"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(400L) + SEPARATOR + FULL_NAME + SEPARATOR + "4"
+                )
+
+            job.cancel()
+        }
+
+    @Test
+    fun int_doesNotLogIfSameValue() =
+        testScope.runTest {
+            systemClock.setCurrentTimeMillis(100L)
+            val flow = flow {
+                for (bool in listOf(2, 3, 3, 3, 2, 6, 6)) {
+                    systemClock.advanceTime(100L)
+                    emit(bool)
+                }
+            }
+
+            val flowWithLogging =
+                flow.logDiffsForTable(
+                    tableLogBuffer,
+                    COLUMN_PREFIX,
+                    COLUMN_NAME,
+                    initialValue = 1,
+                )
+
+            val job = launch { flowWithLogging.collect() }
+
+            val logs = dumpLog()
+            // Input flow: 1@100, 2@200, 3@300, 3@400, 3@500, 2@600, 6@700, 6@800
+            // Output log: 1@100, 2@200, 3@300, -----, -----, 2@600, 6@700, -----
+            val expected1 =
+                TABLE_LOG_DATE_FORMAT.format(100L) + SEPARATOR + FULL_NAME + SEPARATOR + "1"
+            val expected2 =
+                TABLE_LOG_DATE_FORMAT.format(200L) + SEPARATOR + FULL_NAME + SEPARATOR + "2"
+            val expected3 =
+                TABLE_LOG_DATE_FORMAT.format(300L) + SEPARATOR + FULL_NAME + SEPARATOR + "3"
+            val expected6 =
+                TABLE_LOG_DATE_FORMAT.format(600L) + SEPARATOR + FULL_NAME + SEPARATOR + "2"
+            val expected7 =
+                TABLE_LOG_DATE_FORMAT.format(700L) + SEPARATOR + FULL_NAME + SEPARATOR + "6"
+            assertThat(logs).contains(expected1)
+            assertThat(logs).contains(expected2)
+            assertThat(logs).contains(expected3)
+            assertThat(logs).contains(expected6)
+            assertThat(logs).contains(expected7)
+
+            val unexpected4 =
+                TABLE_LOG_DATE_FORMAT.format(400L) + SEPARATOR + FULL_NAME + SEPARATOR + "3"
+            val unexpected5 =
+                TABLE_LOG_DATE_FORMAT.format(500L) + SEPARATOR + FULL_NAME + SEPARATOR + "3"
+            val unexpected8 =
+                TABLE_LOG_DATE_FORMAT.format(800L) + SEPARATOR + FULL_NAME + SEPARATOR + "6"
+            assertThat(logs).doesNotContain(unexpected4)
+            assertThat(logs).doesNotContain(unexpected5)
+            assertThat(logs).doesNotContain(unexpected8)
+            job.cancel()
+        }
+
+    @Test
+    fun int_worksForStateFlows() =
+        testScope.runTest {
+            val flow = MutableStateFlow(1111)
+
+            val flowWithLogging =
+                flow.logDiffsForTable(
+                    tableLogBuffer,
+                    COLUMN_PREFIX,
+                    COLUMN_NAME,
+                    initialValue = 1111,
+                )
+
+            systemClock.setCurrentTimeMillis(50L)
+            val job = launch { flowWithLogging.collect() }
+            assertThat(dumpLog())
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(50L) + SEPARATOR + FULL_NAME + SEPARATOR + "1111"
+                )
+
+            systemClock.setCurrentTimeMillis(100L)
+            flow.emit(2222)
+            assertThat(dumpLog())
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(100L) + SEPARATOR + FULL_NAME + SEPARATOR + "2222"
+                )
+
+            systemClock.setCurrentTimeMillis(200L)
+            flow.emit(3333)
+            assertThat(dumpLog())
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(200L) + SEPARATOR + FULL_NAME + SEPARATOR + "3333"
+                )
+
+            // Doesn't log duplicates
+            systemClock.setCurrentTimeMillis(300L)
+            flow.emit(3333)
+            assertThat(dumpLog())
+                .doesNotContain(
+                    TABLE_LOG_DATE_FORMAT.format(300L) + SEPARATOR + FULL_NAME + SEPARATOR + "3333"
+                )
+
+            job.cancel()
+        }
+
+    // ---- Flow<String> tests ----
+
+    @Test
+    fun string_doesNotLogWhenNotCollected() {
+        val flow = flowOf("val5", "val6", "val7")
+
+        flow.logDiffsForTable(
+            tableLogBuffer,
+            COLUMN_PREFIX,
+            COLUMN_NAME,
+            initialValue = "val1234",
+        )
+
+        val logs = dumpLog()
+        assertThat(logs).doesNotContain(COLUMN_PREFIX)
+        assertThat(logs).doesNotContain(COLUMN_NAME)
+        assertThat(logs).doesNotContain("val1234")
+    }
+
+    @Test
+    fun string_logsInitialWhenCollected() =
+        testScope.runTest {
+            val flow = flowOf("val5", "val6", "val7")
+
+            val flowWithLogging =
+                flow.logDiffsForTable(
+                    tableLogBuffer,
+                    COLUMN_PREFIX,
+                    COLUMN_NAME,
+                    initialValue = "val1234",
+                )
+
+            systemClock.setCurrentTimeMillis(3000L)
+            val job = launch { flowWithLogging.collect() }
+
+            val logs = dumpLog()
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(3000L) +
+                        SEPARATOR +
+                        FULL_NAME +
+                        SEPARATOR +
+                        "val1234"
+                )
+
+            job.cancel()
+        }
+
+    @Test
+    fun string_logsUpdates() =
+        testScope.runTest {
+            systemClock.setCurrentTimeMillis(100L)
+            val flow = flow {
+                for (int in listOf("val2", "val3", "val4")) {
+                    systemClock.advanceTime(100L)
+                    emit(int)
+                }
+            }
+
+            val flowWithLogging =
+                flow.logDiffsForTable(
+                    tableLogBuffer,
+                    COLUMN_PREFIX,
+                    COLUMN_NAME,
+                    initialValue = "val1",
+                )
+
+            val job = launch { flowWithLogging.collect() }
+
+            val logs = dumpLog()
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(100L) + SEPARATOR + FULL_NAME + SEPARATOR + "val1"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(200L) + SEPARATOR + FULL_NAME + SEPARATOR + "val2"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(300L) + SEPARATOR + FULL_NAME + SEPARATOR + "val3"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(400L) + SEPARATOR + FULL_NAME + SEPARATOR + "val4"
+                )
+
+            job.cancel()
+        }
+
+    @Test
+    fun string_logsNull() =
+        testScope.runTest {
+            systemClock.setCurrentTimeMillis(100L)
+            val flow = flow {
+                for (int in listOf(null, "something", null)) {
+                    systemClock.advanceTime(100L)
+                    emit(int)
+                }
+            }
+
+            val flowWithLogging =
+                flow.logDiffsForTable(
+                    tableLogBuffer,
+                    COLUMN_PREFIX,
+                    COLUMN_NAME,
+                    initialValue = "start",
+                )
+
+            val job = launch { flowWithLogging.collect() }
+
+            val logs = dumpLog()
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(100L) + SEPARATOR + FULL_NAME + SEPARATOR + "start"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(200L) + SEPARATOR + FULL_NAME + SEPARATOR + "null"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(300L) +
+                        SEPARATOR +
+                        FULL_NAME +
+                        SEPARATOR +
+                        "something"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(400L) + SEPARATOR + FULL_NAME + SEPARATOR + "null"
+                )
+
+            job.cancel()
+        }
+
+    @Test
+    fun string_doesNotLogIfSameValue() =
+        testScope.runTest {
+            systemClock.setCurrentTimeMillis(100L)
+            val flow = flow {
+                for (bool in listOf("start", "new", "new", "newer", "newest", "newest")) {
+                    systemClock.advanceTime(100L)
+                    emit(bool)
+                }
+            }
+
+            val flowWithLogging =
+                flow.logDiffsForTable(
+                    tableLogBuffer,
+                    COLUMN_PREFIX,
+                    COLUMN_NAME,
+                    initialValue = "start",
+                )
+
+            val job = launch { flowWithLogging.collect() }
+
+            val logs = dumpLog()
+            // Input flow: start@100, start@200, new@300, new@400, newer@500, newest@600, newest@700
+            // Output log: start@100, ---------, new@300, -------, newer@500, newest@600, ----------
+            val expected1 =
+                TABLE_LOG_DATE_FORMAT.format(100L) + SEPARATOR + FULL_NAME + SEPARATOR + "start"
+            val expected3 =
+                TABLE_LOG_DATE_FORMAT.format(300L) + SEPARATOR + FULL_NAME + SEPARATOR + "new"
+            val expected5 =
+                TABLE_LOG_DATE_FORMAT.format(500L) + SEPARATOR + FULL_NAME + SEPARATOR + "newer"
+            val expected6 =
+                TABLE_LOG_DATE_FORMAT.format(600L) + SEPARATOR + FULL_NAME + SEPARATOR + "newest"
+            assertThat(logs).contains(expected1)
+            assertThat(logs).contains(expected3)
+            assertThat(logs).contains(expected5)
+            assertThat(logs).contains(expected6)
+
+            val unexpected2 =
+                TABLE_LOG_DATE_FORMAT.format(200L) + SEPARATOR + FULL_NAME + SEPARATOR + "start"
+            val unexpected4 =
+                TABLE_LOG_DATE_FORMAT.format(400L) + SEPARATOR + FULL_NAME + SEPARATOR + "new"
+            val unexpected7 =
+                TABLE_LOG_DATE_FORMAT.format(700L) + SEPARATOR + FULL_NAME + SEPARATOR + "newest"
+            assertThat(logs).doesNotContain(unexpected2)
+            assertThat(logs).doesNotContain(unexpected4)
+            assertThat(logs).doesNotContain(unexpected7)
+
+            job.cancel()
+        }
+
+    @Test
+    fun string_worksForStateFlows() =
+        testScope.runTest {
+            val flow = MutableStateFlow("initial")
+
+            val flowWithLogging =
+                flow.logDiffsForTable(
+                    tableLogBuffer,
+                    COLUMN_PREFIX,
+                    COLUMN_NAME,
+                    initialValue = "initial",
+                )
+
+            systemClock.setCurrentTimeMillis(50L)
+            val job = launch { flowWithLogging.collect() }
+            assertThat(dumpLog())
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(50L) +
+                        SEPARATOR +
+                        FULL_NAME +
+                        SEPARATOR +
+                        "initial"
+                )
+
+            systemClock.setCurrentTimeMillis(100L)
+            flow.emit("nextVal")
+            assertThat(dumpLog())
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(100L) +
+                        SEPARATOR +
+                        FULL_NAME +
+                        SEPARATOR +
+                        "nextVal"
+                )
+
+            systemClock.setCurrentTimeMillis(200L)
+            flow.emit("nextNextVal")
+            assertThat(dumpLog())
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(200L) +
+                        SEPARATOR +
+                        FULL_NAME +
+                        SEPARATOR +
+                        "nextNextVal"
+                )
+
+            // Doesn't log duplicates
+            systemClock.setCurrentTimeMillis(300L)
+            flow.emit("nextNextVal")
+            assertThat(dumpLog())
+                .doesNotContain(
+                    TABLE_LOG_DATE_FORMAT.format(300L) +
+                        SEPARATOR +
+                        FULL_NAME +
+                        SEPARATOR +
+                        "nextNextVal"
+                )
+
+            job.cancel()
+        }
+
+    // ---- Flow<Diffable> tests ----
+
+    @Test
+    fun diffable_doesNotLogWhenNotCollected() {
+        val flow =
+            flowOf(
+                TestDiffable(1, "1", true),
+                TestDiffable(2, "2", false),
+            )
+
+        val initial = TestDiffable(0, "0", false)
+        flow.logDiffsForTable(
+            tableLogBuffer,
+            COLUMN_PREFIX,
+            initial,
+        )
+
+        val logs = dumpLog()
+        assertThat(logs).doesNotContain(COLUMN_PREFIX)
+        assertThat(logs).doesNotContain(TestDiffable.COL_FULL)
+        assertThat(logs).doesNotContain(TestDiffable.COL_INT)
+        assertThat(logs).doesNotContain(TestDiffable.COL_STRING)
+        assertThat(logs).doesNotContain(TestDiffable.COL_BOOLEAN)
+    }
+
+    @Test
+    fun diffable_logsInitialWhenCollected_usingLogFull() =
+        testScope.runTest {
+            val flow =
+                flowOf(
+                    TestDiffable(1, "1", true),
+                    TestDiffable(2, "2", false),
+                )
+
+            val initial = TestDiffable(1234, "string1234", false)
+            val flowWithLogging =
+                flow.logDiffsForTable(
+                    tableLogBuffer,
+                    COLUMN_PREFIX,
+                    initial,
+                )
+
+            systemClock.setCurrentTimeMillis(3000L)
+            val job = launch { flowWithLogging.collect() }
+
+            val logs = dumpLog()
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(3000L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_FULL +
+                        SEPARATOR +
+                        "true"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(3000L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_INT +
+                        SEPARATOR +
+                        "1234"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(3000L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_STRING +
+                        SEPARATOR +
+                        "string1234"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(3000L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_BOOLEAN +
+                        SEPARATOR +
+                        "false"
+                )
+            job.cancel()
+        }
+
+    @Test
+    fun diffable_logsUpdates_usingLogDiffs() =
+        testScope.runTest {
+            val initialValue = TestDiffable(0, "string0", false)
+            val diffables =
+                listOf(
+                    TestDiffable(1, "string1", true),
+                    TestDiffable(2, "string1", true),
+                    TestDiffable(2, "string2", false),
+                )
+
+            systemClock.setCurrentTimeMillis(100L)
+            val flow = flow {
+                for (diffable in diffables) {
+                    systemClock.advanceTime(100L)
+                    emit(diffable)
+                }
+            }
+
+            val flowWithLogging =
+                flow.logDiffsForTable(
+                    tableLogBuffer,
+                    COLUMN_PREFIX,
+                    initialValue,
+                )
+
+            val job = launch { flowWithLogging.collect() }
+
+            val logs = dumpLog()
+
+            // Initial -> first: everything different
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(200L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_FULL +
+                        SEPARATOR +
+                        "false"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(200L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_INT +
+                        SEPARATOR +
+                        "1"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(200L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_STRING +
+                        SEPARATOR +
+                        "string1"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(200L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_BOOLEAN +
+                        SEPARATOR +
+                        "true"
+                )
+
+            // First -> second: int different
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(300L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_FULL +
+                        SEPARATOR +
+                        "false"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(300L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_INT +
+                        SEPARATOR +
+                        "2"
+                )
+            assertThat(logs)
+                .doesNotContain(
+                    TABLE_LOG_DATE_FORMAT.format(300L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_STRING +
+                        SEPARATOR +
+                        "string1"
+                )
+            assertThat(logs)
+                .doesNotContain(
+                    TABLE_LOG_DATE_FORMAT.format(300L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_BOOLEAN +
+                        SEPARATOR +
+                        "true"
+                )
+
+            // Second -> third: string & boolean different
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(400L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_FULL +
+                        SEPARATOR +
+                        "false"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(400L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_STRING +
+                        SEPARATOR +
+                        "string2"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(400L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_BOOLEAN +
+                        SEPARATOR +
+                        "false"
+                )
+            assertThat(logs)
+                .doesNotContain(
+                    TABLE_LOG_DATE_FORMAT.format(400L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_INT +
+                        SEPARATOR +
+                        "2"
+                )
+
+            job.cancel()
+        }
+
+    @Test
+    fun diffable_worksForStateFlows() =
+        testScope.runTest {
+            val initialValue = TestDiffable(0, "string0", false)
+            val flow = MutableStateFlow(initialValue)
+            val flowWithLogging =
+                flow.logDiffsForTable(
+                    tableLogBuffer,
+                    COLUMN_PREFIX,
+                    initialValue,
+                )
+
+            systemClock.setCurrentTimeMillis(50L)
+            val job = launch { flowWithLogging.collect() }
+
+            var logs = dumpLog()
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(50L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_INT +
+                        SEPARATOR +
+                        "0"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(50L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_STRING +
+                        SEPARATOR +
+                        "string0"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(50L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_BOOLEAN +
+                        SEPARATOR +
+                        "false"
+                )
+
+            systemClock.setCurrentTimeMillis(100L)
+            flow.emit(TestDiffable(1, "string1", true))
+
+            logs = dumpLog()
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(100L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_INT +
+                        SEPARATOR +
+                        "1"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(100L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_STRING +
+                        SEPARATOR +
+                        "string1"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(100L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_BOOLEAN +
+                        SEPARATOR +
+                        "true"
+                )
+
+            // Doesn't log duplicates
+            systemClock.setCurrentTimeMillis(200L)
+            flow.emit(TestDiffable(1, "newString", true))
+
+            logs = dumpLog()
+            assertThat(logs)
+                .doesNotContain(
+                    TABLE_LOG_DATE_FORMAT.format(200L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_INT +
+                        SEPARATOR +
+                        "1"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(200L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_STRING +
+                        SEPARATOR +
+                        "newString"
+                )
+            assertThat(logs)
+                .doesNotContain(
+                    TABLE_LOG_DATE_FORMAT.format(200L) +
+                        SEPARATOR +
+                        COLUMN_PREFIX +
+                        "." +
+                        TestDiffable.COL_BOOLEAN +
+                        SEPARATOR +
+                        "true"
+                )
+
+            job.cancel()
+        }
+
+    private fun dumpLog(): String {
+        val outputWriter = StringWriter()
+        tableLogBuffer.dump(PrintWriter(outputWriter), arrayOf())
+        return outputWriter.toString()
+    }
+
+    class TestDiffable(
+        private val testInt: Int,
+        private val testString: String,
+        private val testBoolean: Boolean,
+    ) : Diffable<TestDiffable> {
+        override fun logDiffs(prevVal: TestDiffable, row: TableRowLogger) {
+            row.logChange(COL_FULL, false)
+
+            if (testInt != prevVal.testInt) {
+                row.logChange(COL_INT, testInt)
+            }
+            if (testString != prevVal.testString) {
+                row.logChange(COL_STRING, testString)
+            }
+            if (testBoolean != prevVal.testBoolean) {
+                row.logChange(COL_BOOLEAN, testBoolean)
+            }
+        }
+
+        override fun logFull(row: TableRowLogger) {
+            row.logChange(COL_FULL, true)
+            row.logChange(COL_INT, testInt)
+            row.logChange(COL_STRING, testString)
+            row.logChange(COL_BOOLEAN, testBoolean)
+        }
+
+        companion object {
+            const val COL_INT = "intColumn"
+            const val COL_STRING = "stringColumn"
+            const val COL_BOOLEAN = "booleanColumn"
+            const val COL_FULL = "loggedFullColumn"
+        }
+    }
+
+    private companion object {
+        const val MAX_SIZE = 50
+        const val BUFFER_NAME = "LogDiffsForTableTest"
+        const val COLUMN_PREFIX = "columnPrefix"
+        const val COLUMN_NAME = "columnName"
+        const val FULL_NAME = "$COLUMN_PREFIX.$COLUMN_NAME"
+        private const val SEPARATOR = "|"
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferFactoryTest.kt
new file mode 100644
index 0000000..411b1bd
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferFactoryTest.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log.table
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+
+@SmallTest
+class TableLogBufferFactoryTest : SysuiTestCase() {
+    private val dumpManager: DumpManager = mock()
+    private val systemClock = FakeSystemClock()
+    private val underTest = TableLogBufferFactory(dumpManager, systemClock)
+
+    @Test
+    fun `create - always creates new instance`() {
+        val b1 = underTest.create(NAME_1, SIZE)
+        val b1_copy = underTest.create(NAME_1, SIZE)
+        val b2 = underTest.create(NAME_2, SIZE)
+        val b2_copy = underTest.create(NAME_2, SIZE)
+
+        assertThat(b1).isNotSameInstanceAs(b1_copy)
+        assertThat(b1).isNotSameInstanceAs(b2)
+        assertThat(b2).isNotSameInstanceAs(b2_copy)
+    }
+
+    @Test
+    fun `getOrCreate - reuses instance`() {
+        val b1 = underTest.getOrCreate(NAME_1, SIZE)
+        val b1_copy = underTest.getOrCreate(NAME_1, SIZE)
+        val b2 = underTest.getOrCreate(NAME_2, SIZE)
+        val b2_copy = underTest.getOrCreate(NAME_2, SIZE)
+
+        assertThat(b1).isSameInstanceAs(b1_copy)
+        assertThat(b2).isSameInstanceAs(b2_copy)
+        assertThat(b1).isNotSameInstanceAs(b2)
+        assertThat(b1_copy).isNotSameInstanceAs(b2_copy)
+    }
+
+    companion object {
+        const val NAME_1 = "name 1"
+        const val NAME_2 = "name 2"
+
+        const val SIZE = 8
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataCombineLatestTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataCombineLatestTest.java
index 4d2d0f0..c0639f3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataCombineLatestTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataCombineLatestTest.java
@@ -79,7 +79,7 @@
                 USER_ID, true, APP, null, ARTIST, TITLE, null,
                 new ArrayList<>(), new ArrayList<>(), null, PACKAGE, null, null, null, true, null,
                 MediaData.PLAYBACK_LOCAL, false, KEY, false, false, false, 0L,
-                InstanceId.fakeInstanceId(-1), -1);
+                InstanceId.fakeInstanceId(-1), -1, false);
         mDeviceData = new MediaDeviceData(true, null, DEVICE_NAME, null, false);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
index 52b694f..1687fdc 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
@@ -17,6 +17,7 @@
 package com.android.systemui.media.controls.pipeline
 
 import android.app.Notification
+import android.app.Notification.FLAG_NO_CLEAR
 import android.app.Notification.MediaStyle
 import android.app.PendingIntent
 import android.app.smartspace.SmartspaceAction
@@ -228,6 +229,7 @@
         whenever(mediaSmartspaceTarget.iconGrid).thenReturn(validRecommendationList)
         whenever(mediaSmartspaceTarget.creationTimeMillis).thenReturn(1234L)
         whenever(mediaFlags.areMediaSessionActionsEnabled(any(), any())).thenReturn(false)
+        whenever(mediaFlags.isExplicitIndicatorEnabled()).thenReturn(true)
         whenever(logger.getNewInstanceId()).thenReturn(instanceIdSequence.newInstanceId())
     }
 
@@ -300,6 +302,60 @@
     }
 
     @Test
+    fun testLoadMetadata_withExplicitIndicator() {
+        val metadata =
+            MediaMetadata.Builder().run {
+                putString(MediaMetadata.METADATA_KEY_ARTIST, SESSION_ARTIST)
+                putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_TITLE)
+                putLong(
+                    MediaConstants.METADATA_KEY_IS_EXPLICIT,
+                    MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT
+                )
+                build()
+            }
+        whenever(mediaControllerFactory.create(anyObject())).thenReturn(controller)
+        whenever(controller.metadata).thenReturn(metadata)
+
+        mediaDataManager.addListener(listener)
+        mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+
+        assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
+        assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
+        verify(listener)
+            .onMediaDataLoaded(
+                eq(KEY),
+                eq(null),
+                capture(mediaDataCaptor),
+                eq(true),
+                eq(0),
+                eq(false)
+            )
+        assertThat(mediaDataCaptor.value!!.isExplicit).isTrue()
+    }
+
+    @Test
+    fun testOnMetaDataLoaded_withoutExplicitIndicator() {
+        whenever(mediaControllerFactory.create(anyObject())).thenReturn(controller)
+        whenever(controller.metadata).thenReturn(metadataBuilder.build())
+
+        mediaDataManager.addListener(listener)
+        mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+
+        assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
+        assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
+        verify(listener)
+            .onMediaDataLoaded(
+                eq(KEY),
+                eq(null),
+                capture(mediaDataCaptor),
+                eq(true),
+                eq(0),
+                eq(false)
+            )
+        assertThat(mediaDataCaptor.value!!.isExplicit).isFalse()
+    }
+
+    @Test
     fun testOnMetaDataLoaded_callsListener() {
         addNotificationAndLoad()
         verify(logger)
@@ -603,6 +659,53 @@
     }
 
     @Test
+    fun testAddResumptionControls_withExplicitIndicator() {
+        val bundle = Bundle()
+        // WHEN resumption controls are added with explicit indicator
+        bundle.putLong(
+            MediaConstants.METADATA_KEY_IS_EXPLICIT,
+            MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT
+        )
+        val desc =
+            MediaDescription.Builder().run {
+                setTitle(SESSION_TITLE)
+                setExtras(bundle)
+                build()
+            }
+        val currentTime = clock.elapsedRealtime()
+        mediaDataManager.addResumptionControls(
+            USER_ID,
+            desc,
+            Runnable {},
+            session.sessionToken,
+            APP_NAME,
+            pendingIntent,
+            PACKAGE_NAME
+        )
+        assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
+        assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
+        // THEN the media data indicates that it is for resumption
+        verify(listener)
+            .onMediaDataLoaded(
+                eq(PACKAGE_NAME),
+                eq(null),
+                capture(mediaDataCaptor),
+                eq(true),
+                eq(0),
+                eq(false)
+            )
+        val data = mediaDataCaptor.value
+        assertThat(data.resumption).isTrue()
+        assertThat(data.song).isEqualTo(SESSION_TITLE)
+        assertThat(data.app).isEqualTo(APP_NAME)
+        assertThat(data.actions).hasSize(1)
+        assertThat(data.semanticActions!!.playOrPause).isNotNull()
+        assertThat(data.lastActive).isAtLeast(currentTime)
+        assertThat(data.isExplicit).isTrue()
+        verify(logger).logResumeMediaAdded(anyInt(), eq(PACKAGE_NAME), eq(data.instanceId))
+    }
+
+    @Test
     fun testResumptionDisabled_dismissesResumeControls() {
         // WHEN there are resume controls and resumption is switched off
         val desc =
@@ -1349,6 +1452,39 @@
         assertThat(mediaDataCaptor.value.semanticActions).isNull()
     }
 
+    @Test
+    fun testNoClearNotOngoing_canDismiss() {
+        mediaNotification =
+            SbnBuilder().run {
+                setPkg(PACKAGE_NAME)
+                modifyNotification(context).also {
+                    it.setSmallIcon(android.R.drawable.ic_media_pause)
+                    it.setStyle(MediaStyle().apply { setMediaSession(session.sessionToken) })
+                    it.setOngoing(false)
+                    it.setFlag(FLAG_NO_CLEAR, true)
+                }
+                build()
+            }
+        addNotificationAndLoad()
+        assertThat(mediaDataCaptor.value.isClearable).isTrue()
+    }
+
+    @Test
+    fun testOngoing_cannotDismiss() {
+        mediaNotification =
+            SbnBuilder().run {
+                setPkg(PACKAGE_NAME)
+                modifyNotification(context).also {
+                    it.setSmallIcon(android.R.drawable.ic_media_pause)
+                    it.setStyle(MediaStyle().apply { setMediaSession(session.sessionToken) })
+                    it.setOngoing(true)
+                }
+                build()
+            }
+        addNotificationAndLoad()
+        assertThat(mediaDataCaptor.value.isClearable).isFalse()
+    }
+
     /** Helper function to add a media notification and capture the resulting MediaData */
     private fun addNotificationAndLoad() {
         mediaDataManager.onNotificationAdded(KEY, mediaNotification)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
index 6ca34e0..e4e95e5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
@@ -17,8 +17,10 @@
 package com.android.systemui.media.controls.ui
 
 import android.app.PendingIntent
+import android.content.res.Configuration
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
+import android.util.MathUtils.abs
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.InstanceId
 import com.android.systemui.SysuiTestCase
@@ -30,14 +32,11 @@
 import com.android.systemui.media.controls.models.recommendation.SmartspaceMediaData
 import com.android.systemui.media.controls.pipeline.EMPTY_SMARTSPACE_MEDIA_DATA
 import com.android.systemui.media.controls.pipeline.MediaDataManager
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.ANIMATION_BASE_DURATION
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.DURATION
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.PAGINATION_DELAY
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.TRANSFORM_BEZIER
 import com.android.systemui.media.controls.ui.MediaHierarchyManager.Companion.LOCATION_QS
 import com.android.systemui.media.controls.util.MediaUiEventLogger
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.qs.PageIndicator
 import com.android.systemui.statusbar.notification.collection.provider.OnReorderingAllowedListener
 import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider
 import com.android.systemui.statusbar.policy.ConfigurationController
@@ -55,6 +54,7 @@
 import org.mockito.ArgumentCaptor
 import org.mockito.Captor
 import org.mockito.Mock
+import org.mockito.Mockito.floatThat
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when` as whenever
@@ -85,7 +85,12 @@
     @Mock lateinit var debugLogger: MediaCarouselControllerLogger
     @Mock lateinit var mediaViewController: MediaViewController
     @Mock lateinit var smartspaceMediaData: SmartspaceMediaData
+    @Mock lateinit var mediaCarousel: MediaScrollView
+    @Mock lateinit var pageIndicator: PageIndicator
     @Captor lateinit var listener: ArgumentCaptor<MediaDataManager.Listener>
+    @Captor
+    lateinit var configListener: ArgumentCaptor<ConfigurationController.ConfigurationListener>
+    @Captor lateinit var newConfig: ArgumentCaptor<Configuration>
     @Captor lateinit var visualStabilityCallback: ArgumentCaptor<OnReorderingAllowedListener>
 
     private val clock = FakeSystemClock()
@@ -111,6 +116,7 @@
                 logger,
                 debugLogger
             )
+        verify(configurationController).addCallback(capture(configListener))
         verify(mediaDataManager).addListener(capture(listener))
         verify(visualStabilityProvider)
             .addPersistentReorderingAllowedListener(capture(visualStabilityCallback))
@@ -642,24 +648,56 @@
     @Test
     fun testSetCurrentState_UpdatePageIndicatorAlphaWhenSquish() {
         val delta = 0.0001F
-        val paginationSquishMiddle =
-            TRANSFORM_BEZIER.getInterpolation(
-                (PAGINATION_DELAY + DURATION / 2) / ANIMATION_BASE_DURATION
-            )
-        val paginationSquishEnd =
-            TRANSFORM_BEZIER.getInterpolation(
-                (PAGINATION_DELAY + DURATION) / ANIMATION_BASE_DURATION
-            )
+        mediaCarouselController.mediaCarousel = mediaCarousel
+        mediaCarouselController.pageIndicator = pageIndicator
+        whenever(mediaCarousel.measuredHeight).thenReturn(100)
+        whenever(pageIndicator.translationY).thenReturn(80F)
+        whenever(pageIndicator.height).thenReturn(10)
         whenever(mediaHostStatesManager.mediaHostStates)
             .thenReturn(mutableMapOf(LOCATION_QS to mediaHostState))
         whenever(mediaHostState.visible).thenReturn(true)
         mediaCarouselController.currentEndLocation = LOCATION_QS
-        whenever(mediaHostState.squishFraction).thenReturn(paginationSquishMiddle)
+        whenever(mediaHostState.squishFraction).thenReturn(0.938F)
         mediaCarouselController.updatePageIndicatorAlpha()
-        assertEquals(mediaCarouselController.pageIndicator.alpha, 0.5F, delta)
+        verify(pageIndicator).alpha = floatThat { abs(it - 0.5F) < delta }
 
-        whenever(mediaHostState.squishFraction).thenReturn(paginationSquishEnd)
+        whenever(mediaHostState.squishFraction).thenReturn(1.0F)
         mediaCarouselController.updatePageIndicatorAlpha()
-        assertEquals(mediaCarouselController.pageIndicator.alpha, 1.0F, delta)
+        verify(pageIndicator).alpha = floatThat { abs(it - 1.0F) < delta }
+    }
+
+    @Ignore("b/253229241")
+    @Test
+    fun testOnConfigChanged_playersAreAddedBack() {
+        listener.value.onMediaDataLoaded(
+            "playing local",
+            null,
+            DATA.copy(
+                active = true,
+                isPlaying = true,
+                playbackLocation = MediaData.PLAYBACK_LOCAL,
+                resumption = false
+            )
+        )
+        listener.value.onMediaDataLoaded(
+            "paused local",
+            null,
+            DATA.copy(
+                active = true,
+                isPlaying = false,
+                playbackLocation = MediaData.PLAYBACK_LOCAL,
+                resumption = false
+            )
+        )
+
+        val playersSize = MediaPlayerData.players().size
+
+        configListener.value.onConfigChanged(capture(newConfig))
+
+        assertEquals(playersSize, MediaPlayerData.players().size)
+        assertEquals(
+            MediaPlayerData.getMediaPlayerIndex("playing local"),
+            mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex
+        )
     }
 }
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 b65f5cb..b35dd26 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
@@ -54,6 +54,7 @@
 import androidx.lifecycle.LiveData
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.InstanceId
+import com.android.internal.widget.CachingIconView
 import com.android.systemui.ActivityIntentHelper
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
@@ -81,6 +82,7 @@
 import com.android.systemui.statusbar.NotificationLockscreenUserManager
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.surfaceeffects.ripple.MultiRippleView
+import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseAnimationConfig
 import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseView
 import com.android.systemui.util.animation.TransitionLayout
 import com.android.systemui.util.concurrency.FakeExecutor
@@ -154,6 +156,7 @@
     @Mock private lateinit var albumView: ImageView
     private lateinit var titleText: TextView
     private lateinit var artistText: TextView
+    private lateinit var explicitIndicator: CachingIconView
     private lateinit var seamless: ViewGroup
     private lateinit var seamlessButton: View
     @Mock private lateinit var seamlessBackground: RippleDrawable
@@ -216,14 +219,15 @@
             this.set(Flags.UMO_SURFACE_RIPPLE, false)
             this.set(Flags.UMO_TURBULENCE_NOISE, false)
             this.set(Flags.MEDIA_FALSING_PENALTY, true)
+            this.set(Flags.MEDIA_EXPLICIT_INDICATOR, true)
         }
 
     @JvmField @Rule val mockito = MockitoJUnit.rule()
 
     @Before
     fun setUp() {
-        bgExecutor = FakeExecutor(FakeSystemClock())
-        mainExecutor = FakeExecutor(FakeSystemClock())
+        bgExecutor = FakeExecutor(clock)
+        mainExecutor = FakeExecutor(clock)
         whenever(mediaViewController.expandedLayout).thenReturn(expandedSet)
         whenever(mediaViewController.collapsedLayout).thenReturn(collapsedSet)
 
@@ -350,6 +354,7 @@
         appIcon = ImageView(context)
         titleText = TextView(context)
         artistText = TextView(context)
+        explicitIndicator = CachingIconView(context).also { it.id = R.id.media_explicit_indicator }
         seamless = FrameLayout(context)
         seamless.foreground = seamlessBackground
         seamlessButton = View(context)
@@ -396,6 +401,7 @@
         whenever(albumView.foreground).thenReturn(mock(Drawable::class.java))
         whenever(viewHolder.titleText).thenReturn(titleText)
         whenever(viewHolder.artistText).thenReturn(artistText)
+        whenever(viewHolder.explicitIndicator).thenReturn(explicitIndicator)
         whenever(seamlessBackground.getDrawable(0)).thenReturn(mock(GradientDrawable::class.java))
         whenever(viewHolder.seamless).thenReturn(seamless)
         whenever(viewHolder.seamlessButton).thenReturn(seamlessButton)
@@ -1019,6 +1025,7 @@
 
     @Test
     fun bindText() {
+        useRealConstraintSets()
         player.attachPlayer(viewHolder)
         player.bindPlayer(mediaData, PACKAGE)
 
@@ -1036,6 +1043,8 @@
         handler.onAnimationEnd(mockAnimator)
         assertThat(titleText.getText()).isEqualTo(TITLE)
         assertThat(artistText.getText()).isEqualTo(ARTIST)
+        assertThat(expandedSet.getVisibility(explicitIndicator.id)).isEqualTo(ConstraintSet.GONE)
+        assertThat(collapsedSet.getVisibility(explicitIndicator.id)).isEqualTo(ConstraintSet.GONE)
 
         // Rebinding should not trigger animation
         player.bindPlayer(mediaData, PACKAGE)
@@ -1043,6 +1052,36 @@
     }
 
     @Test
+    fun bindTextWithExplicitIndicator() {
+        useRealConstraintSets()
+        val mediaDataWitExp = mediaData.copy(isExplicit = true)
+        player.attachPlayer(viewHolder)
+        player.bindPlayer(mediaDataWitExp, PACKAGE)
+
+        // Capture animation handler
+        val captor = argumentCaptor<Animator.AnimatorListener>()
+        verify(mockAnimator, times(2)).addListener(captor.capture())
+        val handler = captor.value
+
+        // Validate text views unchanged but animation started
+        assertThat(titleText.getText()).isEqualTo("")
+        assertThat(artistText.getText()).isEqualTo("")
+        verify(mockAnimator, times(1)).start()
+
+        // Binding only after animator runs
+        handler.onAnimationEnd(mockAnimator)
+        assertThat(titleText.getText()).isEqualTo(TITLE)
+        assertThat(artistText.getText()).isEqualTo(ARTIST)
+        assertThat(expandedSet.getVisibility(explicitIndicator.id)).isEqualTo(ConstraintSet.VISIBLE)
+        assertThat(collapsedSet.getVisibility(explicitIndicator.id))
+            .isEqualTo(ConstraintSet.VISIBLE)
+
+        // Rebinding should not trigger animation
+        player.bindPlayer(mediaData, PACKAGE)
+        verify(mockAnimator, times(3)).start()
+    }
+
+    @Test
     fun bindTextInterrupted() {
         val data0 = mediaData.copy(artist = "ARTIST_0")
         val data1 = mediaData.copy(artist = "ARTIST_1")
@@ -2083,6 +2122,27 @@
         assertThat(player.mRipplesFinishedListener).isNull()
     }
 
+    @Test
+    fun playTurbulenceNoise_finishesAfterDuration() {
+        fakeFeatureFlag.set(Flags.UMO_SURFACE_RIPPLE, true)
+        fakeFeatureFlag.set(Flags.UMO_TURBULENCE_NOISE, true)
+
+        player.attachPlayer(viewHolder)
+
+        mainExecutor.execute {
+            player.mRipplesFinishedListener.onRipplesFinish()
+
+            assertThat(turbulenceNoiseView.visibility).isEqualTo(View.VISIBLE)
+
+            clock.advanceTime(
+                MediaControlPanel.TURBULENCE_NOISE_PLAY_DURATION +
+                    TurbulenceNoiseAnimationConfig.DEFAULT_EASING_DURATION_IN_MILLIS.toLong()
+            )
+
+            assertThat(turbulenceNoiseView.visibility).isEqualTo(View.INVISIBLE)
+        }
+    }
+
     private fun getScrubbingChangeListener(): SeekBarViewModel.ScrubbingChangeListener =
         withArgCaptor {
             verify(seekBarViewModel).setScrubbingChangeListener(capture())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt
index 920801f..a579518 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt
@@ -29,6 +29,7 @@
 import com.android.systemui.controls.controller.ControlsControllerImplTest.Companion.eq
 import com.android.systemui.dreams.DreamOverlayStateController
 import com.android.systemui.keyguard.WakefulnessLifecycle
+import com.android.systemui.media.controls.pipeline.MediaDataManager
 import com.android.systemui.media.dream.MediaDreamComplication
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.shade.ShadeExpansionStateManager
@@ -76,6 +77,7 @@
     @Mock private lateinit var mediaCarouselScrollHandler: MediaCarouselScrollHandler
     @Mock private lateinit var wakefulnessLifecycle: WakefulnessLifecycle
     @Mock private lateinit var keyguardViewController: KeyguardViewController
+    @Mock private lateinit var mediaDataManager: MediaDataManager
     @Mock private lateinit var uniqueObjectHostView: UniqueObjectHostView
     @Mock private lateinit var dreamOverlayStateController: DreamOverlayStateController
     @Captor
@@ -110,6 +112,7 @@
                 keyguardStateController,
                 bypassController,
                 mediaCarouselController,
+                mediaDataManager,
                 keyguardViewController,
                 dreamOverlayStateController,
                 configurationController,
@@ -125,6 +128,7 @@
         setupHost(qsHost, MediaHierarchyManager.LOCATION_QS, QS_TOP)
         setupHost(qqsHost, MediaHierarchyManager.LOCATION_QQS, QQS_TOP)
         whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE)
+        whenever(mediaDataManager.hasActiveMedia()).thenReturn(true)
         whenever(mediaCarouselController.mediaCarouselScrollHandler)
             .thenReturn(mediaCarouselScrollHandler)
         val observer = wakefullnessObserver.value
@@ -357,17 +361,31 @@
     }
 
     @Test
-    fun isCurrentlyInGuidedTransformation_hostNotVisible_returnsTrue() {
+    fun isCurrentlyInGuidedTransformation_hostNotVisible_returnsFalse_with_active() {
         goToLockscreen()
         enterGuidedTransformation()
         whenever(lockHost.visible).thenReturn(false)
         whenever(qsHost.visible).thenReturn(true)
         whenever(qqsHost.visible).thenReturn(true)
+        whenever(mediaDataManager.hasActiveMediaOrRecommendation()).thenReturn(true)
 
         assertThat(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).isFalse()
     }
 
     @Test
+    fun isCurrentlyInGuidedTransformation_hostNotVisible_returnsTrue_without_active() {
+        // To keep the appearing behavior, we need to be in a guided transition
+        goToLockscreen()
+        enterGuidedTransformation()
+        whenever(lockHost.visible).thenReturn(false)
+        whenever(qsHost.visible).thenReturn(true)
+        whenever(qqsHost.visible).thenReturn(true)
+        whenever(mediaDataManager.hasActiveMediaOrRecommendation()).thenReturn(false)
+
+        assertThat(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).isTrue()
+    }
+
+    @Test
     fun testDream() {
         goToDream()
         setMediaDreamComplicationEnabled(true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt
index 6b76155..4ed6d7c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt
@@ -22,13 +22,6 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.ANIMATION_BASE_DURATION
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.CONTROLS_DELAY
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.DETAILS_DELAY
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.DURATION
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.MEDIACONTAINERS_DELAY
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.MEDIATITLES_DELAY
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.TRANSFORM_BEZIER
 import com.android.systemui.util.animation.MeasurementInput
 import com.android.systemui.util.animation.TransitionLayout
 import com.android.systemui.util.animation.TransitionViewState
@@ -58,10 +51,12 @@
     @Mock private lateinit var mockCopiedState: TransitionViewState
     @Mock private lateinit var detailWidgetState: WidgetState
     @Mock private lateinit var controlWidgetState: WidgetState
+    @Mock private lateinit var bgWidgetState: WidgetState
     @Mock private lateinit var mediaTitleWidgetState: WidgetState
+    @Mock private lateinit var mediaSubTitleWidgetState: WidgetState
     @Mock private lateinit var mediaContainerWidgetState: WidgetState
 
-    val delta = 0.0001F
+    val delta = 0.1F
 
     private lateinit var mediaViewController: MediaViewController
 
@@ -75,7 +70,11 @@
     @Test
     fun testObtainViewState_applySquishFraction_toPlayerTransitionViewState_height() {
         mediaViewController.attach(player, MediaViewController.TYPE.PLAYER)
-        player.measureState = TransitionViewState().apply { this.height = 100 }
+        player.measureState =
+            TransitionViewState().apply {
+                this.height = 100
+                this.measureHeight = 100
+            }
         mediaHostStateHolder.expansion = 1f
         val widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY)
         val heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY)
@@ -85,10 +84,12 @@
         // Test no squish
         mediaHostStateHolder.squishFraction = 1f
         assertTrue(mediaViewController.obtainViewState(mediaHostStateHolder)!!.height == 100)
+        assertTrue(mediaViewController.obtainViewState(mediaHostStateHolder)!!.measureHeight == 100)
 
         // Test half squish
         mediaHostStateHolder.squishFraction = 0.5f
         assertTrue(mediaViewController.obtainViewState(mediaHostStateHolder)!!.height == 50)
+        assertTrue(mediaViewController.obtainViewState(mediaHostStateHolder)!!.measureHeight == 100)
     }
 
     @Test
@@ -104,10 +105,12 @@
         // Test no squish
         mediaHostStateHolder.squishFraction = 1f
         assertTrue(mediaViewController.obtainViewState(mediaHostStateHolder)!!.height == 100)
+        assertTrue(mediaViewController.obtainViewState(mediaHostStateHolder)!!.measureHeight == 100)
 
         // Test half squish
         mediaHostStateHolder.squishFraction = 0.5f
         assertTrue(mediaViewController.obtainViewState(mediaHostStateHolder)!!.height == 50)
+        assertTrue(mediaViewController.obtainViewState(mediaHostStateHolder)!!.measureHeight == 100)
     }
 
     @Test
@@ -120,29 +123,21 @@
                     R.id.header_artist to detailWidgetState
                 )
             )
-
-        val detailSquishMiddle =
-            TRANSFORM_BEZIER.getInterpolation(
-                (DETAILS_DELAY + DURATION / 2) / ANIMATION_BASE_DURATION
-            )
-        mediaViewController.squishViewState(mockViewState, detailSquishMiddle)
+        whenever(mockCopiedState.measureHeight).thenReturn(200)
+        // detail widgets occupy [90, 100]
+        whenever(detailWidgetState.y).thenReturn(90F)
+        whenever(detailWidgetState.height).thenReturn(10)
+        // control widgets occupy [150, 170]
+        whenever(controlWidgetState.y).thenReturn(150F)
+        whenever(controlWidgetState.height).thenReturn(20)
+        // in current beizer, when the progress reach 0.38, the result will be 0.5
+        mediaViewController.squishViewState(mockViewState, 119F / 200F)
         verify(detailWidgetState).alpha = floatThat { kotlin.math.abs(it - 0.5F) < delta }
-
-        val detailSquishEnd =
-            TRANSFORM_BEZIER.getInterpolation((DETAILS_DELAY + DURATION) / ANIMATION_BASE_DURATION)
-        mediaViewController.squishViewState(mockViewState, detailSquishEnd)
+        mediaViewController.squishViewState(mockViewState, 150F / 200F)
         verify(detailWidgetState).alpha = floatThat { kotlin.math.abs(it - 1.0F) < delta }
-
-        val controlSquishMiddle =
-            TRANSFORM_BEZIER.getInterpolation(
-                (CONTROLS_DELAY + DURATION / 2) / ANIMATION_BASE_DURATION
-            )
-        mediaViewController.squishViewState(mockViewState, controlSquishMiddle)
+        mediaViewController.squishViewState(mockViewState, 181.4F / 200F)
         verify(controlWidgetState).alpha = floatThat { kotlin.math.abs(it - 0.5F) < delta }
-
-        val controlSquishEnd =
-            TRANSFORM_BEZIER.getInterpolation((CONTROLS_DELAY + DURATION) / ANIMATION_BASE_DURATION)
-        mediaViewController.squishViewState(mockViewState, controlSquishEnd)
+        mediaViewController.squishViewState(mockViewState, 200F / 200F)
         verify(controlWidgetState).alpha = floatThat { kotlin.math.abs(it - 1.0F) < delta }
     }
 
@@ -153,36 +148,33 @@
             .thenReturn(
                 mutableMapOf(
                     R.id.media_title1 to mediaTitleWidgetState,
+                    R.id.media_subtitle1 to mediaSubTitleWidgetState,
                     R.id.media_cover1_container to mediaContainerWidgetState
                 )
             )
+        whenever(mockCopiedState.measureHeight).thenReturn(360)
+        // media container widgets occupy [20, 300]
+        whenever(mediaContainerWidgetState.y).thenReturn(20F)
+        whenever(mediaContainerWidgetState.height).thenReturn(280)
+        // media title widgets occupy [320, 330]
+        whenever(mediaTitleWidgetState.y).thenReturn(320F)
+        whenever(mediaTitleWidgetState.height).thenReturn(10)
+        // media subtitle widgets occupy [340, 350]
+        whenever(mediaSubTitleWidgetState.y).thenReturn(340F)
+        whenever(mediaSubTitleWidgetState.height).thenReturn(10)
 
-        val containerSquishMiddle =
-            TRANSFORM_BEZIER.getInterpolation(
-                (MEDIACONTAINERS_DELAY + DURATION / 2) / ANIMATION_BASE_DURATION
-            )
-        mediaViewController.squishViewState(mockViewState, containerSquishMiddle)
+        // in current beizer, when the progress reach 0.38, the result will be 0.5
+        mediaViewController.squishViewState(mockViewState, 307.6F / 360F)
         verify(mediaContainerWidgetState).alpha = floatThat { kotlin.math.abs(it - 0.5F) < delta }
-
-        val containerSquishEnd =
-            TRANSFORM_BEZIER.getInterpolation(
-                (MEDIACONTAINERS_DELAY + DURATION) / ANIMATION_BASE_DURATION
-            )
-        mediaViewController.squishViewState(mockViewState, containerSquishEnd)
+        mediaViewController.squishViewState(mockViewState, 320F / 360F)
         verify(mediaContainerWidgetState).alpha = floatThat { kotlin.math.abs(it - 1.0F) < delta }
-
-        val titleSquishMiddle =
-            TRANSFORM_BEZIER.getInterpolation(
-                (MEDIATITLES_DELAY + DURATION / 2) / ANIMATION_BASE_DURATION
-            )
-        mediaViewController.squishViewState(mockViewState, titleSquishMiddle)
+        // media title and media subtitle are in same widget group, should be calculate together and
+        // have same alpha
+        mediaViewController.squishViewState(mockViewState, 353.8F / 360F)
         verify(mediaTitleWidgetState).alpha = floatThat { kotlin.math.abs(it - 0.5F) < delta }
-
-        val titleSquishEnd =
-            TRANSFORM_BEZIER.getInterpolation(
-                (MEDIATITLES_DELAY + DURATION) / ANIMATION_BASE_DURATION
-            )
-        mediaViewController.squishViewState(mockViewState, titleSquishEnd)
+        verify(mediaSubTitleWidgetState).alpha = floatThat { kotlin.math.abs(it - 0.5F) < delta }
+        mediaViewController.squishViewState(mockViewState, 360F / 360F)
         verify(mediaTitleWidgetState).alpha = floatThat { kotlin.math.abs(it - 1.0F) < delta }
+        verify(mediaSubTitleWidgetState).alpha = floatThat { kotlin.math.abs(it - 1.0F) < delta }
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
index 094d69a..9a0bd9e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
@@ -243,6 +243,13 @@
     }
 
     @Test
+    public void dismissDialog_closesDialogByBroadcastSender() {
+        mMediaOutputBaseDialogImpl.dismissDialog();
+
+        verify(mBroadcastSender).closeSystemDialogs();
+    }
+
+    @Test
     public void whenBroadcasting_verifyLeBroadcastServiceCallBackIsRegisteredAndUnregistered() {
         when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
                 mLocalBluetoothLeBroadcast);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
index b16a39f..117751c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
@@ -102,8 +102,6 @@
     private MediaOutputController.Callback mCb = mock(MediaOutputController.Callback.class);
     private MediaDevice mMediaDevice1 = mock(MediaDevice.class);
     private MediaDevice mMediaDevice2 = mock(MediaDevice.class);
-    private MediaItem mMediaItem1 = mock(MediaItem.class);
-    private MediaItem mMediaItem2 = mock(MediaItem.class);
     private NearbyDevice mNearbyDevice1 = mock(NearbyDevice.class);
     private NearbyDevice mNearbyDevice2 = mock(NearbyDevice.class);
     private MediaMetadata mMediaMetadata = mock(MediaMetadata.class);
@@ -127,7 +125,6 @@
     private LocalMediaManager mLocalMediaManager;
     private List<MediaController> mMediaControllers = new ArrayList<>();
     private List<MediaDevice> mMediaDevices = new ArrayList<>();
-    private List<MediaItem> mMediaItemList = new ArrayList<>();
     private List<NearbyDevice> mNearbyDevices = new ArrayList<>();
     private MediaDescription mMediaDescription;
     private List<RoutingSessionInfo> mRoutingSessionInfos = new ArrayList<>();
@@ -149,7 +146,9 @@
                 Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager,
                 mKeyguardManager, mFlags);
         when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(false);
+        when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ROUTES_PROCESSING)).thenReturn(false);
         mLocalMediaManager = spy(mMediaOutputController.mLocalMediaManager);
+        when(mLocalMediaManager.isPreferenceRouteListingExist()).thenReturn(false);
         mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
         MediaDescription.Builder builder = new MediaDescription.Builder();
         builder.setTitle(TEST_SONG);
@@ -160,16 +159,12 @@
         when(mMediaDevice2.getId()).thenReturn(TEST_DEVICE_2_ID);
         mMediaDevices.add(mMediaDevice1);
         mMediaDevices.add(mMediaDevice2);
-        when(mMediaItem1.getMediaDevice()).thenReturn(Optional.of(mMediaDevice1));
-        when(mMediaItem2.getMediaDevice()).thenReturn(Optional.of(mMediaDevice2));
-        mMediaItemList.add(mMediaItem1);
-        mMediaItemList.add(mMediaItem2);
 
 
         when(mNearbyDevice1.getMediaRoute2Id()).thenReturn(TEST_DEVICE_1_ID);
-        when(mNearbyDevice1.getRangeZone()).thenReturn(NearbyDevice.RANGE_CLOSE);
+        when(mNearbyDevice1.getRangeZone()).thenReturn(NearbyDevice.RANGE_FAR);
         when(mNearbyDevice2.getMediaRoute2Id()).thenReturn(TEST_DEVICE_2_ID);
-        when(mNearbyDevice2.getRangeZone()).thenReturn(NearbyDevice.RANGE_FAR);
+        when(mNearbyDevice2.getRangeZone()).thenReturn(NearbyDevice.RANGE_CLOSE);
         mNearbyDevices.add(mNearbyDevice1);
         mNearbyDevices.add(mNearbyDevice2);
     }
@@ -257,6 +252,13 @@
     }
 
     @Test
+    public void tryToLaunchMediaApplication_nullIntent_skip() {
+        mMediaOutputController.tryToLaunchMediaApplication();
+
+        verify(mCb, never()).dismissDialog();
+    }
+
+    @Test
     public void onDevicesUpdated_unregistersNearbyDevicesCallback() throws RemoteException {
         mMediaOutputController.start(mCb);
 
@@ -274,8 +276,20 @@
         mMediaOutputController.onDevicesUpdated(mNearbyDevices);
         mMediaOutputController.onDeviceListUpdate(mMediaDevices);
 
-        verify(mMediaDevice1).setRangeZone(NearbyDevice.RANGE_CLOSE);
-        verify(mMediaDevice2).setRangeZone(NearbyDevice.RANGE_FAR);
+        verify(mMediaDevice1).setRangeZone(NearbyDevice.RANGE_FAR);
+        verify(mMediaDevice2).setRangeZone(NearbyDevice.RANGE_CLOSE);
+    }
+
+    @Test
+    public void onDeviceListUpdate_withNearbyDevices_rankByRangeInformation()
+            throws RemoteException {
+        mMediaOutputController.start(mCb);
+        reset(mCb);
+
+        mMediaOutputController.onDevicesUpdated(mNearbyDevices);
+        mMediaOutputController.onDeviceListUpdate(mMediaDevices);
+
+        assertThat(mMediaDevices.get(0).getId()).isEqualTo(TEST_DEVICE_1_ID);
     }
 
     @Test
@@ -292,6 +306,22 @@
     }
 
     @Test
+    public void routeProcessSupport_onDeviceListUpdate_preferenceExist_NotUpdatesRangeInformation()
+            throws RemoteException {
+        when(mLocalMediaManager.isPreferenceRouteListingExist()).thenReturn(true);
+        when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ROUTES_PROCESSING)).thenReturn(true);
+        when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(true);
+        mMediaOutputController.start(mCb);
+        reset(mCb);
+
+        mMediaOutputController.onDevicesUpdated(mNearbyDevices);
+        mMediaOutputController.onDeviceListUpdate(mMediaDevices);
+
+        verify(mMediaDevice1, never()).setRangeZone(anyInt());
+        verify(mMediaDevice2, never()).setRangeZone(anyInt());
+    }
+
+    @Test
     public void advanced_onDeviceListUpdate_verifyDeviceListCallback() {
         when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(true);
         mMediaOutputController.start(mCb);
@@ -307,6 +337,35 @@
 
         assertThat(devices.containsAll(mMediaDevices)).isTrue();
         assertThat(devices.size()).isEqualTo(mMediaDevices.size());
+        assertThat(mMediaOutputController.getMediaItemList().size()).isEqualTo(
+                mMediaDevices.size() + 2);
+        verify(mCb).onDeviceListChanged();
+    }
+
+    @Test
+    public void advanced_categorizeMediaItems_withSuggestedDevice_verifyDeviceListSize() {
+        when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(true);
+        when(mMediaDevice1.isSuggestedDevice()).thenReturn(true);
+        when(mMediaDevice2.isSuggestedDevice()).thenReturn(false);
+
+        mMediaOutputController.start(mCb);
+        reset(mCb);
+        mMediaOutputController.getMediaItemList().clear();
+        mMediaOutputController.onDeviceListUpdate(mMediaDevices);
+        final List<MediaDevice> devices = new ArrayList<>();
+        int dividerSize = 0;
+        for (MediaItem item : mMediaOutputController.getMediaItemList()) {
+            if (item.getMediaDevice().isPresent()) {
+                devices.add(item.getMediaDevice().get());
+            }
+            if (item.getMediaItemType() == MediaItem.MediaItemType.TYPE_GROUP_DIVIDER) {
+                dividerSize++;
+            }
+        }
+
+        assertThat(devices.containsAll(mMediaDevices)).isTrue();
+        assertThat(devices.size()).isEqualTo(mMediaDevices.size());
+        assertThat(dividerSize).isEqualTo(2);
         verify(mCb).onDeviceListChanged();
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt
index 9c4e849..b3e621e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt
@@ -48,6 +48,7 @@
     viewUtil: ViewUtil,
     wakeLockBuilder: WakeLock.Builder,
     systemClock: SystemClock,
+    rippleController: MediaTttReceiverRippleController,
 ) :
     MediaTttChipControllerReceiver(
         commandQueue,
@@ -65,6 +66,7 @@
         viewUtil,
         wakeLockBuilder,
         systemClock,
+        rippleController,
     ) {
     override fun animateViewOut(view: ViewGroup, removalReason: String?, onAnimationEnd: Runnable) {
         // Just bypass the animation in tests
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
index cefc742..5e40898 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
@@ -85,6 +85,8 @@
     private lateinit var windowManager: WindowManager
     @Mock
     private lateinit var commandQueue: CommandQueue
+    @Mock
+    private lateinit var rippleController: MediaTttReceiverRippleController
     private lateinit var commandQueueCallback: CommandQueue.Callbacks
     private lateinit var fakeAppIconDrawable: Drawable
     private lateinit var uiEventLoggerFake: UiEventLoggerFake
@@ -134,6 +136,7 @@
             viewUtil,
             fakeWakeLockBuilder,
             fakeClock,
+            rippleController,
         )
         controllerReceiver.start()
 
@@ -163,6 +166,7 @@
             viewUtil,
             fakeWakeLockBuilder,
             fakeClock,
+            rippleController,
         )
         controllerReceiver.start()
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt
index 4cc12c7..54d4460 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt
@@ -45,13 +45,18 @@
 import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.VibratorHelper
 import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.temporarydisplay.TemporaryViewDisplayController
 import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator
 import com.android.systemui.temporarydisplay.chipbar.ChipbarInfo
 import com.android.systemui.temporarydisplay.chipbar.ChipbarLogger
 import com.android.systemui.temporarydisplay.chipbar.FakeChipbarCoordinator
+import com.android.systemui.temporarydisplay.chipbar.SwipeChipbarAwayGestureHandler
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.capture
 import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.time.FakeSystemClock
 import com.android.systemui.util.view.ViewUtil
 import com.android.systemui.util.wakelock.WakeLockFake
@@ -61,6 +66,7 @@
 import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor
 import org.mockito.Mock
+import org.mockito.Mockito.atLeast
 import org.mockito.Mockito.never
 import org.mockito.Mockito.reset
 import org.mockito.Mockito.verify
@@ -93,6 +99,7 @@
     @Mock private lateinit var viewUtil: ViewUtil
     @Mock private lateinit var windowManager: WindowManager
     @Mock private lateinit var vibratorHelper: VibratorHelper
+    @Mock private lateinit var swipeHandler: SwipeChipbarAwayGestureHandler
     private lateinit var fakeWakeLockBuilder: WakeLockFake.Builder
     private lateinit var fakeWakeLock: WakeLockFake
     private lateinit var chipbarCoordinator: ChipbarCoordinator
@@ -143,6 +150,7 @@
                 powerManager,
                 falsingManager,
                 falsingCollector,
+                swipeHandler,
                 viewUtil,
                 vibratorHelper,
                 fakeWakeLockBuilder,
@@ -161,9 +169,7 @@
             )
         underTest.start()
 
-        val callbackCaptor = ArgumentCaptor.forClass(CommandQueue.Callbacks::class.java)
-        verify(commandQueue).addCallback(callbackCaptor.capture())
-        commandQueueCallback = callbackCaptor.value!!
+        setCommandQueueCallback()
     }
 
     @Test
@@ -206,6 +212,21 @@
     }
 
     @Test
+    fun commandQueueCallback_almostCloseToStartCast_deviceNameBlank_showsDefaultDeviceName() {
+        commandQueueCallback.updateMediaTapToTransferSenderDisplay(
+            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST,
+            routeInfoWithBlankDeviceName,
+            null,
+        )
+
+        val chipbarView = getChipbarView()
+        assertThat(chipbarView.getChipText())
+            .contains(context.getString(R.string.media_ttt_default_device_type))
+        assertThat(chipbarView.getChipText())
+            .isNotEqualTo(ChipStateSender.ALMOST_CLOSE_TO_START_CAST.getExpectedStateText())
+    }
+
+    @Test
     fun commandQueueCallback_almostCloseToEndCast_triggersCorrectChip() {
         commandQueueCallback.updateMediaTapToTransferSenderDisplay(
             StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST,
@@ -248,6 +269,21 @@
     }
 
     @Test
+    fun commandQueueCallback_transferToReceiverTriggered_deviceNameBlank_showsDefaultDeviceName() {
+        commandQueueCallback.updateMediaTapToTransferSenderDisplay(
+            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED,
+            routeInfoWithBlankDeviceName,
+            null,
+        )
+
+        val chipbarView = getChipbarView()
+        assertThat(chipbarView.getChipText())
+            .contains(context.getString(R.string.media_ttt_default_device_type))
+        assertThat(chipbarView.getChipText())
+            .isNotEqualTo(ChipStateSender.TRANSFER_TO_RECEIVER_TRIGGERED.getExpectedStateText())
+    }
+
+    @Test
     fun commandQueueCallback_transferToThisDeviceTriggered_triggersCorrectChip() {
         commandQueueCallback.updateMediaTapToTransferSenderDisplay(
             StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED,
@@ -890,6 +926,172 @@
         verify(windowManager).removeView(any())
     }
 
+    @Test
+    fun newState_viewListenerRegistered() {
+        val mockChipbarCoordinator = mock<ChipbarCoordinator>()
+        underTest =
+            MediaTttSenderCoordinator(
+                mockChipbarCoordinator,
+                commandQueue,
+                context,
+                logger,
+                mediaTttFlags,
+                uiEventLogger,
+            )
+        underTest.start()
+        // Re-set the command queue callback since we've created a new [MediaTttSenderCoordinator]
+        // with a new callback.
+        setCommandQueueCallback()
+
+        commandQueueCallback.updateMediaTapToTransferSenderDisplay(
+            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST,
+            routeInfo,
+            null,
+        )
+
+        verify(mockChipbarCoordinator).registerListener(any())
+    }
+
+    @Test
+    fun onInfoPermanentlyRemoved_viewListenerUnregistered() {
+        val mockChipbarCoordinator = mock<ChipbarCoordinator>()
+        underTest =
+            MediaTttSenderCoordinator(
+                mockChipbarCoordinator,
+                commandQueue,
+                context,
+                logger,
+                mediaTttFlags,
+                uiEventLogger,
+            )
+        underTest.start()
+        setCommandQueueCallback()
+
+        commandQueueCallback.updateMediaTapToTransferSenderDisplay(
+            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST,
+            routeInfo,
+            null,
+        )
+
+        val listenerCaptor = argumentCaptor<TemporaryViewDisplayController.Listener>()
+        verify(mockChipbarCoordinator).registerListener(capture(listenerCaptor))
+
+        // WHEN the listener is notified that the view has been removed
+        listenerCaptor.value.onInfoPermanentlyRemoved(DEFAULT_ID)
+
+        // THEN the media coordinator unregisters the listener
+        verify(mockChipbarCoordinator).unregisterListener(listenerCaptor.value)
+    }
+
+    @Test
+    fun onInfoPermanentlyRemoved_wrongId_viewListenerNotUnregistered() {
+        val mockChipbarCoordinator = mock<ChipbarCoordinator>()
+        underTest =
+            MediaTttSenderCoordinator(
+                mockChipbarCoordinator,
+                commandQueue,
+                context,
+                logger,
+                mediaTttFlags,
+                uiEventLogger,
+            )
+        underTest.start()
+        setCommandQueueCallback()
+
+        commandQueueCallback.updateMediaTapToTransferSenderDisplay(
+            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST,
+            routeInfo,
+            null,
+        )
+
+        val listenerCaptor = argumentCaptor<TemporaryViewDisplayController.Listener>()
+        verify(mockChipbarCoordinator).registerListener(capture(listenerCaptor))
+
+        // WHEN the listener is notified that a different view has been removed
+        listenerCaptor.value.onInfoPermanentlyRemoved("differentViewId")
+
+        // THEN the media coordinator doesn't unregister the listener
+        verify(mockChipbarCoordinator, never()).unregisterListener(listenerCaptor.value)
+    }
+
+    @Test
+    fun farFromReceiverState_viewListenerUnregistered() {
+        val mockChipbarCoordinator = mock<ChipbarCoordinator>()
+        underTest =
+            MediaTttSenderCoordinator(
+                mockChipbarCoordinator,
+                commandQueue,
+                context,
+                logger,
+                mediaTttFlags,
+                uiEventLogger,
+            )
+        underTest.start()
+        setCommandQueueCallback()
+
+        commandQueueCallback.updateMediaTapToTransferSenderDisplay(
+            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST,
+            routeInfo,
+            null,
+        )
+
+        val listenerCaptor = argumentCaptor<TemporaryViewDisplayController.Listener>()
+        verify(mockChipbarCoordinator).registerListener(capture(listenerCaptor))
+
+        // WHEN we go to the FAR_FROM_RECEIVER state
+        commandQueueCallback.updateMediaTapToTransferSenderDisplay(
+            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
+            routeInfo,
+            null
+        )
+
+        // THEN the media coordinator unregisters the listener
+        verify(mockChipbarCoordinator).unregisterListener(listenerCaptor.value)
+    }
+
+    @Test
+    fun statesWithDifferentIds_onInfoPermanentlyRemovedForOneId_viewListenerNotUnregistered() {
+        val mockChipbarCoordinator = mock<ChipbarCoordinator>()
+        underTest =
+            MediaTttSenderCoordinator(
+                mockChipbarCoordinator,
+                commandQueue,
+                context,
+                logger,
+                mediaTttFlags,
+                uiEventLogger,
+            )
+        underTest.start()
+        setCommandQueueCallback()
+
+        // WHEN there are two different media transfers with different IDs
+        commandQueueCallback.updateMediaTapToTransferSenderDisplay(
+            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST,
+            MediaRoute2Info.Builder("route1", OTHER_DEVICE_NAME)
+                .addFeature("feature")
+                .setClientPackageName(PACKAGE_NAME)
+                .build(),
+            null,
+        )
+        commandQueueCallback.updateMediaTapToTransferSenderDisplay(
+            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST,
+            MediaRoute2Info.Builder("route2", OTHER_DEVICE_NAME)
+                .addFeature("feature")
+                .setClientPackageName(PACKAGE_NAME)
+                .build(),
+            null,
+        )
+
+        val listenerCaptor = argumentCaptor<TemporaryViewDisplayController.Listener>()
+        verify(mockChipbarCoordinator, atLeast(1)).registerListener(capture(listenerCaptor))
+
+        // THEN one of them is removed
+        listenerCaptor.value.onInfoPermanentlyRemoved("route1")
+
+        // THEN the media coordinator doesn't unregister the listener (since route2 is still active)
+        verify(mockChipbarCoordinator, never()).unregisterListener(listenerCaptor.value)
+    }
+
     private fun getChipbarView(): ViewGroup {
         val viewCaptor = ArgumentCaptor.forClass(View::class.java)
         verify(windowManager).addView(viewCaptor.capture(), any())
@@ -930,15 +1132,30 @@
             null
         )
     }
+
+    private fun setCommandQueueCallback() {
+        val callbackCaptor = argumentCaptor<CommandQueue.Callbacks>()
+        verify(commandQueue).addCallback(capture(callbackCaptor))
+        commandQueueCallback = callbackCaptor.value
+        reset(commandQueue)
+    }
 }
 
+private const val DEFAULT_ID = "defaultId"
 private const val APP_NAME = "Fake app name"
 private const val OTHER_DEVICE_NAME = "My Tablet"
+private const val BLANK_DEVICE_NAME = " "
 private const val PACKAGE_NAME = "com.android.systemui"
 private const val TIMEOUT = 10000
 
 private val routeInfo =
-    MediaRoute2Info.Builder("id", OTHER_DEVICE_NAME)
+    MediaRoute2Info.Builder(DEFAULT_ID, OTHER_DEVICE_NAME)
+        .addFeature("feature")
+        .setClientPackageName(PACKAGE_NAME)
+        .build()
+
+private val routeInfoWithBlankDeviceName =
+    MediaRoute2Info.Builder(DEFAULT_ID, BLANK_DEVICE_NAME)
         .addFeature("feature")
         .setClientPackageName(PACKAGE_NAME)
         .build()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorControllerTest.kt
index 19d2d33..1042ea7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorControllerTest.kt
@@ -1,12 +1,16 @@
 package com.android.systemui.mediaprojection.appselector
 
 import android.content.ComponentName
+import android.os.UserHandle
 import android.testing.AndroidTestingRunner
 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.mediaprojection.appselector.data.RecentTask
 import com.android.systemui.mediaprojection.appselector.data.RecentTaskListProvider
 import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import org.junit.Test
@@ -21,11 +25,17 @@
     private val scope = CoroutineScope(Dispatchers.Unconfined)
     private val appSelectorComponentName = ComponentName("com.test", "AppSelector")
 
+    private val hostUserHandle = UserHandle.of(123)
+    private val otherUserHandle = UserHandle.of(456)
+
     private val view: MediaProjectionAppSelectorView = mock()
+    private val featureFlags: FeatureFlags = mock()
 
     private val controller = MediaProjectionAppSelectorController(
         taskListProvider,
         view,
+        featureFlags,
+        hostUserHandle,
         scope,
         appSelectorComponentName
     )
@@ -98,15 +108,72 @@
         )
     }
 
+    @Test
+    fun initRecentTasksWithAppSelectorTasks_enterprisePoliciesDisabled_bindsOnlyTasksWithHostProfile() {
+        givenEnterprisePoliciesFeatureFlag(enabled = false)
+
+        val tasks = listOf(
+            createRecentTask(taskId = 1, userId = hostUserHandle.identifier),
+            createRecentTask(taskId = 2, userId = otherUserHandle.identifier),
+            createRecentTask(taskId = 3, userId = hostUserHandle.identifier),
+            createRecentTask(taskId = 4, userId = otherUserHandle.identifier),
+            createRecentTask(taskId = 5, userId = hostUserHandle.identifier),
+        )
+        taskListProvider.tasks = tasks
+
+        controller.init()
+
+        verify(view).bind(
+            listOf(
+                createRecentTask(taskId = 1, userId = hostUserHandle.identifier),
+                createRecentTask(taskId = 3, userId = hostUserHandle.identifier),
+                createRecentTask(taskId = 5, userId = hostUserHandle.identifier),
+            )
+        )
+    }
+
+    @Test
+    fun initRecentTasksWithAppSelectorTasks_enterprisePoliciesEnabled_bindsAllTasks() {
+        givenEnterprisePoliciesFeatureFlag(enabled = true)
+
+        val tasks = listOf(
+            createRecentTask(taskId = 1, userId = hostUserHandle.identifier),
+            createRecentTask(taskId = 2, userId = otherUserHandle.identifier),
+            createRecentTask(taskId = 3, userId = hostUserHandle.identifier),
+            createRecentTask(taskId = 4, userId = otherUserHandle.identifier),
+            createRecentTask(taskId = 5, userId = hostUserHandle.identifier),
+        )
+        taskListProvider.tasks = tasks
+
+        controller.init()
+
+        // TODO(b/233348916) should filter depending on the policies
+        verify(view).bind(
+            listOf(
+                createRecentTask(taskId = 1, userId = hostUserHandle.identifier),
+                createRecentTask(taskId = 2, userId = otherUserHandle.identifier),
+                createRecentTask(taskId = 3, userId = hostUserHandle.identifier),
+                createRecentTask(taskId = 4, userId = otherUserHandle.identifier),
+                createRecentTask(taskId = 5, userId = hostUserHandle.identifier),
+            )
+        )
+    }
+
+    private fun givenEnterprisePoliciesFeatureFlag(enabled: Boolean) {
+        whenever(featureFlags.isEnabled(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES))
+            .thenReturn(enabled)
+    }
+
     private fun createRecentTask(
         taskId: Int,
-        topActivityComponent: ComponentName? = null
+        topActivityComponent: ComponentName? = null,
+        userId: Int = hostUserHandle.identifier
     ): RecentTask {
         return RecentTask(
             taskId = taskId,
             topActivityComponent = topActivityComponent,
             baseIntentComponent = ComponentName("com", "Test"),
-            userId = 0,
+            userId = userId,
             colorBackground = 0
         )
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.java b/packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.java
index 1bc4719..1a35502 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.java
@@ -31,10 +31,7 @@
 import org.junit.runner.RunWith;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
@@ -69,7 +66,7 @@
         // Expressive applies hue rotations to the theme color. The input theme color has hue
         // 117, ensuring the hue changed significantly is a strong signal styles are being applied.
         ColorScheme colorScheme = new ColorScheme(wallpaperColors, false, Style.EXPRESSIVE);
-        Assert.assertEquals(357.77, Cam.fromInt(colorScheme.getAccent1().get(6)).getHue(), 0.1);
+        Assert.assertEquals(357.77, Cam.fromInt(colorScheme.getAccent1().getS500()).getHue(), 0.1);
     }
 
 
@@ -111,7 +108,8 @@
     public void testTertiaryHueWrapsProperly() {
         int colorInt = 0xffB3588A; // H350 C50 T50
         ColorScheme colorScheme = new ColorScheme(colorInt, false /* darkTheme */);
-        int tertiaryMid = colorScheme.getAccent3().get(colorScheme.getAccent3().size() / 2);
+        int tertiaryMid = colorScheme.getAccent3().getAllShades().get(
+                colorScheme.getShadeCount() / 2);
         Cam cam = Cam.fromInt(tertiaryMid);
         Assert.assertEquals(cam.getHue(), 50.0, 10.0);
     }
@@ -121,7 +119,8 @@
         int colorInt = 0xffB3588A; // H350 C50 T50
         ColorScheme colorScheme = new ColorScheme(colorInt, false /* darkTheme */,
                 Style.SPRITZ /* style */);
-        int primaryMid = colorScheme.getAccent1().get(colorScheme.getAccent1().size() / 2);
+        int primaryMid = colorScheme.getAccent1().getAllShades().get(
+                colorScheme.getShadeCount() / 2);
         Cam cam = Cam.fromInt(primaryMid);
         Assert.assertEquals(cam.getChroma(), 12.0, 1.0);
     }
@@ -131,7 +130,8 @@
         int colorInt = 0xffB3588A; // H350 C50 T50
         ColorScheme colorScheme = new ColorScheme(colorInt, false /* darkTheme */,
                 Style.VIBRANT /* style */);
-        int neutralMid = colorScheme.getNeutral1().get(colorScheme.getNeutral1().size() / 2);
+        int neutralMid = colorScheme.getNeutral1().getAllShades().get(
+                colorScheme.getShadeCount() / 2);
         Cam cam = Cam.fromInt(neutralMid);
         Assert.assertTrue("chroma was " + cam.getChroma(), Math.floor(cam.getChroma()) <= 12.0);
     }
@@ -141,7 +141,8 @@
         int colorInt = 0xffB3588A; // H350 C50 T50
         ColorScheme colorScheme = new ColorScheme(colorInt, false /* darkTheme */,
                 Style.EXPRESSIVE /* style */);
-        int neutralMid = colorScheme.getNeutral1().get(colorScheme.getNeutral1().size() / 2);
+        int neutralMid = colorScheme.getNeutral1().getAllShades().get(
+                colorScheme.getShadeCount() / 2);
         Cam cam = Cam.fromInt(neutralMid);
         Assert.assertTrue(cam.getChroma() <= 8.0);
     }
@@ -151,10 +152,11 @@
         int colorInt = 0xffB3588A; // H350 C50 T50
         ColorScheme colorScheme = new ColorScheme(colorInt, false /* darkTheme */,
                 Style.MONOCHROMATIC /* style */);
-        int neutralMid = colorScheme.getNeutral1().get(colorScheme.getNeutral1().size() / 2);
+        int neutralMid = colorScheme.getNeutral1().getAllShades().get(
+                colorScheme.getShadeCount() / 2);
         Assert.assertTrue(
                 Color.red(neutralMid) == Color.green(neutralMid)
-                && Color.green(neutralMid) == Color.blue(neutralMid)
+                        && Color.green(neutralMid) == Color.blue(neutralMid)
         );
     }
 
@@ -190,15 +192,14 @@
                 xml.append("        <").append(styleName).append(">");
 
                 List<String> colors = new ArrayList<>();
-                for (Stream<Integer> stream: Arrays.asList(colorScheme.getAccent1().stream(),
-                        colorScheme.getAccent2().stream(),
-                        colorScheme.getAccent3().stream(),
-                        colorScheme.getNeutral1().stream(),
-                        colorScheme.getNeutral2().stream())) {
+
+                colorScheme.getAllHues().forEach(schemeHue -> {
                     colors.add("ffffff");
-                    colors.addAll(stream.map(Integer::toHexString).map(s -> s.substring(2)).collect(
-                            Collectors.toList()));
-                }
+                    schemeHue.getAllShades().forEach(tone -> {
+                        colors.add(Integer.toHexString(tone).substring(2));
+                    });
+                });
+
                 xml.append(String.join(",", colors));
                 xml.append("</").append(styleName).append(">\n");
             }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java
index 1865ef6..ce6a98c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java
@@ -146,7 +146,7 @@
         verify(mNavbarTaskbarStateUpdater, times(1))
                 .updateAccessibilityServicesState();
         verify(mNavbarTaskbarStateUpdater, times(1))
-                .updateAssistantAvailable(anyBoolean());
+                .updateAssistantAvailable(anyBoolean(), anyBoolean());
     }
 
     @Test
@@ -160,14 +160,14 @@
         verify(mNavbarTaskbarStateUpdater, times(1))
                 .updateAccessibilityServicesState();
         verify(mNavbarTaskbarStateUpdater, times(1))
-                .updateAssistantAvailable(anyBoolean());
+                .updateAssistantAvailable(anyBoolean(), anyBoolean());
 
         mNavBarHelper.onConnectionChanged(true);
         // assert no more callbacks fired
         verify(mNavbarTaskbarStateUpdater, times(1))
                 .updateAccessibilityServicesState();
         verify(mNavbarTaskbarStateUpdater, times(2))
-                .updateAssistantAvailable(anyBoolean());
+                .updateAssistantAvailable(anyBoolean(), anyBoolean());
     }
 
     @Test
@@ -180,7 +180,7 @@
         verify(mNavbarTaskbarStateUpdater, times(2))
                 .updateAccessibilityServicesState();
         verify(mNavbarTaskbarStateUpdater, times(1))
-                .updateAssistantAvailable(anyBoolean());
+                .updateAssistantAvailable(anyBoolean(), anyBoolean());
     }
 
     @Test
@@ -193,7 +193,7 @@
         verify(mNavbarTaskbarStateUpdater, times(1))
                 .updateAccessibilityServicesState();
         verify(mNavbarTaskbarStateUpdater, times(2))
-                .updateAssistantAvailable(anyBoolean());
+                .updateAssistantAvailable(anyBoolean(), anyBoolean());
     }
 
     @Test
@@ -212,7 +212,7 @@
         verify(mNavbarTaskbarStateUpdater, times(1))
                 .updateAccessibilityServicesState();
         verify(mNavbarTaskbarStateUpdater, times(1))
-                .updateAssistantAvailable(anyBoolean());
+                .updateAssistantAvailable(anyBoolean(), anyBoolean());
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java
index 9bf27a2..8058b85 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java
@@ -51,11 +51,12 @@
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.shared.recents.utilities.Utilities;
+import com.android.systemui.shared.system.TaskStackChangeListeners;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.AutoHideController;
 import com.android.systemui.statusbar.phone.LightBarController;
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.util.settings.SecureSettings;
 import com.android.wm.shell.back.BackAnimation;
 import com.android.wm.shell.pip.Pip;
 
@@ -102,13 +103,14 @@
                         mock(NavBarHelper.class),
                         mTaskbarDelegate,
                         mNavigationBarFactory,
-                        mock(StatusBarKeyguardViewManager.class),
                         mock(DumpManager.class),
                         mock(AutoHideController.class),
                         mock(LightBarController.class),
+                        TaskStackChangeListeners.getTestInstance(),
                         Optional.of(mock(Pip.class)),
                         Optional.of(mock(BackAnimation.class)),
-                        mock(FeatureFlags.class)));
+                        mock(FeatureFlags.class),
+                        mock(SecureSettings.class)));
         initializeNavigationBars();
         mMockitoSession = mockitoSession().mockStatic(Utilities.class).startMocking();
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
index 80adbf0..2ad865e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
@@ -28,6 +28,7 @@
 
 import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.HOME_BUTTON_LONG_PRESS_DURATION_MS;
 import static com.android.systemui.navigationbar.NavigationBar.NavBarActionEvent.NAVBAR_ASSIST_LONGPRESS;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -44,6 +45,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityManager;
 import android.content.Context;
 import android.content.res.Resources;
 import android.hardware.display.DisplayManagerGlobal;
@@ -90,6 +92,7 @@
 import com.android.systemui.shade.NotificationShadeWindowView;
 import com.android.systemui.shade.ShadeController;
 import com.android.systemui.shared.rotation.RotationButtonController;
+import com.android.systemui.shared.system.TaskStackChangeListeners;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.NotificationShadeDepthController;
@@ -203,6 +206,8 @@
     private ViewRootImpl mViewRootImpl;
     private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
     private DeviceConfigProxyFake mDeviceConfigProxyFake = new DeviceConfigProxyFake();
+    private TaskStackChangeListeners mTaskStackChangeListeners =
+            TaskStackChangeListeners.getTestInstance();
 
     @Rule
     public final LeakCheckedTest.SysuiLeakCheck mLeakCheck = new LeakCheckedTest.SysuiLeakCheck();
@@ -437,6 +442,14 @@
         verify(mNavBarHelper, times(1)).getCurrentSysuiState();
     }
 
+    @Test
+    public void testScreenPinningEnabled_updatesSysuiState() {
+        mNavigationBar.init();
+        mTaskStackChangeListeners.getListenerImpl().onLockTaskModeChanged(
+                ActivityManager.LOCK_TASK_MODE_PINNED);
+        verify(mMockSysUiState).setFlag(eq(SYSUI_STATE_SCREEN_PINNING), eq(true));
+    }
+
     private NavigationBar createNavBar(Context context) {
         DeviceProvisionedController deviceProvisionedController =
                 mock(DeviceProvisionedController.class);
@@ -481,7 +494,8 @@
                 mEdgeBackGestureHandler,
                 Optional.of(mock(BackAnimation.class)),
                 mUserContextProvider,
-                mWakefulnessLifecycle));
+                mWakefulnessLifecycle,
+                mTaskStackChangeListeners));
     }
 
     private void processAllMessages() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt
index 1742c69..537dfb8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt
@@ -1,11 +1,14 @@
 package com.android.systemui.navigationbar
 
+import android.app.ActivityManager
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.model.SysUiState
 import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler
 import com.android.systemui.recents.OverviewProxyService
+import com.android.systemui.shared.system.QuickStepContract
+import com.android.systemui.shared.system.TaskStackChangeListeners
 import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.phone.AutoHideController
 import com.android.systemui.statusbar.phone.LightBarController
@@ -14,6 +17,7 @@
 import com.android.wm.shell.pip.Pip
 import org.junit.Before
 import org.junit.Test
+import org.mockito.ArgumentMatchers
 import org.mockito.Mock
 import org.mockito.Mockito.`when`
 import org.mockito.Mockito.any
@@ -30,6 +34,7 @@
     val MODE_GESTURE = 0;
     val MODE_THREE_BUTTON = 1;
 
+    private lateinit var mTaskStackChangeListeners: TaskStackChangeListeners
     private lateinit var mTaskbarDelegate: TaskbarDelegate
     @Mock
     lateinit var mEdgeBackGestureHandlerFactory : EdgeBackGestureHandler.Factory
@@ -69,11 +74,12 @@
         `when`(mLightBarControllerFactory.create(any())).thenReturn(mLightBarTransitionController)
         `when`(mNavBarHelper.currentSysuiState).thenReturn(mCurrentSysUiState)
         `when`(mSysUiState.setFlag(anyInt(), anyBoolean())).thenReturn(mSysUiState)
+        mTaskStackChangeListeners = TaskStackChangeListeners.getTestInstance()
         mTaskbarDelegate = TaskbarDelegate(context, mEdgeBackGestureHandlerFactory,
                 mLightBarControllerFactory)
         mTaskbarDelegate.setDependencies(mCommandQueue, mOverviewProxyService, mNavBarHelper,
         mNavigationModeController, mSysUiState, mDumpManager, mAutoHideController,
-                mLightBarController, mOptionalPip, mBackAnimation)
+                mLightBarController, mOptionalPip, mBackAnimation, mTaskStackChangeListeners)
     }
 
     @Test
@@ -90,4 +96,15 @@
         mTaskbarDelegate.init(DISPLAY_ID)
         verify(mEdgeBackGestureHandler, times(1)).onNavigationModeChanged(MODE_GESTURE)
     }
+
+    @Test
+    fun screenPinningEnabled_updatesSysuiState() {
+        mTaskbarDelegate.init(DISPLAY_ID)
+        mTaskStackChangeListeners.listenerImpl.onLockTaskModeChanged(
+            ActivityManager.LOCK_TASK_MODE_PINNED)
+        verify(mSysUiState, times(1)).setFlag(
+            ArgumentMatchers.eq(QuickStepContract.SYSUI_STATE_SCREEN_PINNING),
+            ArgumentMatchers.eq(true)
+        )
+    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
index 4a9c750..8440455 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
@@ -24,7 +24,7 @@
 import android.test.suitebuilder.annotation.SmallTest
 import androidx.test.runner.AndroidJUnit4
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.notetask.NoteTaskIntentResolver.Companion.NOTES_ACTION
+import com.android.systemui.notetask.NoteTaskIntentResolver.Companion.ACTION_CREATE_NOTE
 import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity
 import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.eq
@@ -50,7 +50,7 @@
 @RunWith(AndroidJUnit4::class)
 internal class NoteTaskControllerTest : SysuiTestCase() {
 
-    private val notesIntent = Intent(NOTES_ACTION)
+    private val notesIntent = Intent(ACTION_CREATE_NOTE)
 
     @Mock lateinit var context: Context
     @Mock lateinit var packageManager: PackageManager
@@ -93,7 +93,7 @@
         createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
 
         verify(context).startActivity(notesIntent)
-        verify(bubbles, never()).showAppBubble(notesIntent)
+        verify(bubbles, never()).showOrHideAppBubble(notesIntent)
     }
 
     @Test
@@ -102,7 +102,7 @@
 
         createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
 
-        verify(bubbles).showAppBubble(notesIntent)
+        verify(bubbles).showOrHideAppBubble(notesIntent)
         verify(context, never()).startActivity(notesIntent)
     }
 
@@ -113,7 +113,7 @@
         createNoteTaskController().showNoteTask(isInMultiWindowMode = true)
 
         verify(context).startActivity(notesIntent)
-        verify(bubbles, never()).showAppBubble(notesIntent)
+        verify(bubbles, never()).showOrHideAppBubble(notesIntent)
     }
 
     @Test
@@ -123,7 +123,7 @@
         createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
 
         verify(context, never()).startActivity(notesIntent)
-        verify(bubbles, never()).showAppBubble(notesIntent)
+        verify(bubbles, never()).showOrHideAppBubble(notesIntent)
     }
 
     @Test
@@ -133,7 +133,7 @@
         createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
 
         verify(context, never()).startActivity(notesIntent)
-        verify(bubbles, never()).showAppBubble(notesIntent)
+        verify(bubbles, never()).showOrHideAppBubble(notesIntent)
     }
 
     @Test
@@ -143,7 +143,7 @@
         createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
 
         verify(context, never()).startActivity(notesIntent)
-        verify(bubbles, never()).showAppBubble(notesIntent)
+        verify(bubbles, never()).showOrHideAppBubble(notesIntent)
     }
 
     @Test
@@ -153,7 +153,7 @@
         createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
 
         verify(context, never()).startActivity(notesIntent)
-        verify(bubbles, never()).showAppBubble(notesIntent)
+        verify(bubbles, never()).showOrHideAppBubble(notesIntent)
     }
 
     @Test
@@ -161,7 +161,7 @@
         createNoteTaskController(isEnabled = false).showNoteTask()
 
         verify(context, never()).startActivity(notesIntent)
-        verify(bubbles, never()).showAppBubble(notesIntent)
+        verify(bubbles, never()).showOrHideAppBubble(notesIntent)
     }
 
     @Test
@@ -171,7 +171,7 @@
         createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
 
         verify(context, never()).startActivity(notesIntent)
-        verify(bubbles, never()).showAppBubble(notesIntent)
+        verify(bubbles, never()).showOrHideAppBubble(notesIntent)
     }
     // endregion
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt
index 538131a..010ac5b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt
@@ -106,7 +106,9 @@
     // region handleSystemKey
     @Test
     fun handleSystemKey_receiveValidSystemKey_shouldShowNoteTask() {
-        createNoteTaskInitializer().callbacks.handleSystemKey(KeyEvent.KEYCODE_VIDEO_APP_1)
+        createNoteTaskInitializer()
+            .callbacks
+            .handleSystemKey(NoteTaskController.NOTE_TASK_KEY_EVENT)
 
         verify(noteTaskController).showNoteTask()
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskIntentResolverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskIntentResolverTest.kt
index dd2cc2f..bbe60f4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskIntentResolverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskIntentResolverTest.kt
@@ -23,11 +23,10 @@
 import android.content.pm.PackageManager
 import android.content.pm.PackageManager.ResolveInfoFlags
 import android.content.pm.ResolveInfo
-import android.content.pm.ServiceInfo
 import android.test.suitebuilder.annotation.SmallTest
 import androidx.test.runner.AndroidJUnit4
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.notetask.NoteTaskIntentResolver.Companion.NOTES_ACTION
+import com.android.systemui.notetask.NoteTaskIntentResolver.Companion.ACTION_CREATE_NOTE
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
@@ -58,19 +57,13 @@
     }
 
     private fun createResolveInfo(
-        packageName: String = "PackageName",
-        activityInfo: ActivityInfo? = null,
+        activityInfo: ActivityInfo? = createActivityInfo(),
     ): ResolveInfo {
-        return ResolveInfo().apply {
-            serviceInfo =
-                ServiceInfo().apply {
-                    applicationInfo = ApplicationInfo().apply { this.packageName = packageName }
-                }
-            this.activityInfo = activityInfo
-        }
+        return ResolveInfo().apply { this.activityInfo = activityInfo }
     }
 
     private fun createActivityInfo(
+        packageName: String = "PackageName",
         name: String? = "ActivityName",
         exported: Boolean = true,
         enabled: Boolean = true,
@@ -87,6 +80,7 @@
             if (turnScreenOn) {
                 flags = flags or ActivityInfo.FLAG_TURN_SCREEN_ON
             }
+            this.applicationInfo = ApplicationInfo().apply { this.packageName = packageName }
         }
     }
 
@@ -107,7 +101,8 @@
         val actual = resolver.resolveIntent()
 
         val expected =
-            Intent(NOTES_ACTION)
+            Intent(ACTION_CREATE_NOTE)
+                .setPackage("PackageName")
                 .setComponent(ComponentName("PackageName", "ActivityName"))
                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
         // Compares the string representation of both intents, as they are different instances.
@@ -204,7 +199,9 @@
 
     @Test
     fun resolveIntent_packageNameIsBlank_shouldReturnNull() {
-        givenQueryIntentActivities { listOf(createResolveInfo(packageName = "")) }
+        givenQueryIntentActivities {
+            listOf(createResolveInfo(createActivityInfo(packageName = "")))
+        }
 
         val actual = resolver.resolveIntent()
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt
new file mode 100644
index 0000000..a1d42a0
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.notetask.quickaffordance
+
+import android.test.suitebuilder.annotation.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.common.shared.model.ContentDescription
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.LockScreenState
+import com.android.systemui.notetask.NoteTaskController
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+/**
+ * Tests for [NoteTaskQuickAffordanceConfig].
+ *
+ * Build/Install/Run:
+ * - atest SystemUITests:NoteTaskQuickAffordanceConfigTest
+ */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+internal class NoteTaskQuickAffordanceConfigTest : SysuiTestCase() {
+
+    @Mock lateinit var noteTaskController: NoteTaskController
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        whenever(noteTaskController.showNoteTask()).then {}
+    }
+
+    private fun createUnderTest(isEnabled: Boolean) =
+        NoteTaskQuickAffordanceConfig(
+            context = context,
+            noteTaskController = noteTaskController,
+            isEnabled = isEnabled,
+        )
+
+    @Test
+    fun lockScreenState_isNotEnabled_shouldEmitHidden() = runTest {
+        val underTest = createUnderTest(isEnabled = false)
+
+        val actual = collectLastValue(underTest.lockScreenState)
+
+        assertThat(actual()).isEqualTo(LockScreenState.Hidden)
+    }
+
+    @Test
+    fun lockScreenState_isEnabled_shouldEmitVisible() = runTest {
+        val stringResult = "Notetaking"
+        val underTest = createUnderTest(isEnabled = true)
+
+        val actual = collectLastValue(underTest.lockScreenState)
+
+        val expected =
+            LockScreenState.Visible(
+                icon =
+                    Icon.Resource(
+                        res = R.drawable.ic_note_task_shortcut_keyguard,
+                        contentDescription = ContentDescription.Loaded(stringResult),
+                    )
+            )
+        assertThat(actual()).isEqualTo(expected)
+    }
+
+    @Test
+    fun onTriggered_shouldLaunchNoteTask() {
+        val underTest = createUnderTest(isEnabled = false)
+
+        underTest.onTriggered(expandable = null)
+
+        verify(noteTaskController).showNoteTask()
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
index a56990f..4a6158f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
@@ -30,6 +30,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityManager;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.content.BroadcastReceiver;
@@ -53,6 +54,7 @@
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.broadcast.BroadcastSender;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.util.NotificationChannels;
 
@@ -82,6 +84,8 @@
     @Mock
     private UiEventLogger mUiEventLogger;
     @Mock
+    private UserTracker mUserTracker;
+    @Mock
     private View mView;
 
     private BroadcastReceiver mReceiver;
@@ -103,8 +107,12 @@
         mContext.addMockSystemService(NotificationManager.class, mMockNotificationManager);
         ActivityStarter starter = mDependency.injectMockDependency(ActivityStarter.class);
         BroadcastSender broadcastSender = mDependency.injectMockDependency(BroadcastSender.class);
+        when(mUserTracker.getUserId()).thenReturn(ActivityManager.getCurrentUser());
+        when(mUserTracker.getUserHandle()).thenReturn(
+                UserHandle.of(ActivityManager.getCurrentUser()));
         mPowerNotificationWarnings = new PowerNotificationWarnings(wrapper, starter,
-                broadcastSender, () -> mBatteryController, mDialogLaunchAnimator, mUiEventLogger);
+                broadcastSender, () -> mBatteryController, mDialogLaunchAnimator, mUiEventLogger,
+                mUserTracker);
         BatteryStateSnapshot snapshot = new BatteryStateSnapshot(100, false, false, 1,
                 BatteryManager.BATTERY_HEALTH_GOOD, 5, 15);
         mPowerNotificationWarnings.updateSnapshot(snapshot);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index ffe918d..42ef9c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -151,7 +151,7 @@
     @Test
     public void transitionToFullShade_setsAlphaUsingShadeInterpolator() {
         QSFragment fragment = resumeAndGetFragment();
-        setStatusBarState(StatusBarState.SHADE);
+        setStatusBarCurrentAndUpcomingState(StatusBarState.SHADE);
         boolean isTransitioningToFullShade = true;
         float transitionProgress = 0.5f;
         float squishinessFraction = 0.5f;
@@ -167,7 +167,7 @@
     public void
             transitionToFullShade_onKeyguard_noBouncer_setsAlphaUsingLinearInterpolator() {
         QSFragment fragment = resumeAndGetFragment();
-        setStatusBarState(KEYGUARD);
+        setStatusBarCurrentAndUpcomingState(KEYGUARD);
         when(mQSPanelController.isBouncerInTransit()).thenReturn(false);
         boolean isTransitioningToFullShade = true;
         float transitionProgress = 0.5f;
@@ -183,7 +183,7 @@
     public void
             transitionToFullShade_onKeyguard_bouncerActive_setsAlphaUsingBouncerInterpolator() {
         QSFragment fragment = resumeAndGetFragment();
-        setStatusBarState(KEYGUARD);
+        setStatusBarCurrentAndUpcomingState(KEYGUARD);
         when(mQSPanelController.isBouncerInTransit()).thenReturn(true);
         boolean isTransitioningToFullShade = true;
         float transitionProgress = 0.5f;
@@ -482,6 +482,15 @@
         assertEquals(175, mediaHostClip.bottom);
     }
 
+    @Test
+    public void testQsUpdatesQsAnimatorWithUpcomingState() {
+        QSFragment fragment = resumeAndGetFragment();
+        setStatusBarCurrentAndUpcomingState(SHADE);
+        fragment.onUpcomingStateChanged(KEYGUARD);
+
+        verify(mQSAnimator).setOnKeyguard(true);
+    }
+
     @Override
     protected Fragment instantiate(Context context, String className, Bundle arguments) {
         MockitoAnnotations.initMocks(this);
@@ -591,8 +600,9 @@
         return getFragment();
     }
 
-    private void setStatusBarState(int statusBarState) {
+    private void setStatusBarCurrentAndUpcomingState(int statusBarState) {
         when(mStatusBarStateController.getState()).thenReturn(statusBarState);
+        when(mStatusBarStateController.getCurrentOrUpcomingState()).thenReturn(statusBarState);
         getFragment().onStateChanged(statusBarState);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSFactoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSFactoryImplTest.kt
index ca3182a..3281fa9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSFactoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSFactoryImplTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.qs.tiles.BluetoothTile
 import com.android.systemui.qs.tiles.CameraToggleTile
 import com.android.systemui.qs.tiles.CastTile
-import com.android.systemui.qs.tiles.CellularTile
 import com.android.systemui.qs.tiles.ColorCorrectionTile
 import com.android.systemui.qs.tiles.ColorInversionTile
 import com.android.systemui.qs.tiles.DataSaverTile
@@ -49,7 +48,6 @@
 import com.android.systemui.qs.tiles.RotationLockTile
 import com.android.systemui.qs.tiles.ScreenRecordTile
 import com.android.systemui.qs.tiles.UiModeNightTile
-import com.android.systemui.qs.tiles.WifiTile
 import com.android.systemui.qs.tiles.WorkModeTile
 import com.android.systemui.util.leak.GarbageMonitor
 import com.google.common.truth.Truth.assertThat
@@ -63,10 +61,8 @@
 import org.mockito.Mockito.`when` as whenever
 
 private val specMap = mapOf(
-        "wifi" to WifiTile::class.java,
         "internet" to InternetTile::class.java,
         "bt" to BluetoothTile::class.java,
-        "cell" to CellularTile::class.java,
         "dnd" to DndTile::class.java,
         "inversion" to ColorInversionTile::class.java,
         "airplane" to AirplaneModeTile::class.java,
@@ -102,10 +98,8 @@
     @Mock(answer = Answers.RETURNS_SELF) private lateinit var customTileBuilder: CustomTile.Builder
     @Mock private lateinit var customTile: CustomTile
 
-    @Mock private lateinit var wifiTile: WifiTile
     @Mock private lateinit var internetTile: InternetTile
     @Mock private lateinit var bluetoothTile: BluetoothTile
-    @Mock private lateinit var cellularTile: CellularTile
     @Mock private lateinit var dndTile: DndTile
     @Mock private lateinit var colorInversionTile: ColorInversionTile
     @Mock private lateinit var airplaneTile: AirplaneModeTile
@@ -146,10 +140,8 @@
         factory = QSFactoryImpl(
                 { qsHost },
                 { customTileBuilder },
-                { wifiTile },
                 { internetTile },
                 { bluetoothTile },
-                { cellularTile },
                 { dndTile },
                 { colorInversionTile },
                 { airplaneTile },
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt
index 08a90b7..18e40f6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt
@@ -30,7 +30,6 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingManagerFake
 import com.android.systemui.qs.QSUserSwitcherEvent
-import com.android.systemui.qs.user.UserSwitchDialogController
 import com.android.systemui.statusbar.policy.UserSwitcherController
 import com.android.systemui.user.data.source.UserRecord
 import org.junit.Assert.assertEquals
@@ -42,7 +41,6 @@
 import org.mockito.ArgumentMatchers.anyBoolean
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mock
-import org.mockito.Mockito.mock
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
@@ -152,15 +150,6 @@
         assertNull(adapter.users.find { it.isManageUsers })
     }
 
-    @Test
-    fun clickDismissDialog() {
-        val shower: UserSwitchDialogController.DialogShower =
-            mock(UserSwitchDialogController.DialogShower::class.java)
-        adapter.injectDialogShower(shower)
-        adapter.onUserListItemClicked(createUserRecord(current = true, guest = false), shower)
-        verify(shower).dismiss()
-    }
-
     private fun createUserRecord(current: Boolean, guest: Boolean) =
         UserRecord(
             UserInfo(0 /* id */, "name", 0 /* flags */),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt
index 46a502a..ed3f1a0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt
@@ -22,15 +22,12 @@
 import android.graphics.Insets
 import android.graphics.Rect
 import android.hardware.HardwareBuffer
-import android.os.Bundle
 import android.os.UserHandle
 import android.view.WindowManager.ScreenshotSource.SCREENSHOT_KEY_CHORD
 import android.view.WindowManager.ScreenshotSource.SCREENSHOT_OTHER
 import android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN
 import android.view.WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE
-import com.android.internal.util.ScreenshotHelper.HardwareBitmapBundler
-import com.android.internal.util.ScreenshotHelper.HardwareBitmapBundler.bundleToHardwareBitmap
-import com.android.internal.util.ScreenshotHelper.ScreenshotRequest
+import com.android.internal.util.ScreenshotRequest
 import com.android.systemui.flags.FakeFeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.screenshot.ScreenshotPolicy.DisplayContentInfo
@@ -49,7 +46,6 @@
     private val bounds = Rect(25, 25, 75, 75)
 
     private val scope = CoroutineScope(Dispatchers.Unconfined)
-    private val dispatcher = Dispatchers.Unconfined
     private val policy = FakeScreenshotPolicy()
     private val flags = FakeFeatureFlags()
 
@@ -58,7 +54,8 @@
     fun testProcessAsync() {
         flags.set(Flags.SCREENSHOT_WORK_PROFILE_POLICY, false)
 
-        val request = ScreenshotRequest(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_CHORD)
+        val request =
+            ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_CHORD).build()
         val processor = RequestProcessor(imageCapture, policy, flags, scope)
 
         var result: ScreenshotRequest? = null
@@ -80,7 +77,8 @@
     fun testFullScreenshot_workProfilePolicyDisabled() = runBlocking {
         flags.set(Flags.SCREENSHOT_WORK_PROFILE_POLICY, false)
 
-        val request = ScreenshotRequest(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_CHORD)
+        val request =
+            ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_CHORD).build()
         val processor = RequestProcessor(imageCapture, policy, flags, scope)
 
         val processedRequest = processor.process(request)
@@ -97,9 +95,11 @@
         policy.setManagedProfile(USER_ID, false)
         policy.setDisplayContentInfo(
             policy.getDefaultDisplayId(),
-            DisplayContentInfo(component, bounds, UserHandle.of(USER_ID), TASK_ID))
+            DisplayContentInfo(component, bounds, UserHandle.of(USER_ID), TASK_ID)
+        )
 
-        val request = ScreenshotRequest(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_OTHER)
+        val request =
+            ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_OTHER).build()
         val processor = RequestProcessor(imageCapture, policy, flags, scope)
 
         val processedRequest = processor.process(request)
@@ -120,17 +120,20 @@
 
         // Indicate that the primary content belongs to a manged profile
         policy.setManagedProfile(USER_ID, true)
-        policy.setDisplayContentInfo(policy.getDefaultDisplayId(),
-            DisplayContentInfo(component, bounds, UserHandle.of(USER_ID), TASK_ID))
+        policy.setDisplayContentInfo(
+            policy.getDefaultDisplayId(),
+            DisplayContentInfo(component, bounds, UserHandle.of(USER_ID), TASK_ID)
+        )
 
-        val request = ScreenshotRequest(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_CHORD)
+        val request =
+            ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_CHORD).build()
         val processor = RequestProcessor(imageCapture, policy, flags, scope)
 
         val processedRequest = processor.process(request)
 
         // Expect a task snapshot is taken, overriding the full screen mode
         assertThat(processedRequest.type).isEqualTo(TAKE_SCREENSHOT_PROVIDED_IMAGE)
-        assertThat(bitmap.equalsHardwareBitmapBundle(processedRequest.bitmapBundle)).isTrue()
+        assertThat(bitmap.equalsHardwareBitmap(processedRequest.bitmap)).isTrue()
         assertThat(processedRequest.boundsInScreen).isEqualTo(bounds)
         assertThat(processedRequest.insets).isEqualTo(Insets.NONE)
         assertThat(processedRequest.taskId).isEqualTo(TASK_ID)
@@ -147,10 +150,16 @@
         val processor = RequestProcessor(imageCapture, policy, flags, scope)
 
         val bitmap = makeHardwareBitmap(100, 100)
-        val bitmapBundle = HardwareBitmapBundler.hardwareBitmapToBundle(bitmap)
 
-        val request = ScreenshotRequest(TAKE_SCREENSHOT_PROVIDED_IMAGE, SCREENSHOT_OTHER,
-            bitmapBundle, bounds, Insets.NONE, TASK_ID, USER_ID, component)
+        val request =
+            ScreenshotRequest.Builder(TAKE_SCREENSHOT_PROVIDED_IMAGE, SCREENSHOT_OTHER)
+                .setTopComponent(component)
+                .setTaskId(TASK_ID)
+                .setUserId(USER_ID)
+                .setBitmap(bitmap)
+                .setBoundsOnScreen(bounds)
+                .setInsets(Insets.NONE)
+                .build()
 
         val processedRequest = processor.process(request)
 
@@ -168,10 +177,16 @@
         policy.setManagedProfile(USER_ID, false)
 
         val bitmap = makeHardwareBitmap(100, 100)
-        val bitmapBundle = HardwareBitmapBundler.hardwareBitmapToBundle(bitmap)
 
-        val request = ScreenshotRequest(TAKE_SCREENSHOT_PROVIDED_IMAGE, SCREENSHOT_OTHER,
-            bitmapBundle, bounds, Insets.NONE, TASK_ID, USER_ID, component)
+        val request =
+            ScreenshotRequest.Builder(TAKE_SCREENSHOT_PROVIDED_IMAGE, SCREENSHOT_OTHER)
+                .setTopComponent(component)
+                .setTaskId(TASK_ID)
+                .setUserId(USER_ID)
+                .setBitmap(bitmap)
+                .setBoundsOnScreen(bounds)
+                .setInsets(Insets.NONE)
+                .build()
 
         val processedRequest = processor.process(request)
 
@@ -190,10 +205,16 @@
         policy.setManagedProfile(USER_ID, true)
 
         val bitmap = makeHardwareBitmap(100, 100)
-        val bitmapBundle = HardwareBitmapBundler.hardwareBitmapToBundle(bitmap)
 
-        val request = ScreenshotRequest(TAKE_SCREENSHOT_PROVIDED_IMAGE, SCREENSHOT_OTHER,
-            bitmapBundle, bounds, Insets.NONE, TASK_ID, USER_ID, component)
+        val request =
+            ScreenshotRequest.Builder(TAKE_SCREENSHOT_PROVIDED_IMAGE, SCREENSHOT_OTHER)
+                .setTopComponent(component)
+                .setTaskId(TASK_ID)
+                .setUserId(USER_ID)
+                .setBitmap(bitmap)
+                .setBoundsOnScreen(bounds)
+                .setInsets(Insets.NONE)
+                .build()
 
         val processedRequest = processor.process(request)
 
@@ -202,14 +223,18 @@
     }
 
     private fun makeHardwareBitmap(width: Int, height: Int): Bitmap {
-        val buffer = HardwareBuffer.create(width, height, HardwareBuffer.RGBA_8888, 1,
-            HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE)
+        val buffer =
+            HardwareBuffer.create(
+                width,
+                height,
+                HardwareBuffer.RGBA_8888,
+                1,
+                HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE
+            )
         return Bitmap.wrapHardwareBuffer(buffer, ColorSpace.get(ColorSpace.Named.SRGB))!!
     }
 
-    private fun Bitmap.equalsHardwareBitmapBundle(bundle: Bundle): Boolean {
-        val provided = bundleToHardwareBitmap(bundle)
-        return provided.hardwareBuffer == this.hardwareBuffer &&
-                provided.colorSpace == this.colorSpace
+    private fun Bitmap.equalsHardwareBitmap(bitmap: Bitmap): Boolean {
+        return bitmap.hardwareBuffer == this.hardwareBuffer && bitmap.colorSpace == this.colorSpace
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt
index fa1fedb..f935019 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt
@@ -35,11 +35,9 @@
 import android.view.WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.testing.UiEventLoggerFake
-import com.android.internal.util.ScreenshotHelper
-import com.android.internal.util.ScreenshotHelper.ScreenshotRequest
+import com.android.internal.util.ScreenshotRequest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.flags.FakeFeatureFlags
-import com.android.systemui.flags.Flags.SCREENSHOT_REQUEST_PROCESSOR
 import com.android.systemui.flags.Flags.SCREENSHOT_WORK_PROFILE_POLICY
 import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_REQUESTED_KEY_CHORD
 import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_REQUESTED_OVERVIEW
@@ -81,27 +79,41 @@
     private val flags = FakeFeatureFlags()
     private val topComponent = ComponentName(mContext, TakeScreenshotServiceTest::class.java)
 
-    private val service = TakeScreenshotService(
-        controller, userManager, devicePolicyManager, eventLogger,
-        notificationsController, mContext, Runnable::run, flags, requestProcessor)
+    private val service =
+        TakeScreenshotService(
+            controller,
+            userManager,
+            devicePolicyManager,
+            eventLogger,
+            notificationsController,
+            mContext,
+            Runnable::run,
+            flags,
+            requestProcessor
+        )
 
     @Before
     fun setUp() {
         whenever(devicePolicyManager.resources).thenReturn(devicePolicyResourcesManager)
-        whenever(devicePolicyManager.getScreenCaptureDisabled(
-            /* admin component (null: any admin) */ isNull(), eq(UserHandle.USER_ALL)))
+        whenever(
+                devicePolicyManager.getScreenCaptureDisabled(
+                    /* admin component (null: any admin) */ isNull(),
+                    eq(UserHandle.USER_ALL)
+                )
+            )
             .thenReturn(false)
         whenever(userManager.isUserUnlocked).thenReturn(true)
 
         // Stub request processor as a synchronous no-op for tests with the flag enabled
         doAnswer {
-            val request: ScreenshotRequest = it.getArgument(0) as ScreenshotRequest
-            val consumer: Consumer<ScreenshotRequest> = it.getArgument(1)
-            consumer.accept(request)
-        }.`when`(requestProcessor).processAsync(/* request= */ any(), /* callback= */ any())
+                val request: ScreenshotRequest = it.getArgument(0) as ScreenshotRequest
+                val consumer: Consumer<ScreenshotRequest> = it.getArgument(1)
+                consumer.accept(request)
+            }
+            .`when`(requestProcessor)
+            .processAsync(/* request= */ any(), /* callback= */ any())
 
         // Flipped in selected test cases
-        flags.set(SCREENSHOT_REQUEST_PROCESSOR, false)
         flags.set(SCREENSHOT_WORK_PROFILE_POLICY, false)
 
         service.attach(
@@ -110,7 +122,8 @@
             /* className = */ null,
             /* token = */ null,
             application,
-            /* activityManager = */ null)
+            /* activityManager = */ null
+        )
     }
 
     @Test
@@ -127,88 +140,89 @@
 
     @Test
     fun takeScreenshotFullscreen() {
-        val request = ScreenshotRequest(
-            TAKE_SCREENSHOT_FULLSCREEN,
-            SCREENSHOT_KEY_CHORD,
-            topComponent)
+        val request =
+            ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_CHORD)
+                .setTopComponent(topComponent)
+                .build()
 
-        service.handleRequest(request, { /* onSaved */ }, callback)
+        service.handleRequest(request, { /* onSaved */}, callback)
 
-        verify(controller, times(1)).takeScreenshotFullscreen(
-            eq(topComponent),
-            /* onSavedListener = */ any(),
-            /* requestCallback = */ any())
+        verify(controller, times(1))
+            .takeScreenshotFullscreen(
+                eq(topComponent),
+                /* onSavedListener = */ any(),
+                /* requestCallback = */ any()
+            )
 
         assertEquals("Expected one UiEvent", eventLogger.numLogs(), 1)
         val logEvent = eventLogger.get(0)
 
-        assertEquals("Expected SCREENSHOT_REQUESTED UiEvent",
-            logEvent.eventId, SCREENSHOT_REQUESTED_KEY_CHORD.id)
-        assertEquals("Expected supplied package name",
-            topComponent.packageName, eventLogger.get(0).packageName)
-    }
-
-    @Test
-    fun takeScreenshot_requestProcessorEnabled() {
-        flags.set(SCREENSHOT_REQUEST_PROCESSOR, true)
-
-        val request = ScreenshotRequest(
-            TAKE_SCREENSHOT_FULLSCREEN,
-            SCREENSHOT_KEY_CHORD,
-            topComponent)
-
-        service.handleRequest(request, { /* onSaved */ }, callback)
-
-        verify(controller, times(1)).takeScreenshotFullscreen(
-            eq(topComponent),
-            /* onSavedListener = */ any(),
-            /* requestCallback = */ any())
-
-        assertEquals("Expected one UiEvent", eventLogger.numLogs(), 1)
-        val logEvent = eventLogger.get(0)
-
-        assertEquals("Expected SCREENSHOT_REQUESTED UiEvent",
-            logEvent.eventId, SCREENSHOT_REQUESTED_KEY_CHORD.id)
-        assertEquals("Expected supplied package name",
-            topComponent.packageName, eventLogger.get(0).packageName)
+        assertEquals(
+            "Expected SCREENSHOT_REQUESTED UiEvent",
+            logEvent.eventId,
+            SCREENSHOT_REQUESTED_KEY_CHORD.id
+        )
+        assertEquals(
+            "Expected supplied package name",
+            topComponent.packageName,
+            eventLogger.get(0).packageName
+        )
     }
 
     @Test
     fun takeScreenshotProvidedImage() {
         val bounds = Rect(50, 50, 150, 150)
         val bitmap = makeHardwareBitmap(100, 100)
-        val bitmapBundle = ScreenshotHelper.HardwareBitmapBundler.hardwareBitmapToBundle(bitmap)
 
-        val request = ScreenshotRequest(TAKE_SCREENSHOT_PROVIDED_IMAGE, SCREENSHOT_OVERVIEW,
-            bitmapBundle, bounds, Insets.NONE, TASK_ID, USER_ID, topComponent)
+        val request =
+            ScreenshotRequest.Builder(TAKE_SCREENSHOT_PROVIDED_IMAGE, SCREENSHOT_OVERVIEW)
+                .setTopComponent(topComponent)
+                .setTaskId(TASK_ID)
+                .setUserId(USER_ID)
+                .setBitmap(bitmap)
+                .setBoundsOnScreen(bounds)
+                .setInsets(Insets.NONE)
+                .build()
 
-        service.handleRequest(request, { /* onSaved */ }, callback)
+        service.handleRequest(request, { /* onSaved */}, callback)
 
-        verify(controller, times(1)).handleImageAsScreenshot(
-            argThat { b -> b.equalsHardwareBitmap(bitmap) },
-            eq(bounds),
-            eq(Insets.NONE), eq(TASK_ID), eq(USER_ID), eq(topComponent),
-            /* onSavedListener = */ any(), /* requestCallback = */ any())
+        verify(controller, times(1))
+            .handleImageAsScreenshot(
+                argThat { b -> b.equalsHardwareBitmap(bitmap) },
+                eq(bounds),
+                eq(Insets.NONE),
+                eq(TASK_ID),
+                eq(USER_ID),
+                eq(topComponent),
+                /* onSavedListener = */ any(),
+                /* requestCallback = */ any()
+            )
 
         assertEquals("Expected one UiEvent", eventLogger.numLogs(), 1)
         val logEvent = eventLogger.get(0)
 
-        assertEquals("Expected SCREENSHOT_REQUESTED_* UiEvent",
-            logEvent.eventId, SCREENSHOT_REQUESTED_OVERVIEW.id)
-        assertEquals("Expected supplied package name",
-            topComponent.packageName, eventLogger.get(0).packageName)
+        assertEquals(
+            "Expected SCREENSHOT_REQUESTED_* UiEvent",
+            logEvent.eventId,
+            SCREENSHOT_REQUESTED_OVERVIEW.id
+        )
+        assertEquals(
+            "Expected supplied package name",
+            topComponent.packageName,
+            eventLogger.get(0).packageName
+        )
     }
 
     @Test
     fun takeScreenshotFullscreen_userLocked() {
         whenever(userManager.isUserUnlocked).thenReturn(false)
 
-        val request = ScreenshotRequest(
-            TAKE_SCREENSHOT_FULLSCREEN,
-            SCREENSHOT_KEY_CHORD,
-            topComponent)
+        val request =
+            ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_CHORD)
+                .setTopComponent(topComponent)
+                .build()
 
-        service.handleRequest(request, { /* onSaved */ }, callback)
+        service.handleRequest(request, { /* onSaved */}, callback)
 
         verify(notificationsController, times(1)).notifyScreenshotError(anyInt())
         verify(callback, times(1)).reportError()
@@ -217,21 +231,24 @@
 
     @Test
     fun takeScreenshotFullscreen_screenCaptureDisabled_allUsers() {
-        whenever(devicePolicyManager.getScreenCaptureDisabled(
-            isNull(), eq(UserHandle.USER_ALL))
-        ).thenReturn(true)
+        whenever(devicePolicyManager.getScreenCaptureDisabled(isNull(), eq(UserHandle.USER_ALL)))
+            .thenReturn(true)
 
-        whenever(devicePolicyResourcesManager.getString(
-            eq(SCREENSHOT_BLOCKED_BY_ADMIN),
-            /* Supplier<String> */ any(),
-        )).thenReturn("SCREENSHOT_BLOCKED_BY_ADMIN")
+        whenever(
+                devicePolicyResourcesManager.getString(
+                    eq(SCREENSHOT_BLOCKED_BY_ADMIN),
+                    /* Supplier<String> */
+                    any(),
+                )
+            )
+            .thenReturn("SCREENSHOT_BLOCKED_BY_ADMIN")
 
-        val request = ScreenshotRequest(
-            TAKE_SCREENSHOT_FULLSCREEN,
-            SCREENSHOT_KEY_CHORD,
-            topComponent)
+        val request =
+            ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_CHORD)
+                .setTopComponent(topComponent)
+                .build()
 
-        service.handleRequest(request, { /* onSaved */ }, callback)
+        service.handleRequest(request, { /* onSaved */}, callback)
 
         // error shown: Toast.makeText(...).show(), untestable
         verify(callback, times(1)).reportError()
@@ -241,14 +258,20 @@
 
 private fun Bitmap.equalsHardwareBitmap(other: Bitmap): Boolean {
     return config == HARDWARE &&
-            other.config == HARDWARE &&
-            hardwareBuffer == other.hardwareBuffer &&
-            colorSpace == other.colorSpace
+        other.config == HARDWARE &&
+        hardwareBuffer == other.hardwareBuffer &&
+        colorSpace == other.colorSpace
 }
 
 /** A hardware Bitmap is mandated by use of ScreenshotHelper.HardwareBitmapBundler */
 private fun makeHardwareBitmap(width: Int, height: Int): Bitmap {
-    val buffer = HardwareBuffer.create(width, height, HardwareBuffer.RGBA_8888, 1,
-        HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE)
+    val buffer =
+        HardwareBuffer.create(
+            width,
+            height,
+            HardwareBuffer.RGBA_8888,
+            1,
+            HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE
+        )
     return Bitmap.wrapHardwareBuffer(buffer, ColorSpace.get(ColorSpace.Named.SRGB))!!
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java
new file mode 100644
index 0000000..bd04b3c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java
@@ -0,0 +1,160 @@
+/*
+ * 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.screenshot;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.util.FakeSharedPreferences;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.ArgumentMatchers;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class WorkProfileMessageControllerTest {
+    private static final String DEFAULT_LABEL = "default label";
+    private static final String BADGED_DEFAULT_LABEL = "badged default label";
+    private static final String APP_LABEL = "app label";
+    private static final String BADGED_APP_LABEL = "badged app label";
+    private static final UserHandle NON_WORK_USER = UserHandle.of(0);
+    private static final UserHandle WORK_USER = UserHandle.of(10);
+
+    @Mock
+    private UserManager mUserManager;
+    @Mock
+    private PackageManager mPackageManager;
+    @Mock
+    private Context mContext;
+    @Mock
+    private WorkProfileMessageController.WorkProfileMessageDisplay mMessageDisplay;
+    @Mock
+    private Drawable mActivityIcon;
+    @Mock
+    private Drawable mBadgedActivityIcon;
+    @Mock
+    private ActivityInfo mActivityInfo;
+    @Captor
+    private ArgumentCaptor<Runnable> mRunnableArgumentCaptor;
+
+    private FakeSharedPreferences mSharedPreferences = new FakeSharedPreferences();
+
+    private WorkProfileMessageController mMessageController;
+
+    @Before
+    public void setup() throws PackageManager.NameNotFoundException {
+        MockitoAnnotations.initMocks(this);
+
+        when(mUserManager.isManagedProfile(eq(WORK_USER.getIdentifier()))).thenReturn(true);
+        when(mContext.getSharedPreferences(
+                eq(WorkProfileMessageController.SHARED_PREFERENCES_NAME),
+                eq(Context.MODE_PRIVATE))).thenReturn(mSharedPreferences);
+        when(mContext.getString(ArgumentMatchers.anyInt())).thenReturn(DEFAULT_LABEL);
+        when(mPackageManager.getUserBadgedLabel(eq(DEFAULT_LABEL), any()))
+                .thenReturn(BADGED_DEFAULT_LABEL);
+        when(mPackageManager.getUserBadgedLabel(eq(APP_LABEL), any()))
+                .thenReturn(BADGED_APP_LABEL);
+        when(mPackageManager.getActivityIcon(any(ComponentName.class)))
+                .thenReturn(mActivityIcon);
+        when(mPackageManager.getUserBadgedIcon(
+                any(), any())).thenReturn(mBadgedActivityIcon);
+        when(mPackageManager.getActivityInfo(any(),
+                any(PackageManager.ComponentInfoFlags.class))).thenReturn(mActivityInfo);
+        when(mActivityInfo.loadLabel(eq(mPackageManager))).thenReturn(APP_LABEL);
+
+        mSharedPreferences.edit().putBoolean(
+                WorkProfileMessageController.PREFERENCE_KEY, false).apply();
+
+        mMessageController = new WorkProfileMessageController(mContext, mUserManager,
+                mPackageManager);
+    }
+
+    @Test
+    public void testOnScreenshotTaken_notManaged() {
+        mMessageController.onScreenshotTaken(NON_WORK_USER, mMessageDisplay);
+
+        verify(mMessageDisplay, never())
+                .showWorkProfileMessage(any(), nullable(Drawable.class), any());
+    }
+
+    @Test
+    public void testOnScreenshotTaken_alreadyDismissed() {
+        mSharedPreferences.edit().putBoolean(
+                WorkProfileMessageController.PREFERENCE_KEY, true).apply();
+
+        mMessageController.onScreenshotTaken(WORK_USER, mMessageDisplay);
+
+        verify(mMessageDisplay, never())
+                .showWorkProfileMessage(any(), nullable(Drawable.class), any());
+    }
+
+    @Test
+    public void testOnScreenshotTaken_packageNotFound()
+            throws PackageManager.NameNotFoundException {
+        when(mPackageManager.getActivityInfo(any(),
+                any(PackageManager.ComponentInfoFlags.class))).thenThrow(
+                new PackageManager.NameNotFoundException());
+
+        mMessageController.onScreenshotTaken(WORK_USER, mMessageDisplay);
+
+        verify(mMessageDisplay).showWorkProfileMessage(
+                eq(BADGED_DEFAULT_LABEL), eq(null), any());
+    }
+
+    @Test
+    public void testOnScreenshotTaken() {
+        mMessageController.onScreenshotTaken(WORK_USER, mMessageDisplay);
+
+        verify(mMessageDisplay).showWorkProfileMessage(
+                eq(BADGED_APP_LABEL), eq(mBadgedActivityIcon), mRunnableArgumentCaptor.capture());
+
+        // Dismiss hasn't been tapped, preference untouched.
+        assertFalse(
+                mSharedPreferences.getBoolean(WorkProfileMessageController.PREFERENCE_KEY, false));
+
+        mRunnableArgumentCaptor.getValue().run();
+
+        // After dismiss has been tapped, the setting should be updated.
+        assertTrue(
+                mSharedPreferences.getBoolean(WorkProfileMessageController.PREFERENCE_KEY, false));
+    }
+}
+
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplReceiveTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplReceiveTest.kt
new file mode 100644
index 0000000..3710281
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplReceiveTest.kt
@@ -0,0 +1,100 @@
+package com.android.systemui.settings
+
+import android.content.Context
+import android.content.Intent
+import android.content.pm.UserInfo
+import android.os.Handler
+import android.os.UserHandle
+import android.os.UserManager
+import androidx.concurrent.futures.DirectExecutor
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.capture
+import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.Executor
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(Parameterized::class)
+class UserTrackerImplReceiveTest : SysuiTestCase() {
+
+    companion object {
+
+        @JvmStatic
+        @Parameterized.Parameters
+        fun data(): Iterable<String> =
+            listOf(
+                Intent.ACTION_USER_INFO_CHANGED,
+                Intent.ACTION_MANAGED_PROFILE_AVAILABLE,
+                Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE,
+                Intent.ACTION_MANAGED_PROFILE_ADDED,
+                Intent.ACTION_MANAGED_PROFILE_REMOVED,
+                Intent.ACTION_MANAGED_PROFILE_UNLOCKED
+            )
+    }
+
+    private val executor: Executor = DirectExecutor.INSTANCE
+
+    @Mock private lateinit var context: Context
+    @Mock private lateinit var userManager: UserManager
+    @Mock(stubOnly = true) private lateinit var dumpManager: DumpManager
+    @Mock(stubOnly = true) private lateinit var handler: Handler
+
+    @Parameterized.Parameter lateinit var intentAction: String
+    @Mock private lateinit var callback: UserTracker.Callback
+    @Captor private lateinit var captor: ArgumentCaptor<List<UserInfo>>
+
+    private lateinit var tracker: UserTrackerImpl
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+
+        `when`(context.user).thenReturn(UserHandle.SYSTEM)
+        `when`(context.createContextAsUser(ArgumentMatchers.any(), anyInt())).thenReturn(context)
+
+        tracker = UserTrackerImpl(context, userManager, dumpManager, handler)
+    }
+
+    @Test
+    fun `calls callback and updates profiles when an intent received`() {
+        tracker.initialize(0)
+        tracker.addCallback(callback, executor)
+        val profileID = tracker.userId + 10
+
+        `when`(userManager.getProfiles(anyInt())).thenAnswer { invocation ->
+            val id = invocation.getArgument<Int>(0)
+            val info = UserInfo(id, "", UserInfo.FLAG_FULL)
+            val infoProfile =
+                UserInfo(
+                    id + 10,
+                    "",
+                    "",
+                    UserInfo.FLAG_MANAGED_PROFILE,
+                    UserManager.USER_TYPE_PROFILE_MANAGED
+                )
+            infoProfile.profileGroupId = id
+            listOf(info, infoProfile)
+        }
+
+        tracker.onReceive(context, Intent(intentAction))
+
+        verify(callback, times(0)).onUserChanged(anyInt(), any())
+        verify(callback, times(1)).onProfilesChanged(capture(captor))
+        assertThat(captor.value.map { it.id }).containsExactly(0, profileID)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt
index 52462c7..e65bbb1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt
@@ -124,6 +124,16 @@
 
         verify(context).registerReceiverForAllUsers(
                 eq(tracker), capture(captor), isNull(), eq(handler))
+        with(captor.value) {
+            assertThat(countActions()).isEqualTo(7)
+            assertThat(hasAction(Intent.ACTION_USER_SWITCHED)).isTrue()
+            assertThat(hasAction(Intent.ACTION_USER_INFO_CHANGED)).isTrue()
+            assertThat(hasAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE)).isTrue()
+            assertThat(hasAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)).isTrue()
+            assertThat(hasAction(Intent.ACTION_MANAGED_PROFILE_ADDED)).isTrue()
+            assertThat(hasAction(Intent.ACTION_MANAGED_PROFILE_REMOVED)).isTrue()
+            assertThat(hasAction(Intent.ACTION_MANAGED_PROFILE_UNLOCKED)).isTrue()
+        }
     }
 
     @Test
@@ -280,37 +290,6 @@
     }
 
     @Test
-    fun testCallbackCalledOnProfileChanged() {
-        tracker.initialize(0)
-        val callback = TestCallback()
-        tracker.addCallback(callback, executor)
-        val profileID = tracker.userId + 10
-
-        `when`(userManager.getProfiles(anyInt())).thenAnswer { invocation ->
-            val id = invocation.getArgument<Int>(0)
-            val info = UserInfo(id, "", UserInfo.FLAG_FULL)
-            val infoProfile = UserInfo(
-                    id + 10,
-                    "",
-                    "",
-                    UserInfo.FLAG_MANAGED_PROFILE,
-                    UserManager.USER_TYPE_PROFILE_MANAGED
-            )
-            infoProfile.profileGroupId = id
-            listOf(info, infoProfile)
-        }
-
-        val intent = Intent(Intent.ACTION_MANAGED_PROFILE_AVAILABLE)
-                .putExtra(Intent.EXTRA_USER, UserHandle.of(profileID))
-
-        tracker.onReceive(context, intent)
-
-        assertThat(callback.calledOnUserChanged).isEqualTo(0)
-        assertThat(callback.calledOnProfilesChanged).isEqualTo(1)
-        assertThat(callback.lastUserProfiles.map { it.id }).containsExactly(0, profileID)
-    }
-
-    @Test
     fun testCallbackCalledOnUserInfoChanged() {
         tracker.initialize(0)
         val callback = TestCallback()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
index 88651c1..ed9baf5b1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.shade
 
 import android.testing.AndroidTestingRunner
+import android.view.ViewGroup
 import androidx.constraintlayout.widget.ConstraintSet
 import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
 import androidx.constraintlayout.widget.ConstraintSet.START
@@ -92,12 +93,12 @@
             assertThat(getConstraint(R.id.clock).layout.horizontalBias).isEqualTo(0f)
 
             assertThat(getConstraint(R.id.date).layout.startToStart).isEqualTo(PARENT_ID)
-            assertThat(getConstraint(R.id.date).layout.horizontalBias).isEqualTo(0f)
+            assertThat(getConstraint(R.id.date).layout.horizontalBias).isEqualTo(0.5f)
 
             assertThat(getConstraint(R.id.batteryRemainingIcon).layout.endToEnd)
                 .isEqualTo(PARENT_ID)
             assertThat(getConstraint(R.id.batteryRemainingIcon).layout.horizontalBias)
-                .isEqualTo(1f)
+                .isEqualTo(0.5f)
 
             assertThat(getConstraint(R.id.privacy_container).layout.endToEnd)
                 .isEqualTo(R.id.end_guide)
@@ -108,11 +109,12 @@
     @Test
     fun testEdgeElementsAlignedWithEdge_largeScreen() {
         with(largeScreenConstraint) {
-            assertThat(getConstraint(R.id.clock).layout.startToStart).isEqualTo(PARENT_ID)
-            assertThat(getConstraint(R.id.clock).layout.horizontalBias).isEqualTo(0f)
+            assertThat(getConstraint(R.id.clock).layout.startToEnd).isEqualTo(R.id.begin_guide)
+            assertThat(getConstraint(R.id.clock).layout.horizontalBias).isEqualTo(0.5f)
 
-            assertThat(getConstraint(R.id.privacy_container).layout.endToEnd).isEqualTo(PARENT_ID)
-            assertThat(getConstraint(R.id.privacy_container).layout.horizontalBias).isEqualTo(1f)
+            assertThat(getConstraint(R.id.privacy_container).layout.endToStart)
+                .isEqualTo(R.id.end_guide)
+            assertThat(getConstraint(R.id.privacy_container).layout.horizontalBias).isEqualTo(0.5f)
         }
     }
 
@@ -218,7 +220,12 @@
                 .isEqualTo(cutoutEnd - padding)
         }
 
-        assertThat(changes.largeScreenConstraintsChanges).isNull()
+        with(largeScreenConstraint) {
+            assertThat(getConstraint(R.id.begin_guide).layout.guideBegin)
+                .isEqualTo(cutoutStart - padding)
+            assertThat(getConstraint(R.id.end_guide).layout.guideEnd)
+                .isEqualTo(cutoutEnd - padding)
+        }
     }
 
     @Test
@@ -245,7 +252,10 @@
             assertThat(getConstraint(R.id.end_guide).layout.guideEnd).isEqualTo(0)
         }
 
-        assertThat(changes.largeScreenConstraintsChanges).isNull()
+        with(largeScreenConstraint) {
+            assertThat(getConstraint(R.id.begin_guide).layout.guideBegin).isEqualTo(0)
+            assertThat(getConstraint(R.id.end_guide).layout.guideEnd).isEqualTo(0)
+        }
     }
 
     @Test
@@ -331,10 +341,8 @@
         val views = mapOf(
                 R.id.clock to "clock",
                 R.id.date to "date",
-                R.id.statusIcons to "icons",
                 R.id.privacy_container to "privacy",
                 R.id.carrier_group to "carriers",
-                R.id.batteryRemainingIcon to "battery",
         )
         views.forEach { (id, name) ->
             assertWithMessage("$name has 0 height in qqs")
@@ -352,11 +360,8 @@
     fun testCheckViewsDontChangeSizeBetweenAnimationConstraints() {
         val views = mapOf(
                 R.id.clock to "clock",
-                R.id.date to "date",
-                R.id.statusIcons to "icons",
                 R.id.privacy_container to "privacy",
                 R.id.carrier_group to "carriers",
-                R.id.batteryRemainingIcon to "battery",
         )
         views.forEach { (id, name) ->
             expect.withMessage("$name changes height")
@@ -369,8 +374,8 @@
     }
 
     private fun Int.fromConstraint() = when (this) {
-        -1 -> "MATCH_PARENT"
-        -2 -> "WRAP_CONTENT"
+        ViewGroup.LayoutParams.MATCH_PARENT -> "MATCH_PARENT"
+        ViewGroup.LayoutParams.WRAP_CONTENT -> "WRAP_CONTENT"
         else -> toString()
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
index 1d30ad9..f580f5e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
@@ -182,6 +182,7 @@
             null
         }
         whenever(view.visibility).thenAnswer { _ -> viewVisibility }
+        whenever(view.alpha).thenReturn(1f)
 
         whenever(iconManagerFactory.create(any(), any())).thenReturn(iconManager)
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt
index b4c8f98..b568122 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt
@@ -1,5 +1,6 @@
 package com.android.systemui.shade
 
+import android.animation.ValueAnimator
 import android.app.StatusBarManager
 import android.content.Context
 import android.testing.AndroidTestingRunner
@@ -30,6 +31,7 @@
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.capture
+import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
 import org.junit.After
 import org.junit.Before
@@ -37,6 +39,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Answers
+import org.mockito.ArgumentMatchers.anyFloat
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mock
 import org.mockito.Mockito.mock
@@ -75,6 +78,7 @@
 
     @JvmField @Rule val mockitoRule = MockitoJUnit.rule()
     var viewVisibility = View.GONE
+    var viewAlpha = 1f
 
     private lateinit var mLargeScreenShadeHeaderController: LargeScreenShadeHeaderController
     private lateinit var carrierIconSlots: List<String>
@@ -101,6 +105,13 @@
             null
         }
         whenever(view.visibility).thenAnswer { _ -> viewVisibility }
+
+        whenever(view.setAlpha(anyFloat())).then {
+            viewAlpha = it.arguments[0] as Float
+            null
+        }
+        whenever(view.alpha).thenAnswer { _ -> viewAlpha }
+
         whenever(variableDateViewControllerFactory.create(any()))
             .thenReturn(variableDateViewController)
         whenever(iconManagerFactory.create(any(), any())).thenReturn(iconManager)
@@ -155,6 +166,16 @@
     }
 
     @Test
+    fun alphaChangesUpdateVisibility() {
+        makeShadeVisible()
+        mLargeScreenShadeHeaderController.shadeExpandedFraction = 0f
+        assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
+
+        mLargeScreenShadeHeaderController.shadeExpandedFraction = 1f
+        assertThat(viewVisibility).isEqualTo(View.VISIBLE)
+    }
+
+    @Test
     fun singleCarrier_enablesCarrierIconsInStatusIcons() {
         whenever(qsCarrierGroupController.isSingleCarrier).thenReturn(true)
 
@@ -239,6 +260,39 @@
     }
 
     @Test
+    fun testShadeExpanded_true_alpha_zero_invisible() {
+        view.alpha = 0f
+        mLargeScreenShadeHeaderController.largeScreenActive = true
+        mLargeScreenShadeHeaderController.qsVisible = true
+
+        assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
+    }
+
+    @Test
+    fun animatorCallsUpdateVisibilityOnUpdate() {
+        val animator = mock(ViewPropertyAnimator::class.java, Answers.RETURNS_SELF)
+        whenever(view.animate()).thenReturn(animator)
+
+        mLargeScreenShadeHeaderController.startCustomizingAnimation(show = false, 0L)
+
+        val updateCaptor = argumentCaptor<ValueAnimator.AnimatorUpdateListener>()
+        verify(animator).setUpdateListener(capture(updateCaptor))
+
+        mLargeScreenShadeHeaderController.largeScreenActive = true
+        mLargeScreenShadeHeaderController.qsVisible = true
+
+        view.alpha = 1f
+        updateCaptor.value.onAnimationUpdate(mock())
+
+        assertThat(viewVisibility).isEqualTo(View.VISIBLE)
+
+        view.alpha = 0f
+        updateCaptor.value.onAnimationUpdate(mock())
+
+        assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
+    }
+
+    @Test
     fun demoMode_attachDemoMode() {
         val cb = argumentCaptor<DemoMode>()
         verify(demoModeController).addCallback(capture(cb))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
index 65b2ac0..0f3d4a8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
@@ -103,10 +103,14 @@
 import com.android.systemui.fragments.FragmentHostManager;
 import com.android.systemui.fragments.FragmentService;
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
+import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
 import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor;
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
 import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingTransitionViewModel;
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenToOccludedTransitionViewModel;
 import com.android.systemui.keyguard.ui.viewmodel.OccludedToLockscreenTransitionViewModel;
 import com.android.systemui.media.controls.pipeline.MediaDataManager;
 import com.android.systemui.media.controls.ui.KeyguardMediaController;
@@ -293,8 +297,13 @@
     @Mock private KeyguardBottomAreaInteractor mKeyguardBottomAreaInteractor;
     @Mock private DreamingToLockscreenTransitionViewModel mDreamingToLockscreenTransitionViewModel;
     @Mock private OccludedToLockscreenTransitionViewModel mOccludedToLockscreenTransitionViewModel;
+    @Mock private LockscreenToDreamingTransitionViewModel mLockscreenToDreamingTransitionViewModel;
+    @Mock private LockscreenToOccludedTransitionViewModel mLockscreenToOccludedTransitionViewModel;
+    @Mock private GoneToDreamingTransitionViewModel mGoneToDreamingTransitionViewModel;
+
     @Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
     @Mock private CoroutineDispatcher mMainDispatcher;
+    @Mock private AlternateBouncerInteractor mAlternateBouncerInteractor;
     @Mock private MotionEvent mDownMotionEvent;
     @Captor
     private ArgumentCaptor<NotificationStackScrollLayout.OnEmptySpaceClickListener>
@@ -511,8 +520,12 @@
                 systemClock,
                 mKeyguardBottomAreaViewModel,
                 mKeyguardBottomAreaInteractor,
+                mAlternateBouncerInteractor,
                 mDreamingToLockscreenTransitionViewModel,
                 mOccludedToLockscreenTransitionViewModel,
+                mLockscreenToDreamingTransitionViewModel,
+                mGoneToDreamingTransitionViewModel,
+                mLockscreenToOccludedTransitionViewModel,
                 mMainDispatcher,
                 mKeyguardTransitionInteractor,
                 mDumpManager);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
index d7d17b5..526dc8d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
@@ -46,11 +46,14 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.colorextraction.ColorExtractor;
+import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
@@ -68,6 +71,8 @@
 import org.mockito.MockitoAnnotations;
 import org.mockito.Spy;
 
+import java.util.List;
+
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
 @SmallTest
@@ -89,14 +94,23 @@
     @Mock private ScreenOffAnimationController mScreenOffAnimationController;
     @Mock private AuthController mAuthController;
     @Mock private ShadeExpansionStateManager mShadeExpansionStateManager;
+    @Mock private ShadeWindowLogger mShadeWindowLogger;
     @Captor private ArgumentCaptor<WindowManager.LayoutParams> mLayoutParameters;
+    @Captor private ArgumentCaptor<StatusBarStateController.StateListener> mStateListener;
 
     private NotificationShadeWindowControllerImpl mNotificationShadeWindowController;
-
+    private float mPreferredRefreshRate = -1;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        // Preferred refresh rate is equal to the first displayMode's refresh rate
+        mPreferredRefreshRate = mContext.getDisplay().getSupportedModes()[0].getRefreshRate();
+        overrideResource(
+                R.integer.config_keyguardRefreshRate,
+                (int) mPreferredRefreshRate
+        );
+
         when(mDozeParameters.getAlwaysOn()).thenReturn(true);
         when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors);
 
@@ -104,7 +118,8 @@
                 mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController,
                 mConfigurationController, mKeyguardViewMediator, mKeyguardBypassController,
                 mColorExtractor, mDumpManager, mKeyguardStateController,
-                mScreenOffAnimationController, mAuthController, mShadeExpansionStateManager) {
+                mScreenOffAnimationController, mAuthController, mShadeExpansionStateManager,
+                mShadeWindowLogger) {
                     @Override
                     protected boolean isDebuggable() {
                         return false;
@@ -115,6 +130,7 @@
 
         mNotificationShadeWindowController.attach();
         verify(mWindowManager).addView(eq(mNotificationShadeWindowView), any());
+        verify(mStatusBarStateController).addCallback(mStateListener.capture(), anyInt());
     }
 
     @Test
@@ -332,4 +348,59 @@
         assertThat(mLayoutParameters.getValue().screenOrientation)
                 .isEqualTo(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
     }
+
+    @Test
+    public void udfpsEnrolled_minAndMaxRefreshRateSetToPreferredRefreshRate() {
+        // GIVEN udfps is enrolled
+        when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(true);
+
+        // WHEN keyguard is showing
+        setKeyguardShowing();
+
+        // THEN min and max refresh rate is set to the preferredRefreshRate
+        verify(mWindowManager, atLeastOnce()).updateViewLayout(any(), mLayoutParameters.capture());
+        final List<WindowManager.LayoutParams> lpList = mLayoutParameters.getAllValues();
+        final WindowManager.LayoutParams lp = lpList.get(lpList.size() - 1);
+        assertThat(lp.preferredMaxDisplayRefreshRate).isEqualTo(mPreferredRefreshRate);
+        assertThat(lp.preferredMinDisplayRefreshRate).isEqualTo(mPreferredRefreshRate);
+    }
+
+    @Test
+    public void udfpsNotEnrolled_refreshRateUnset() {
+        // GIVEN udfps is NOT enrolled
+        when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(false);
+
+        // WHEN keyguard is showing
+        setKeyguardShowing();
+
+        // THEN min and max refresh rate aren't set (set to 0)
+        verify(mWindowManager, atLeastOnce()).updateViewLayout(any(), mLayoutParameters.capture());
+        final List<WindowManager.LayoutParams> lpList = mLayoutParameters.getAllValues();
+        final WindowManager.LayoutParams lp = lpList.get(lpList.size() - 1);
+        assertThat(lp.preferredMaxDisplayRefreshRate).isEqualTo(0);
+        assertThat(lp.preferredMinDisplayRefreshRate).isEqualTo(0);
+    }
+
+    @Test
+    public void keyguardNotShowing_refreshRateUnset() {
+        // GIVEN UDFPS is enrolled
+        when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(true);
+
+        // WHEN keyguard is NOT showing
+        mNotificationShadeWindowController.setKeyguardShowing(false);
+
+        // THEN min and max refresh rate aren't set (set to 0)
+        verify(mWindowManager, atLeastOnce()).updateViewLayout(any(), mLayoutParameters.capture());
+        final List<WindowManager.LayoutParams> lpList = mLayoutParameters.getAllValues();
+        final WindowManager.LayoutParams lp = lpList.get(lpList.size() - 1);
+        assertThat(lp.preferredMaxDisplayRefreshRate).isEqualTo(0);
+        assertThat(lp.preferredMinDisplayRefreshRate).isEqualTo(0);
+    }
+
+    private void setKeyguardShowing() {
+        mNotificationShadeWindowController.setKeyguardShowing(true);
+        mNotificationShadeWindowController.setKeyguardGoingAway(false);
+        mNotificationShadeWindowController.setKeyguardFadingAway(false);
+        mStateListener.getValue().onStateChanged(StatusBarState.KEYGUARD);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
index c3207c2..4c76825 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
@@ -30,6 +30,8 @@
 import com.android.systemui.dock.DockManager
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController
+import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel
 import com.android.systemui.shade.NotificationShadeWindowView.InteractionEventHandler
 import com.android.systemui.statusbar.LockscreenShadeTransitionController
@@ -97,10 +99,13 @@
     private lateinit var pulsingGestureListener: PulsingGestureListener
     @Mock
     private lateinit var notificationInsetsController: NotificationInsetsController
+    @Mock
+    private lateinit var alternateBouncerInteractor: AlternateBouncerInteractor
     @Mock lateinit var keyguardBouncerComponentFactory: KeyguardBouncerComponent.Factory
     @Mock lateinit var keyguardBouncerContainer: ViewGroup
     @Mock lateinit var keyguardBouncerComponent: KeyguardBouncerComponent
     @Mock lateinit var keyguardHostViewController: KeyguardHostViewController
+    @Mock lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor
 
     private lateinit var interactionEventHandlerCaptor: ArgumentCaptor<InteractionEventHandler>
     private lateinit var interactionEventHandler: InteractionEventHandler
@@ -132,7 +137,9 @@
             pulsingGestureListener,
             featureFlags,
             keyguardBouncerViewModel,
-            keyguardBouncerComponentFactory
+            keyguardBouncerComponentFactory,
+            alternateBouncerInteractor,
+            keyguardTransitionInteractor,
         )
         underTest.setupExpandedStatusBar()
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java
index 4bf00c4..d435624 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java
@@ -40,6 +40,8 @@
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
+import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel;
 import com.android.systemui.statusbar.DragDownHelper;
 import com.android.systemui.statusbar.LockscreenShadeTransitionController;
@@ -93,6 +95,8 @@
     @Mock private KeyguardBouncerViewModel mKeyguardBouncerViewModel;
     @Mock private KeyguardBouncerComponent.Factory mKeyguardBouncerComponentFactory;
     @Mock private NotificationInsetsController mNotificationInsetsController;
+    @Mock private AlternateBouncerInteractor mAlternateBouncerInteractor;
+    @Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
 
     @Captor private ArgumentCaptor<NotificationShadeWindowView.InteractionEventHandler>
             mInteractionEventHandlerCaptor;
@@ -132,7 +136,9 @@
                 mPulsingGestureListener,
                 mFeatureFlags,
                 mKeyguardBouncerViewModel,
-                mKeyguardBouncerComponentFactory
+                mKeyguardBouncerComponentFactory,
+                mAlternateBouncerInteractor,
+                mKeyguardTransitionInteractor
         );
         mController.setupExpandedStatusBar();
         mController.setDragDownHelper(mDragDownHelper);
@@ -155,7 +161,7 @@
 
         // WHEN showing alt auth, not dozing, drag down helper doesn't want to intercept
         when(mStatusBarStateController.isDozing()).thenReturn(false);
-        when(mStatusBarKeyguardViewManager.isShowingAlternateBouncer()).thenReturn(true);
+        when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
         when(mDragDownHelper.onInterceptTouchEvent(any())).thenReturn(false);
 
         // THEN we should intercept touch
@@ -168,7 +174,7 @@
 
         // WHEN not showing alt auth, not dozing, drag down helper doesn't want to intercept
         when(mStatusBarStateController.isDozing()).thenReturn(false);
-        when(mStatusBarKeyguardViewManager.isShowingAlternateBouncer()).thenReturn(false);
+        when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(false);
         when(mDragDownHelper.onInterceptTouchEvent(any())).thenReturn(false);
 
         // THEN we shouldn't intercept touch
@@ -181,7 +187,7 @@
 
         // WHEN showing alt auth, not dozing, drag down helper doesn't want to intercept
         when(mStatusBarStateController.isDozing()).thenReturn(false);
-        when(mStatusBarKeyguardViewManager.isShowingAlternateBouncer()).thenReturn(true);
+        when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
         when(mDragDownHelper.onInterceptTouchEvent(any())).thenReturn(false);
 
         // THEN we should handle the touch
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/PulsingGestureListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/PulsingGestureListenerTest.kt
index 3e769e9..76aa08a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/PulsingGestureListenerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/PulsingGestureListenerTest.kt
@@ -29,6 +29,7 @@
 import com.android.systemui.dump.DumpManager
 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.CentralSurfaces
 import com.android.systemui.tuner.TunerService
 import com.android.systemui.tuner.TunerService.Tunable
@@ -69,6 +70,8 @@
     private lateinit var statusBarStateController: StatusBarStateController
     @Mock
     private lateinit var shadeLogger: ShadeLogger
+    @Mock
+    private lateinit var userTracker: UserTracker
 
     private lateinit var tunableCaptor: ArgumentCaptor<Tunable>
     private lateinit var underTest: PulsingGestureListener
@@ -85,6 +88,7 @@
                 ambientDisplayConfiguration,
                 statusBarStateController,
                 shadeLogger,
+                userTracker,
                 tunerService,
                 dumpManager
         )
diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/BcSmartspaceConfigProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/smartspace/BcSmartspaceConfigProviderTest.kt
new file mode 100644
index 0000000..5fb1e79
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/smartspace/BcSmartspaceConfigProviderTest.kt
@@ -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.systemui.smartspace
+
+import android.testing.AndroidTestingRunner
+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.smartspace.config.BcSmartspaceConfigProvider
+import com.android.systemui.util.mockito.whenever
+import junit.framework.Assert.assertFalse
+import junit.framework.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class BcSmartspaceConfigProviderTest : SysuiTestCase() {
+    @Mock private lateinit var featureFlags: FeatureFlags
+
+    private lateinit var configProvider: BcSmartspaceConfigProvider
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        configProvider = BcSmartspaceConfigProvider(featureFlags)
+    }
+
+    @Test
+    fun isDefaultDateWeatherDisabled_flagIsTrue_returnsTrue() {
+        whenever(featureFlags.isEnabled(Flags.SMARTSPACE_DATE_WEATHER_DECOUPLED)).thenReturn(true)
+
+        assertTrue(configProvider.isDefaultDateWeatherDisabled)
+    }
+
+    @Test
+    fun isDefaultDateWeatherDisabled_flagIsFalse_returnsFalse() {
+        whenever(featureFlags.isEnabled(Flags.SMARTSPACE_DATE_WEATHER_DECOUPLED)).thenReturn(false)
+
+        assertFalse(configProvider.isDefaultDateWeatherDisabled)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
index 37f96c8..c5432c5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
@@ -27,6 +27,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dreams.smartspace.DreamSmartspaceController
+import com.android.systemui.plugins.BcSmartspaceConfigPlugin
 import com.android.systemui.plugins.BcSmartspaceDataPlugin
 import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceView
 import com.android.systemui.plugins.FalsingManager
@@ -94,10 +95,14 @@
     private class TestView(context: Context?) : View(context), SmartspaceView {
         override fun registerDataProvider(plugin: BcSmartspaceDataPlugin?) {}
 
+        override fun registerConfigProvider(plugin: BcSmartspaceConfigPlugin?) {}
+
         override fun setPrimaryTextColor(color: Int) {}
 
         override fun setIsDreaming(isDreaming: Boolean) {}
 
+        override fun setUiSurface(uiSurface: String) {}
+
         override fun setDozeAmount(amount: Float) {}
 
         override fun setIntentStarter(intentStarter: BcSmartspaceDataPlugin.IntentStarter?) {}
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 8d96932..610bb13 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -99,6 +99,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.AlternateBouncerInteractor;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
@@ -177,6 +178,8 @@
     @Mock
     private FaceHelpMessageDeferral mFaceHelpMessageDeferral;
     @Mock
+    private AlternateBouncerInteractor mAlternateBouncerInteractor;
+    @Mock
     private ScreenLifecycle mScreenLifecycle;
     @Mock
     private AuthController mAuthController;
@@ -273,7 +276,8 @@
                 mUserManager, mExecutor, mExecutor, mFalsingManager,
                 mAuthController, mLockPatternUtils, mScreenLifecycle,
                 mKeyguardBypassController, mAccessibilityManager,
-                mFaceHelpMessageDeferral, mock(KeyguardLogger.class));
+                mFaceHelpMessageDeferral, mock(KeyguardLogger.class),
+                mAlternateBouncerInteractor);
         mController.init();
         mController.setIndicationArea(mIndicationArea);
         verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture());
@@ -661,6 +665,7 @@
         String message = mContext.getString(R.string.keyguard_retry);
         when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(true);
         when(mKeyguardUpdateMonitor.isFaceEnrolled()).thenReturn(true);
+        when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(false);
 
         mController.setVisible(true);
         mController.getKeyguardCallback().onBiometricError(FACE_ERROR_TIMEOUT,
@@ -670,6 +675,21 @@
     }
 
     @Test
+    public void transientIndication_swipeUpToRetry_faceAuthenticated() {
+        createController();
+        String message = mContext.getString(R.string.keyguard_retry);
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(true);
+        when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(true);
+        when(mKeyguardUpdateMonitor.isFaceEnrolled()).thenReturn(true);
+
+        mController.setVisible(true);
+        mController.getKeyguardCallback().onBiometricError(FACE_ERROR_TIMEOUT,
+                "A message", BiometricSourceType.FACE);
+
+        verify(mStatusBarKeyguardViewManager, never()).setKeyguardMessage(eq(message), any());
+    }
+
+    @Test
     public void faceErrorTimeout_whenFingerprintEnrolled_doesNotShowMessage() {
         createController();
         when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
index 3d11ced..702f278 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
@@ -244,6 +244,14 @@
     }
 
     @Test
+    fun testGoToLockedShadeAlwaysCreatesQSAnimationInSplitShade() {
+        enableSplitShade()
+        transitionController.goToLockedShade(null, needsQSAnimation = true)
+        verify(notificationPanelController).animateToFullShade(anyLong())
+        assertNotNull(transitionController.dragDownAnimator)
+    }
+
+    @Test
     fun testDragDownAmountDoesntCallOutInLockedDownShade() {
         whenever(nsslController.isInLockedDownShade).thenReturn(true)
         transitionController.dragDownAmount = 10f
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
index 790865b..4bcb54d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
@@ -36,6 +36,7 @@
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.BcSmartspaceConfigPlugin
 import com.android.systemui.plugins.BcSmartspaceDataPlugin
 import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceTargetListener
 import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceView
@@ -55,21 +56,21 @@
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.settings.SecureSettings
 import com.android.systemui.util.time.FakeSystemClock
-import java.util.Optional
-import java.util.concurrent.Executor
 import org.junit.Before
 import org.junit.Test
 import org.mockito.ArgumentCaptor
 import org.mockito.Captor
 import org.mockito.Mock
+import org.mockito.Mockito.`when`
 import org.mockito.Mockito.anyInt
 import org.mockito.Mockito.clearInvocations
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.never
 import org.mockito.Mockito.spy
 import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
+import java.util.Optional
+import java.util.concurrent.Executor
 
 @SmallTest
 class LockscreenSmartspaceControllerTest : SysuiTestCase() {
@@ -115,6 +116,9 @@
     private lateinit var plugin: BcSmartspaceDataPlugin
 
     @Mock
+    private lateinit var configPlugin: BcSmartspaceConfigPlugin
+
+    @Mock
     private lateinit var controllerListener: SmartspaceTargetListener
 
     @Captor
@@ -209,7 +213,8 @@
                 executor,
                 bgExecutor,
                 handler,
-                Optional.of(plugin)
+                Optional.of(plugin),
+                Optional.of(configPlugin),
         )
 
         verify(deviceProvisionedController).addCallback(capture(deviceProvisionedCaptor))
@@ -518,7 +523,9 @@
 
         // THEN the existing session is reused and views are registered
         verify(smartspaceManager, never()).createSmartspaceSession(any())
+        verify(smartspaceView2).setUiSurface(BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD)
         verify(smartspaceView2).registerDataProvider(plugin)
+        verify(smartspaceView2).registerConfigProvider(configPlugin)
     }
 
     @Test
@@ -554,7 +561,9 @@
 
         controller.stateChangeListener.onViewAttachedToWindow(view)
 
+        verify(smartspaceView).setUiSurface(BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD)
         verify(smartspaceView).registerDataProvider(plugin)
+        verify(smartspaceView).registerConfigProvider(configPlugin)
         verify(smartspaceSession)
                 .addOnTargetsAvailableListener(any(), capture(sessionListenerCaptor))
         sessionListener = sessionListenerCaptor.value
@@ -636,12 +645,18 @@
             override fun registerDataProvider(plugin: BcSmartspaceDataPlugin?) {
             }
 
+            override fun registerConfigProvider(plugin: BcSmartspaceConfigPlugin?) {
+            }
+
             override fun setPrimaryTextColor(color: Int) {
             }
 
             override fun setIsDreaming(isDreaming: Boolean) {
             }
 
+            override fun setUiSurface(uiSurface: String) {
+            }
+
             override fun setDozeAmount(amount: Float) {
             }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java
index 09f8a10..a869038 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java
@@ -39,7 +39,6 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
 
 import static java.util.Arrays.asList;
 import static java.util.Collections.singletonList;
@@ -137,7 +136,6 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         allowTestableLooperAsMainThread();
-        when(mNotifPipelineFlags.isStabilityIndexFixEnabled()).thenReturn(true);
 
         mListBuilder = new ShadeListBuilder(
                 mDumpManager,
@@ -1998,29 +1996,7 @@
     }
 
     @Test
-    public void testActiveOrdering_withLegacyStability() {
-        when(mNotifPipelineFlags.isSemiStableSortEnabled()).thenReturn(false);
-        assertOrder("ABCDEFG", "ABCDEFG", "ABCDEFG", true); // no change
-        assertOrder("ABCDEFG", "ACDEFXBG", "ACDEFXBG", true); // X
-        assertOrder("ABCDEFG", "ACDEFBG", "ACDEFBG", true); // no change
-        assertOrder("ABCDEFG", "ACDEFBXZG", "ACDEFBXZG", true); // Z and X
-        assertOrder("ABCDEFG", "AXCDEZFBG", "AXCDEZFBG", true); // Z and X + gap
-    }
-
-    @Test
-    public void testStableOrdering_withLegacyStability() {
-        when(mNotifPipelineFlags.isSemiStableSortEnabled()).thenReturn(false);
-        mStabilityManager.setAllowEntryReordering(false);
-        assertOrder("ABCDEFG", "ABCDEFG", "ABCDEFG", true); // no change
-        assertOrder("ABCDEFG", "ACDEFXBG", "XABCDEFG", false); // X
-        assertOrder("ABCDEFG", "ACDEFBG", "ABCDEFG", false); // no change
-        assertOrder("ABCDEFG", "ACDEFBXZG", "XZABCDEFG", false); // Z and X
-        assertOrder("ABCDEFG", "AXCDEZFBG", "XZABCDEFG", false); // Z and X + gap
-    }
-
-    @Test
     public void testStableOrdering() {
-        when(mNotifPipelineFlags.isSemiStableSortEnabled()).thenReturn(true);
         mStabilityManager.setAllowEntryReordering(false);
         // No input or output
         assertOrder("", "", "", true);
@@ -2076,7 +2052,6 @@
 
     @Test
     public void testActiveOrdering() {
-        when(mNotifPipelineFlags.isSemiStableSortEnabled()).thenReturn(true);
         assertOrder("ABCDEFG", "ACDEFXBG", "ACDEFXBG", true); // X
         assertOrder("ABCDEFG", "ACDEFBG", "ACDEFBG", true); // no change
         assertOrder("ABCDEFG", "ACDEFBXZG", "ACDEFBXZG", true); // Z and X
@@ -2133,7 +2108,6 @@
 
     @Test
     public void stableOrderingDisregardedWithSectionChange() {
-        when(mNotifPipelineFlags.isSemiStableSortEnabled()).thenReturn(true);
         // GIVEN the first sectioner's packages can be changed from run-to-run
         List<String> mutableSectionerPackages = new ArrayList<>();
         mutableSectionerPackages.add(PACKAGE_1);
@@ -2229,49 +2203,7 @@
     }
 
     @Test
-    public void groupRevertingToSummaryDoesNotRetainStablePositionWithLegacyIndexLogic() {
-        when(mNotifPipelineFlags.isStabilityIndexFixEnabled()).thenReturn(false);
-
-        // GIVEN a notification group is on screen
-        mStabilityManager.setAllowEntryReordering(false);
-
-        // WHEN the list is originally built with reordering disabled (and section changes allowed)
-        addNotif(0, PACKAGE_1).setRank(2);
-        addNotif(1, PACKAGE_1).setRank(3);
-        addGroupSummary(2, PACKAGE_1, "group").setRank(4);
-        addGroupChild(3, PACKAGE_1, "group").setRank(5);
-        addGroupChild(4, PACKAGE_1, "group").setRank(6);
-        dispatchBuild();
-
-        verifyBuiltList(
-                notif(0),
-                notif(1),
-                group(
-                        summary(2),
-                        child(3),
-                        child(4)
-                )
-        );
-
-        // WHEN the notification summary rank increases and children removed
-        setNewRank(notif(2).entry, 1);
-        mEntrySet.remove(4);
-        mEntrySet.remove(3);
-        dispatchBuild();
-
-        // VERIFY the summary (incorrectly) moves to the top of the section where it is ranked,
-        // despite visual stability being active
-        verifyBuiltList(
-                notif(2),
-                notif(0),
-                notif(1)
-        );
-    }
-
-    @Test
     public void groupRevertingToSummaryRetainsStablePosition() {
-        when(mNotifPipelineFlags.isStabilityIndexFixEnabled()).thenReturn(true);
-
         // GIVEN a notification group is on screen
         mStabilityManager.setAllowEntryReordering(false);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/TargetSdkResolverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/TargetSdkResolverTest.kt
index 8275c0c..9b3626b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/TargetSdkResolverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/TargetSdkResolverTest.kt
@@ -127,6 +127,6 @@
                 NotificationManager.IMPORTANCE_DEFAULT,
                 null, null,
                 null, null, null, true, 0, false, -1, false, null, null, false, false,
-                false, null, 0, false)
+                false, null, 0, false, 0)
     }
 }
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 be6b1dc..2686238 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
@@ -321,7 +321,7 @@
         val testDispatcher = UnconfinedTestDispatcher()
         val testScope = TestScope(testDispatcher)
         val fakeSettings = FakeSettings().apply {
-            putBool(Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS, true)
+            putInt(Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS, 1)
         }
         val seenNotificationsProvider = SeenNotificationsProviderImpl()
         val keyguardCoordinator =
@@ -372,14 +372,14 @@
 
         var showOnlyUnseenNotifsOnKeyguardSetting: Boolean
             get() =
-                fakeSettings.getBoolForUser(
+                fakeSettings.getIntForUser(
                     Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS,
                     UserHandle.USER_CURRENT,
-                )
+                ) == 1
             set(value) {
-                fakeSettings.putBoolForUser(
+                fakeSettings.putIntForUser(
                     Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS,
-                    value,
+                    if (value) 1 else 2,
                     UserHandle.USER_CURRENT,
                 )
             }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
index 601771d..03af527 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
@@ -41,6 +41,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityManager;
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.PendingIntent;
@@ -59,6 +60,7 @@
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.notification.NotifPipelineFlags;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
@@ -107,6 +109,8 @@
     UiEventLoggerFake mUiEventLoggerFake;
     @Mock
     PendingIntent mPendingIntent;
+    @Mock
+    UserTracker mUserTracker;
 
     private NotificationInterruptStateProviderImpl mNotifInterruptionStateProvider;
 
@@ -114,6 +118,7 @@
     public void setup() {
         MockitoAnnotations.initMocks(this);
         when(mFlags.fullScreenIntentRequiresKeyguard()).thenReturn(false);
+        when(mUserTracker.getUserId()).thenReturn(ActivityManager.getCurrentUser());
 
         mUiEventLoggerFake = new UiEventLoggerFake();
 
@@ -131,7 +136,8 @@
                         mMockHandler,
                         mFlags,
                         mKeyguardNotificationVisibilityProvider,
-                        mUiEventLoggerFake);
+                        mUiEventLoggerFake,
+                        mUserTracker);
         mNotifInterruptionStateProvider.mUseHeadsUp = true;
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
index ee8db18..4559a23 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
@@ -44,22 +44,31 @@
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.graphics.Color;
+import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.AnimationDrawable;
+import android.graphics.drawable.Drawable;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
 import android.util.DisplayMetrics;
 import android.view.View;
+import android.widget.ImageView;
 
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.R;
+import com.android.internal.widget.CachingIconView;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.flags.FakeFeatureFlags;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
 import com.android.systemui.statusbar.notification.FeedbackIcon;
+import com.android.systemui.statusbar.notification.SourceType;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.ExpandableView.OnHeightChangedListener;
+import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
 import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer;
 
 import org.junit.Assert;
@@ -71,6 +80,7 @@
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
+import java.util.Arrays;
 import java.util.List;
 
 @SmallTest
@@ -95,6 +105,9 @@
                 mDependency,
                 TestableLooper.get(this));
         mNotificationTestHelper.setDefaultInflationFlags(FLAG_CONTENT_VIEW_ALL);
+        FakeFeatureFlags fakeFeatureFlags = new FakeFeatureFlags();
+        fakeFeatureFlags.set(Flags.NOTIFICATION_ANIMATE_BIG_PICTURE, true);
+        mNotificationTestHelper.setFeatureFlags(fakeFeatureFlags);
         // create a standard private notification row
         Notification normalNotif = mNotificationTestHelper.createNotification();
         normalNotif.publicVersion = null;
@@ -534,4 +547,147 @@
                 /*oldParent=*/ any()
         );
     }
+
+    @Test
+    public void applyRoundnessAndInv_should_be_immediately_applied_on_childrenContainer_legacy() {
+        mGroupRow.useRoundnessSourceTypes(false);
+        Assert.assertEquals(0f, mGroupRow.getBottomRoundness(), 0.001f);
+        Assert.assertEquals(0f, mGroupRow.getChildrenContainer().getBottomRoundness(), 0.001f);
+
+        mGroupRow.requestBottomRoundness(1f, SourceType.from(""), false);
+
+        Assert.assertEquals(1f, mGroupRow.getBottomRoundness(), 0.001f);
+        Assert.assertEquals(1f, mGroupRow.getChildrenContainer().getBottomRoundness(), 0.001f);
+    }
+
+    @Test
+    public void applyRoundnessAndInvalidate_should_be_immediately_applied_on_childrenContainer() {
+        mGroupRow.useRoundnessSourceTypes(true);
+        Assert.assertEquals(0f, mGroupRow.getBottomRoundness(), 0.001f);
+        Assert.assertEquals(0f, mGroupRow.getChildrenContainer().getBottomRoundness(), 0.001f);
+
+        mGroupRow.requestBottomRoundness(1f, SourceType.from(""), false);
+
+        Assert.assertEquals(1f, mGroupRow.getBottomRoundness(), 0.001f);
+        Assert.assertEquals(1f, mGroupRow.getChildrenContainer().getBottomRoundness(), 0.001f);
+    }
+
+    @Test
+    public void testSetContentAnimationRunning_Run() throws Exception {
+        // Create views for the notification row.
+        NotificationContentView publicLayout = mock(NotificationContentView.class);
+        mNotifRow.setPublicLayout(publicLayout);
+        NotificationContentView privateLayout = mock(NotificationContentView.class);
+        mNotifRow.setPrivateLayout(privateLayout);
+
+        mNotifRow.setAnimationRunning(true);
+        verify(publicLayout, times(1)).setContentAnimationRunning(true);
+        verify(privateLayout, times(1)).setContentAnimationRunning(true);
+    }
+
+    @Test
+    public void testSetContentAnimationRunning_Stop() {
+        // Create views for the notification row.
+        NotificationContentView publicLayout = mock(NotificationContentView.class);
+        mNotifRow.setPublicLayout(publicLayout);
+        NotificationContentView privateLayout = mock(NotificationContentView.class);
+        mNotifRow.setPrivateLayout(privateLayout);
+
+        mNotifRow.setAnimationRunning(false);
+        verify(publicLayout, times(1)).setContentAnimationRunning(false);
+        verify(privateLayout, times(1)).setContentAnimationRunning(false);
+    }
+
+    @Test
+    public void testSetContentAnimationRunningInGroupChild_Run() {
+        // Creates parent views on mGroupRow.
+        NotificationContentView publicParentLayout = mock(NotificationContentView.class);
+        mGroupRow.setPublicLayout(publicParentLayout);
+        NotificationContentView privateParentLayout = mock(NotificationContentView.class);
+        mGroupRow.setPrivateLayout(privateParentLayout);
+
+        // Create child views on mNotifRow.
+        NotificationContentView publicChildLayout = mock(NotificationContentView.class);
+        mNotifRow.setPublicLayout(publicChildLayout);
+        NotificationContentView privateChildLayout = mock(NotificationContentView.class);
+        mNotifRow.setPrivateLayout(privateChildLayout);
+        when(mNotifRow.isGroupExpanded()).thenReturn(true);
+        setMockChildrenContainer(mGroupRow, mNotifRow);
+
+        mGroupRow.setAnimationRunning(true);
+        verify(publicParentLayout, times(1)).setContentAnimationRunning(true);
+        verify(privateParentLayout, times(1)).setContentAnimationRunning(true);
+        // The child layouts should be started too.
+        verify(publicChildLayout, times(1)).setContentAnimationRunning(true);
+        verify(privateChildLayout, times(1)).setContentAnimationRunning(true);
+    }
+
+
+    @Test
+    public void testSetIconAnimationRunningGroup_Run() {
+        // Create views for a group row.
+        NotificationContentView publicParentLayout = mock(NotificationContentView.class);
+        mGroupRow.setPublicLayout(publicParentLayout);
+        NotificationContentView privateParentLayout = mock(NotificationContentView.class);
+        mGroupRow.setPrivateLayout(privateParentLayout);
+        when(mGroupRow.isGroupExpanded()).thenReturn(true);
+
+        // Sets up mNotifRow as a child ExpandableNotificationRow.
+        NotificationContentView publicChildLayout = mock(NotificationContentView.class);
+        mNotifRow.setPublicLayout(publicChildLayout);
+        NotificationContentView privateChildLayout = mock(NotificationContentView.class);
+        mNotifRow.setPrivateLayout(privateChildLayout);
+        when(mNotifRow.isGroupExpanded()).thenReturn(true);
+
+        NotificationChildrenContainer mockContainer =
+                setMockChildrenContainer(mGroupRow, mNotifRow);
+
+        // Mock the children view wrappers, and give them each an icon.
+        NotificationViewWrapper mockViewWrapper = mock(NotificationViewWrapper.class);
+        when(mockContainer.getNotificationViewWrapper()).thenReturn(mockViewWrapper);
+        CachingIconView mockIcon = mock(CachingIconView.class);
+        when(mockViewWrapper.getIcon()).thenReturn(mockIcon);
+
+        NotificationViewWrapper mockLowPriorityViewWrapper = mock(NotificationViewWrapper.class);
+        when(mockContainer.getLowPriorityViewWrapper()).thenReturn(mockLowPriorityViewWrapper);
+        CachingIconView mockLowPriorityIcon = mock(CachingIconView.class);
+        when(mockLowPriorityViewWrapper.getIcon()).thenReturn(mockLowPriorityIcon);
+
+        // Give the icon image views drawables, so we can make sure they animate.
+        // We use both AnimationDrawables and AnimatedVectorDrawables to ensure both work.
+        AnimationDrawable drawable = mock(AnimationDrawable.class);
+        AnimatedVectorDrawable vectorDrawable = mock(AnimatedVectorDrawable.class);
+        setDrawableIconsInImageView(mockIcon, drawable, vectorDrawable);
+
+        AnimationDrawable lowPriDrawable = mock(AnimationDrawable.class);
+        AnimatedVectorDrawable lowPriVectorDrawable = mock(AnimatedVectorDrawable.class);
+        setDrawableIconsInImageView(mockLowPriorityIcon, lowPriDrawable, lowPriVectorDrawable);
+
+        mGroupRow.setAnimationRunning(true);
+        verify(drawable, times(1)).start();
+        verify(vectorDrawable, times(1)).start();
+        verify(lowPriDrawable, times(1)).start();
+        verify(lowPriVectorDrawable, times(1)).start();
+    }
+
+    private void setDrawableIconsInImageView(CachingIconView icon, Drawable iconDrawable,
+            Drawable rightIconDrawable) {
+        ImageView iconView = mock(ImageView.class);
+        when(icon.findViewById(com.android.internal.R.id.icon)).thenReturn(iconView);
+        when(iconView.getDrawable()).thenReturn(iconDrawable);
+
+        ImageView rightIconView = mock(ImageView.class);
+        when(icon.findViewById(com.android.internal.R.id.right_icon)).thenReturn(rightIconView);
+        when(rightIconView.getDrawable()).thenReturn(rightIconDrawable);
+    }
+
+    private NotificationChildrenContainer setMockChildrenContainer(
+            ExpandableNotificationRow parentRow, ExpandableNotificationRow childRow) {
+        List<ExpandableNotificationRow> rowList = Arrays.asList(childRow);
+        NotificationChildrenContainer mockContainer = mock(NotificationChildrenContainer.class);
+        when(mockContainer.getNotificationChildCount()).thenReturn(1);
+        when(mockContainer.getAttachedChildren()).thenReturn(rowList);
+        parentRow.setChildrenContainer(mockContainer);
+        return mockContainer;
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FooterViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FooterViewTest.java
index 1f92b0a..819a75b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FooterViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FooterViewTest.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.notification.row;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertTrue;
@@ -98,5 +100,16 @@
 
         mView.setSecondaryVisible(true /* visible */, true /* animate */);
     }
+
+    @Test
+    public void testSetFooterLabelTextAndIcon() {
+        mView.setFooterLabelTextAndIcon(
+                R.string.unlock_to_see_notif_text,
+                R.drawable.ic_friction_lock_closed);
+        assertThat(mView.findViewById(R.id.manage_text).getVisibility()).isEqualTo(View.GONE);
+        assertThat(mView.findSecondaryView().getVisibility()).isEqualTo(View.GONE);
+        assertThat(mView.findViewById(R.id.unlock_prompt_footer).getVisibility())
+                .isEqualTo(View.VISIBLE);
+    }
 }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt
index 562b4df..7b2051d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt
@@ -34,9 +34,12 @@
 import com.android.systemui.statusbar.notification.FeedbackIcon
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
+import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
 import junit.framework.Assert.assertEquals
+import junit.framework.Assert.assertFalse
+import junit.framework.Assert.assertTrue
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -44,6 +47,7 @@
 import org.mockito.Mockito.doReturn
 import org.mockito.Mockito.never
 import org.mockito.Mockito.spy
+import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations.initMocks
 
@@ -305,6 +309,86 @@
         assertEquals(0, getMarginBottom(actionListMarginTarget))
     }
 
+    @Test
+    fun onSetAnimationRunning() {
+        // Given: contractedWrapper, enpandedWrapper, and headsUpWrapper being set
+        val mockContracted = mock<NotificationViewWrapper>()
+        val mockExpanded = mock<NotificationViewWrapper>()
+        val mockHeadsUp = mock<NotificationViewWrapper>()
+
+        view.setContractedWrapper(mockContracted)
+        view.setExpandedWrapper(mockExpanded)
+        view.setHeadsUpWrapper(mockHeadsUp)
+
+        // When: we set content animation running.
+        assertTrue(view.setContentAnimationRunning(true))
+
+        // Then: contractedChild, expandedChild, and headsUpChild should have setAnimationsRunning
+        // called on them.
+        verify(mockContracted, times(1)).setAnimationsRunning(true)
+        verify(mockExpanded, times(1)).setAnimationsRunning(true)
+        verify(mockHeadsUp, times(1)).setAnimationsRunning(true)
+
+        // When: we set content animation running true _again_.
+        assertFalse(view.setContentAnimationRunning(true))
+
+        // Then: the children should not have setAnimationRunning called on them again.
+        // Verify counts number of calls so far on the object, so these still register as 1.
+        verify(mockContracted, times(1)).setAnimationsRunning(true)
+        verify(mockExpanded, times(1)).setAnimationsRunning(true)
+        verify(mockHeadsUp, times(1)).setAnimationsRunning(true)
+    }
+
+    @Test
+    fun onSetAnimationStopped() {
+        // Given: contractedWrapper, expandedWrapper, and headsUpWrapper being set
+        val mockContracted = mock<NotificationViewWrapper>()
+        val mockExpanded = mock<NotificationViewWrapper>()
+        val mockHeadsUp = mock<NotificationViewWrapper>()
+
+        view.setContractedWrapper(mockContracted)
+        view.setExpandedWrapper(mockExpanded)
+        view.setHeadsUpWrapper(mockHeadsUp)
+
+        // When: we set content animation running.
+        assertTrue(view.setContentAnimationRunning(true))
+
+        // Then: contractedChild, expandedChild, and headsUpChild should have setAnimationsRunning
+        // called on them.
+        verify(mockContracted).setAnimationsRunning(true)
+        verify(mockExpanded).setAnimationsRunning(true)
+        verify(mockHeadsUp).setAnimationsRunning(true)
+
+        // When: we set content animation running false, the state changes, so the function
+        // returns true.
+        assertTrue(view.setContentAnimationRunning(false))
+
+        // Then: the children have their animations stopped.
+        verify(mockContracted).setAnimationsRunning(false)
+        verify(mockExpanded).setAnimationsRunning(false)
+        verify(mockHeadsUp).setAnimationsRunning(false)
+    }
+
+    @Test
+    fun onSetAnimationInitStopped() {
+        // Given: contractedWrapper, expandedWrapper, and headsUpWrapper being set
+        val mockContracted = mock<NotificationViewWrapper>()
+        val mockExpanded = mock<NotificationViewWrapper>()
+        val mockHeadsUp = mock<NotificationViewWrapper>()
+
+        view.setContractedWrapper(mockContracted)
+        view.setExpandedWrapper(mockExpanded)
+        view.setHeadsUpWrapper(mockHeadsUp)
+
+        // When: we try to stop the animations before they've been started.
+        assertFalse(view.setContentAnimationRunning(false))
+
+        // Then: the children should not have setAnimationRunning called on them again.
+        verify(mockContracted, never()).setAnimationsRunning(false)
+        verify(mockExpanded, never()).setAnimationsRunning(false)
+        verify(mockHeadsUp, never()).setAnimationsRunning(false)
+    }
+
     private fun createMockContainingNotification(notificationEntry: NotificationEntry) =
         mock<ExpandableNotificationRow>().apply {
             whenever(this.entry).thenReturn(notificationEntry)
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 728e026..e4fc4d5 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
@@ -53,6 +53,7 @@
 import com.android.systemui.TestableDependency;
 import com.android.systemui.classifier.FalsingCollectorFake;
 import com.android.systemui.classifier.FalsingManagerFake;
+import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.media.controls.util.MediaFeatureFlag;
 import com.android.systemui.media.dialog.MediaOutputDialogFactory;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -130,6 +131,7 @@
     public final OnUserInteractionCallback mOnUserInteractionCallback;
     public final Runnable mFutureDismissalRunnable;
     private @InflationFlag int mDefaultInflationFlags;
+    private FeatureFlags mFeatureFlags;
 
     public NotificationTestHelper(
             Context context,
@@ -193,12 +195,17 @@
         mFutureDismissalRunnable = mock(Runnable.class);
         when(mOnUserInteractionCallback.registerFutureDismissal(any(), anyInt()))
                 .thenReturn(mFutureDismissalRunnable);
+        mFeatureFlags = mock(FeatureFlags.class);
     }
 
     public void setDefaultInflationFlags(@InflationFlag int defaultInflationFlags) {
         mDefaultInflationFlags = defaultInflationFlags;
     }
 
+    public void setFeatureFlags(FeatureFlags featureFlags) {
+        mFeatureFlags = featureFlags;
+    }
+
     public ExpandableNotificationRowLogger getMockLogger() {
         return mMockLogger;
     }
@@ -561,7 +568,8 @@
                 mock(NotificationGutsManager.class),
                 mock(MetricsLogger.class),
                 mock(SmartReplyConstants.class),
-                mock(SmartReplyController.class));
+                mock(SmartReplyController.class),
+                mFeatureFlags);
 
         row.setAboveShelfChangedListener(aboveShelf -> { });
         mBindStage.getStageParams(entry).requireContentViews(extraInflationFlags);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapperTest.java
index 509ba41..8f88501 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapperTest.java
@@ -16,11 +16,12 @@
 
 package com.android.systemui.statusbar.notification.row.wrapper;
 
+import static org.junit.Assert.assertNotNull;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
 
 import android.app.Notification;
-import android.content.Context;
+import android.graphics.drawable.AnimatedImageDrawable;
 import android.graphics.drawable.Icon;
 import android.os.Bundle;
 import android.testing.AndroidTestingRunner;
@@ -28,11 +29,11 @@
 import android.testing.TestableLooper.RunWithLooper;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.widget.LinearLayout;
-import android.widget.TextView;
 
 import androidx.test.filters.SmallTest;
 
+import com.android.internal.R;
+import com.android.internal.widget.BigPictureNotificationImageView;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
@@ -73,4 +74,38 @@
                 Notification.EXTRA_LARGE_ICON_BIG, new Bundle());
         wrapper.onContentUpdated(mRow);
     }
+
+    @Test
+    public void setAnimationsRunning_Run() {
+        BigPictureNotificationImageView imageView = mView.findViewById(R.id.big_picture);
+        AnimatedImageDrawable mockDrawable = mock(AnimatedImageDrawable.class);
+
+        assertNotNull(imageView);
+        imageView.setImageDrawable(mockDrawable);
+
+        NotificationViewWrapper wrapper = new NotificationBigPictureTemplateViewWrapper(mContext,
+                mView, mRow);
+        // Required to re-initialize the imageView to the imageView created above.
+        wrapper.onContentUpdated(mRow);
+
+        wrapper.setAnimationsRunning(true);
+        verify(mockDrawable).start();
+    }
+
+    @Test
+    public void setAnimationsRunning_Stop() {
+        BigPictureNotificationImageView imageView = mView.findViewById(R.id.big_picture);
+        AnimatedImageDrawable mockDrawable = mock(AnimatedImageDrawable.class);
+
+        assertNotNull(imageView);
+        imageView.setImageDrawable(mockDrawable);
+
+        NotificationViewWrapper wrapper = new NotificationBigPictureTemplateViewWrapper(mContext,
+                mView, mRow);
+        // Required to re-initialize the imageView to the imageView created above.
+        wrapper.onContentUpdated(mRow);
+
+        wrapper.setAnimationsRunning(false);
+        verify(mockDrawable).stop();
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapperTest.kt
new file mode 100644
index 0000000..3fa68bb
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapperTest.kt
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.row.wrapper
+
+import android.graphics.drawable.AnimatedImageDrawable
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.testing.TestableLooper.RunWithLooper
+import android.view.View
+import androidx.test.filters.SmallTest
+import com.android.internal.R
+import com.android.internal.widget.CachingIconView
+import com.android.internal.widget.ConversationLayout
+import com.android.internal.widget.MessagingGroup
+import com.android.internal.widget.MessagingImageMessage
+import com.android.internal.widget.MessagingLinearLayout
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import com.android.systemui.statusbar.notification.row.NotificationTestHelper
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.mock
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenever
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper
+class NotificationConversationTemplateViewWrapperTest : SysuiTestCase() {
+
+    private lateinit var mRow: ExpandableNotificationRow
+    private lateinit var helper: NotificationTestHelper
+
+    @Before
+    fun setUp() {
+        allowTestableLooperAsMainThread()
+        helper = NotificationTestHelper(mContext, mDependency, TestableLooper.get(this))
+        mRow = helper.createRow()
+    }
+
+    @Test
+    fun setAnimationsRunning_Run() {
+        // Creates a mocked out NotificationEntry of ConversationLayout type,
+        // with a mock imageMessage.drawable embedded in its MessagingImageMessages
+        // (both top level, and in a group).
+        val mockDrawable = mock<AnimatedImageDrawable>()
+        val mockDrawable2 = mock<AnimatedImageDrawable>()
+        val mockLayoutView: View = fakeConversationLayout(mockDrawable, mockDrawable2)
+
+        val wrapper: NotificationViewWrapper =
+            NotificationConversationTemplateViewWrapper(mContext, mockLayoutView, mRow)
+        wrapper.onContentUpdated(mRow)
+        wrapper.setAnimationsRunning(true)
+
+        // Verifies that each AnimatedImageDrawable is started animating.
+        verify(mockDrawable).start()
+        verify(mockDrawable2).start()
+    }
+
+    @Test
+    fun setAnimationsRunning_Stop() {
+        // Creates a mocked out NotificationEntry of ConversationLayout type,
+        // with a mock imageMessage.drawable embedded in its MessagingImageMessages
+        // (both top level, and in a group).
+        val mockDrawable = mock<AnimatedImageDrawable>()
+        val mockDrawable2 = mock<AnimatedImageDrawable>()
+        val mockLayoutView: View = fakeConversationLayout(mockDrawable, mockDrawable2)
+
+        val wrapper: NotificationViewWrapper =
+            NotificationConversationTemplateViewWrapper(mContext, mockLayoutView, mRow)
+        wrapper.onContentUpdated(mRow)
+        wrapper.setAnimationsRunning(false)
+
+        // Verifies that each AnimatedImageDrawable is started animating.
+        verify(mockDrawable).stop()
+        verify(mockDrawable2).stop()
+    }
+
+    private fun fakeConversationLayout(
+        mockDrawableGroupMessage: AnimatedImageDrawable,
+        mockDrawableImageMessage: AnimatedImageDrawable
+    ): View {
+        val mockMessagingImageMessage: MessagingImageMessage =
+            mock<MessagingImageMessage>().apply {
+                whenever(drawable).thenReturn(mockDrawableImageMessage)
+            }
+        val mockImageMessageContainer: MessagingLinearLayout =
+            mock<MessagingLinearLayout>().apply {
+                whenever(childCount).thenReturn(1)
+                whenever(getChildAt(any())).thenReturn(mockMessagingImageMessage)
+            }
+
+        val mockMessagingImageMessageForGroup: MessagingImageMessage =
+            mock<MessagingImageMessage>().apply {
+                whenever(drawable).thenReturn(mockDrawableGroupMessage)
+            }
+        val mockMessageContainer: MessagingLinearLayout =
+            mock<MessagingLinearLayout>().apply {
+                whenever(childCount).thenReturn(1)
+                whenever(getChildAt(any())).thenReturn(mockMessagingImageMessageForGroup)
+            }
+        val mockGroup: MessagingGroup =
+            mock<MessagingGroup>().apply {
+                whenever(messageContainer).thenReturn(mockMessageContainer)
+            }
+        val mockView: View =
+            mock<ConversationLayout>().apply {
+                whenever(messagingGroups).thenReturn(ArrayList<MessagingGroup>(listOf(mockGroup)))
+                whenever(imageMessageContainer).thenReturn(mockImageMessageContainer)
+                whenever(messagingLinearLayout).thenReturn(mockMessageContainer)
+
+                // These must be mocked as they're required to be nonnull.
+                whenever(requireViewById<View>(R.id.conversation_icon_container)).thenReturn(mock())
+                whenever(requireViewById<CachingIconView>(R.id.conversation_icon))
+                    .thenReturn(mock())
+                whenever(findViewById<CachingIconView>(R.id.icon)).thenReturn(mock())
+                whenever(requireViewById<View>(R.id.conversation_icon_badge_bg)).thenReturn(mock())
+                whenever(requireViewById<View>(R.id.expand_button)).thenReturn(mock())
+                whenever(requireViewById<View>(R.id.expand_button_container)).thenReturn(mock())
+                whenever(requireViewById<View>(R.id.conversation_icon_badge_ring))
+                    .thenReturn(mock())
+                whenever(requireViewById<View>(R.id.app_name_text)).thenReturn(mock())
+                whenever(requireViewById<View>(R.id.conversation_text)).thenReturn(mock())
+            }
+        return mockView
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMessagingTemplateViewWrapperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMessagingTemplateViewWrapperTest.kt
new file mode 100644
index 0000000..c0444b5
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMessagingTemplateViewWrapperTest.kt
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.row.wrapper
+
+import android.graphics.drawable.AnimatedImageDrawable
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.testing.TestableLooper.RunWithLooper
+import android.view.View
+import androidx.test.filters.SmallTest
+import com.android.internal.widget.MessagingGroup
+import com.android.internal.widget.MessagingImageMessage
+import com.android.internal.widget.MessagingLayout
+import com.android.internal.widget.MessagingLinearLayout
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import com.android.systemui.statusbar.notification.row.NotificationTestHelper
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.mock
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenever
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper
+class NotificationMessagingTemplateViewWrapperTest : SysuiTestCase() {
+
+    private lateinit var mRow: ExpandableNotificationRow
+    private lateinit var helper: NotificationTestHelper
+
+    @Before
+    fun setUp() {
+        allowTestableLooperAsMainThread()
+        helper = NotificationTestHelper(mContext, mDependency, TestableLooper.get(this))
+        mRow = helper.createRow()
+    }
+
+    @Test
+    fun setAnimationsRunning_Run() {
+        // Creates a mocked out NotificationEntry of MessagingLayout/MessagingStyle type,
+        // with a mock imageMessage.drawable embedded in its MessagingImageMessage.
+        val mockDrawable = mock<AnimatedImageDrawable>()
+        val mockLayoutView: View = fakeMessagingLayout(mockDrawable)
+
+        val wrapper: NotificationViewWrapper =
+            NotificationMessagingTemplateViewWrapper(mContext, mockLayoutView, mRow)
+        wrapper.setAnimationsRunning(true)
+
+        // Verifies that each AnimatedImageDrawable is started animating.
+        verify(mockDrawable).start()
+    }
+
+    @Test
+    fun setAnimationsRunning_Stop() {
+        // Creates a mocked out NotificationEntry of MessagingLayout/MessagingStyle type,
+        // with a mock imageMessage.drawable embedded in its MessagingImageMessage.
+        val mockDrawable = mock<AnimatedImageDrawable>()
+        val mockLayoutView: View = fakeMessagingLayout(mockDrawable)
+
+        val wrapper: NotificationViewWrapper =
+            NotificationMessagingTemplateViewWrapper(mContext, mockLayoutView, mRow)
+        wrapper.setAnimationsRunning(false)
+
+        // Verifies that each AnimatedImageDrawable is started animating.
+        verify(mockDrawable).stop()
+    }
+
+    private fun fakeMessagingLayout(mockDrawable: AnimatedImageDrawable): View {
+        val mockMessagingImageMessage: MessagingImageMessage =
+            mock<MessagingImageMessage>().apply { whenever(drawable).thenReturn(mockDrawable) }
+        val mockMessageContainer: MessagingLinearLayout =
+            mock<MessagingLinearLayout>().apply {
+                whenever(childCount).thenReturn(1)
+                whenever(getChildAt(any())).thenReturn(mockMessagingImageMessage)
+            }
+        val mockGroup: MessagingGroup =
+            mock<MessagingGroup>().apply {
+                whenever(messageContainer).thenReturn(mockMessageContainer)
+            }
+        val mockView: View =
+            mock<MessagingLayout>().apply {
+                whenever(messagingGroups).thenReturn(ArrayList<MessagingGroup>(listOf(mockGroup)))
+            }
+        return mockView
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java
index fd1944e..e41929f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java
@@ -26,14 +26,18 @@
 
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.notification.LegacySourceType;
+import com.android.systemui.statusbar.notification.SourceType;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
+import com.android.systemui.statusbar.notification.row.wrapper.NotificationHeaderViewWrapper;
 
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.List;
+
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
@@ -185,4 +189,57 @@
         Assert.assertEquals(1f, row2.getTopRoundness(), /* delta = */ 0f);
         Assert.assertEquals(1f, row2.getBottomRoundness(), /* delta = */ 0f);
     }
+
+    @Test
+    public void applyRoundnessAndInvalidate_should_be_immediately_applied_on_last_child_legacy() {
+        mChildrenContainer.useRoundnessSourceTypes(false);
+        List<ExpandableNotificationRow> children = mChildrenContainer.getAttachedChildren();
+        ExpandableNotificationRow notificationRow = children.get(children.size() - 1);
+        Assert.assertEquals(0f, mChildrenContainer.getBottomRoundness(), 0.001f);
+        Assert.assertEquals(0f, notificationRow.getBottomRoundness(), 0.001f);
+
+        mChildrenContainer.requestBottomRoundness(1f, SourceType.from(""), false);
+
+        Assert.assertEquals(1f, mChildrenContainer.getBottomRoundness(), 0.001f);
+        Assert.assertEquals(1f, notificationRow.getBottomRoundness(), 0.001f);
+    }
+
+    @Test
+    public void applyRoundnessAndInvalidate_should_be_immediately_applied_on_last_child() {
+        mChildrenContainer.useRoundnessSourceTypes(true);
+        List<ExpandableNotificationRow> children = mChildrenContainer.getAttachedChildren();
+        ExpandableNotificationRow notificationRow = children.get(children.size() - 1);
+        Assert.assertEquals(0f, mChildrenContainer.getBottomRoundness(), 0.001f);
+        Assert.assertEquals(0f, notificationRow.getBottomRoundness(), 0.001f);
+
+        mChildrenContainer.requestBottomRoundness(1f, SourceType.from(""), false);
+
+        Assert.assertEquals(1f, mChildrenContainer.getBottomRoundness(), 0.001f);
+        Assert.assertEquals(1f, notificationRow.getBottomRoundness(), 0.001f);
+    }
+
+    @Test
+    public void applyRoundnessAndInvalidate_should_be_immediately_applied_on_header() {
+        mChildrenContainer.useRoundnessSourceTypes(true);
+
+        NotificationHeaderViewWrapper header = mChildrenContainer.getNotificationHeaderWrapper();
+        Assert.assertEquals(0f, header.getTopRoundness(), 0.001f);
+
+        mChildrenContainer.requestTopRoundness(1f, SourceType.from(""), false);
+
+        Assert.assertEquals(1f, header.getTopRoundness(), 0.001f);
+    }
+
+    @Test
+    public void applyRoundnessAndInvalidate_should_be_immediately_applied_on_headerLowPriority() {
+        mChildrenContainer.useRoundnessSourceTypes(true);
+        mChildrenContainer.setIsLowPriority(true);
+
+        NotificationHeaderViewWrapper header = mChildrenContainer.getNotificationHeaderWrapper();
+        Assert.assertEquals(0f, header.getTopRoundness(), 0.001f);
+
+        mChildrenContainer.requestTopRoundness(1f, SourceType.from(""), false);
+
+        Assert.assertEquals(1f, header.getTopRoundness(), 0.001f);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
index 645052f..9f6f082 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
@@ -21,6 +21,7 @@
 import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_ALL;
 
 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.Mockito.RETURNS_DEEP_STUBS;
@@ -65,6 +66,7 @@
 import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProviderImpl;
 import com.android.systemui.statusbar.notification.collection.provider.VisibilityLocationProviderDelegator;
 import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
+import com.android.systemui.statusbar.notification.collection.render.NotifStats;
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
 import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -78,6 +80,7 @@
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.tuner.TunerService;
+import com.android.systemui.util.settings.SecureSettings;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -135,10 +138,14 @@
     @Mock private ShadeTransitionController mShadeTransitionController;
     @Mock private FeatureFlags mFeatureFlags;
     @Mock private NotificationTargetsHelper mNotificationTargetsHelper;
+    @Mock private SecureSettings mSecureSettings;
 
     @Captor
     private ArgumentCaptor<StatusBarStateController.StateListener> mStateListenerArgumentCaptor;
 
+    private final SeenNotificationsProviderImpl mSeenNotificationsProvider =
+            new SeenNotificationsProviderImpl();
+
     private NotificationStackScrollLayoutController mController;
 
     @Before
@@ -180,14 +187,15 @@
                 mUiEventLogger,
                 mRemoteInputManager,
                 mVisibilityLocationProviderDelegator,
-                new SeenNotificationsProviderImpl(),
+                mSeenNotificationsProvider,
                 mShadeController,
                 mJankMonitor,
                 mStackLogger,
                 mLogger,
                 mNotificationStackSizeCalculator,
                 mFeatureFlags,
-                mNotificationTargetsHelper
+                mNotificationTargetsHelper,
+                mSecureSettings
         );
 
         when(mNotificationStackScrollLayout.isAttachedToWindow()).thenReturn(true);
@@ -233,16 +241,14 @@
         mController.updateShowEmptyShadeView();
         verify(mNotificationStackScrollLayout).updateEmptyShadeView(
                 /* visible= */ true,
-                /* notifVisibleInShade= */ true,
-                /* areSeenNotifsFiltered= */false);
+                /* notifVisibleInShade= */ true);
 
         setupShowEmptyShadeViewState(false);
         reset(mNotificationStackScrollLayout);
         mController.updateShowEmptyShadeView();
         verify(mNotificationStackScrollLayout).updateEmptyShadeView(
                 /* visible= */ false,
-                /* notifVisibleInShade= */ true,
-                /* areSeenNotifsFiltered= */false);
+                /* notifVisibleInShade= */ true);
     }
 
     @Test
@@ -255,16 +261,14 @@
         mController.updateShowEmptyShadeView();
         verify(mNotificationStackScrollLayout).updateEmptyShadeView(
                 /* visible= */ true,
-                /* notifVisibleInShade= */ false,
-                /* areSeenNotifsFiltered= */false);
+                /* notifVisibleInShade= */ false);
 
         setupShowEmptyShadeViewState(false);
         reset(mNotificationStackScrollLayout);
         mController.updateShowEmptyShadeView();
         verify(mNotificationStackScrollLayout).updateEmptyShadeView(
                 /* visible= */ false,
-                /* notifVisibleInShade= */ false,
-                /* areSeenNotifsFiltered= */false);
+                /* notifVisibleInShade= */ false);
     }
 
     @Test
@@ -283,16 +287,14 @@
         mController.updateShowEmptyShadeView();
         verify(mNotificationStackScrollLayout).updateEmptyShadeView(
                 /* visible= */ true,
-                /* notifVisibleInShade= */ false,
-                /* areSeenNotifsFiltered= */false);
+                /* notifVisibleInShade= */ false);
 
         mController.setQsFullScreen(true);
         reset(mNotificationStackScrollLayout);
         mController.updateShowEmptyShadeView();
         verify(mNotificationStackScrollLayout).updateEmptyShadeView(
                 /* visible= */ true,
-                /* notifVisibleInShade= */ false,
-                /* areSeenNotifsFiltered= */false);
+                /* notifVisibleInShade= */ false);
     }
 
     @Test
@@ -400,6 +402,17 @@
         verify(mNotificationStackScrollLayout).setIsRemoteInputActive(true);
     }
 
+    @Test
+    public void testSetNotifStats_updatesHasFilteredOutSeenNotifications() {
+        when(mNotifPipelineFlags.getShouldFilterUnseenNotifsOnKeyguard()).thenReturn(true);
+        mSeenNotificationsProvider.setHasFilteredOutSeenNotifications(true);
+        mController.attach(mNotificationStackScrollLayout);
+        mController.getNotifStackController().setNotifStats(NotifStats.getEmpty());
+        verify(mNotificationStackScrollLayout).setHasFilteredOutSeenNotifications(true);
+        verify(mNotificationStackScrollLayout).updateFooter();
+        verify(mNotificationStackScrollLayout).updateEmptyShadeView(anyBoolean(), anyBoolean());
+    }
+
     private LogMaker logMatcher(int category, int type) {
         return argThat(new LogMatcher(category, type));
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 7622549..dd7143a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -30,6 +30,7 @@
 import static junit.framework.Assert.assertTrue;
 
 import static org.junit.Assert.assertFalse;
+import static org.mockito.AdditionalMatchers.not;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyFloat;
@@ -53,6 +54,7 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.TextView;
 
 import androidx.test.annotation.UiThreadTest;
 import androidx.test.filters.SmallTest;
@@ -328,7 +330,7 @@
     public void updateEmptyView_dndSuppressing() {
         when(mEmptyShadeView.willBeGone()).thenReturn(true);
 
-        mStackScroller.updateEmptyShadeView(true, true, false);
+        mStackScroller.updateEmptyShadeView(true, true);
 
         verify(mEmptyShadeView).setText(R.string.dnd_suppressing_shade_text);
     }
@@ -338,7 +340,7 @@
         mStackScroller.setEmptyShadeView(mEmptyShadeView);
         when(mEmptyShadeView.willBeGone()).thenReturn(true);
 
-        mStackScroller.updateEmptyShadeView(true, false, false);
+        mStackScroller.updateEmptyShadeView(true, false);
 
         verify(mEmptyShadeView).setText(R.string.empty_shade_text);
     }
@@ -347,10 +349,10 @@
     public void updateEmptyView_noNotificationsToDndSuppressing() {
         mStackScroller.setEmptyShadeView(mEmptyShadeView);
         when(mEmptyShadeView.willBeGone()).thenReturn(true);
-        mStackScroller.updateEmptyShadeView(true, false, false);
+        mStackScroller.updateEmptyShadeView(true, false);
         verify(mEmptyShadeView).setText(R.string.empty_shade_text);
 
-        mStackScroller.updateEmptyShadeView(true, true, false);
+        mStackScroller.updateEmptyShadeView(true, true);
         verify(mEmptyShadeView).setText(R.string.dnd_suppressing_shade_text);
     }
 
@@ -818,6 +820,29 @@
         assertEquals(0f, mAmbientState.getStackY());
     }
 
+    @Test
+    public void hasFilteredOutSeenNotifs_updateFooter() {
+        mStackScroller.setCurrentUserSetup(true);
+
+        // add footer
+        mStackScroller.inflateFooterView();
+        TextView footerLabel =
+                mStackScroller.mFooterView.requireViewById(R.id.unlock_prompt_footer);
+
+        mStackScroller.setHasFilteredOutSeenNotifications(true);
+        mStackScroller.updateFooter();
+
+        assertThat(footerLabel.getVisibility()).isEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void hasFilteredOutSeenNotifs_updateEmptyShadeView() {
+        mStackScroller.setHasFilteredOutSeenNotifications(true);
+        mStackScroller.updateEmptyShadeView(true, false);
+
+        verify(mEmptyShadeView).setFooterText(not(0));
+    }
+
     private void setBarStateForTest(int state) {
         // Can't inject this through the listener or we end up on the actual implementation
         // rather than the mock because the spy just coppied the anonymous inner /shruggie.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
index 4ccbc6d..091bb54 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
@@ -24,6 +24,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.isNotNull;
 import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.doReturn;
@@ -74,6 +75,7 @@
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 import org.mockito.Spy;
+import org.mockito.stubbing.Answer;
 
 import java.util.Collections;
 import java.util.List;
@@ -115,8 +117,10 @@
     @Spy private PackageManager mPackageManager;
     private final boolean mIsReduceBrightColorsAvailable = true;
 
-    private AutoTileManager mAutoTileManager;
+    private AutoTileManager mAutoTileManager; // under test
+
     private SecureSettings mSecureSettings;
+    private ManagedProfileController.Callback mManagedProfileCallback;
 
     @Before
     public void setUp() throws Exception {
@@ -303,7 +307,7 @@
 
         InOrder inOrderManagedProfile = inOrder(mManagedProfileController);
         inOrderManagedProfile.verify(mManagedProfileController).removeCallback(any());
-        inOrderManagedProfile.verify(mManagedProfileController, never()).addCallback(any());
+        inOrderManagedProfile.verify(mManagedProfileController).addCallback(any());
 
         if (ColorDisplayManager.isNightDisplayAvailable(mContext)) {
             InOrder inOrderNightDisplay = inOrder(mNightDisplayListener);
@@ -504,6 +508,40 @@
     }
 
     @Test
+    public void managedProfileAdded_tileAdded() {
+        when(mAutoAddTracker.isAdded(eq("work"))).thenReturn(false);
+        mAutoTileManager = createAutoTileManager(mContext);
+        Mockito.doAnswer((Answer<Object>) invocation -> {
+            mManagedProfileCallback = invocation.getArgument(0);
+            return null;
+        }).when(mManagedProfileController).addCallback(any());
+        mAutoTileManager.init();
+        when(mManagedProfileController.hasActiveProfile()).thenReturn(true);
+
+        mManagedProfileCallback.onManagedProfileChanged();
+
+        verify(mQsTileHost, times(1)).addTile(eq("work"));
+        verify(mAutoAddTracker, times(1)).setTileAdded(eq("work"));
+    }
+
+    @Test
+    public void managedProfileRemoved_tileRemoved() {
+        when(mAutoAddTracker.isAdded(eq("work"))).thenReturn(true);
+        mAutoTileManager = createAutoTileManager(mContext);
+        Mockito.doAnswer((Answer<Object>) invocation -> {
+            mManagedProfileCallback = invocation.getArgument(0);
+            return null;
+        }).when(mManagedProfileController).addCallback(any());
+        mAutoTileManager.init();
+        when(mManagedProfileController.hasActiveProfile()).thenReturn(false);
+
+        mManagedProfileCallback.onManagedProfileChanged();
+
+        verify(mQsTileHost, times(1)).removeTile(eq("work"));
+        verify(mAutoAddTracker, times(1)).setTileRemoved(eq("work"));
+    }
+
+    @Test
     public void testEmptyArray_doesNotCrash() {
         mContext.getOrCreateTestableResources().addOverride(
                 R.array.config_quickSettingsAutoAdd, new String[0]);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
index 74f8c61..daf7dd0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
@@ -57,6 +59,7 @@
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.VibratorHelper;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.time.FakeSystemClock;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -122,6 +125,7 @@
     private VibratorHelper mVibratorHelper;
     @Mock
     private BiometricUnlockLogger mLogger;
+    private final FakeSystemClock mSystemClock = new FakeSystemClock();
     private BiometricUnlockController mBiometricUnlockController;
 
     @Before
@@ -144,7 +148,9 @@
                 mMetricsLogger, mDumpManager, mPowerManager, mLogger,
                 mNotificationMediaManager, mWakefulnessLifecycle, mScreenLifecycle,
                 mAuthController, mStatusBarStateController, mKeyguardUnlockAnimationController,
-                mSessionTracker, mLatencyTracker, mScreenOffAnimationController, mVibratorHelper);
+                mSessionTracker, mLatencyTracker, mScreenOffAnimationController, mVibratorHelper,
+                mSystemClock
+        );
         mBiometricUnlockController.setKeyguardViewController(mStatusBarKeyguardViewManager);
         mBiometricUnlockController.addBiometricModeListener(mBiometricModeListener);
         when(mUpdateMonitor.getStrongAuthTracker()).thenReturn(mStrongAuthTracker);
@@ -207,7 +213,7 @@
 
         verify(mKeyguardViewMediator).onWakeAndUnlocking();
         assertThat(mBiometricUnlockController.getMode())
-                .isEqualTo(BiometricUnlockController.MODE_WAKE_AND_UNLOCK);
+                .isEqualTo(MODE_WAKE_AND_UNLOCK);
     }
 
     @Test
@@ -457,4 +463,83 @@
         // THEN wakeup the device
         verify(mPowerManager).wakeUp(anyLong(), anyInt(), anyString());
     }
+
+    @Test
+    public void onSideFingerprintSuccess_recentPowerButtonPress_noHaptic() {
+        // GIVEN side fingerprint enrolled, last wake reason was power button
+        when(mAuthController.isSfpsEnrolled(anyInt())).thenReturn(true);
+        when(mWakefulnessLifecycle.getLastWakeReason())
+                .thenReturn(PowerManager.WAKE_REASON_POWER_BUTTON);
+
+        // GIVEN last wake time just occurred
+        when(mWakefulnessLifecycle.getLastWakeTime()).thenReturn(mSystemClock.uptimeMillis());
+
+        // WHEN biometric fingerprint succeeds
+        givenFingerprintModeUnlockCollapsing();
+        mBiometricUnlockController.startWakeAndUnlock(BiometricSourceType.FINGERPRINT,
+                true);
+
+        // THEN DO NOT vibrate the device
+        verify(mVibratorHelper, never()).vibrateAuthSuccess(anyString());
+    }
+
+    @Test
+    public void onSideFingerprintSuccess_oldPowerButtonPress_playHaptic() {
+        // GIVEN side fingerprint enrolled, last wake reason was power button
+        when(mAuthController.isSfpsEnrolled(anyInt())).thenReturn(true);
+        when(mWakefulnessLifecycle.getLastWakeReason())
+                .thenReturn(PowerManager.WAKE_REASON_POWER_BUTTON);
+
+        // GIVEN last wake time was 500ms ago
+        when(mWakefulnessLifecycle.getLastWakeTime()).thenReturn(mSystemClock.uptimeMillis());
+        mSystemClock.advanceTime(500);
+
+        // WHEN biometric fingerprint succeeds
+        givenFingerprintModeUnlockCollapsing();
+        mBiometricUnlockController.startWakeAndUnlock(BiometricSourceType.FINGERPRINT,
+                true);
+
+        // THEN vibrate the device
+        verify(mVibratorHelper).vibrateAuthSuccess(anyString());
+    }
+
+    @Test
+    public void onSideFingerprintSuccess_recentGestureWakeUp_playHaptic() {
+        // GIVEN side fingerprint enrolled, wakeup just happened
+        when(mAuthController.isSfpsEnrolled(anyInt())).thenReturn(true);
+        when(mWakefulnessLifecycle.getLastWakeTime()).thenReturn(mSystemClock.uptimeMillis());
+
+        // GIVEN last wake reason was from a gesture
+        when(mWakefulnessLifecycle.getLastWakeReason())
+                .thenReturn(PowerManager.WAKE_REASON_GESTURE);
+
+        // WHEN biometric fingerprint succeeds
+        givenFingerprintModeUnlockCollapsing();
+        mBiometricUnlockController.startWakeAndUnlock(BiometricSourceType.FINGERPRINT,
+                true);
+
+        // THEN vibrate the device
+        verify(mVibratorHelper).vibrateAuthSuccess(anyString());
+    }
+
+    @Test
+    public void onSideFingerprintFail_alwaysPlaysHaptic() {
+        // GIVEN side fingerprint enrolled, last wake reason was recent power button
+        when(mAuthController.isSfpsEnrolled(anyInt())).thenReturn(true);
+        when(mWakefulnessLifecycle.getLastWakeReason())
+                .thenReturn(PowerManager.WAKE_REASON_POWER_BUTTON);
+        when(mWakefulnessLifecycle.getLastWakeTime()).thenReturn(mSystemClock.uptimeMillis());
+
+        // WHEN biometric fingerprint fails
+        mBiometricUnlockController.onBiometricAuthFailed(BiometricSourceType.FINGERPRINT);
+
+        // THEN always vibrate the device
+        verify(mVibratorHelper).vibrateAuthError(anyString());
+    }
+
+    private void givenFingerprintModeUnlockCollapsing() {
+        when(mUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
+        when(mUpdateMonitor.isDeviceInteractive()).thenReturn(true);
+        when(mKeyguardStateController.isShowing()).thenReturn(true);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
index 3fccd37..b879cf2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
@@ -25,8 +25,10 @@
 import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityManager;
 import android.app.StatusBarManager;
 import android.os.PowerManager;
+import android.os.UserHandle;
 import android.os.Vibrator;
 import android.testing.AndroidTestingRunner;
 import android.view.InsetsVisibilities;
@@ -41,6 +43,7 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shade.CameraLauncher;
 import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.shade.ShadeController;
@@ -88,6 +91,7 @@
     @Mock private StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
     @Mock private SystemBarAttributesListener mSystemBarAttributesListener;
     @Mock private Lazy<CameraLauncher> mCameraLauncherLazy;
+    @Mock private UserTracker mUserTracker;
 
     CentralSurfacesCommandQueueCallbacks mSbcqCallbacks;
 
@@ -120,8 +124,11 @@
                 new DisableFlagsLogger(),
                 DEFAULT_DISPLAY,
                 mSystemBarAttributesListener,
-                mCameraLauncherLazy);
+                mCameraLauncherLazy,
+                mUserTracker);
 
+        when(mUserTracker.getUserHandle()).thenReturn(
+                UserHandle.of(ActivityManager.getCurrentUser()));
         when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
         when(mRemoteInputQuickSettingsDisabler.adjustDisableFlags(anyInt()))
                 .thenAnswer((Answer<Integer>) invocation -> invocation.getArgument(0));
@@ -140,7 +147,7 @@
 
         // Trying to open it does nothing.
         mSbcqCallbacks.animateExpandNotificationsPanel();
-        verify(mNotificationPanelViewController, never()).expandWithoutQs();
+        verify(mNotificationPanelViewController, never()).expandShadeToNotifications();
         mSbcqCallbacks.animateExpandSettingsPanel(null);
         verify(mNotificationPanelViewController, never()).expand(anyBoolean());
     }
@@ -158,7 +165,7 @@
 
         // Can now be opened.
         mSbcqCallbacks.animateExpandNotificationsPanel();
-        verify(mNotificationPanelViewController).expandWithoutQs();
+        verify(mNotificationPanelViewController).expandShadeToNotifications();
         mSbcqCallbacks.animateExpandSettingsPanel(null);
         verify(mNotificationPanelViewController).expandWithQs();
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index 09254ad..b1363a0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -44,6 +44,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityManager;
 import android.app.IWallpaperManager;
 import android.app.Notification;
 import android.app.NotificationChannel;
@@ -110,6 +111,7 @@
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
 import com.android.systemui.keyguard.ui.viewmodel.LightRevealScrimViewModel;
 import com.android.systemui.navigationbar.NavigationBarController;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
@@ -117,6 +119,7 @@
 import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.recents.ScreenPinningRequest;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.settings.brightness.BrightnessSliderController;
 import com.android.systemui.shade.CameraLauncher;
 import com.android.systemui.shade.NotificationPanelView;
@@ -177,8 +180,6 @@
 import com.android.wm.shell.bubbles.Bubbles;
 import com.android.wm.shell.startingsurface.StartingSurface;
 
-import dagger.Lazy;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -191,6 +192,8 @@
 import java.io.PrintWriter;
 import java.util.Optional;
 
+import dagger.Lazy;
+
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper(setAsMainLooper = true)
@@ -297,6 +300,7 @@
     @Mock private WiredChargingRippleController mWiredChargingRippleController;
     @Mock private Lazy<CameraLauncher> mCameraLauncherLazy;
     @Mock private CameraLauncher mCameraLauncher;
+    @Mock private AlternateBouncerInteractor mAlternateBouncerInteractor;
     /**
      * The process of registering/unregistering a predictive back callback requires a
      * ViewRootImpl, which is present IRL, but may be missing during a Mockito unit test.
@@ -304,6 +308,7 @@
      */
     @Mock private ViewRootImpl mViewRootImpl;
     @Mock private WindowOnBackInvokedDispatcher mOnBackInvokedDispatcher;
+    @Mock private UserTracker mUserTracker;
     @Captor private ArgumentCaptor<OnBackInvokedCallback> mOnBackInvokedCallback;
     @Mock IPowerManager mPowerManagerService;
 
@@ -319,6 +324,10 @@
     public void setup() throws Exception {
         MockitoAnnotations.initMocks(this);
 
+        // CentralSurfacesImpl's runtime flag check fails if the flag is absent.
+        // This value is unused, because test manifest is opted in.
+        mFeatureFlags.set(Flags.WM_ENABLE_PREDICTIVE_BACK_SYSUI, false);
+
         IThermalService thermalService = mock(IThermalService.class);
         mPowerManager = new PowerManager(mContext, mPowerManagerService, thermalService,
                 Handler.createAsync(Looper.myLooper()));
@@ -336,7 +345,8 @@
                         new Handler(TestableLooper.get(this).getLooper()),
                         mock(NotifPipelineFlags.class),
                         mock(KeyguardNotificationVisibilityProvider.class),
-                        mock(UiEventLogger.class));
+                        mock(UiEventLogger.class),
+                        mUserTracker);
 
         mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class));
         mContext.addMockSystemService(FingerprintManager.class, mock(FingerprintManager.class));
@@ -378,7 +388,8 @@
         }).when(mStatusBarKeyguardViewManager).addAfterKeyguardGoneRunnable(any());
 
         mWakefulnessLifecycle =
-                new WakefulnessLifecycle(mContext, mIWallpaperManager, mDumpManager);
+                new WakefulnessLifecycle(mContext, mIWallpaperManager, mFakeSystemClock,
+                        mDumpManager);
         mWakefulnessLifecycle.dispatchStartedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
         mWakefulnessLifecycle.dispatchFinishedWakingUp();
 
@@ -416,6 +427,9 @@
 
         when(mOperatorNameViewControllerFactory.create(any()))
                 .thenReturn(mOperatorNameViewController);
+        when(mUserTracker.getUserId()).thenReturn(ActivityManager.getCurrentUser());
+        when(mUserTracker.getUserHandle()).thenReturn(
+                UserHandle.of(ActivityManager.getCurrentUser()));
 
         mCentralSurfaces = new CentralSurfacesImpl(
                 mContext,
@@ -504,7 +518,10 @@
                 mWiredChargingRippleController,
                 mDreamManager,
                 mCameraLauncherLazy,
-                () -> mLightRevealScrimViewModel) {
+                () -> mLightRevealScrimViewModel,
+                mAlternateBouncerInteractor,
+                mUserTracker
+        ) {
             @Override
             protected ViewRootImpl getViewRootImpl() {
                 return mViewRootImpl;
@@ -539,6 +556,7 @@
         mCentralSurfaces.startKeyguard();
         mInitController.executePostInitTasks();
         notificationLogger.setUpWithContainer(mNotificationListContainer);
+        mCentralSurfaces.registerCallbacks();
     }
 
     @Test
@@ -1274,7 +1292,8 @@
                 Handler mainHandler,
                 NotifPipelineFlags flags,
                 KeyguardNotificationVisibilityProvider keyguardNotificationVisibilityProvider,
-                UiEventLogger uiEventLogger) {
+                UiEventLogger uiEventLogger,
+                UserTracker userTracker) {
             super(
                     contentResolver,
                     powerManager,
@@ -1288,7 +1307,8 @@
                     mainHandler,
                     flags,
                     keyguardNotificationVisibilityProvider,
-                    uiEventLogger
+                    uiEventLogger,
+                    userTracker
             );
             mUseHeadsUp = true;
         }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
index 077b41a..eb5edbc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
@@ -23,8 +23,13 @@
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityManager;
 import android.content.res.Resources;
 import android.hardware.display.AmbientDisplayConfiguration;
 import android.os.Handler;
@@ -39,10 +44,10 @@
 import com.android.systemui.doze.AlwaysOnDisplayPolicy;
 import com.android.systemui.doze.DozeScreenState;
 import com.android.systemui.dump.DumpManager;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.unfold.FoldAodAnimationController;
@@ -52,6 +57,8 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
@@ -69,7 +76,6 @@
     @Mock private PowerManager mPowerManager;
     @Mock private TunerService mTunerService;
     @Mock private BatteryController mBatteryController;
-    @Mock private FeatureFlags mFeatureFlags;
     @Mock private DumpManager mDumpManager;
     @Mock private ScreenOffAnimationController mScreenOffAnimationController;
     @Mock private FoldAodAnimationController mFoldAodAnimationController;
@@ -78,6 +84,8 @@
     @Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     @Mock private StatusBarStateController mStatusBarStateController;
     @Mock private ConfigurationController mConfigurationController;
+    @Mock private UserTracker mUserTracker;
+    @Captor private ArgumentCaptor<BatteryStateChangeCallback> mBatteryStateChangeCallback;
 
     /**
      * The current value of PowerManager's dozeAfterScreenOff property.
@@ -102,6 +110,7 @@
 
         when(mSysUIUnfoldComponent.getFoldAodAnimationController())
                 .thenReturn(mFoldAodAnimationController);
+        when(mUserTracker.getUserId()).thenReturn(ActivityManager.getCurrentUser());
 
         mDozeParameters = new DozeParameters(
             mContext,
@@ -113,16 +122,17 @@
             mBatteryController,
             mTunerService,
             mDumpManager,
-            mFeatureFlags,
             mScreenOffAnimationController,
             Optional.of(mSysUIUnfoldComponent),
             mUnlockedScreenOffAnimationController,
             mKeyguardUpdateMonitor,
             mConfigurationController,
-            mStatusBarStateController
+            mStatusBarStateController,
+            mUserTracker
         );
 
-        when(mFeatureFlags.isEnabled(Flags.LOCKSCREEN_ANIMATIONS)).thenReturn(true);
+        verify(mBatteryController).addCallback(mBatteryStateChangeCallback.capture());
+
         setAodEnabledForTest(true);
         setShouldControlUnlockedScreenOffForTest(true);
         setDisplayNeedsBlankingForTest(false);
@@ -173,6 +183,29 @@
         assertThat(mDozeParameters.getAlwaysOn()).isFalse();
     }
 
+    @Test
+    public void testGetAlwaysOn_whenBatterySaverCallback() {
+        DozeParameters.Callback callback = mock(DozeParameters.Callback.class);
+        mDozeParameters.addCallback(callback);
+
+        when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(true);
+        when(mBatteryController.isAodPowerSave()).thenReturn(true);
+
+        // Both lines should trigger an event
+        mDozeParameters.onTuningChanged(Settings.Secure.DOZE_ALWAYS_ON, "1");
+        mBatteryStateChangeCallback.getValue().onPowerSaveChanged(true);
+
+        verify(callback, times(2)).onAlwaysOnChange();
+        assertThat(mDozeParameters.getAlwaysOn()).isFalse();
+
+        reset(callback);
+        when(mBatteryController.isAodPowerSave()).thenReturn(false);
+        mBatteryStateChangeCallback.getValue().onPowerSaveChanged(true);
+
+        verify(callback).onAlwaysOnChange();
+        assertThat(mDozeParameters.getAlwaysOn()).isTrue();
+    }
+
     /**
      * PowerManager.setDozeAfterScreenOff(true) means we are not controlling screen off, and calling
      * it with false means we are. Confusing, but sure - make sure that we call PowerManager with
@@ -196,17 +229,6 @@
     }
 
     @Test
-    public void testControlUnlockedScreenOffAnimationDisabled_dozeAfterScreenOff() {
-        when(mFeatureFlags.isEnabled(Flags.LOCKSCREEN_ANIMATIONS)).thenReturn(false);
-
-        assertFalse(mDozeParameters.shouldControlUnlockedScreenOff());
-
-        // Trigger the setter for the current value.
-        mDozeParameters.setControlScreenOffAnimation(mDozeParameters.shouldControlScreenOff());
-        assertFalse(mDozeParameters.shouldControlScreenOff());
-    }
-
-    @Test
     public void propagatesAnimateScreenOff_noAlwaysOn() {
         setAodEnabledForTest(false);
         setDisplayNeedsBlankingForTest(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
index df7ee43..2f49535 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
@@ -16,8 +16,8 @@
 
 package com.android.systemui.statusbar.phone;
 
-import static com.android.systemui.statusbar.phone.KeyguardBouncer.EXPANSION_HIDDEN;
-import static com.android.systemui.statusbar.phone.KeyguardBouncer.EXPANSION_VISIBLE;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_HIDDEN;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_VISIBLE;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -58,8 +58,8 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.FalsingCollector;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
+import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
-import com.android.systemui.statusbar.phone.KeyguardBouncer.PrimaryBouncerExpansionCallback;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import org.junit.Assert;
@@ -87,7 +87,7 @@
     @Mock
     private KeyguardHostViewController mKeyguardHostViewController;
     @Mock
-    private KeyguardBouncer.PrimaryBouncerExpansionCallback mExpansionCallback;
+    private PrimaryBouncerExpansionCallback mExpansionCallback;
     @Mock
     private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     @Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt
new file mode 100644
index 0000000..3e90ed9
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt
@@ -0,0 +1,255 @@
+/*
+ * 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.phone
+
+import android.content.pm.PackageManager
+import android.test.suitebuilder.annotation.SmallTest
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.shade.ShadeExpansionStateManager
+import com.android.systemui.statusbar.NotificationLockscreenUserManager
+import com.android.systemui.statusbar.policy.DevicePostureController
+import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_CLOSED
+import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_FLIPPED
+import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_OPENED
+import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_UNKNOWN
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.tuner.TunerService
+import com.google.common.truth.Truth.assertThat
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.reset
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenever
+import org.mockito.junit.MockitoJUnit
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class KeyguardBypassControllerTest : SysuiTestCase() {
+
+    private lateinit var keyguardBypassController: KeyguardBypassController
+    private lateinit var postureControllerCallback: DevicePostureController.Callback
+    @Mock private lateinit var tunerService: TunerService
+    @Mock private lateinit var statusBarStateController: StatusBarStateController
+    @Mock private lateinit var lockscreenUserManager: NotificationLockscreenUserManager
+    @Mock private lateinit var keyguardStateController: KeyguardStateController
+    @Mock private lateinit var shadeExpansionStateManager: ShadeExpansionStateManager
+    @Mock private lateinit var devicePostureController: DevicePostureController
+    @Mock private lateinit var dumpManager: DumpManager
+    @Mock private lateinit var packageManager: PackageManager
+    @Captor
+    private val postureCallbackCaptor =
+        ArgumentCaptor.forClass(DevicePostureController.Callback::class.java)
+    @JvmField @Rule val mockito = MockitoJUnit.rule()
+
+    @Before
+    fun setUp() {
+        context.setMockPackageManager(packageManager)
+        whenever(packageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true)
+        whenever(keyguardStateController.isFaceAuthEnabled).thenReturn(true)
+    }
+
+    @After
+    fun tearDown() {
+        reset(devicePostureController)
+        reset(keyguardStateController)
+    }
+
+    private fun defaultConfigPostureClosed() {
+        context.orCreateTestableResources.addOverride(
+            R.integer.config_face_auth_supported_posture,
+            DEVICE_POSTURE_CLOSED
+        )
+        initKeyguardBypassController()
+        verify(devicePostureController).addCallback(postureCallbackCaptor.capture())
+        postureControllerCallback = postureCallbackCaptor.value
+    }
+
+    private fun defaultConfigPostureOpened() {
+        context.orCreateTestableResources.addOverride(
+            R.integer.config_face_auth_supported_posture,
+            DEVICE_POSTURE_OPENED
+        )
+        initKeyguardBypassController()
+        verify(devicePostureController).addCallback(postureCallbackCaptor.capture())
+        postureControllerCallback = postureCallbackCaptor.value
+    }
+
+    private fun defaultConfigPostureFlipped() {
+        context.orCreateTestableResources.addOverride(
+            R.integer.config_face_auth_supported_posture,
+            DEVICE_POSTURE_FLIPPED
+        )
+        initKeyguardBypassController()
+        verify(devicePostureController).addCallback(postureCallbackCaptor.capture())
+        postureControllerCallback = postureCallbackCaptor.value
+    }
+
+    private fun defaultConfigPostureUnknown() {
+        context.orCreateTestableResources.addOverride(
+            R.integer.config_face_auth_supported_posture,
+            DEVICE_POSTURE_UNKNOWN
+        )
+        initKeyguardBypassController()
+        verify(devicePostureController, never()).addCallback(postureCallbackCaptor.capture())
+    }
+
+    private fun initKeyguardBypassController() {
+        keyguardBypassController =
+            KeyguardBypassController(
+                context,
+                tunerService,
+                statusBarStateController,
+                lockscreenUserManager,
+                keyguardStateController,
+                shadeExpansionStateManager,
+                devicePostureController,
+                dumpManager
+            )
+    }
+
+    @Test
+    fun configDevicePostureClosed_matchState_isPostureAllowedForFaceAuth_returnTrue() {
+        defaultConfigPostureClosed()
+
+        postureControllerCallback.onPostureChanged(DEVICE_POSTURE_CLOSED)
+
+        assertThat(keyguardBypassController.isPostureAllowedForFaceAuth()).isTrue()
+    }
+
+    @Test
+    fun configDevicePostureOpen_matchState_isPostureAllowedForFaceAuth_returnTrue() {
+        defaultConfigPostureOpened()
+
+        postureControllerCallback.onPostureChanged(DEVICE_POSTURE_OPENED)
+
+        assertThat(keyguardBypassController.isPostureAllowedForFaceAuth()).isTrue()
+    }
+
+    @Test
+    fun configDevicePostureFlipped_matchState_isPostureAllowedForFaceAuth_returnTrue() {
+        defaultConfigPostureFlipped()
+
+        postureControllerCallback.onPostureChanged(DEVICE_POSTURE_FLIPPED)
+
+        assertThat(keyguardBypassController.isPostureAllowedForFaceAuth()).isTrue()
+    }
+
+    @Test
+    fun configDevicePostureClosed_changeOpened_isPostureAllowedForFaceAuth_returnFalse() {
+        defaultConfigPostureClosed()
+
+        postureControllerCallback.onPostureChanged(DEVICE_POSTURE_OPENED)
+
+        assertThat(keyguardBypassController.isPostureAllowedForFaceAuth()).isFalse()
+    }
+
+    @Test
+    fun configDevicePostureClosed_changeFlipped_isPostureAllowedForFaceAuth_returnFalse() {
+        defaultConfigPostureClosed()
+
+        postureControllerCallback.onPostureChanged(DEVICE_POSTURE_FLIPPED)
+
+        assertThat(keyguardBypassController.isPostureAllowedForFaceAuth()).isFalse()
+    }
+
+    @Test
+    fun configDevicePostureOpened_changeClosed_isPostureAllowedForFaceAuth_returnFalse() {
+        defaultConfigPostureOpened()
+
+        postureControllerCallback.onPostureChanged(DEVICE_POSTURE_CLOSED)
+
+        assertThat(keyguardBypassController.isPostureAllowedForFaceAuth()).isFalse()
+    }
+
+    @Test
+    fun configDevicePostureOpened_changeFlipped_isPostureAllowedForFaceAuth_returnFalse() {
+        defaultConfigPostureOpened()
+
+        postureControllerCallback.onPostureChanged(DEVICE_POSTURE_FLIPPED)
+
+        assertThat(keyguardBypassController.isPostureAllowedForFaceAuth()).isFalse()
+    }
+
+    @Test
+    fun configDevicePostureFlipped_changeClosed_isPostureAllowedForFaceAuth_returnFalse() {
+        defaultConfigPostureFlipped()
+
+        postureControllerCallback.onPostureChanged(DEVICE_POSTURE_CLOSED)
+
+        assertThat(keyguardBypassController.isPostureAllowedForFaceAuth()).isFalse()
+    }
+
+    @Test
+    fun configDevicePostureFlipped_changeOpened_isPostureAllowedForFaceAuth_returnFalse() {
+        defaultConfigPostureFlipped()
+
+        postureControllerCallback.onPostureChanged(DEVICE_POSTURE_OPENED)
+
+        assertThat(keyguardBypassController.isPostureAllowedForFaceAuth()).isFalse()
+    }
+
+    @Test
+    fun defaultConfigPostureClosed_canOverrideByPassAlways_shouldReturnFalse() {
+        context.orCreateTestableResources.addOverride(
+            R.integer.config_face_unlock_bypass_override,
+            1 /* FACE_UNLOCK_BYPASS_ALWAYS */
+        )
+
+        defaultConfigPostureClosed()
+
+        postureControllerCallback.onPostureChanged(DEVICE_POSTURE_OPENED)
+
+        assertThat(keyguardBypassController.bypassEnabled).isFalse()
+    }
+
+    @Test
+    fun defaultConfigPostureUnknown_canNotOverrideByPassAlways_shouldReturnTrue() {
+        context.orCreateTestableResources.addOverride(
+            R.integer.config_face_unlock_bypass_override,
+            1 /* FACE_UNLOCK_BYPASS_ALWAYS */
+        )
+
+        defaultConfigPostureUnknown()
+
+        assertThat(keyguardBypassController.bypassEnabled).isTrue()
+    }
+
+    @Test
+    fun defaultConfigPostureUnknown_canNotOverrideByPassNever_shouldReturnFalse() {
+        context.orCreateTestableResources.addOverride(
+            R.integer.config_face_unlock_bypass_override,
+            2 /* FACE_UNLOCK_BYPASS_NEVER */
+        )
+
+        defaultConfigPostureUnknown()
+
+        assertThat(keyguardBypassController.bypassEnabled).isFalse()
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt
index 64dee95..305b9fe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt
@@ -31,6 +31,7 @@
 import com.android.systemui.privacy.PrivacyItemController
 import com.android.systemui.privacy.logging.PrivacyLogger
 import com.android.systemui.screenrecord.RecordingController
+import com.android.systemui.settings.UserTracker
 import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.policy.BluetoothController
 import com.android.systemui.statusbar.policy.CastController
@@ -71,61 +72,37 @@
         private const val ALARM_SLOT = "alarm"
     }
 
-    @Mock
-    private lateinit var iconController: StatusBarIconController
-    @Mock
-    private lateinit var commandQueue: CommandQueue
-    @Mock
-    private lateinit var broadcastDispatcher: BroadcastDispatcher
-    @Mock
-    private lateinit var castController: CastController
-    @Mock
-    private lateinit var hotspotController: HotspotController
-    @Mock
-    private lateinit var bluetoothController: BluetoothController
-    @Mock
-    private lateinit var nextAlarmController: NextAlarmController
-    @Mock
-    private lateinit var userInfoController: UserInfoController
-    @Mock
-    private lateinit var rotationLockController: RotationLockController
-    @Mock
-    private lateinit var dataSaverController: DataSaverController
-    @Mock
-    private lateinit var zenModeController: ZenModeController
-    @Mock
-    private lateinit var deviceProvisionedController: DeviceProvisionedController
-    @Mock
-    private lateinit var keyguardStateController: KeyguardStateController
-    @Mock
-    private lateinit var locationController: LocationController
-    @Mock
-    private lateinit var sensorPrivacyController: SensorPrivacyController
-    @Mock
-    private lateinit var iActivityManager: IActivityManager
-    @Mock
-    private lateinit var alarmManager: AlarmManager
-    @Mock
-    private lateinit var userManager: UserManager
-    @Mock
-    private lateinit var devicePolicyManager: DevicePolicyManager
-    @Mock
-    private lateinit var recordingController: RecordingController
-    @Mock
-    private lateinit var telecomManager: TelecomManager
-    @Mock
-    private lateinit var sharedPreferences: SharedPreferences
-    @Mock
-    private lateinit var dateFormatUtil: DateFormatUtil
+    @Mock private lateinit var iconController: StatusBarIconController
+    @Mock private lateinit var commandQueue: CommandQueue
+    @Mock private lateinit var broadcastDispatcher: BroadcastDispatcher
+    @Mock private lateinit var castController: CastController
+    @Mock private lateinit var hotspotController: HotspotController
+    @Mock private lateinit var bluetoothController: BluetoothController
+    @Mock private lateinit var nextAlarmController: NextAlarmController
+    @Mock private lateinit var userInfoController: UserInfoController
+    @Mock private lateinit var rotationLockController: RotationLockController
+    @Mock private lateinit var dataSaverController: DataSaverController
+    @Mock private lateinit var zenModeController: ZenModeController
+    @Mock private lateinit var deviceProvisionedController: DeviceProvisionedController
+    @Mock private lateinit var keyguardStateController: KeyguardStateController
+    @Mock private lateinit var locationController: LocationController
+    @Mock private lateinit var sensorPrivacyController: SensorPrivacyController
+    @Mock private lateinit var iActivityManager: IActivityManager
+    @Mock private lateinit var alarmManager: AlarmManager
+    @Mock private lateinit var userManager: UserManager
+    @Mock private lateinit var userTracker: UserTracker
+    @Mock private lateinit var devicePolicyManager: DevicePolicyManager
+    @Mock private lateinit var recordingController: RecordingController
+    @Mock private lateinit var telecomManager: TelecomManager
+    @Mock private lateinit var sharedPreferences: SharedPreferences
+    @Mock private lateinit var dateFormatUtil: DateFormatUtil
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private lateinit var ringerModeTracker: RingerModeTracker
-    @Mock
-    private lateinit var privacyItemController: PrivacyItemController
-    @Mock
-    private lateinit var privacyLogger: PrivacyLogger
+    @Mock private lateinit var privacyItemController: PrivacyItemController
+    @Mock private lateinit var privacyLogger: PrivacyLogger
     @Captor
     private lateinit var alarmCallbackCaptor:
-            ArgumentCaptor<NextAlarmController.NextAlarmChangeCallback>
+        ArgumentCaptor<NextAlarmController.NextAlarmChangeCallback>
 
     private lateinit var executor: FakeExecutor
     private lateinit var statusBarPolicy: PhoneStatusBarPolicy
@@ -137,8 +114,8 @@
         executor = FakeExecutor(FakeSystemClock())
         testableLooper = TestableLooper.get(this)
         context.orCreateTestableResources.addOverride(
-                com.android.internal.R.string.status_bar_alarm_clock,
-                ALARM_SLOT
+            com.android.internal.R.string.status_bar_alarm_clock,
+            ALARM_SLOT
         )
         statusBarPolicy = createStatusBarPolicy()
     }
@@ -195,36 +172,37 @@
 
     private fun createStatusBarPolicy(): PhoneStatusBarPolicy {
         return PhoneStatusBarPolicy(
-                iconController,
-                commandQueue,
-                broadcastDispatcher,
-                executor,
-                testableLooper.looper,
-                context.resources,
-                castController,
-                hotspotController,
-                bluetoothController,
-                nextAlarmController,
-                userInfoController,
-                rotationLockController,
-                dataSaverController,
-                zenModeController,
-                deviceProvisionedController,
-                keyguardStateController,
-                locationController,
-                sensorPrivacyController,
-                iActivityManager,
-                alarmManager,
-                userManager,
-                devicePolicyManager,
-                recordingController,
-                telecomManager,
-                /* displayId = */ 0,
-                sharedPreferences,
-                dateFormatUtil,
-                ringerModeTracker,
-                privacyItemController,
-                privacyLogger
+            iconController,
+            commandQueue,
+            broadcastDispatcher,
+            executor,
+            testableLooper.looper,
+            context.resources,
+            castController,
+            hotspotController,
+            bluetoothController,
+            nextAlarmController,
+            userInfoController,
+            rotationLockController,
+            dataSaverController,
+            zenModeController,
+            deviceProvisionedController,
+            keyguardStateController,
+            locationController,
+            sensorPrivacyController,
+            iActivityManager,
+            alarmManager,
+            userManager,
+            userTracker,
+            devicePolicyManager,
+            recordingController,
+            telecomManager,
+            /* displayId = */ 0,
+            sharedPreferences,
+            dateFormatUtil,
+            ringerModeTracker,
+            privacyItemController,
+            privacyLogger
         )
     }
 }
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 e475905..c0537a6 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
@@ -58,6 +58,7 @@
 import com.android.systemui.animation.ShadeInterpolation;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
+import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants;
 import com.android.systemui.scrim.ScrimView;
 import com.android.systemui.statusbar.policy.FakeConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -629,6 +630,7 @@
 
     @Test
     public void transitionToUnlocked() {
+        mScrimController.setClipsQsScrim(false);
         mScrimController.setRawPanelExpansionFraction(0f);
         mScrimController.transitionTo(ScrimState.UNLOCKED);
         finishAnimationsImmediately();
@@ -644,14 +646,21 @@
         ));
 
         // Back scrim should be visible after start dragging
-        mScrimController.setRawPanelExpansionFraction(0.3f);
+        mScrimController.setRawPanelExpansionFraction(0.29f);
         assertScrimAlpha(Map.of(
                 mScrimInFront, TRANSPARENT,
                 mNotificationsScrim, TRANSPARENT,
                 mScrimBehind, SEMI_TRANSPARENT));
 
+        // Back scrim should be opaque at 30%
+        mScrimController.setRawPanelExpansionFraction(0.3f);
+        assertScrimAlpha(Map.of(
+                mScrimInFront, TRANSPARENT,
+                mNotificationsScrim, TRANSPARENT,
+                mScrimBehind, OPAQUE));
+
         // Then, notification scrim should fade in
-        mScrimController.setRawPanelExpansionFraction(0.7f);
+        mScrimController.setRawPanelExpansionFraction(0.31f);
         assertScrimAlpha(Map.of(
                 mScrimInFront, TRANSPARENT,
                 mNotificationsScrim, SEMI_TRANSPARENT,
@@ -1562,7 +1571,7 @@
     @Test
     public void transitionToDreaming() {
         mScrimController.setRawPanelExpansionFraction(0f);
-        mScrimController.setBouncerHiddenFraction(KeyguardBouncer.EXPANSION_HIDDEN);
+        mScrimController.setBouncerHiddenFraction(KeyguardBouncerConstants.EXPANSION_HIDDEN);
         mScrimController.transitionTo(ScrimState.DREAMING);
         finishAnimationsImmediately();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImplTest.kt
new file mode 100644
index 0000000..3bc288a2
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImplTest.kt
@@ -0,0 +1,309 @@
+/*
+ * 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.phone
+
+import android.os.UserHandle
+import androidx.test.filters.SmallTest
+import com.android.internal.statusbar.StatusBarIcon
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.phone.StatusBarIconController.TAG_PRIMARY
+import com.android.systemui.statusbar.phone.StatusBarIconControllerImpl.EXTERNAL_SLOT_SUFFIX
+import com.android.systemui.util.mockito.mock
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.mockito.Mockito.verify
+
+@SmallTest
+class StatusBarIconControllerImplTest : SysuiTestCase() {
+
+    private lateinit var underTest: StatusBarIconControllerImpl
+
+    private lateinit var iconList: StatusBarIconList
+    private val iconGroup: StatusBarIconController.IconManager = mock()
+
+    @Before
+    fun setUp() {
+        iconList = StatusBarIconList(arrayOf())
+        underTest =
+            StatusBarIconControllerImpl(
+                context,
+                mock(),
+                mock(),
+                mock(),
+                mock(),
+                mock(),
+                iconList,
+                mock(),
+            )
+        underTest.addIconGroup(iconGroup)
+    }
+
+    /** Regression test for b/255428281. */
+    @Test
+    fun internalAndExternalIconWithSameName_bothDisplayed() {
+        val slotName = "mute"
+
+        // Internal
+        underTest.setIcon(slotName, /* resourceId= */ 10, "contentDescription")
+
+        // External
+        val externalIcon =
+            StatusBarIcon(
+                "external.package",
+                UserHandle.ALL,
+                /* iconId= */ 2,
+                /* iconLevel= */ 0,
+                /* number= */ 0,
+                "contentDescription",
+            )
+        underTest.setIcon(slotName, externalIcon)
+
+        assertThat(iconList.slots).hasSize(2)
+        // Whichever was added last comes first
+        assertThat(iconList.slots[0].name).isEqualTo(slotName + EXTERNAL_SLOT_SUFFIX)
+        assertThat(iconList.slots[1].name).isEqualTo(slotName)
+        assertThat(iconList.slots[0].hasIconsInSlot()).isTrue()
+        assertThat(iconList.slots[1].hasIconsInSlot()).isTrue()
+    }
+
+    /** Regression test for b/255428281. */
+    @Test
+    fun internalAndExternalIconWithSameName_externalRemoved_viaRemoveIcon_internalStays() {
+        val slotName = "mute"
+
+        // Internal
+        underTest.setIcon(slotName, /* resourceId= */ 10, "contentDescription")
+
+        // External
+        underTest.setIcon(slotName, createExternalIcon())
+
+        // WHEN the external icon is removed via #removeIcon
+        underTest.removeIcon(slotName)
+
+        // THEN the external icon is removed but the internal icon remains
+        // Note: [StatusBarIconList] never removes slots from its list, it just sets the holder for
+        // the slot to null when an icon is removed.
+        assertThat(iconList.slots).hasSize(2)
+        assertThat(iconList.slots[0].name).isEqualTo(slotName + EXTERNAL_SLOT_SUFFIX)
+        assertThat(iconList.slots[1].name).isEqualTo(slotName)
+        assertThat(iconList.slots[0].hasIconsInSlot()).isFalse() // Indicates removal
+        assertThat(iconList.slots[1].hasIconsInSlot()).isTrue()
+
+        verify(iconGroup).onRemoveIcon(0)
+    }
+
+    /** Regression test for b/255428281. */
+    @Test
+    fun internalAndExternalIconWithSameName_externalRemoved_viaRemoveAll_internalStays() {
+        val slotName = "mute"
+
+        // Internal
+        underTest.setIcon(slotName, /* resourceId= */ 10, "contentDescription")
+
+        // External
+        underTest.setIcon(slotName, createExternalIcon())
+
+        // WHEN the external icon is removed via #removeAllIconsForExternalSlot
+        underTest.removeAllIconsForExternalSlot(slotName)
+
+        // THEN the external icon is removed but the internal icon remains
+        assertThat(iconList.slots).hasSize(2)
+        assertThat(iconList.slots[0].name).isEqualTo(slotName + EXTERNAL_SLOT_SUFFIX)
+        assertThat(iconList.slots[1].name).isEqualTo(slotName)
+        assertThat(iconList.slots[0].hasIconsInSlot()).isFalse() // Indicates removal
+        assertThat(iconList.slots[1].hasIconsInSlot()).isTrue()
+
+        verify(iconGroup).onRemoveIcon(0)
+    }
+
+    /** Regression test for b/255428281. */
+    @Test
+    fun internalAndExternalIconWithSameName_externalRemoved_viaSetNull_internalStays() {
+        val slotName = "mute"
+
+        // Internal
+        underTest.setIcon(slotName, /* resourceId= */ 10, "contentDescription")
+
+        // External
+        underTest.setIcon(slotName, createExternalIcon())
+
+        // WHEN the external icon is removed via a #setIcon(null)
+        underTest.setIcon(slotName, /* icon= */ null)
+
+        // THEN the external icon is removed but the internal icon remains
+        assertThat(iconList.slots).hasSize(2)
+        assertThat(iconList.slots[0].name).isEqualTo(slotName + EXTERNAL_SLOT_SUFFIX)
+        assertThat(iconList.slots[1].name).isEqualTo(slotName)
+        assertThat(iconList.slots[0].hasIconsInSlot()).isFalse() // Indicates removal
+        assertThat(iconList.slots[1].hasIconsInSlot()).isTrue()
+
+        verify(iconGroup).onRemoveIcon(0)
+    }
+
+    /** Regression test for b/255428281. */
+    @Test
+    fun internalAndExternalIconWithSameName_internalRemoved_viaRemove_externalStays() {
+        val slotName = "mute"
+
+        // Internal
+        underTest.setIcon(slotName, /* resourceId= */ 10, "contentDescription")
+
+        // External
+        underTest.setIcon(slotName, createExternalIcon())
+
+        // WHEN the internal icon is removed via #removeIcon
+        underTest.removeIcon(slotName, /* tag= */ 0)
+
+        // THEN the external icon is removed but the internal icon remains
+        assertThat(iconList.slots).hasSize(2)
+        assertThat(iconList.slots[0].name).isEqualTo(slotName + EXTERNAL_SLOT_SUFFIX)
+        assertThat(iconList.slots[1].name).isEqualTo(slotName)
+        assertThat(iconList.slots[0].hasIconsInSlot()).isTrue()
+        assertThat(iconList.slots[1].hasIconsInSlot()).isFalse() // Indicates removal
+
+        verify(iconGroup).onRemoveIcon(1)
+    }
+
+    /** Regression test for b/255428281. */
+    @Test
+    fun internalAndExternalIconWithSameName_internalRemoved_viaRemoveAll_externalStays() {
+        val slotName = "mute"
+
+        // Internal
+        underTest.setIcon(slotName, /* resourceId= */ 10, "contentDescription")
+
+        // External
+        underTest.setIcon(slotName, createExternalIcon())
+
+        // WHEN the internal icon is removed via #removeAllIconsForSlot
+        underTest.removeAllIconsForSlot(slotName)
+
+        // THEN the external icon is removed but the internal icon remains
+        assertThat(iconList.slots).hasSize(2)
+        assertThat(iconList.slots[0].name).isEqualTo(slotName + EXTERNAL_SLOT_SUFFIX)
+        assertThat(iconList.slots[1].name).isEqualTo(slotName)
+        assertThat(iconList.slots[0].hasIconsInSlot()).isTrue()
+        assertThat(iconList.slots[1].hasIconsInSlot()).isFalse() // Indicates removal
+
+        verify(iconGroup).onRemoveIcon(1)
+    }
+
+    /** Regression test for b/255428281. */
+    @Test
+    fun internalAndExternalIconWithSameName_internalUpdatedIndependently() {
+        val slotName = "mute"
+
+        // Internal
+        underTest.setIcon(slotName, /* resourceId= */ 10, "contentDescription")
+
+        // External
+        val startingExternalIcon =
+            StatusBarIcon(
+                "external.package",
+                UserHandle.ALL,
+                /* iconId= */ 20,
+                /* iconLevel= */ 0,
+                /* number= */ 0,
+                "externalDescription",
+            )
+        underTest.setIcon(slotName, startingExternalIcon)
+
+        // WHEN the internal icon is updated
+        underTest.setIcon(slotName, /* resourceId= */ 11, "newContentDescription")
+
+        // THEN only the internal slot gets the updates
+        val internalSlot = iconList.slots[1]
+        val internalHolder = internalSlot.getHolderForTag(TAG_PRIMARY)!!
+        assertThat(internalSlot.name).isEqualTo(slotName)
+        assertThat(internalHolder.icon!!.contentDescription).isEqualTo("newContentDescription")
+        assertThat(internalHolder.icon!!.icon.resId).isEqualTo(11)
+
+        // And the external slot has its own values
+        val externalSlot = iconList.slots[0]
+        val externalHolder = externalSlot.getHolderForTag(TAG_PRIMARY)!!
+        assertThat(externalSlot.name).isEqualTo(slotName + EXTERNAL_SLOT_SUFFIX)
+        assertThat(externalHolder.icon!!.contentDescription).isEqualTo("externalDescription")
+        assertThat(externalHolder.icon!!.icon.resId).isEqualTo(20)
+    }
+
+    /** Regression test for b/255428281. */
+    @Test
+    fun internalAndExternalIconWithSameName_externalUpdatedIndependently() {
+        val slotName = "mute"
+
+        // Internal
+        underTest.setIcon(slotName, /* resourceId= */ 10, "contentDescription")
+
+        // External
+        val startingExternalIcon =
+            StatusBarIcon(
+                "external.package",
+                UserHandle.ALL,
+                /* iconId= */ 20,
+                /* iconLevel= */ 0,
+                /* number= */ 0,
+                "externalDescription",
+            )
+        underTest.setIcon(slotName, startingExternalIcon)
+
+        // WHEN the external icon is updated
+        val newExternalIcon =
+            StatusBarIcon(
+                "external.package",
+                UserHandle.ALL,
+                /* iconId= */ 21,
+                /* iconLevel= */ 0,
+                /* number= */ 0,
+                "newExternalDescription",
+            )
+        underTest.setIcon(slotName, newExternalIcon)
+
+        // THEN only the external slot gets the updates
+        val externalSlot = iconList.slots[0]
+        val externalHolder = externalSlot.getHolderForTag(TAG_PRIMARY)!!
+        assertThat(externalSlot.name).isEqualTo(slotName + EXTERNAL_SLOT_SUFFIX)
+        assertThat(externalHolder.icon!!.contentDescription).isEqualTo("newExternalDescription")
+        assertThat(externalHolder.icon!!.icon.resId).isEqualTo(21)
+
+        // And the internal slot has its own values
+        val internalSlot = iconList.slots[1]
+        val internalHolder = internalSlot.getHolderForTag(TAG_PRIMARY)!!
+        assertThat(internalSlot.name).isEqualTo(slotName)
+        assertThat(internalHolder.icon!!.contentDescription).isEqualTo("contentDescription")
+        assertThat(internalHolder.icon!!.icon.resId).isEqualTo(10)
+    }
+
+    @Test
+    fun externalSlot_alreadyEndsWithSuffix_suffixNotAddedTwice() {
+        underTest.setIcon("myslot$EXTERNAL_SLOT_SUFFIX", createExternalIcon())
+
+        assertThat(iconList.slots).hasSize(1)
+        assertThat(iconList.slots[0].name).isEqualTo("myslot$EXTERNAL_SLOT_SUFFIX")
+    }
+
+    private fun createExternalIcon(): StatusBarIcon {
+        return StatusBarIcon(
+            "external.package",
+            UserHandle.ALL,
+            /* iconId= */ 2,
+            /* iconLevel= */ 0,
+            /* number= */ 0,
+            "contentDescription",
+        )
+    }
+}
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 14a319b..1ba0a36 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
@@ -17,6 +17,8 @@
 package com.android.systemui.statusbar.phone;
 
 import static com.android.systemui.flags.Flags.MODERN_BOUNCER;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_HIDDEN;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_VISIBLE;
 
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
@@ -37,6 +39,8 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewRootImpl;
+import android.window.BackEvent;
+import android.window.OnBackAnimationCallback;
 import android.window.OnBackInvokedCallback;
 import android.window.OnBackInvokedDispatcher;
 import android.window.WindowOnBackInvokedDispatcher;
@@ -54,9 +58,12 @@
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.dreams.DreamOverlayStateController;
 import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.keyguard.data.BouncerView;
 import com.android.systemui.keyguard.data.BouncerViewDelegate;
+import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor;
+import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback;
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor;
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
@@ -105,7 +112,6 @@
     @Mock private KeyguardBouncer.Factory mKeyguardBouncerFactory;
     @Mock private KeyguardMessageAreaController.Factory mKeyguardMessageAreaFactory;
     @Mock private KeyguardMessageAreaController mKeyguardMessageAreaController;
-    @Mock private StatusBarKeyguardViewManager.AlternateBouncer mAlternateBouncer;
     @Mock private KeyguardMessageArea mKeyguardMessageArea;
     @Mock private ShadeController mShadeController;
     @Mock private SysUIUnfoldComponent mSysUiUnfoldComponent;
@@ -115,18 +121,23 @@
     @Mock private KeyguardSecurityModel mKeyguardSecurityModel;
     @Mock private PrimaryBouncerCallbackInteractor mPrimaryBouncerCallbackInteractor;
     @Mock private PrimaryBouncerInteractor mPrimaryBouncerInteractor;
+    @Mock private AlternateBouncerInteractor mAlternateBouncerInteractor;
     @Mock private BouncerView mBouncerView;
     @Mock private BouncerViewDelegate mBouncerViewDelegate;
+    @Mock private OnBackAnimationCallback mBouncerViewDelegateBackCallback;
 
     private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
-    private KeyguardBouncer.PrimaryBouncerExpansionCallback mBouncerExpansionCallback;
+    private PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback
+            mBouncerExpansionCallback;
     private FakeKeyguardStateController mKeyguardStateController =
             spy(new FakeKeyguardStateController());
 
-    @Mock private ViewRootImpl mViewRootImpl;
-    @Mock private WindowOnBackInvokedDispatcher mOnBackInvokedDispatcher;
+    @Mock
+    private ViewRootImpl mViewRootImpl;
+    @Mock
+    private WindowOnBackInvokedDispatcher mOnBackInvokedDispatcher;
     @Captor
-    private ArgumentCaptor<OnBackInvokedCallback> mOnBackInvokedCallback;
+    private ArgumentCaptor<OnBackInvokedCallback> mBackCallbackCaptor;
 
 
     @Before
@@ -137,6 +148,10 @@
         when(mKeyguardMessageAreaFactory.create(any(KeyguardMessageArea.class)))
                 .thenReturn(mKeyguardMessageAreaController);
         when(mBouncerView.getDelegate()).thenReturn(mBouncerViewDelegate);
+        when(mBouncerViewDelegate.getBackCallback()).thenReturn(mBouncerViewDelegateBackCallback);
+        when(mFeatureFlags
+                .isEnabled(Flags.WM_ENABLE_PREDICTIVE_BACK_BOUNCER_ANIM))
+                .thenReturn(true);
 
         when(mFeatureFlags.isEnabled(MODERN_BOUNCER)).thenReturn(true);
 
@@ -163,7 +178,8 @@
                         mFeatureFlags,
                         mPrimaryBouncerCallbackInteractor,
                         mPrimaryBouncerInteractor,
-                        mBouncerView) {
+                        mBouncerView,
+                        mAlternateBouncerInteractor) {
                     @Override
                     public ViewRootImpl getViewRootImpl() {
                         return mViewRootImpl;
@@ -179,8 +195,8 @@
                 mNotificationContainer,
                 mBypassController);
         mStatusBarKeyguardViewManager.show(null);
-        ArgumentCaptor<KeyguardBouncer.PrimaryBouncerExpansionCallback> callbackArgumentCaptor =
-                ArgumentCaptor.forClass(KeyguardBouncer.PrimaryBouncerExpansionCallback.class);
+        ArgumentCaptor<PrimaryBouncerExpansionCallback> callbackArgumentCaptor =
+                ArgumentCaptor.forClass(PrimaryBouncerExpansionCallback.class);
         verify(mPrimaryBouncerCallbackInteractor).addBouncerExpansionCallback(
                 callbackArgumentCaptor.capture());
         mBouncerExpansionCallback = callbackArgumentCaptor.getValue();
@@ -189,7 +205,8 @@
     @Test
     public void dismissWithAction_AfterKeyguardGoneSetToFalse() {
         OnDismissAction action = () -> false;
-        Runnable cancelAction = () -> {};
+        Runnable cancelAction = () -> {
+        };
         mStatusBarKeyguardViewManager.dismissWithAction(
                 action, cancelAction, false /* afterKeyguardGone */);
         verify(mPrimaryBouncerInteractor).setDismissAction(eq(action), eq(cancelAction));
@@ -253,7 +270,7 @@
         when(mPrimaryBouncerInteractor.isInTransit()).thenReturn(true);
 
         mStatusBarKeyguardViewManager.onPanelExpansionChanged(EXPANSION_EVENT);
-        verify(mPrimaryBouncerInteractor).setPanelExpansion(eq(KeyguardBouncer.EXPANSION_HIDDEN));
+        verify(mPrimaryBouncerInteractor).setPanelExpansion(eq(EXPANSION_HIDDEN));
     }
 
     @Test
@@ -281,7 +298,7 @@
                 .thenReturn(BiometricUnlockController.MODE_WAKE_AND_UNLOCK);
         mStatusBarKeyguardViewManager.onPanelExpansionChanged(
                 expansionEvent(
-                        /* fraction= */ KeyguardBouncer.EXPANSION_VISIBLE,
+                        /* fraction= */ EXPANSION_VISIBLE,
                         /* expanded= */ true,
                         /* tracking= */ false));
         verify(mPrimaryBouncerInteractor, never()).setPanelExpansion(anyFloat());
@@ -298,7 +315,7 @@
                 .thenReturn(BiometricUnlockController.MODE_DISMISS_BOUNCER);
         mStatusBarKeyguardViewManager.onPanelExpansionChanged(
                 expansionEvent(
-                        /* fraction= */ KeyguardBouncer.EXPANSION_VISIBLE,
+                        /* fraction= */ EXPANSION_VISIBLE,
                         /* expanded= */ true,
                         /* tracking= */ false));
         verify(mPrimaryBouncerInteractor, never()).setPanelExpansion(anyFloat());
@@ -309,7 +326,7 @@
         when(mKeyguardStateController.isOccluded()).thenReturn(true);
         mStatusBarKeyguardViewManager.onPanelExpansionChanged(
                 expansionEvent(
-                        /* fraction= */ KeyguardBouncer.EXPANSION_VISIBLE,
+                        /* fraction= */ EXPANSION_VISIBLE,
                         /* expanded= */ true,
                         /* tracking= */ false));
         verify(mPrimaryBouncerInteractor, never()).setPanelExpansion(anyFloat());
@@ -326,7 +343,7 @@
                 .thenReturn(BiometricUnlockController.MODE_SHOW_BOUNCER);
         mStatusBarKeyguardViewManager.onPanelExpansionChanged(
                 expansionEvent(
-                        /* fraction= */ KeyguardBouncer.EXPANSION_VISIBLE,
+                        /* fraction= */ EXPANSION_VISIBLE,
                         /* expanded= */ true,
                         /* tracking= */ false));
         verify(mPrimaryBouncerInteractor, never()).setPanelExpansion(anyFloat());
@@ -337,7 +354,7 @@
         when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE_LOCKED);
         mStatusBarKeyguardViewManager.onPanelExpansionChanged(
                 expansionEvent(
-                        /* fraction= */ KeyguardBouncer.EXPANSION_VISIBLE,
+                        /* fraction= */ EXPANSION_VISIBLE,
                         /* expanded= */ true,
                         /* tracking= */ false));
         verify(mPrimaryBouncerInteractor, never()).setPanelExpansion(anyFloat());
@@ -434,37 +451,35 @@
 
     @Test
     public void testShowing_whenAlternateAuthShowing() {
-        mStatusBarKeyguardViewManager.setAlternateBouncer(mAlternateBouncer);
         when(mPrimaryBouncerInteractor.isFullyShowing()).thenReturn(false);
-        when(mAlternateBouncer.isShowingAlternateBouncer()).thenReturn(true);
+        when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
         assertTrue(
-                "Is showing not accurate when alternative auth showing",
+                "Is showing not accurate when alternative bouncer is visible",
                 mStatusBarKeyguardViewManager.isBouncerShowing());
     }
 
     @Test
     public void testWillBeShowing_whenAlternateAuthShowing() {
-        mStatusBarKeyguardViewManager.setAlternateBouncer(mAlternateBouncer);
         when(mPrimaryBouncerInteractor.isFullyShowing()).thenReturn(false);
-        when(mAlternateBouncer.isShowingAlternateBouncer()).thenReturn(true);
+        when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
         assertTrue(
-                "Is or will be showing not accurate when alternative auth showing",
+                "Is or will be showing not accurate when alternate bouncer is visible",
                 mStatusBarKeyguardViewManager.primaryBouncerIsOrWillBeShowing());
     }
 
     @Test
-    public void testHideAlternateBouncer_onShowBouncer() {
-        // GIVEN alt auth is showing
-        mStatusBarKeyguardViewManager.setAlternateBouncer(mAlternateBouncer);
+    public void testHideAlternateBouncer_onShowPrimaryBouncer() {
+        reset(mAlternateBouncerInteractor);
+
+        // GIVEN alt bouncer is showing
         when(mPrimaryBouncerInteractor.isFullyShowing()).thenReturn(false);
-        when(mAlternateBouncer.isShowingAlternateBouncer()).thenReturn(true);
-        reset(mAlternateBouncer);
+        when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
 
         // WHEN showBouncer is called
         mStatusBarKeyguardViewManager.showPrimaryBouncer(true);
 
         // THEN alt bouncer should be hidden
-        verify(mAlternateBouncer).hideAlternateBouncer();
+        verify(mAlternateBouncerInteractor).hide();
     }
 
     @Test
@@ -479,11 +494,9 @@
 
     @Test
     public void testShowAltAuth_unlockingWithBiometricNotAllowed() {
-        // GIVEN alt auth exists, unlocking with biometric isn't allowed
-        mStatusBarKeyguardViewManager.setAlternateBouncer(mAlternateBouncer);
+        // GIVEN cannot use alternate bouncer
         when(mPrimaryBouncerInteractor.isFullyShowing()).thenReturn(false);
-        when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean()))
-                .thenReturn(false);
+        when(mAlternateBouncerInteractor.canShowAlternateBouncerForFingerprint()).thenReturn(false);
 
         // WHEN showGenericBouncer is called
         final boolean scrimmed = true;
@@ -491,21 +504,19 @@
 
         // THEN regular bouncer is shown
         verify(mPrimaryBouncerInteractor).show(eq(scrimmed));
-        verify(mAlternateBouncer, never()).showAlternateBouncer();
     }
 
     @Test
     public void testShowAlternateBouncer_unlockingWithBiometricAllowed() {
-        // GIVEN alt auth exists, unlocking with biometric is allowed
-        mStatusBarKeyguardViewManager.setAlternateBouncer(mAlternateBouncer);
+        // GIVEN will show alternate bouncer
         when(mPrimaryBouncerInteractor.isFullyShowing()).thenReturn(false);
-        when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
+        when(mAlternateBouncerInteractor.show()).thenReturn(true);
 
         // WHEN showGenericBouncer is called
         mStatusBarKeyguardViewManager.showBouncer(true);
 
         // THEN alt auth bouncer is shown
-        verify(mAlternateBouncer).showAlternateBouncer();
+        verify(mAlternateBouncerInteractor).show();
         verify(mPrimaryBouncerInteractor, never()).show(anyBoolean());
     }
 
@@ -543,12 +554,12 @@
         mBouncerExpansionCallback.onVisibilityChanged(true);
         verify(mOnBackInvokedDispatcher).registerOnBackInvokedCallback(
                 eq(OnBackInvokedDispatcher.PRIORITY_OVERLAY),
-                mOnBackInvokedCallback.capture());
+                mBackCallbackCaptor.capture());
 
         /* verify that the same callback is unregistered when the bouncer becomes invisible */
         mBouncerExpansionCallback.onVisibilityChanged(false);
         verify(mOnBackInvokedDispatcher).unregisterOnBackInvokedCallback(
-                eq(mOnBackInvokedCallback.getValue()));
+                eq(mBackCallbackCaptor.getValue()));
     }
 
     @Test
@@ -557,18 +568,63 @@
         /* capture the predictive back callback during registration */
         verify(mOnBackInvokedDispatcher).registerOnBackInvokedCallback(
                 eq(OnBackInvokedDispatcher.PRIORITY_OVERLAY),
-                mOnBackInvokedCallback.capture());
+                mBackCallbackCaptor.capture());
 
         when(mPrimaryBouncerInteractor.isFullyShowing()).thenReturn(true);
         when(mCentralSurfaces.shouldKeyguardHideImmediately()).thenReturn(true);
         /* invoke the back callback directly */
-        mOnBackInvokedCallback.getValue().onBackInvoked();
+        mBackCallbackCaptor.getValue().onBackInvoked();
 
         /* verify that the bouncer will be hidden as a result of the invocation */
         verify(mCentralSurfaces).setBouncerShowing(eq(false));
     }
 
     @Test
+    public void testPredictiveBackCallback_noBackAnimationForFullScreenBouncer() {
+        when(mKeyguardSecurityModel.getSecurityMode(anyInt()))
+                .thenReturn(KeyguardSecurityModel.SecurityMode.SimPin);
+        mBouncerExpansionCallback.onVisibilityChanged(true);
+        /* capture the predictive back callback during registration */
+        verify(mOnBackInvokedDispatcher).registerOnBackInvokedCallback(
+                eq(OnBackInvokedDispatcher.PRIORITY_OVERLAY),
+                mBackCallbackCaptor.capture());
+        assertTrue(mBackCallbackCaptor.getValue() instanceof OnBackAnimationCallback);
+
+        OnBackAnimationCallback backCallback =
+                (OnBackAnimationCallback) mBackCallbackCaptor.getValue();
+
+        BackEvent event = new BackEvent(0, 0, 0, BackEvent.EDGE_LEFT);
+        backCallback.onBackStarted(event);
+        verify(mBouncerViewDelegateBackCallback, never()).onBackStarted(any());
+    }
+
+    @Test
+    public void testPredictiveBackCallback_forwardsBackDispatches() {
+        mBouncerExpansionCallback.onVisibilityChanged(true);
+        /* capture the predictive back callback during registration */
+        verify(mOnBackInvokedDispatcher).registerOnBackInvokedCallback(
+                eq(OnBackInvokedDispatcher.PRIORITY_OVERLAY),
+                mBackCallbackCaptor.capture());
+        assertTrue(mBackCallbackCaptor.getValue() instanceof OnBackAnimationCallback);
+
+        OnBackAnimationCallback backCallback =
+                (OnBackAnimationCallback) mBackCallbackCaptor.getValue();
+
+        BackEvent event = new BackEvent(0, 0, 0, BackEvent.EDGE_LEFT);
+        backCallback.onBackStarted(event);
+        verify(mBouncerViewDelegateBackCallback).onBackStarted(eq(event));
+
+        backCallback.onBackProgressed(event);
+        verify(mBouncerViewDelegateBackCallback).onBackProgressed(eq(event));
+
+        backCallback.onBackInvoked();
+        verify(mBouncerViewDelegateBackCallback).onBackInvoked();
+
+        backCallback.onBackCancelled();
+        verify(mBouncerViewDelegateBackCallback).onBackCancelled();
+    }
+
+    @Test
     public void testReportBouncerOnDreamWhenVisible() {
         mBouncerExpansionCallback.onVisibilityChanged(true);
         verify(mCentralSurfaces).setBouncerShowingOverDream(false);
@@ -613,7 +669,8 @@
                         mFeatureFlags,
                         mPrimaryBouncerCallbackInteractor,
                         mPrimaryBouncerInteractor,
-                        mBouncerView) {
+                        mBouncerView,
+                        mAlternateBouncerInteractor) {
                     @Override
                     public ViewRootImpl getViewRootImpl() {
                         return mViewRootImpl;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest_Old.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest_Old.java
index 96fba39..55ab681 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest_Old.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest_Old.java
@@ -17,6 +17,8 @@
 package com.android.systemui.statusbar.phone;
 
 import static com.android.systemui.flags.Flags.MODERN_BOUNCER;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_HIDDEN;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_VISIBLE;
 
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
@@ -56,7 +58,9 @@
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.keyguard.data.BouncerView;
 import com.android.systemui.keyguard.data.BouncerViewDelegate;
+import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor;
+import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback;
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor;
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
@@ -109,7 +113,6 @@
     @Mock private KeyguardMessageAreaController.Factory mKeyguardMessageAreaFactory;
     @Mock private KeyguardMessageAreaController mKeyguardMessageAreaController;
     @Mock private KeyguardBouncer mPrimaryBouncer;
-    @Mock private StatusBarKeyguardViewManager.AlternateBouncer mAlternateBouncer;
     @Mock private KeyguardMessageArea mKeyguardMessageArea;
     @Mock private ShadeController mShadeController;
     @Mock private SysUIUnfoldComponent mSysUiUnfoldComponent;
@@ -119,11 +122,13 @@
     @Mock private KeyguardSecurityModel mKeyguardSecurityModel;
     @Mock private PrimaryBouncerCallbackInteractor mPrimaryBouncerCallbackInteractor;
     @Mock private PrimaryBouncerInteractor mPrimaryBouncerInteractor;
+    @Mock private AlternateBouncerInteractor mAlternateBouncerInteractor;
     @Mock private BouncerView mBouncerView;
     @Mock private BouncerViewDelegate mBouncerViewDelegate;
 
     private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
-    private KeyguardBouncer.PrimaryBouncerExpansionCallback mBouncerExpansionCallback;
+    private PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback
+            mBouncerExpansionCallback;
     private FakeKeyguardStateController mKeyguardStateController =
             spy(new FakeKeyguardStateController());
 
@@ -138,7 +143,7 @@
         MockitoAnnotations.initMocks(this);
         when(mKeyguardBouncerFactory.create(
                 any(ViewGroup.class),
-                any(KeyguardBouncer.PrimaryBouncerExpansionCallback.class)))
+                any(PrimaryBouncerExpansionCallback.class)))
                 .thenReturn(mPrimaryBouncer);
         when(mCentralSurfaces.getBouncerContainer()).thenReturn(mContainer);
         when(mContainer.findViewById(anyInt())).thenReturn(mKeyguardMessageArea);
@@ -169,7 +174,8 @@
                         mFeatureFlags,
                         mPrimaryBouncerCallbackInteractor,
                         mPrimaryBouncerInteractor,
-                        mBouncerView) {
+                        mBouncerView,
+                        mAlternateBouncerInteractor) {
                     @Override
                     public ViewRootImpl getViewRootImpl() {
                         return mViewRootImpl;
@@ -185,8 +191,8 @@
                 mNotificationContainer,
                 mBypassController);
         mStatusBarKeyguardViewManager.show(null);
-        ArgumentCaptor<KeyguardBouncer.PrimaryBouncerExpansionCallback> callbackArgumentCaptor =
-                ArgumentCaptor.forClass(KeyguardBouncer.PrimaryBouncerExpansionCallback.class);
+        ArgumentCaptor<PrimaryBouncerExpansionCallback> callbackArgumentCaptor =
+                ArgumentCaptor.forClass(PrimaryBouncerExpansionCallback.class);
         verify(mKeyguardBouncerFactory).create(any(ViewGroup.class),
                 callbackArgumentCaptor.capture());
         mBouncerExpansionCallback = callbackArgumentCaptor.getValue();
@@ -259,7 +265,7 @@
         when(mPrimaryBouncer.inTransit()).thenReturn(true);
 
         mStatusBarKeyguardViewManager.onPanelExpansionChanged(EXPANSION_EVENT);
-        verify(mPrimaryBouncer).setExpansion(eq(KeyguardBouncer.EXPANSION_HIDDEN));
+        verify(mPrimaryBouncer).setExpansion(eq(EXPANSION_HIDDEN));
     }
 
     @Test
@@ -287,7 +293,7 @@
                 .thenReturn(BiometricUnlockController.MODE_WAKE_AND_UNLOCK);
         mStatusBarKeyguardViewManager.onPanelExpansionChanged(
                 expansionEvent(
-                        /* fraction= */ KeyguardBouncer.EXPANSION_VISIBLE,
+                        /* fraction= */ EXPANSION_VISIBLE,
                         /* expanded= */ true,
                         /* tracking= */ false));
         verify(mPrimaryBouncer, never()).setExpansion(anyFloat());
@@ -304,7 +310,7 @@
                 .thenReturn(BiometricUnlockController.MODE_DISMISS_BOUNCER);
         mStatusBarKeyguardViewManager.onPanelExpansionChanged(
                 expansionEvent(
-                        /* fraction= */ KeyguardBouncer.EXPANSION_VISIBLE,
+                        /* fraction= */ EXPANSION_VISIBLE,
                         /* expanded= */ true,
                         /* tracking= */ false));
         verify(mPrimaryBouncer, never()).setExpansion(anyFloat());
@@ -315,7 +321,7 @@
         when(mKeyguardStateController.isOccluded()).thenReturn(true);
         mStatusBarKeyguardViewManager.onPanelExpansionChanged(
                 expansionEvent(
-                        /* fraction= */ KeyguardBouncer.EXPANSION_VISIBLE,
+                        /* fraction= */ EXPANSION_VISIBLE,
                         /* expanded= */ true,
                         /* tracking= */ false));
         verify(mPrimaryBouncer, never()).setExpansion(anyFloat());
@@ -332,7 +338,7 @@
                 .thenReturn(BiometricUnlockController.MODE_SHOW_BOUNCER);
         mStatusBarKeyguardViewManager.onPanelExpansionChanged(
                 expansionEvent(
-                        /* fraction= */ KeyguardBouncer.EXPANSION_VISIBLE,
+                        /* fraction= */ EXPANSION_VISIBLE,
                         /* expanded= */ true,
                         /* tracking= */ false));
         verify(mPrimaryBouncer, never()).setExpansion(anyFloat());
@@ -343,7 +349,7 @@
         when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE_LOCKED);
         mStatusBarKeyguardViewManager.onPanelExpansionChanged(
                 expansionEvent(
-                        /* fraction= */ KeyguardBouncer.EXPANSION_VISIBLE,
+                        /* fraction= */ EXPANSION_VISIBLE,
                         /* expanded= */ true,
                         /* tracking= */ false));
         verify(mPrimaryBouncer, never()).setExpansion(anyFloat());
@@ -439,41 +445,6 @@
     }
 
     @Test
-    public void testShowing_whenAlternateAuthShowing() {
-        mStatusBarKeyguardViewManager.setAlternateBouncer(mAlternateBouncer);
-        when(mPrimaryBouncer.isShowing()).thenReturn(false);
-        when(mAlternateBouncer.isShowingAlternateBouncer()).thenReturn(true);
-        assertTrue(
-                "Is showing not accurate when alternative auth showing",
-                mStatusBarKeyguardViewManager.isBouncerShowing());
-    }
-
-    @Test
-    public void testWillBeShowing_whenAlternateAuthShowing() {
-        mStatusBarKeyguardViewManager.setAlternateBouncer(mAlternateBouncer);
-        when(mPrimaryBouncer.isShowing()).thenReturn(false);
-        when(mAlternateBouncer.isShowingAlternateBouncer()).thenReturn(true);
-        assertTrue(
-                "Is or will be showing not accurate when alternative auth showing",
-                mStatusBarKeyguardViewManager.primaryBouncerIsOrWillBeShowing());
-    }
-
-    @Test
-    public void testHideAlternateBouncer_onShowBouncer() {
-        // GIVEN alt auth is showing
-        mStatusBarKeyguardViewManager.setAlternateBouncer(mAlternateBouncer);
-        when(mPrimaryBouncer.isShowing()).thenReturn(false);
-        when(mAlternateBouncer.isShowingAlternateBouncer()).thenReturn(true);
-        reset(mAlternateBouncer);
-
-        // WHEN showBouncer is called
-        mStatusBarKeyguardViewManager.showPrimaryBouncer(true);
-
-        // THEN alt bouncer should be hidden
-        verify(mAlternateBouncer).hideAlternateBouncer();
-    }
-
-    @Test
     public void testBouncerIsOrWillBeShowing_whenBouncerIsInTransit() {
         when(mPrimaryBouncer.isShowing()).thenReturn(false);
         when(mPrimaryBouncer.inTransit()).thenReturn(true);
@@ -484,38 +455,6 @@
     }
 
     @Test
-    public void testShowAltAuth_unlockingWithBiometricNotAllowed() {
-        // GIVEN alt auth exists, unlocking with biometric isn't allowed
-        mStatusBarKeyguardViewManager.setAlternateBouncer(mAlternateBouncer);
-        when(mPrimaryBouncer.isShowing()).thenReturn(false);
-        when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean()))
-                .thenReturn(false);
-
-        // WHEN showGenericBouncer is called
-        final boolean scrimmed = true;
-        mStatusBarKeyguardViewManager.showBouncer(scrimmed);
-
-        // THEN regular bouncer is shown
-        verify(mPrimaryBouncer).show(anyBoolean(), eq(scrimmed));
-        verify(mAlternateBouncer, never()).showAlternateBouncer();
-    }
-
-    @Test
-    public void testShowAlternateBouncer_unlockingWithBiometricAllowed() {
-        // GIVEN alt auth exists, unlocking with biometric is allowed
-        mStatusBarKeyguardViewManager.setAlternateBouncer(mAlternateBouncer);
-        when(mPrimaryBouncer.isShowing()).thenReturn(false);
-        when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
-
-        // WHEN showGenericBouncer is called
-        mStatusBarKeyguardViewManager.showBouncer(true);
-
-        // THEN alt auth bouncer is shown
-        verify(mAlternateBouncer).showAlternateBouncer();
-        verify(mPrimaryBouncer, never()).show(anyBoolean(), anyBoolean());
-    }
-
-    @Test
     public void testUpdateResources_delegatesToBouncer() {
         mStatusBarKeyguardViewManager.updateResources();
 
@@ -628,7 +567,8 @@
                         mFeatureFlags,
                         mPrimaryBouncerCallbackInteractor,
                         mPrimaryBouncerInteractor,
-                        mBouncerView) {
+                        mBouncerView,
+                        mAlternateBouncerInteractor) {
                     @Override
                     public ViewRootImpl getViewRootImpl() {
                         return mViewRootImpl;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
index 19658e6..ccc57ad 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
@@ -33,6 +33,7 @@
 import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityManager;
 import android.app.KeyguardManager;
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -59,6 +60,7 @@
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.shade.NotificationShadeWindowViewController;
 import com.android.systemui.shade.ShadeControllerImpl;
@@ -139,6 +141,8 @@
     private ActivityLaunchAnimator mActivityLaunchAnimator;
     @Mock
     private InteractionJankMonitor mJankMonitor;
+    @Mock
+    private UserTracker mUserTracker;
     private final FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
     private ExpandableNotificationRow mNotificationRow;
     private ExpandableNotificationRow mBubbleNotificationRow;
@@ -183,6 +187,8 @@
         when(mVisibilityProvider.obtain(any(NotificationEntry.class), anyBoolean()))
                 .thenAnswer(invocation -> NotificationVisibility.obtain(
                         invocation.<NotificationEntry>getArgument(0).getKey(), 0, 1, false));
+        when(mUserTracker.getUserHandle()).thenReturn(
+                UserHandle.of(ActivityManager.getCurrentUser()));
 
         HeadsUpManagerPhone headsUpManager = mock(HeadsUpManagerPhone.class);
         NotificationLaunchAnimatorControllerProvider notificationAnimationProvider =
@@ -222,7 +228,8 @@
                         mActivityLaunchAnimator,
                         notificationAnimationProvider,
                         mock(LaunchFullScreenIntentProvider.class),
-                        mock(FeatureFlags.class)
+                        mock(FeatureFlags.class),
+                        mUserTracker
                 );
 
         // set up dismissKeyguardThenExecute to synchronously invoke the OnDismissAction arg
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
index 438271c..f230b87 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
@@ -58,7 +58,6 @@
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.DisableFlagsLogger;
 import com.android.systemui.statusbar.OperatorNameViewController;
-import com.android.systemui.statusbar.connectivity.NetworkController;
 import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
 import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
 import com.android.systemui.statusbar.phone.NotificationIconAreaController;
@@ -92,7 +91,6 @@
     private StatusBarLocationPublisher mLocationPublisher;
     // Set in instantiate()
     private StatusBarIconController mStatusBarIconController;
-    private NetworkController mNetworkController;
     private KeyguardStateController mKeyguardStateController;
 
     private final CommandQueue mCommandQueue = mock(CommandQueue.class);
@@ -424,7 +422,6 @@
         mAnimationScheduler = mock(SystemStatusAnimationScheduler.class);
         mLocationPublisher = mock(StatusBarLocationPublisher.class);
         mStatusBarIconController = mock(StatusBarIconController.class);
-        mNetworkController = mock(NetworkController.class);
         mStatusBarStateController = mock(StatusBarStateController.class);
         mKeyguardStateController = mock(KeyguardStateController.class);
         mOperatorNameViewController = mock(OperatorNameViewController.class);
@@ -448,7 +445,6 @@
                 mStatusBarHideIconsForBouncerManager,
                 mKeyguardStateController,
                 mNotificationPanelViewController,
-                mNetworkController,
                 mStatusBarStateController,
                 mCommandQueue,
                 mCarrierConfigTracker,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
index d30222f..711e4ac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
@@ -50,7 +50,9 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor
-import org.mockito.ArgumentMatchers.*
+import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.anyString
+import org.mockito.ArgumentMatchers.nullable
 import org.mockito.Mock
 import org.mockito.Mockito.`when`
 import org.mockito.Mockito.eq
@@ -83,7 +85,8 @@
     private lateinit var notifCollectionListener: NotifCollectionListener
 
     @Mock private lateinit var mockOngoingCallFlags: OngoingCallFlags
-    @Mock private lateinit var mockSwipeStatusBarAwayGestureHandler: SwipeStatusBarAwayGestureHandler
+    @Mock private lateinit var mockSwipeStatusBarAwayGestureHandler:
+        SwipeStatusBarAwayGestureHandler
     @Mock private lateinit var mockOngoingCallListener: OngoingCallListener
     @Mock private lateinit var mockActivityStarter: ActivityStarter
     @Mock private lateinit var mockIActivityManager: IActivityManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt
index d6a9ee3..53cd71f1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt
@@ -19,6 +19,7 @@
 import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
 import kotlinx.coroutines.flow.MutableStateFlow
 
 // TODO(b/261632894): remove this in favor of the real impl or DemoMobileConnectionRepository
@@ -29,12 +30,11 @@
     private val _connectionInfo = MutableStateFlow(MobileConnectionModel())
     override val connectionInfo = _connectionInfo
 
+    override val numberOfLevels = MutableStateFlow(DEFAULT_NUM_LEVELS)
+
     private val _dataEnabled = MutableStateFlow(true)
     override val dataEnabled = _dataEnabled
 
-    private val _isDefaultDataSubscription = MutableStateFlow(true)
-    override val isDefaultDataSubscription = _isDefaultDataSubscription
-
     override val cdmaRoaming = MutableStateFlow(false)
 
     override val networkName =
@@ -47,8 +47,4 @@
     fun setDataEnabled(enabled: Boolean) {
         _dataEnabled.value = enabled
     }
-
-    fun setIsDefaultDataSubscription(isDefault: Boolean) {
-        _isDefaultDataSubscription.value = isDefault
-    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt
index 7f93328..0add905e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt
@@ -26,6 +26,7 @@
 import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
 import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
+import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.MutableStateFlow
 
 // TODO(b/261632894): remove this in favor of the real impl or DemoMobileConnectionsRepository
@@ -56,6 +57,7 @@
 
     private val _activeMobileDataSubscriptionId = MutableStateFlow(INVALID_SUBSCRIPTION_ID)
     override val activeMobileDataSubscriptionId = _activeMobileDataSubscriptionId
+    override val activeSubChangedInGroupEvent: MutableSharedFlow<Unit> = MutableSharedFlow()
 
     private val _defaultDataSubId = MutableStateFlow(INVALID_SUBSCRIPTION_ID)
     override val defaultDataSubId = _defaultDataSubId
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt
index 5d377a8..0859d14 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt
@@ -34,6 +34,8 @@
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileConnectionsRepositoryImpl
 import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.DemoModeWifiDataSource
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.kotlinArgumentCaptor
 import com.android.systemui.util.mockito.mock
@@ -71,8 +73,10 @@
     private lateinit var underTest: MobileRepositorySwitcher
     private lateinit var realRepo: MobileConnectionsRepositoryImpl
     private lateinit var demoRepo: DemoMobileConnectionsRepository
-    private lateinit var mockDataSource: DemoModeMobileConnectionDataSource
+    private lateinit var mobileDataSource: DemoModeMobileConnectionDataSource
+    private lateinit var wifiDataSource: DemoModeWifiDataSource
     private lateinit var logFactory: TableLogBufferFactory
+    private lateinit var wifiRepository: FakeWifiRepository
 
     @Mock private lateinit var connectivityManager: ConnectivityManager
     @Mock private lateinit var subscriptionManager: SubscriptionManager
@@ -96,10 +100,15 @@
         // Never start in demo mode
         whenever(demoModeController.isInDemoMode).thenReturn(false)
 
-        mockDataSource =
+        mobileDataSource =
             mock<DemoModeMobileConnectionDataSource>().also {
                 whenever(it.mobileEvents).thenReturn(fakeNetworkEventsFlow)
             }
+        wifiDataSource =
+            mock<DemoModeWifiDataSource>().also {
+                whenever(it.wifiEvents).thenReturn(MutableStateFlow(null))
+            }
+        wifiRepository = FakeWifiRepository()
 
         realRepo =
             MobileConnectionsRepositoryImpl(
@@ -113,12 +122,14 @@
                 context,
                 IMMEDIATE,
                 scope,
+                wifiRepository,
                 mock(),
             )
 
         demoRepo =
             DemoMobileConnectionsRepository(
-                dataSource = mockDataSource,
+                mobileDataSource = mobileDataSource,
+                wifiDataSource = wifiDataSource,
                 scope = scope,
                 context = context,
                 logFactory = logFactory,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt
index 2102085..6989b514 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt
@@ -29,6 +29,8 @@
 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel
 import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.DemoModeWifiDataSource
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.model.FakeWifiEventModel
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.FakeSystemClock
@@ -63,10 +65,12 @@
     private val testScope = TestScope(testDispatcher)
 
     private val fakeNetworkEventFlow = MutableStateFlow<FakeNetworkEventModel?>(null)
+    private val fakeWifiEventFlow = MutableStateFlow<FakeWifiEventModel?>(null)
 
     private lateinit var connectionsRepo: DemoMobileConnectionsRepository
     private lateinit var underTest: DemoMobileConnectionRepository
     private lateinit var mockDataSource: DemoModeMobileConnectionDataSource
+    private lateinit var mockWifiDataSource: DemoModeWifiDataSource
 
     @Before
     fun setUp() {
@@ -75,10 +79,15 @@
             mock<DemoModeMobileConnectionDataSource>().also {
                 whenever(it.mobileEvents).thenReturn(fakeNetworkEventFlow)
             }
+        mockWifiDataSource =
+            mock<DemoModeWifiDataSource>().also {
+                whenever(it.wifiEvents).thenReturn(fakeWifiEventFlow)
+            }
 
         connectionsRepo =
             DemoMobileConnectionsRepository(
-                dataSource = mockDataSource,
+                mobileDataSource = mockDataSource,
+                wifiDataSource = mockWifiDataSource,
                 scope = testScope.backgroundScope,
                 context = context,
                 logFactory = logFactory,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt
index cdbe75e..f12d113 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt
@@ -32,6 +32,8 @@
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel.MobileDisabled
 import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.DemoModeWifiDataSource
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.model.FakeWifiEventModel
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.FakeSystemClock
@@ -57,21 +59,28 @@
     private val testScope = TestScope(testDispatcher)
 
     private val fakeNetworkEventFlow = MutableStateFlow<FakeNetworkEventModel?>(null)
+    private val fakeWifiEventFlow = MutableStateFlow<FakeWifiEventModel?>(null)
 
     private lateinit var underTest: DemoMobileConnectionsRepository
-    private lateinit var mockDataSource: DemoModeMobileConnectionDataSource
+    private lateinit var mobileDataSource: DemoModeMobileConnectionDataSource
+    private lateinit var wifiDataSource: DemoModeWifiDataSource
 
     @Before
     fun setUp() {
         // The data source only provides one API, so we can mock it with a flow here for convenience
-        mockDataSource =
+        mobileDataSource =
             mock<DemoModeMobileConnectionDataSource>().also {
                 whenever(it.mobileEvents).thenReturn(fakeNetworkEventFlow)
             }
+        wifiDataSource =
+            mock<DemoModeWifiDataSource>().also {
+                whenever(it.wifiEvents).thenReturn(fakeWifiEventFlow)
+            }
 
         underTest =
             DemoMobileConnectionsRepository(
-                dataSource = mockDataSource,
+                mobileDataSource = mobileDataSource,
+                wifiDataSource = wifiDataSource,
                 scope = testScope.backgroundScope,
                 context = context,
                 logFactory = logFactory,
@@ -81,6 +90,14 @@
     }
 
     @Test
+    fun `connectivity - defaults to connected and validated`() =
+        testScope.runTest {
+            val connectivity = underTest.defaultMobileNetworkConnectivity.value
+            assertThat(connectivity.isConnected).isTrue()
+            assertThat(connectivity.isValidated).isTrue()
+        }
+
+    @Test
     fun `network event - create new subscription`() =
         testScope.runTest {
             var latest: List<SubscriptionModel>? = null
@@ -97,6 +114,22 @@
         }
 
     @Test
+    fun `wifi carrier merged event - create new subscription`() =
+        testScope.runTest {
+            var latest: List<SubscriptionModel>? = null
+            val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
+
+            assertThat(latest).isEmpty()
+
+            fakeWifiEventFlow.value = validCarrierMergedEvent(subId = 5)
+
+            assertThat(latest).hasSize(1)
+            assertThat(latest!![0].subscriptionId).isEqualTo(5)
+
+            job.cancel()
+        }
+
+    @Test
     fun `network event - reuses subscription when same Id`() =
         testScope.runTest {
             var latest: List<SubscriptionModel>? = null
@@ -119,6 +152,28 @@
         }
 
     @Test
+    fun `wifi carrier merged event - reuses subscription when same Id`() =
+        testScope.runTest {
+            var latest: List<SubscriptionModel>? = null
+            val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
+
+            assertThat(latest).isEmpty()
+
+            fakeWifiEventFlow.value = validCarrierMergedEvent(subId = 5, level = 1)
+
+            assertThat(latest).hasSize(1)
+            assertThat(latest!![0].subscriptionId).isEqualTo(5)
+
+            // Second network event comes in with the same subId, does not create a new subscription
+            fakeWifiEventFlow.value = validCarrierMergedEvent(subId = 5, level = 2)
+
+            assertThat(latest).hasSize(1)
+            assertThat(latest!![0].subscriptionId).isEqualTo(5)
+
+            job.cancel()
+        }
+
+    @Test
     fun `multiple subscriptions`() =
         testScope.runTest {
             var latest: List<SubscriptionModel>? = null
@@ -133,6 +188,35 @@
         }
 
     @Test
+    fun `mobile subscription and carrier merged subscription`() =
+        testScope.runTest {
+            var latest: List<SubscriptionModel>? = null
+            val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
+
+            fakeNetworkEventFlow.value = validMobileEvent(subId = 1)
+            fakeWifiEventFlow.value = validCarrierMergedEvent(subId = 5)
+
+            assertThat(latest).hasSize(2)
+
+            job.cancel()
+        }
+
+    @Test
+    fun `multiple mobile subscriptions and carrier merged subscription`() =
+        testScope.runTest {
+            var latest: List<SubscriptionModel>? = null
+            val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
+
+            fakeNetworkEventFlow.value = validMobileEvent(subId = 1)
+            fakeNetworkEventFlow.value = validMobileEvent(subId = 2)
+            fakeWifiEventFlow.value = validCarrierMergedEvent(subId = 3)
+
+            assertThat(latest).hasSize(3)
+
+            job.cancel()
+        }
+
+    @Test
     fun `mobile disabled event - disables connection - subId specified - single conn`() =
         testScope.runTest {
             var latest: List<SubscriptionModel>? = null
@@ -194,6 +278,112 @@
             job.cancel()
         }
 
+    @Test
+    fun `wifi network updates to disabled - carrier merged connection removed`() =
+        testScope.runTest {
+            var latest: List<SubscriptionModel>? = null
+            val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
+
+            fakeWifiEventFlow.value = validCarrierMergedEvent(subId = 1)
+
+            assertThat(latest).hasSize(1)
+
+            fakeWifiEventFlow.value = FakeWifiEventModel.WifiDisabled
+
+            assertThat(latest).isEmpty()
+
+            job.cancel()
+        }
+
+    @Test
+    fun `wifi network updates to active - carrier merged connection removed`() =
+        testScope.runTest {
+            var latest: List<SubscriptionModel>? = null
+            val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
+
+            fakeWifiEventFlow.value = validCarrierMergedEvent(subId = 1)
+
+            assertThat(latest).hasSize(1)
+
+            fakeWifiEventFlow.value =
+                FakeWifiEventModel.Wifi(
+                    level = 1,
+                    activity = 0,
+                    ssid = null,
+                    validated = true,
+                )
+
+            assertThat(latest).isEmpty()
+
+            job.cancel()
+        }
+
+    @Test
+    fun `mobile sub updates to carrier merged - only one connection`() =
+        testScope.runTest {
+            var latestSubsList: List<SubscriptionModel>? = null
+            var connections: List<DemoMobileConnectionRepository>? = null
+            val job =
+                underTest.subscriptions
+                    .onEach { latestSubsList = it }
+                    .onEach { infos ->
+                        connections =
+                            infos.map { info -> underTest.getRepoForSubId(info.subscriptionId) }
+                    }
+                    .launchIn(this)
+
+            fakeNetworkEventFlow.value = validMobileEvent(subId = 3, level = 2)
+            assertThat(latestSubsList).hasSize(1)
+
+            val carrierMergedEvent = validCarrierMergedEvent(subId = 3, level = 1)
+            fakeWifiEventFlow.value = carrierMergedEvent
+            assertThat(latestSubsList).hasSize(1)
+            val connection = connections!!.find { it.subId == 3 }!!
+            assertCarrierMergedConnection(connection, carrierMergedEvent)
+
+            job.cancel()
+        }
+
+    @Test
+    fun `mobile sub updates to carrier merged then back - has old mobile data`() =
+        testScope.runTest {
+            var latestSubsList: List<SubscriptionModel>? = null
+            var connections: List<DemoMobileConnectionRepository>? = null
+            val job =
+                underTest.subscriptions
+                    .onEach { latestSubsList = it }
+                    .onEach { infos ->
+                        connections =
+                            infos.map { info -> underTest.getRepoForSubId(info.subscriptionId) }
+                    }
+                    .launchIn(this)
+
+            val mobileEvent = validMobileEvent(subId = 3, level = 2)
+            fakeNetworkEventFlow.value = mobileEvent
+            assertThat(latestSubsList).hasSize(1)
+
+            val carrierMergedEvent = validCarrierMergedEvent(subId = 3, level = 1)
+            fakeWifiEventFlow.value = carrierMergedEvent
+            assertThat(latestSubsList).hasSize(1)
+            var connection = connections!!.find { it.subId == 3 }!!
+            assertCarrierMergedConnection(connection, carrierMergedEvent)
+
+            // WHEN the carrier merged is removed
+            fakeWifiEventFlow.value =
+                FakeWifiEventModel.Wifi(
+                    level = 4,
+                    activity = 0,
+                    ssid = null,
+                    validated = true,
+                )
+
+            // THEN the subId=3 connection goes back to the mobile information
+            connection = connections!!.find { it.subId == 3 }!!
+            assertConnection(connection, mobileEvent)
+
+            job.cancel()
+        }
+
     /** Regression test for b/261706421 */
     @Test
     fun `multiple connections - remove all - does not throw`() =
@@ -289,6 +479,51 @@
             job.cancel()
         }
 
+    @Test
+    fun `demo connection - two connections - update carrier merged - no affect on first`() =
+        testScope.runTest {
+            var currentEvent1 = validMobileEvent(subId = 1)
+            var connection1: DemoMobileConnectionRepository? = null
+            var currentEvent2 = validCarrierMergedEvent(subId = 2)
+            var connection2: DemoMobileConnectionRepository? = null
+            var connections: List<DemoMobileConnectionRepository>? = null
+            val job =
+                underTest.subscriptions
+                    .onEach { infos ->
+                        connections =
+                            infos.map { info -> underTest.getRepoForSubId(info.subscriptionId) }
+                    }
+                    .launchIn(this)
+
+            fakeNetworkEventFlow.value = currentEvent1
+            fakeWifiEventFlow.value = currentEvent2
+            assertThat(connections).hasSize(2)
+            connections!!.forEach {
+                when (it.subId) {
+                    1 -> connection1 = it
+                    2 -> connection2 = it
+                    else -> Assert.fail("Unexpected subscription")
+                }
+            }
+
+            assertConnection(connection1!!, currentEvent1)
+            assertCarrierMergedConnection(connection2!!, currentEvent2)
+
+            // WHEN the event changes for connection 2, it updates, and connection 1 stays the same
+            currentEvent2 = validCarrierMergedEvent(subId = 2, level = 4)
+            fakeWifiEventFlow.value = currentEvent2
+            assertConnection(connection1!!, currentEvent1)
+            assertCarrierMergedConnection(connection2!!, currentEvent2)
+
+            // and vice versa
+            currentEvent1 = validMobileEvent(subId = 1, inflateStrength = true)
+            fakeNetworkEventFlow.value = currentEvent1
+            assertConnection(connection1!!, currentEvent1)
+            assertCarrierMergedConnection(connection2!!, currentEvent2)
+
+            job.cancel()
+        }
+
     private fun assertConnection(
         conn: DemoMobileConnectionRepository,
         model: FakeNetworkEventModel
@@ -315,6 +550,21 @@
             else -> {}
         }
     }
+
+    private fun assertCarrierMergedConnection(
+        conn: DemoMobileConnectionRepository,
+        model: FakeWifiEventModel.CarrierMerged,
+    ) {
+        val connectionInfo: MobileConnectionModel = conn.connectionInfo.value
+        assertThat(conn.subId).isEqualTo(model.subscriptionId)
+        assertThat(connectionInfo.cdmaLevel).isEqualTo(model.level)
+        assertThat(connectionInfo.primaryLevel).isEqualTo(model.level)
+        assertThat(connectionInfo.carrierNetworkChangeActive).isEqualTo(false)
+        assertThat(connectionInfo.isRoaming).isEqualTo(false)
+        assertThat(connectionInfo.isEmergencyOnly).isFalse()
+        assertThat(connectionInfo.isGsm).isFalse()
+        assertThat(connectionInfo.dataConnectionState).isEqualTo(DataConnectionState.Connected)
+    }
 }
 
 /** Convenience to create a valid fake network event with minimal params */
@@ -339,3 +589,14 @@
         roaming = roaming,
         name = "demo name",
     )
+
+fun validCarrierMergedEvent(
+    subId: Int = 1,
+    level: Int = 1,
+    numberOfLevels: Int = 4,
+): FakeWifiEventModel.CarrierMerged =
+    FakeWifiEventModel.CarrierMerged(
+        subscriptionId = subId,
+        level = level,
+        numberOfLevels = numberOfLevels,
+    )
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt
new file mode 100644
index 0000000..ea90150
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.mobile.data.repository.prod
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
+import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel
+import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
+import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType
+import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
+import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.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.MockitoAnnotations
+
+@SmallTest
+@OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidTestingRunner::class)
+class CarrierMergedConnectionRepositoryTest : SysuiTestCase() {
+
+    private lateinit var underTest: CarrierMergedConnectionRepository
+
+    private lateinit var wifiRepository: FakeWifiRepository
+    @Mock private lateinit var logger: TableLogBuffer
+
+    private val testDispatcher = UnconfinedTestDispatcher()
+    private val testScope = TestScope(testDispatcher)
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        wifiRepository = FakeWifiRepository()
+
+        underTest =
+            CarrierMergedConnectionRepository(
+                SUB_ID,
+                logger,
+                NetworkNameModel.Default("name"),
+                testScope.backgroundScope,
+                wifiRepository,
+            )
+    }
+
+    @Test
+    fun connectionInfo_inactiveWifi_isDefault() =
+        testScope.runTest {
+            var latest: MobileConnectionModel? = null
+            val job = underTest.connectionInfo.onEach { latest = it }.launchIn(this)
+
+            wifiRepository.setWifiNetwork(WifiNetworkModel.Inactive)
+
+            assertThat(latest).isEqualTo(MobileConnectionModel())
+
+            job.cancel()
+        }
+
+    @Test
+    fun connectionInfo_activeWifi_isDefault() =
+        testScope.runTest {
+            var latest: MobileConnectionModel? = null
+            val job = underTest.connectionInfo.onEach { latest = it }.launchIn(this)
+
+            wifiRepository.setWifiNetwork(WifiNetworkModel.Active(networkId = NET_ID, level = 1))
+
+            assertThat(latest).isEqualTo(MobileConnectionModel())
+
+            job.cancel()
+        }
+
+    @Test
+    fun connectionInfo_carrierMergedWifi_isValidAndFieldsComeFromWifiNetwork() =
+        testScope.runTest {
+            var latest: MobileConnectionModel? = null
+            val job = underTest.connectionInfo.onEach { latest = it }.launchIn(this)
+
+            wifiRepository.setIsWifiEnabled(true)
+            wifiRepository.setIsWifiDefault(true)
+
+            wifiRepository.setWifiNetwork(
+                WifiNetworkModel.CarrierMerged(
+                    networkId = NET_ID,
+                    subscriptionId = SUB_ID,
+                    level = 3,
+                )
+            )
+
+            val expected =
+                MobileConnectionModel(
+                    primaryLevel = 3,
+                    cdmaLevel = 3,
+                    dataConnectionState = DataConnectionState.Connected,
+                    dataActivityDirection =
+                        DataActivityModel(
+                            hasActivityIn = false,
+                            hasActivityOut = false,
+                        ),
+                    resolvedNetworkType = ResolvedNetworkType.CarrierMergedNetworkType,
+                    isRoaming = false,
+                    isEmergencyOnly = false,
+                    operatorAlphaShort = null,
+                    isInService = true,
+                    isGsm = false,
+                    carrierNetworkChangeActive = false,
+                )
+            assertThat(latest).isEqualTo(expected)
+
+            job.cancel()
+        }
+
+    @Test
+    fun connectionInfo_carrierMergedWifi_wrongSubId_isDefault() =
+        testScope.runTest {
+            var latest: MobileConnectionModel? = null
+            val job = underTest.connectionInfo.onEach { latest = it }.launchIn(this)
+
+            wifiRepository.setWifiNetwork(
+                WifiNetworkModel.CarrierMerged(
+                    networkId = NET_ID,
+                    subscriptionId = SUB_ID + 10,
+                    level = 3,
+                )
+            )
+
+            assertThat(latest).isEqualTo(MobileConnectionModel())
+            assertThat(latest!!.primaryLevel).isNotEqualTo(3)
+            assertThat(latest!!.resolvedNetworkType)
+                .isNotEqualTo(ResolvedNetworkType.CarrierMergedNetworkType)
+
+            job.cancel()
+        }
+
+    // This scenario likely isn't possible, but write a test for it anyway
+    @Test
+    fun connectionInfo_carrierMergedButNotEnabled_isDefault() =
+        testScope.runTest {
+            var latest: MobileConnectionModel? = null
+            val job = underTest.connectionInfo.onEach { latest = it }.launchIn(this)
+
+            wifiRepository.setWifiNetwork(
+                WifiNetworkModel.CarrierMerged(
+                    networkId = NET_ID,
+                    subscriptionId = SUB_ID,
+                    level = 3,
+                )
+            )
+            wifiRepository.setIsWifiEnabled(false)
+
+            assertThat(latest).isEqualTo(MobileConnectionModel())
+
+            job.cancel()
+        }
+
+    // This scenario likely isn't possible, but write a test for it anyway
+    @Test
+    fun connectionInfo_carrierMergedButWifiNotDefault_isDefault() =
+        testScope.runTest {
+            var latest: MobileConnectionModel? = null
+            val job = underTest.connectionInfo.onEach { latest = it }.launchIn(this)
+
+            wifiRepository.setWifiNetwork(
+                WifiNetworkModel.CarrierMerged(
+                    networkId = NET_ID,
+                    subscriptionId = SUB_ID,
+                    level = 3,
+                )
+            )
+            wifiRepository.setIsWifiDefault(false)
+
+            assertThat(latest).isEqualTo(MobileConnectionModel())
+
+            job.cancel()
+        }
+
+    @Test
+    fun numberOfLevels_comesFromCarrierMerged() =
+        testScope.runTest {
+            var latest: Int? = null
+            val job = underTest.numberOfLevels.onEach { latest = it }.launchIn(this)
+
+            wifiRepository.setWifiNetwork(
+                WifiNetworkModel.CarrierMerged(
+                    networkId = NET_ID,
+                    subscriptionId = SUB_ID,
+                    level = 1,
+                    numberOfLevels = 6,
+                )
+            )
+
+            assertThat(latest).isEqualTo(6)
+
+            job.cancel()
+        }
+
+    @Test
+    fun dataEnabled_matchesWifiEnabled() =
+        testScope.runTest {
+            var latest: Boolean? = null
+            val job = underTest.dataEnabled.onEach { latest = it }.launchIn(this)
+
+            wifiRepository.setIsWifiEnabled(true)
+            assertThat(latest).isTrue()
+
+            wifiRepository.setIsWifiEnabled(false)
+            assertThat(latest).isFalse()
+
+            job.cancel()
+        }
+
+    @Test
+    fun cdmaRoaming_alwaysFalse() =
+        testScope.runTest {
+            var latest: Boolean? = null
+            val job = underTest.cdmaRoaming.onEach { latest = it }.launchIn(this)
+
+            assertThat(latest).isFalse()
+
+            job.cancel()
+        }
+
+    private companion object {
+        const val SUB_ID = 123
+        const val NET_ID = 456
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt
new file mode 100644
index 0000000..c02a4df
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt
@@ -0,0 +1,389 @@
+/*
+ * 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.pipeline.mobile.data.repository.prod
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.log.table.TableLogBufferFactory
+import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel
+import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
+import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+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.mockito.Mockito.never
+import org.mockito.Mockito.verify
+
+/**
+ * This repo acts as a dispatcher to either the `typical` or `carrier merged` versions of the
+ * repository interface it's switching on. These tests just need to verify that the entire interface
+ * properly switches over when the value of `isCarrierMerged` changes.
+ */
+@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+class FullMobileConnectionRepositoryTest : SysuiTestCase() {
+    private lateinit var underTest: FullMobileConnectionRepository
+
+    private val testDispatcher = UnconfinedTestDispatcher()
+    private val testScope = TestScope(testDispatcher)
+    private val mobileMappings = FakeMobileMappingsProxy()
+    private val tableLogBuffer = mock<TableLogBuffer>()
+    private val mobileFactory = mock<MobileConnectionRepositoryImpl.Factory>()
+    private val carrierMergedFactory = mock<CarrierMergedConnectionRepository.Factory>()
+
+    private lateinit var connectionsRepo: FakeMobileConnectionsRepository
+    private val globalMobileDataSettingChangedEvent: Flow<Unit>
+        get() = connectionsRepo.globalMobileDataSettingChangedEvent
+
+    private lateinit var mobileRepo: FakeMobileConnectionRepository
+    private lateinit var carrierMergedRepo: FakeMobileConnectionRepository
+
+    @Before
+    fun setUp() {
+        connectionsRepo = FakeMobileConnectionsRepository(mobileMappings, tableLogBuffer)
+
+        mobileRepo = FakeMobileConnectionRepository(SUB_ID, tableLogBuffer)
+        carrierMergedRepo = FakeMobileConnectionRepository(SUB_ID, tableLogBuffer)
+
+        whenever(
+                mobileFactory.build(
+                    eq(SUB_ID),
+                    any(),
+                    eq(DEFAULT_NAME),
+                    eq(SEP),
+                    eq(globalMobileDataSettingChangedEvent),
+                )
+            )
+            .thenReturn(mobileRepo)
+        whenever(carrierMergedFactory.build(eq(SUB_ID), any(), eq(DEFAULT_NAME)))
+            .thenReturn(carrierMergedRepo)
+    }
+
+    @Test
+    fun startingIsCarrierMerged_usesCarrierMergedInitially() =
+        testScope.runTest {
+            val carrierMergedConnectionInfo =
+                MobileConnectionModel(
+                    operatorAlphaShort = "Carrier Merged Operator",
+                )
+            carrierMergedRepo.setConnectionInfo(carrierMergedConnectionInfo)
+
+            initializeRepo(startingIsCarrierMerged = true)
+
+            assertThat(underTest.activeRepo.value).isEqualTo(carrierMergedRepo)
+            assertThat(underTest.connectionInfo.value).isEqualTo(carrierMergedConnectionInfo)
+            verify(mobileFactory, never())
+                .build(
+                    SUB_ID,
+                    tableLogBuffer,
+                    DEFAULT_NAME,
+                    SEP,
+                    globalMobileDataSettingChangedEvent
+                )
+        }
+
+    @Test
+    fun startingNotCarrierMerged_usesTypicalInitially() =
+        testScope.runTest {
+            val mobileConnectionInfo =
+                MobileConnectionModel(
+                    operatorAlphaShort = "Typical Operator",
+                )
+            mobileRepo.setConnectionInfo(mobileConnectionInfo)
+
+            initializeRepo(startingIsCarrierMerged = false)
+
+            assertThat(underTest.activeRepo.value).isEqualTo(mobileRepo)
+            assertThat(underTest.connectionInfo.value).isEqualTo(mobileConnectionInfo)
+            verify(carrierMergedFactory, never()).build(SUB_ID, tableLogBuffer, DEFAULT_NAME)
+        }
+
+    @Test
+    fun activeRepo_matchesIsCarrierMerged() =
+        testScope.runTest {
+            initializeRepo(startingIsCarrierMerged = false)
+            var latest: MobileConnectionRepository? = null
+            val job = underTest.activeRepo.onEach { latest = it }.launchIn(this)
+
+            underTest.setIsCarrierMerged(true)
+
+            assertThat(latest).isEqualTo(carrierMergedRepo)
+
+            underTest.setIsCarrierMerged(false)
+
+            assertThat(latest).isEqualTo(mobileRepo)
+
+            underTest.setIsCarrierMerged(true)
+
+            assertThat(latest).isEqualTo(carrierMergedRepo)
+
+            job.cancel()
+        }
+
+    @Test
+    fun connectionInfo_getsUpdatesFromRepo_carrierMerged() =
+        testScope.runTest {
+            initializeRepo(startingIsCarrierMerged = false)
+
+            var latest: MobileConnectionModel? = null
+            val job = underTest.connectionInfo.onEach { latest = it }.launchIn(this)
+
+            underTest.setIsCarrierMerged(true)
+
+            val info1 =
+                MobileConnectionModel(
+                    operatorAlphaShort = "Carrier Merged Operator",
+                    primaryLevel = 1,
+                )
+            carrierMergedRepo.setConnectionInfo(info1)
+
+            assertThat(latest).isEqualTo(info1)
+
+            val info2 =
+                MobileConnectionModel(
+                    operatorAlphaShort = "Carrier Merged Operator #2",
+                    primaryLevel = 2,
+                )
+            carrierMergedRepo.setConnectionInfo(info2)
+
+            assertThat(latest).isEqualTo(info2)
+
+            val info3 =
+                MobileConnectionModel(
+                    operatorAlphaShort = "Carrier Merged Operator #3",
+                    primaryLevel = 3,
+                )
+            carrierMergedRepo.setConnectionInfo(info3)
+
+            assertThat(latest).isEqualTo(info3)
+
+            job.cancel()
+        }
+
+    @Test
+    fun connectionInfo_getsUpdatesFromRepo_mobile() =
+        testScope.runTest {
+            initializeRepo(startingIsCarrierMerged = false)
+
+            var latest: MobileConnectionModel? = null
+            val job = underTest.connectionInfo.onEach { latest = it }.launchIn(this)
+
+            underTest.setIsCarrierMerged(false)
+
+            val info1 =
+                MobileConnectionModel(
+                    operatorAlphaShort = "Typical Merged Operator",
+                    primaryLevel = 1,
+                )
+            mobileRepo.setConnectionInfo(info1)
+
+            assertThat(latest).isEqualTo(info1)
+
+            val info2 =
+                MobileConnectionModel(
+                    operatorAlphaShort = "Typical Merged Operator #2",
+                    primaryLevel = 2,
+                )
+            mobileRepo.setConnectionInfo(info2)
+
+            assertThat(latest).isEqualTo(info2)
+
+            val info3 =
+                MobileConnectionModel(
+                    operatorAlphaShort = "Typical Merged Operator #3",
+                    primaryLevel = 3,
+                )
+            mobileRepo.setConnectionInfo(info3)
+
+            assertThat(latest).isEqualTo(info3)
+
+            job.cancel()
+        }
+
+    @Test
+    fun connectionInfo_updatesWhenCarrierMergedUpdates() =
+        testScope.runTest {
+            initializeRepo(startingIsCarrierMerged = false)
+
+            var latest: MobileConnectionModel? = null
+            val job = underTest.connectionInfo.onEach { latest = it }.launchIn(this)
+
+            val carrierMergedInfo =
+                MobileConnectionModel(
+                    operatorAlphaShort = "Carrier Merged Operator",
+                    primaryLevel = 4,
+                )
+            carrierMergedRepo.setConnectionInfo(carrierMergedInfo)
+
+            val mobileInfo =
+                MobileConnectionModel(
+                    operatorAlphaShort = "Typical Operator",
+                    primaryLevel = 2,
+                )
+            mobileRepo.setConnectionInfo(mobileInfo)
+
+            // Start with the mobile info
+            assertThat(latest).isEqualTo(mobileInfo)
+
+            // WHEN isCarrierMerged is set to true
+            underTest.setIsCarrierMerged(true)
+
+            // THEN the carrier merged info is used
+            assertThat(latest).isEqualTo(carrierMergedInfo)
+
+            val newCarrierMergedInfo =
+                MobileConnectionModel(
+                    operatorAlphaShort = "New CM Operator",
+                    primaryLevel = 0,
+                )
+            carrierMergedRepo.setConnectionInfo(newCarrierMergedInfo)
+
+            assertThat(latest).isEqualTo(newCarrierMergedInfo)
+
+            // WHEN isCarrierMerged is set to false
+            underTest.setIsCarrierMerged(false)
+
+            // THEN the typical info is used
+            assertThat(latest).isEqualTo(mobileInfo)
+
+            val newMobileInfo =
+                MobileConnectionModel(
+                    operatorAlphaShort = "New Mobile Operator",
+                    primaryLevel = 3,
+                )
+            mobileRepo.setConnectionInfo(newMobileInfo)
+
+            assertThat(latest).isEqualTo(newMobileInfo)
+
+            job.cancel()
+        }
+
+    @Test
+    fun `factory - reuses log buffers for same connection`() =
+        testScope.runTest {
+            val realLoggerFactory = TableLogBufferFactory(mock(), FakeSystemClock())
+
+            val factory =
+                FullMobileConnectionRepository.Factory(
+                    scope = testScope.backgroundScope,
+                    realLoggerFactory,
+                    mobileFactory,
+                    carrierMergedFactory,
+                )
+
+            // Create two connections for the same subId. Similar to if the connection appeared
+            // and disappeared from the connectionFactory's perspective
+            val connection1 =
+                factory.build(
+                    SUB_ID,
+                    startingIsCarrierMerged = false,
+                    DEFAULT_NAME,
+                    SEP,
+                    globalMobileDataSettingChangedEvent,
+                )
+
+            val connection1Repeat =
+                factory.build(
+                    SUB_ID,
+                    startingIsCarrierMerged = false,
+                    DEFAULT_NAME,
+                    SEP,
+                    globalMobileDataSettingChangedEvent,
+                )
+
+            assertThat(connection1.tableLogBuffer)
+                .isSameInstanceAs(connection1Repeat.tableLogBuffer)
+        }
+
+    @Test
+    fun `factory - reuses log buffers for same sub ID even if carrier merged`() =
+        testScope.runTest {
+            val realLoggerFactory = TableLogBufferFactory(mock(), FakeSystemClock())
+
+            val factory =
+                FullMobileConnectionRepository.Factory(
+                    scope = testScope.backgroundScope,
+                    realLoggerFactory,
+                    mobileFactory,
+                    carrierMergedFactory,
+                )
+
+            val connection1 =
+                factory.build(
+                    SUB_ID,
+                    startingIsCarrierMerged = false,
+                    DEFAULT_NAME,
+                    SEP,
+                    globalMobileDataSettingChangedEvent,
+                )
+
+            // WHEN a connection with the same sub ID but carrierMerged = true is created
+            val connection1Repeat =
+                factory.build(
+                    SUB_ID,
+                    startingIsCarrierMerged = true,
+                    DEFAULT_NAME,
+                    SEP,
+                    globalMobileDataSettingChangedEvent,
+                )
+
+            // THEN the same table is re-used
+            assertThat(connection1.tableLogBuffer)
+                .isSameInstanceAs(connection1Repeat.tableLogBuffer)
+        }
+
+    // TODO(b/238425913): Verify that the logging switches correctly (once the carrier merged repo
+    //   implements logging).
+
+    private fun initializeRepo(startingIsCarrierMerged: Boolean) {
+        underTest =
+            FullMobileConnectionRepository(
+                SUB_ID,
+                startingIsCarrierMerged,
+                tableLogBuffer,
+                DEFAULT_NAME,
+                SEP,
+                globalMobileDataSettingChangedEvent,
+                testScope.backgroundScope,
+                mobileFactory,
+                carrierMergedFactory,
+            )
+    }
+
+    private companion object {
+        const val SUB_ID = 42
+        private val DEFAULT_NAME = NetworkNameModel.Default("default name")
+        private const val SEP = "-"
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
index 7970443..d6b8c0d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
@@ -20,7 +20,10 @@
 import android.os.UserHandle
 import android.provider.Settings
 import android.telephony.CellSignalStrengthCdma
+import android.telephony.NetworkRegistrationInfo
 import android.telephony.ServiceState
+import android.telephony.ServiceState.STATE_IN_SERVICE
+import android.telephony.ServiceState.STATE_OUT_OF_SERVICE
 import android.telephony.SignalStrength
 import android.telephony.SubscriptionInfo
 import android.telephony.TelephonyCallback
@@ -47,7 +50,6 @@
 import android.telephony.TelephonyManager.EXTRA_SPN
 import android.telephony.TelephonyManager.EXTRA_SUBSCRIPTION_ID
 import android.telephony.TelephonyManager.NETWORK_TYPE_LTE
-import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.log.table.TableLogBuffer
@@ -59,6 +61,7 @@
 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.UnknownNetworkType
 import com.android.systemui.statusbar.pipeline.mobile.data.model.toNetworkNameModel
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
 import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
 import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
@@ -115,7 +118,6 @@
                 telephonyManager,
                 globalSettings,
                 fakeBroadcastDispatcher,
-                connectionsRepo.defaultDataSubId,
                 connectionsRepo.globalMobileDataSettingChangedEvent,
                 mobileMappings,
                 IMMEDIATE,
@@ -302,7 +304,6 @@
             var latest: MobileConnectionModel? = null
             val job = underTest.connectionInfo.onEach { latest = it }.launchIn(this)
 
-            val type = NETWORK_TYPE_UNKNOWN
             val expected = UnknownNetworkType
 
             assertThat(latest?.resolvedNetworkType).isEqualTo(expected)
@@ -318,7 +319,7 @@
 
             val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>()
             val type = NETWORK_TYPE_LTE
-            val expected = DefaultNetworkType(type, mobileMappings.toIconKey(type))
+            val expected = DefaultNetworkType(mobileMappings.toIconKey(type))
             val ti = mock<TelephonyDisplayInfo>().also { whenever(it.networkType).thenReturn(type) }
             callback.onDisplayInfoChanged(ti)
 
@@ -335,7 +336,7 @@
 
             val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>()
             val type = OVERRIDE_NETWORK_TYPE_LTE_CA
-            val expected = OverrideNetworkType(type, mobileMappings.toIconKeyOverride(type))
+            val expected = OverrideNetworkType(mobileMappings.toIconKeyOverride(type))
             val ti =
                 mock<TelephonyDisplayInfo>().also {
                     whenever(it.networkType).thenReturn(type)
@@ -379,33 +380,6 @@
         }
 
     @Test
-    fun isDefaultDataSubscription_isDefault() =
-        runBlocking(IMMEDIATE) {
-            connectionsRepo.setDefaultDataSubId(SUB_1_ID)
-
-            var latest: Boolean? = null
-            val job = underTest.isDefaultDataSubscription.onEach { latest = it }.launchIn(this)
-
-            assertThat(latest).isTrue()
-
-            job.cancel()
-        }
-
-    @Test
-    fun isDefaultDataSubscription_isNotDefault() =
-        runBlocking(IMMEDIATE) {
-            // Our subId is SUB_1_ID
-            connectionsRepo.setDefaultDataSubId(123)
-
-            var latest: Boolean? = null
-            val job = underTest.isDefaultDataSubscription.onEach { latest = it }.launchIn(this)
-
-            assertThat(latest).isFalse()
-
-            job.cancel()
-        }
-
-    @Test
     fun isDataConnectionAllowed_subIdSettingUpdate_valueUpdated() =
         runBlocking(IMMEDIATE) {
             val subIdSettingName = "${Settings.Global.MOBILE_DATA}$SUB_1_ID"
@@ -430,6 +404,17 @@
         }
 
     @Test
+    fun numberOfLevels_isDefault() =
+        runBlocking(IMMEDIATE) {
+            var latest: Int? = null
+            val job = underTest.numberOfLevels.onEach { latest = it }.launchIn(this)
+
+            assertThat(latest).isEqualTo(DEFAULT_NUM_LEVELS)
+
+            job.cancel()
+        }
+
+    @Test
     fun `roaming - cdma - queries telephony manager`() =
         runBlocking(IMMEDIATE) {
             var latest: Boolean? = null
@@ -590,6 +575,56 @@
             job.cancel()
         }
 
+    @Test
+    fun `connection model - isInService - not iwlan`() =
+        runBlocking(IMMEDIATE) {
+            var latest: Boolean? = null
+            val job = underTest.connectionInfo.onEach { latest = it.isInService }.launchIn(this)
+
+            val serviceState = ServiceState()
+            serviceState.voiceRegState = STATE_IN_SERVICE
+            serviceState.dataRegState = STATE_IN_SERVICE
+
+            getTelephonyCallbackForType<ServiceStateListener>().onServiceStateChanged(serviceState)
+
+            assertThat(latest).isTrue()
+
+            serviceState.voiceRegState = STATE_OUT_OF_SERVICE
+            getTelephonyCallbackForType<ServiceStateListener>().onServiceStateChanged(serviceState)
+            assertThat(latest).isTrue()
+
+            serviceState.dataRegState = STATE_OUT_OF_SERVICE
+            getTelephonyCallbackForType<ServiceStateListener>().onServiceStateChanged(serviceState)
+            assertThat(latest).isFalse()
+
+            job.cancel()
+        }
+
+    @Test
+    fun `connection model - isInService - is iwlan - voice out of service - data in service`() =
+        runBlocking(IMMEDIATE) {
+            var latest: Boolean? = null
+            val job = underTest.connectionInfo.onEach { latest = it.isInService }.launchIn(this)
+
+            // Mock the service state here so we can make it specifically IWLAN
+            val serviceState: ServiceState = mock()
+            whenever(serviceState.state).thenReturn(STATE_OUT_OF_SERVICE)
+            whenever(serviceState.dataRegistrationState).thenReturn(STATE_IN_SERVICE)
+
+            // See [com.android.settingslib.Utils.isInService] for more info. This is one way to
+            // make the network look like IWLAN
+            val networkRegWlan: NetworkRegistrationInfo = mock()
+            whenever(serviceState.getNetworkRegistrationInfo(any(), any()))
+                .thenReturn(networkRegWlan)
+            whenever(networkRegWlan.registrationState)
+                .thenReturn(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
+
+            getTelephonyCallbackForType<ServiceStateListener>().onServiceStateChanged(serviceState)
+            assertThat(latest).isFalse()
+
+            job.cancel()
+        }
+
     private fun getTelephonyCallbacks(): List<TelephonyCallback> {
         val callbackCaptor = argumentCaptor<TelephonyCallback>()
         Mockito.verify(telephonyManager).registerTelephonyCallback(any(), callbackCaptor.capture())
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 b8cd7a4..ae390a0 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
@@ -38,8 +38,11 @@
 import com.android.systemui.log.table.TableLogBufferFactory
 import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Factory.Companion.tableBufferLogName
 import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
+import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.eq
@@ -72,6 +75,9 @@
     private lateinit var underTest: MobileConnectionsRepositoryImpl
 
     private lateinit var connectionFactory: MobileConnectionRepositoryImpl.Factory
+    private lateinit var carrierMergedFactory: CarrierMergedConnectionRepository.Factory
+    private lateinit var fullConnectionFactory: FullMobileConnectionRepository.Factory
+    private lateinit var wifiRepository: FakeWifiRepository
     @Mock private lateinit var connectivityManager: ConnectivityManager
     @Mock private lateinit var subscriptionManager: SubscriptionManager
     @Mock private lateinit var telephonyManager: TelephonyManager
@@ -94,10 +100,12 @@
             }
         }
 
-        whenever(logBufferFactory.create(anyString(), anyInt())).thenAnswer { _ ->
+        whenever(logBufferFactory.getOrCreate(anyString(), anyInt())).thenAnswer { _ ->
             mock<TableLogBuffer>()
         }
 
+        wifiRepository = FakeWifiRepository()
+
         connectionFactory =
             MobileConnectionRepositoryImpl.Factory(
                 fakeBroadcastDispatcher,
@@ -108,7 +116,18 @@
                 logger = logger,
                 mobileMappingsProxy = mobileMappings,
                 scope = scope,
+            )
+        carrierMergedFactory =
+            CarrierMergedConnectionRepository.Factory(
+                scope,
+                wifiRepository,
+            )
+        fullConnectionFactory =
+            FullMobileConnectionRepository.Factory(
+                scope = scope,
                 logFactory = logBufferFactory,
+                mobileRepoFactory = connectionFactory,
+                carrierMergedRepoFactory = carrierMergedFactory,
             )
 
         underTest =
@@ -123,7 +142,8 @@
                 context,
                 IMMEDIATE,
                 scope,
-                connectionFactory,
+                wifiRepository,
+                fullConnectionFactory,
             )
     }
 
@@ -178,6 +198,40 @@
         }
 
     @Test
+    fun testSubscriptions_carrierMergedOnly_listHasCarrierMerged() =
+        runBlocking(IMMEDIATE) {
+            var latest: List<SubscriptionModel>? = null
+
+            val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
+
+            wifiRepository.setWifiNetwork(WIFI_NETWORK_CM)
+            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
+                .thenReturn(listOf(SUB_CM))
+            getSubscriptionCallback().onSubscriptionsChanged()
+
+            assertThat(latest).isEqualTo(listOf(MODEL_CM))
+
+            job.cancel()
+        }
+
+    @Test
+    fun testSubscriptions_carrierMergedAndOther_listHasBothWithCarrierMergedLast() =
+        runBlocking(IMMEDIATE) {
+            var latest: List<SubscriptionModel>? = null
+
+            val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
+
+            wifiRepository.setWifiNetwork(WIFI_NETWORK_CM)
+            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
+                .thenReturn(listOf(SUB_1, SUB_2, SUB_CM))
+            getSubscriptionCallback().onSubscriptionsChanged()
+
+            assertThat(latest).isEqualTo(listOf(MODEL_1, MODEL_2, MODEL_CM))
+
+            job.cancel()
+        }
+
+    @Test
     fun testActiveDataSubscriptionId_initialValueIsInvalidId() =
         runBlocking(IMMEDIATE) {
             assertThat(underTest.activeMobileDataSubscriptionId.value)
@@ -217,6 +271,96 @@
         }
 
     @Test
+    fun testConnectionRepository_carrierMergedSubId_isCached() =
+        runBlocking(IMMEDIATE) {
+            val job = underTest.subscriptions.launchIn(this)
+
+            wifiRepository.setWifiNetwork(WIFI_NETWORK_CM)
+            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
+                .thenReturn(listOf(SUB_CM))
+            getSubscriptionCallback().onSubscriptionsChanged()
+
+            val repo1 = underTest.getRepoForSubId(SUB_CM_ID)
+            val repo2 = underTest.getRepoForSubId(SUB_CM_ID)
+
+            assertThat(repo1).isSameInstanceAs(repo2)
+
+            job.cancel()
+        }
+
+    @Test
+    fun testConnectionRepository_carrierMergedAndMobileSubs_usesCorrectRepos() =
+        runBlocking(IMMEDIATE) {
+            val job = underTest.subscriptions.launchIn(this)
+
+            wifiRepository.setWifiNetwork(WIFI_NETWORK_CM)
+            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
+                .thenReturn(listOf(SUB_1, SUB_CM))
+            getSubscriptionCallback().onSubscriptionsChanged()
+
+            val carrierMergedRepo = underTest.getRepoForSubId(SUB_CM_ID)
+            val mobileRepo = underTest.getRepoForSubId(SUB_1_ID)
+            assertThat(carrierMergedRepo.getIsCarrierMerged()).isTrue()
+            assertThat(mobileRepo.getIsCarrierMerged()).isFalse()
+
+            job.cancel()
+        }
+
+    @Test
+    fun testSubscriptions_subNoLongerCarrierMerged_repoUpdates() =
+        runBlocking(IMMEDIATE) {
+            val job = underTest.subscriptions.launchIn(this)
+
+            wifiRepository.setWifiNetwork(WIFI_NETWORK_CM)
+            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
+                .thenReturn(listOf(SUB_1, SUB_CM))
+            getSubscriptionCallback().onSubscriptionsChanged()
+
+            val carrierMergedRepo = underTest.getRepoForSubId(SUB_CM_ID)
+            var mobileRepo = underTest.getRepoForSubId(SUB_1_ID)
+            assertThat(carrierMergedRepo.getIsCarrierMerged()).isTrue()
+            assertThat(mobileRepo.getIsCarrierMerged()).isFalse()
+
+            // WHEN the wifi network updates to be not carrier merged
+            wifiRepository.setWifiNetwork(WifiNetworkModel.Active(networkId = 4, level = 1))
+
+            // THEN the repos update
+            val noLongerCarrierMergedRepo = underTest.getRepoForSubId(SUB_CM_ID)
+            mobileRepo = underTest.getRepoForSubId(SUB_1_ID)
+            assertThat(noLongerCarrierMergedRepo.getIsCarrierMerged()).isFalse()
+            assertThat(mobileRepo.getIsCarrierMerged()).isFalse()
+
+            job.cancel()
+        }
+
+    @Test
+    fun testSubscriptions_subBecomesCarrierMerged_repoUpdates() =
+        runBlocking(IMMEDIATE) {
+            val job = underTest.subscriptions.launchIn(this)
+
+            wifiRepository.setWifiNetwork(WifiNetworkModel.Inactive)
+            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
+                .thenReturn(listOf(SUB_1, SUB_CM))
+            getSubscriptionCallback().onSubscriptionsChanged()
+
+            val notYetCarrierMergedRepo = underTest.getRepoForSubId(SUB_CM_ID)
+            var mobileRepo = underTest.getRepoForSubId(SUB_1_ID)
+            assertThat(notYetCarrierMergedRepo.getIsCarrierMerged()).isFalse()
+            assertThat(mobileRepo.getIsCarrierMerged()).isFalse()
+
+            // WHEN the wifi network updates to be carrier merged
+            wifiRepository.setWifiNetwork(WIFI_NETWORK_CM)
+
+            // THEN the repos update
+            val carrierMergedRepo = underTest.getRepoForSubId(SUB_CM_ID)
+            mobileRepo = underTest.getRepoForSubId(SUB_1_ID)
+            assertThat(carrierMergedRepo.getIsCarrierMerged()).isTrue()
+            assertThat(mobileRepo.getIsCarrierMerged()).isFalse()
+
+            job.cancel()
+        }
+
+    @Test
     fun testConnectionCache_clearsInvalidSubscriptions() =
         runBlocking(IMMEDIATE) {
             val job = underTest.subscriptions.launchIn(this)
@@ -242,6 +386,34 @@
             job.cancel()
         }
 
+    @Test
+    fun testConnectionCache_clearsInvalidSubscriptions_includingCarrierMerged() =
+        runBlocking(IMMEDIATE) {
+            val job = underTest.subscriptions.launchIn(this)
+
+            wifiRepository.setWifiNetwork(WIFI_NETWORK_CM)
+            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
+                .thenReturn(listOf(SUB_1, SUB_2, SUB_CM))
+            getSubscriptionCallback().onSubscriptionsChanged()
+
+            // Get repos to trigger caching
+            val repo1 = underTest.getRepoForSubId(SUB_1_ID)
+            val repo2 = underTest.getRepoForSubId(SUB_2_ID)
+            val repoCarrierMerged = underTest.getRepoForSubId(SUB_CM_ID)
+
+            assertThat(underTest.getSubIdRepoCache())
+                .containsExactly(SUB_1_ID, repo1, SUB_2_ID, repo2, SUB_CM_ID, repoCarrierMerged)
+
+            // SUB_2 and SUB_CM disappear
+            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
+                .thenReturn(listOf(SUB_1))
+            getSubscriptionCallback().onSubscriptionsChanged()
+
+            assertThat(underTest.getSubIdRepoCache()).containsExactly(SUB_1_ID, repo1)
+
+            job.cancel()
+        }
+
     /** Regression test for b/261706421 */
     @Test
     fun testConnectionsCache_clearMultipleSubscriptionsAtOnce_doesNotThrow() =
@@ -292,14 +464,14 @@
             // Get repos to trigger creation
             underTest.getRepoForSubId(SUB_1_ID)
             verify(logBufferFactory)
-                .create(
-                    eq(MobileConnectionRepositoryImpl.tableBufferLogName(SUB_1_ID)),
+                .getOrCreate(
+                    eq(tableBufferLogName(SUB_1_ID)),
                     anyInt(),
                 )
             underTest.getRepoForSubId(SUB_2_ID)
             verify(logBufferFactory)
-                .create(
-                    eq(MobileConnectionRepositoryImpl.tableBufferLogName(SUB_2_ID)),
+                .getOrCreate(
+                    eq(tableBufferLogName(SUB_2_ID)),
                     anyInt(),
                 )
 
@@ -448,7 +620,8 @@
                     context,
                     IMMEDIATE,
                     scope,
-                    connectionFactory,
+                    wifiRepository,
+                    fullConnectionFactory,
                 )
 
             var latest: MobileMappings.Config? = null
@@ -558,5 +731,16 @@
 
         private const val NET_ID = 123
         private val NETWORK = mock<Network>().apply { whenever(getNetId()).thenReturn(NET_ID) }
+
+        private const val SUB_CM_ID = 5
+        private val SUB_CM =
+            mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_CM_ID) }
+        private val MODEL_CM = SubscriptionModel(subscriptionId = SUB_CM_ID)
+        private val WIFI_NETWORK_CM =
+            WifiNetworkModel.CarrierMerged(
+                networkId = 3,
+                subscriptionId = SUB_CM_ID,
+                level = 1,
+            )
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
index c494589..7aeaa48 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
@@ -21,6 +21,7 @@
 import com.android.settingslib.mobile.TelephonyIcons
 import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
 import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
 import kotlinx.coroutines.flow.MutableStateFlow
 
@@ -29,6 +30,8 @@
 ) : MobileIconInteractor {
     override val alwaysShowDataRatIcon = MutableStateFlow(false)
 
+    override val alwaysUseCdmaLevel = MutableStateFlow(false)
+
     override val activity =
         MutableStateFlow(
             DataActivityModel(
@@ -37,6 +40,8 @@
             )
         )
 
+    override val isConnected = MutableStateFlow(true)
+
     private val _iconGroup = MutableStateFlow<SignalIcon.MobileIconGroup>(TelephonyIcons.THREE_G)
     override val networkTypeIconGroup = _iconGroup
 
@@ -52,6 +57,8 @@
 
     override val isDataConnected = MutableStateFlow(true)
 
+    override val isInService = MutableStateFlow(true)
+
     private val _isDataEnabled = MutableStateFlow(true)
     override val isDataEnabled = _isDataEnabled
 
@@ -61,7 +68,7 @@
     private val _level = MutableStateFlow(CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN)
     override val level = _level
 
-    private val _numberOfLevels = MutableStateFlow(4)
+    private val _numberOfLevels = MutableStateFlow(DEFAULT_NUM_LEVELS)
     override val numberOfLevels = _numberOfLevels
 
     fun setIconGroup(group: SignalIcon.MobileIconGroup) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt
index 19e5516..172755c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt
@@ -23,6 +23,7 @@
 import com.android.settingslib.SignalIcon.MobileIconGroup
 import com.android.settingslib.mobile.TelephonyIcons
 import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
 import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -58,6 +59,11 @@
 
     override val alwaysShowDataRatIcon = MutableStateFlow(false)
 
+    override val alwaysUseCdmaLevel = MutableStateFlow(false)
+    override val defaultDataSubId = MutableStateFlow(DEFAULT_DATA_SUB_ID)
+
+    override val defaultMobileNetworkConnectivity = MutableStateFlow(MobileConnectivityModel())
+
     private val _defaultMobileIconMapping = MutableStateFlow(TEST_MAPPING)
     override val defaultMobileIconMapping = _defaultMobileIconMapping
 
@@ -75,6 +81,8 @@
     companion object {
         val DEFAULT_ICON = TelephonyIcons.G
 
+        const val DEFAULT_DATA_SUB_ID = 1
+
         // Use [MobileMappings] to define some simple definitions
         const val THREE_G = NETWORK_TYPE_GSM
         const val LTE = NETWORK_TYPE_LTE
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
index 83c5055..c42aba5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
@@ -17,7 +17,6 @@
 package com.android.systemui.statusbar.pipeline.mobile.domain.interactor
 
 import android.telephony.CellSignalStrength
-import android.telephony.SubscriptionInfo
 import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
 import androidx.test.filters.SmallTest
 import com.android.settingslib.SignalIcon.MobileIconGroup
@@ -26,6 +25,7 @@
 import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
 import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
+import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.CarrierMergedNetworkType
 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType
 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.OverrideNetworkType
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository
@@ -34,7 +34,6 @@
 import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconsInteractor.Companion.THREE_G
 import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
 import com.android.systemui.util.mockito.mock
-import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
@@ -61,8 +60,11 @@
                 scope,
                 mobileIconsInteractor.activeDataConnectionHasDataEnabled,
                 mobileIconsInteractor.alwaysShowDataRatIcon,
+                mobileIconsInteractor.alwaysUseCdmaLevel,
+                mobileIconsInteractor.defaultMobileNetworkConnectivity,
                 mobileIconsInteractor.defaultMobileIconMapping,
                 mobileIconsInteractor.defaultMobileIconGroup,
+                mobileIconsInteractor.defaultDataSubId,
                 mobileIconsInteractor.isDefaultConnectionFailed,
                 connectionRepository,
             )
@@ -103,7 +105,27 @@
         }
 
     @Test
-    fun cdma_level_default_unknown() =
+    fun gsm_alwaysShowCdmaTrue_stillUsesGsmLevel() =
+        runBlocking(IMMEDIATE) {
+            connectionRepository.setConnectionInfo(
+                MobileConnectionModel(
+                    isGsm = true,
+                    primaryLevel = GSM_LEVEL,
+                    cdmaLevel = CDMA_LEVEL,
+                ),
+            )
+            mobileIconsInteractor.alwaysUseCdmaLevel.value = true
+
+            var latest: Int? = null
+            val job = underTest.level.onEach { latest = it }.launchIn(this)
+
+            assertThat(latest).isEqualTo(GSM_LEVEL)
+
+            job.cancel()
+        }
+
+    @Test
+    fun notGsm_level_default_unknown() =
         runBlocking(IMMEDIATE) {
             connectionRepository.setConnectionInfo(
                 MobileConnectionModel(isGsm = false),
@@ -117,7 +139,7 @@
         }
 
     @Test
-    fun cdma_usesCdmaLevel() =
+    fun notGsm_alwaysShowCdmaTrue_usesCdmaLevel() =
         runBlocking(IMMEDIATE) {
             connectionRepository.setConnectionInfo(
                 MobileConnectionModel(
@@ -126,6 +148,7 @@
                     cdmaLevel = CDMA_LEVEL
                 ),
             )
+            mobileIconsInteractor.alwaysUseCdmaLevel.value = true
 
             var latest: Int? = null
             val job = underTest.level.onEach { latest = it }.launchIn(this)
@@ -136,12 +159,46 @@
         }
 
     @Test
+    fun notGsm_alwaysShowCdmaFalse_usesPrimaryLevel() =
+        runBlocking(IMMEDIATE) {
+            connectionRepository.setConnectionInfo(
+                MobileConnectionModel(
+                    isGsm = false,
+                    primaryLevel = GSM_LEVEL,
+                    cdmaLevel = CDMA_LEVEL,
+                ),
+            )
+            mobileIconsInteractor.alwaysUseCdmaLevel.value = false
+
+            var latest: Int? = null
+            val job = underTest.level.onEach { latest = it }.launchIn(this)
+
+            assertThat(latest).isEqualTo(GSM_LEVEL)
+
+            job.cancel()
+        }
+
+    @Test
+    fun numberOfLevels_comesFromRepo() =
+        runBlocking(IMMEDIATE) {
+            var latest: Int? = null
+            val job = underTest.numberOfLevels.onEach { latest = it }.launchIn(this)
+
+            connectionRepository.numberOfLevels.value = 5
+            assertThat(latest).isEqualTo(5)
+
+            connectionRepository.numberOfLevels.value = 4
+            assertThat(latest).isEqualTo(4)
+
+            job.cancel()
+        }
+
+    @Test
     fun iconGroup_three_g() =
         runBlocking(IMMEDIATE) {
             connectionRepository.setConnectionInfo(
                 MobileConnectionModel(
-                    resolvedNetworkType =
-                        DefaultNetworkType(THREE_G, mobileMappingsProxy.toIconKey(THREE_G))
+                    resolvedNetworkType = DefaultNetworkType(mobileMappingsProxy.toIconKey(THREE_G))
                 ),
             )
 
@@ -158,8 +215,7 @@
         runBlocking(IMMEDIATE) {
             connectionRepository.setConnectionInfo(
                 MobileConnectionModel(
-                    resolvedNetworkType =
-                        DefaultNetworkType(THREE_G, mobileMappingsProxy.toIconKey(THREE_G))
+                    resolvedNetworkType = DefaultNetworkType(mobileMappingsProxy.toIconKey(THREE_G))
                 ),
             )
 
@@ -170,7 +226,6 @@
                 MobileConnectionModel(
                     resolvedNetworkType =
                         DefaultNetworkType(
-                            FOUR_G,
                             mobileMappingsProxy.toIconKey(FOUR_G),
                         ),
                 ),
@@ -188,10 +243,7 @@
             connectionRepository.setConnectionInfo(
                 MobileConnectionModel(
                     resolvedNetworkType =
-                        OverrideNetworkType(
-                            FIVE_G_OVERRIDE,
-                            mobileMappingsProxy.toIconKeyOverride(FIVE_G_OVERRIDE)
-                        )
+                        OverrideNetworkType(mobileMappingsProxy.toIconKeyOverride(FIVE_G_OVERRIDE))
                 ),
             )
 
@@ -209,10 +261,7 @@
             connectionRepository.setConnectionInfo(
                 MobileConnectionModel(
                     resolvedNetworkType =
-                        DefaultNetworkType(
-                            NETWORK_TYPE_UNKNOWN,
-                            mobileMappingsProxy.toIconKey(NETWORK_TYPE_UNKNOWN)
-                        ),
+                        DefaultNetworkType(mobileMappingsProxy.toIconKey(NETWORK_TYPE_UNKNOWN)),
                 ),
             )
 
@@ -225,6 +274,47 @@
         }
 
     @Test
+    fun iconGroup_carrierMerged_usesOverride() =
+        runBlocking(IMMEDIATE) {
+            connectionRepository.setConnectionInfo(
+                MobileConnectionModel(
+                    resolvedNetworkType = CarrierMergedNetworkType,
+                ),
+            )
+
+            var latest: MobileIconGroup? = null
+            val job = underTest.networkTypeIconGroup.onEach { latest = it }.launchIn(this)
+
+            assertThat(latest).isEqualTo(CarrierMergedNetworkType.iconGroupOverride)
+
+            job.cancel()
+        }
+
+    @Test
+    fun `icon group - checks default data`() =
+        runBlocking(IMMEDIATE) {
+            mobileIconsInteractor.defaultDataSubId.value = SUB_1_ID
+            connectionRepository.setConnectionInfo(
+                MobileConnectionModel(
+                    resolvedNetworkType = DefaultNetworkType(mobileMappingsProxy.toIconKey(THREE_G))
+                ),
+            )
+
+            var latest: MobileIconGroup? = null
+            val job = underTest.networkTypeIconGroup.onEach { latest = it }.launchIn(this)
+
+            assertThat(latest).isEqualTo(TelephonyIcons.THREE_G)
+
+            // Default data sub id changes to something else
+            mobileIconsInteractor.defaultDataSubId.value = 123
+            yield()
+
+            assertThat(latest).isEqualTo(TelephonyIcons.NOT_DEFAULT_DATA)
+
+            job.cancel()
+        }
+
+    @Test
     fun alwaysShowDataRatIcon_matchesParent() =
         runBlocking(IMMEDIATE) {
             var latest: Boolean? = null
@@ -240,6 +330,21 @@
         }
 
     @Test
+    fun alwaysUseCdmaLevel_matchesParent() =
+        runBlocking(IMMEDIATE) {
+            var latest: Boolean? = null
+            val job = underTest.alwaysUseCdmaLevel.onEach { latest = it }.launchIn(this)
+
+            mobileIconsInteractor.alwaysUseCdmaLevel.value = true
+            assertThat(latest).isTrue()
+
+            mobileIconsInteractor.alwaysUseCdmaLevel.value = false
+            assertThat(latest).isFalse()
+
+            job.cancel()
+        }
+
+    @Test
     fun test_isDefaultDataEnabled_matchesParent() =
         runBlocking(IMMEDIATE) {
             var latest: Boolean? = null
@@ -300,6 +405,23 @@
         }
 
     @Test
+    fun `isInService - uses repository value`() =
+        runBlocking(IMMEDIATE) {
+            var latest: Boolean? = null
+            val job = underTest.isInService.onEach { latest = it }.launchIn(this)
+
+            connectionRepository.setConnectionInfo(MobileConnectionModel(isInService = true))
+
+            assertThat(latest).isTrue()
+
+            connectionRepository.setConnectionInfo(MobileConnectionModel(isInService = false))
+
+            assertThat(latest).isFalse()
+
+            job.cancel()
+        }
+
+    @Test
     fun `roaming - is gsm - uses connection model`() =
         runBlocking(IMMEDIATE) {
             var latest: Boolean? = null
@@ -435,8 +557,6 @@
         private const val CDMA_LEVEL = 2
 
         private const val SUB_1_ID = 1
-        private val SUB_1 =
-            mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_1_ID) }
 
         private val DEFAULT_NAME = NetworkNameModel.Default("test default name")
         private val DERIVED_NAME = NetworkNameModel.Derived("test derived name")
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
index 2fa3467..1b62d5c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
@@ -31,11 +31,13 @@
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.advanceTimeBy
+import kotlinx.coroutines.test.runTest
 import kotlinx.coroutines.yield
 import org.junit.After
 import org.junit.Before
@@ -43,13 +45,16 @@
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 class MobileIconsInteractorTest : SysuiTestCase() {
     private lateinit var underTest: MobileIconsInteractor
     private lateinit var connectionsRepository: FakeMobileConnectionsRepository
     private val userSetupRepository = FakeUserSetupRepository()
     private val mobileMappingsProxy = FakeMobileMappingsProxy()
-    private val scope = CoroutineScope(IMMEDIATE)
+
+    private val testDispatcher = UnconfinedTestDispatcher()
+    private val testScope = TestScope(testDispatcher)
 
     @Mock private lateinit var carrierConfigTracker: CarrierConfigTracker
 
@@ -73,7 +78,7 @@
                 connectionsRepository,
                 carrierConfigTracker,
                 userSetupRepository,
-                scope
+                testScope.backgroundScope,
             )
     }
 
@@ -81,7 +86,7 @@
 
     @Test
     fun filteredSubscriptions_default() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             var latest: List<SubscriptionModel>? = null
             val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this)
 
@@ -92,7 +97,7 @@
 
     @Test
     fun filteredSubscriptions_nonOpportunistic_updatesWithMultipleSubs() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             connectionsRepository.setSubscriptions(listOf(SUB_1, SUB_2))
 
             var latest: List<SubscriptionModel>? = null
@@ -105,7 +110,7 @@
 
     @Test
     fun filteredSubscriptions_bothOpportunistic_configFalse_showsActive_3() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             connectionsRepository.setSubscriptions(listOf(SUB_3_OPP, SUB_4_OPP))
             connectionsRepository.setActiveMobileDataSubscriptionId(SUB_3_ID)
             whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
@@ -122,7 +127,7 @@
 
     @Test
     fun filteredSubscriptions_bothOpportunistic_configFalse_showsActive_4() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             connectionsRepository.setSubscriptions(listOf(SUB_3_OPP, SUB_4_OPP))
             connectionsRepository.setActiveMobileDataSubscriptionId(SUB_4_ID)
             whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
@@ -139,7 +144,7 @@
 
     @Test
     fun filteredSubscriptions_oneOpportunistic_configTrue_showsPrimary_active_1() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             connectionsRepository.setSubscriptions(listOf(SUB_1, SUB_3_OPP))
             connectionsRepository.setActiveMobileDataSubscriptionId(SUB_1_ID)
             whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
@@ -157,7 +162,7 @@
 
     @Test
     fun filteredSubscriptions_oneOpportunistic_configTrue_showsPrimary_nonActive_1() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             connectionsRepository.setSubscriptions(listOf(SUB_1, SUB_3_OPP))
             connectionsRepository.setActiveMobileDataSubscriptionId(SUB_3_ID)
             whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
@@ -175,7 +180,7 @@
 
     @Test
     fun activeDataConnection_turnedOn() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             CONNECTION_1.setDataEnabled(true)
             var latest: Boolean? = null
             val job =
@@ -188,7 +193,7 @@
 
     @Test
     fun activeDataConnection_turnedOff() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             CONNECTION_1.setDataEnabled(true)
             var latest: Boolean? = null
             val job =
@@ -204,7 +209,7 @@
 
     @Test
     fun activeDataConnection_invalidSubId() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             var latest: Boolean? = null
             val job =
                 underTest.activeDataConnectionHasDataEnabled.onEach { latest = it }.launchIn(this)
@@ -220,7 +225,7 @@
 
     @Test
     fun failedConnection_connected_validated_notFailed() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             var latest: Boolean? = null
             val job = underTest.isDefaultConnectionFailed.onEach { latest = it }.launchIn(this)
             connectionsRepository.setMobileConnectivity(MobileConnectivityModel(true, true))
@@ -233,7 +238,7 @@
 
     @Test
     fun failedConnection_notConnected_notValidated_notFailed() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             var latest: Boolean? = null
             val job = underTest.isDefaultConnectionFailed.onEach { latest = it }.launchIn(this)
 
@@ -247,7 +252,7 @@
 
     @Test
     fun failedConnection_connected_notValidated_failed() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             var latest: Boolean? = null
             val job = underTest.isDefaultConnectionFailed.onEach { latest = it }.launchIn(this)
 
@@ -261,7 +266,7 @@
 
     @Test
     fun alwaysShowDataRatIcon_configHasTrue() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             var latest: Boolean? = null
             val job = underTest.alwaysShowDataRatIcon.onEach { latest = it }.launchIn(this)
 
@@ -277,7 +282,7 @@
 
     @Test
     fun alwaysShowDataRatIcon_configHasFalse() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             var latest: Boolean? = null
             val job = underTest.alwaysShowDataRatIcon.onEach { latest = it }.launchIn(this)
 
@@ -291,8 +296,318 @@
             job.cancel()
         }
 
+    @Test
+    fun alwaysUseCdmaLevel_configHasTrue() =
+        testScope.runTest {
+            var latest: Boolean? = null
+            val job = underTest.alwaysUseCdmaLevel.onEach { latest = it }.launchIn(this)
+
+            val config = MobileMappings.Config()
+            config.alwaysShowCdmaRssi = true
+            connectionsRepository.defaultDataSubRatConfig.value = config
+            yield()
+
+            assertThat(latest).isTrue()
+
+            job.cancel()
+        }
+
+    @Test
+    fun alwaysUseCdmaLevel_configHasFalse() =
+        testScope.runTest {
+            var latest: Boolean? = null
+            val job = underTest.alwaysUseCdmaLevel.onEach { latest = it }.launchIn(this)
+
+            val config = MobileMappings.Config()
+            config.alwaysShowCdmaRssi = false
+            connectionsRepository.defaultDataSubRatConfig.value = config
+            yield()
+
+            assertThat(latest).isFalse()
+
+            job.cancel()
+        }
+
+    @Test
+    fun `default mobile connectivity - uses repo value`() =
+        testScope.runTest {
+            var latest: MobileConnectivityModel? = null
+            val job =
+                underTest.defaultMobileNetworkConnectivity.onEach { latest = it }.launchIn(this)
+
+            var expected = MobileConnectivityModel(isConnected = true, isValidated = true)
+            connectionsRepository.setMobileConnectivity(expected)
+            assertThat(latest).isEqualTo(expected)
+
+            expected = MobileConnectivityModel(isConnected = false, isValidated = true)
+            connectionsRepository.setMobileConnectivity(expected)
+            assertThat(latest).isEqualTo(expected)
+
+            expected = MobileConnectivityModel(isConnected = true, isValidated = false)
+            connectionsRepository.setMobileConnectivity(expected)
+            assertThat(latest).isEqualTo(expected)
+
+            expected = MobileConnectivityModel(isConnected = false, isValidated = false)
+            connectionsRepository.setMobileConnectivity(expected)
+            assertThat(latest).isEqualTo(expected)
+
+            job.cancel()
+        }
+
+    @Test
+    fun `data switch - in same group - validated matches previous value`() =
+        testScope.runTest {
+            var latest: MobileConnectivityModel? = null
+            val job =
+                underTest.defaultMobileNetworkConnectivity.onEach { latest = it }.launchIn(this)
+
+            connectionsRepository.setMobileConnectivity(
+                MobileConnectivityModel(
+                    isConnected = true,
+                    isValidated = true,
+                )
+            )
+            // Trigger a data change in the same subscription group
+            connectionsRepository.activeSubChangedInGroupEvent.emit(Unit)
+            connectionsRepository.setMobileConnectivity(
+                MobileConnectivityModel(
+                    isConnected = false,
+                    isValidated = false,
+                )
+            )
+
+            assertThat(latest)
+                .isEqualTo(
+                    MobileConnectivityModel(
+                        isConnected = false,
+                        isValidated = true,
+                    )
+                )
+
+            job.cancel()
+        }
+
+    @Test
+    fun `data switch - in same group - validated matches previous value - expires after 2s`() =
+        testScope.runTest {
+            var latest: MobileConnectivityModel? = null
+            val job =
+                underTest.defaultMobileNetworkConnectivity.onEach { latest = it }.launchIn(this)
+
+            connectionsRepository.setMobileConnectivity(
+                MobileConnectivityModel(
+                    isConnected = true,
+                    isValidated = true,
+                )
+            )
+            // Trigger a data change in the same subscription group
+            connectionsRepository.activeSubChangedInGroupEvent.emit(Unit)
+            connectionsRepository.setMobileConnectivity(
+                MobileConnectivityModel(
+                    isConnected = false,
+                    isValidated = false,
+                )
+            )
+            // After 1s, the force validation bit is still present
+            advanceTimeBy(1000)
+            assertThat(latest)
+                .isEqualTo(
+                    MobileConnectivityModel(
+                        isConnected = false,
+                        isValidated = true,
+                    )
+                )
+
+            // After 2s, the force validation expires
+            advanceTimeBy(1001)
+
+            assertThat(latest)
+                .isEqualTo(
+                    MobileConnectivityModel(
+                        isConnected = false,
+                        isValidated = false,
+                    )
+                )
+
+            job.cancel()
+        }
+
+    @Test
+    fun `data switch - in same group - not validated - uses new value immediately`() =
+        testScope.runTest {
+            var latest: MobileConnectivityModel? = null
+            val job =
+                underTest.defaultMobileNetworkConnectivity.onEach { latest = it }.launchIn(this)
+
+            connectionsRepository.setMobileConnectivity(
+                MobileConnectivityModel(
+                    isConnected = true,
+                    isValidated = false,
+                )
+            )
+            connectionsRepository.activeSubChangedInGroupEvent.emit(Unit)
+            connectionsRepository.setMobileConnectivity(
+                MobileConnectivityModel(
+                    isConnected = false,
+                    isValidated = false,
+                )
+            )
+
+            assertThat(latest)
+                .isEqualTo(
+                    MobileConnectivityModel(
+                        isConnected = false,
+                        isValidated = false,
+                    )
+                )
+
+            job.cancel()
+        }
+
+    @Test
+    fun `data switch - lose validation - then switch happens - clears forced bit`() =
+        testScope.runTest {
+            var latest: MobileConnectivityModel? = null
+            val job =
+                underTest.defaultMobileNetworkConnectivity.onEach { latest = it }.launchIn(this)
+
+            // GIVEN the network starts validated
+            connectionsRepository.setMobileConnectivity(
+                MobileConnectivityModel(
+                    isConnected = true,
+                    isValidated = true,
+                )
+            )
+
+            // WHEN a data change happens in the same group
+            connectionsRepository.activeSubChangedInGroupEvent.emit(Unit)
+
+            // WHEN the validation bit is lost
+            connectionsRepository.setMobileConnectivity(
+                MobileConnectivityModel(
+                    isConnected = false,
+                    isValidated = false,
+                )
+            )
+
+            // WHEN another data change happens in the same group
+            connectionsRepository.activeSubChangedInGroupEvent.emit(Unit)
+
+            // THEN the forced validation bit is still removed after 2s
+            assertThat(latest)
+                .isEqualTo(
+                    MobileConnectivityModel(
+                        isConnected = false,
+                        isValidated = true,
+                    )
+                )
+
+            advanceTimeBy(1000)
+
+            assertThat(latest)
+                .isEqualTo(
+                    MobileConnectivityModel(
+                        isConnected = false,
+                        isValidated = true,
+                    )
+                )
+
+            advanceTimeBy(1001)
+
+            assertThat(latest)
+                .isEqualTo(
+                    MobileConnectivityModel(
+                        isConnected = false,
+                        isValidated = false,
+                    )
+                )
+
+            job.cancel()
+        }
+
+    @Test
+    fun `data switch - while already forcing validation - resets clock`() =
+        testScope.runTest {
+            var latest: MobileConnectivityModel? = null
+            val job =
+                underTest.defaultMobileNetworkConnectivity.onEach { latest = it }.launchIn(this)
+            connectionsRepository.setMobileConnectivity(
+                MobileConnectivityModel(
+                    isConnected = true,
+                    isValidated = true,
+                )
+            )
+
+            connectionsRepository.activeSubChangedInGroupEvent.emit(Unit)
+
+            advanceTimeBy(1000)
+
+            // WHEN another change in same group event happens
+            connectionsRepository.activeSubChangedInGroupEvent.emit(Unit)
+            connectionsRepository.setMobileConnectivity(
+                MobileConnectivityModel(
+                    isConnected = false,
+                    isValidated = false,
+                )
+            )
+
+            // THEN the forced validation remains for exactly 2 more seconds from now
+
+            // 1.500s from second event
+            advanceTimeBy(1500)
+            assertThat(latest)
+                .isEqualTo(
+                    MobileConnectivityModel(
+                        isConnected = false,
+                        isValidated = true,
+                    )
+                )
+
+            // 2.001s from the second event
+            advanceTimeBy(501)
+            assertThat(latest)
+                .isEqualTo(
+                    MobileConnectivityModel(
+                        isConnected = false,
+                        isValidated = false,
+                    )
+                )
+
+            job.cancel()
+        }
+
+    @Test
+    fun `data switch - not in same group - uses new values`() =
+        testScope.runTest {
+            var latest: MobileConnectivityModel? = null
+            val job =
+                underTest.defaultMobileNetworkConnectivity.onEach { latest = it }.launchIn(this)
+
+            connectionsRepository.setMobileConnectivity(
+                MobileConnectivityModel(
+                    isConnected = true,
+                    isValidated = true,
+                )
+            )
+            connectionsRepository.setMobileConnectivity(
+                MobileConnectivityModel(
+                    isConnected = false,
+                    isValidated = false,
+                )
+            )
+
+            assertThat(latest)
+                .isEqualTo(
+                    MobileConnectivityModel(
+                        isConnected = false,
+                        isValidated = false,
+                    )
+                )
+
+            job.cancel()
+        }
+
     companion object {
-        private val IMMEDIATE = Dispatchers.Main.immediate
         private val tableLogBuffer =
             TableLogBuffer(8, "MobileIconsInteractorTest", FakeSystemClock())
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt
new file mode 100644
index 0000000..a2c1209
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.mobile.ui.view
+
+import android.content.res.ColorStateList
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.testing.TestableLooper.RunWithLooper
+import android.testing.ViewUtils
+import android.view.View
+import android.widget.ImageView
+import androidx.test.filters.SmallTest
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.statusbar.StatusBarIconView
+import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconInteractor
+import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.LocationBasedMobileViewModel
+import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconViewModel
+import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.QsMobileIconViewModel
+import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
+import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper(setAsMainLooper = true)
+@OptIn(ExperimentalCoroutinesApi::class)
+class ModernStatusBarMobileViewTest : SysuiTestCase() {
+
+    private lateinit var testableLooper: TestableLooper
+    private val testDispatcher = UnconfinedTestDispatcher()
+    private val testScope = TestScope(testDispatcher)
+
+    @Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags
+    @Mock private lateinit var tableLogBuffer: TableLogBuffer
+    @Mock private lateinit var logger: ConnectivityPipelineLogger
+    @Mock private lateinit var constants: ConnectivityConstants
+
+    private lateinit var viewModel: LocationBasedMobileViewModel
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        testableLooper = TestableLooper.get(this)
+
+        val interactor = FakeMobileIconInteractor(tableLogBuffer)
+
+        val viewModelCommon =
+            MobileIconViewModel(
+                subscriptionId = 1,
+                interactor,
+                logger,
+                constants,
+                testScope.backgroundScope,
+            )
+        viewModel = QsMobileIconViewModel(viewModelCommon, statusBarPipelineFlags)
+    }
+
+    // Note: The following tests are more like integration tests, since they stand up a full
+    // [WifiViewModel] and test the interactions between the view, view-binder, and view-model.
+
+    @Test
+    fun setVisibleState_icon_iconShownDotHidden() {
+        val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel)
+
+        view.setVisibleState(StatusBarIconView.STATE_ICON, /* animate= */ false)
+
+        ViewUtils.attachView(view)
+        testableLooper.processAllMessages()
+
+        assertThat(view.getGroupView().visibility).isEqualTo(View.VISIBLE)
+        assertThat(view.getDotView().visibility).isEqualTo(View.GONE)
+
+        ViewUtils.detachView(view)
+    }
+
+    @Test
+    fun setVisibleState_dot_iconHiddenDotShown() {
+        val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel)
+
+        view.setVisibleState(StatusBarIconView.STATE_DOT, /* animate= */ false)
+
+        ViewUtils.attachView(view)
+        testableLooper.processAllMessages()
+
+        assertThat(view.getGroupView().visibility).isEqualTo(View.INVISIBLE)
+        assertThat(view.getDotView().visibility).isEqualTo(View.VISIBLE)
+
+        ViewUtils.detachView(view)
+    }
+
+    @Test
+    fun setVisibleState_hidden_iconAndDotHidden() {
+        val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel)
+
+        view.setVisibleState(StatusBarIconView.STATE_HIDDEN, /* animate= */ false)
+
+        ViewUtils.attachView(view)
+        testableLooper.processAllMessages()
+
+        assertThat(view.getGroupView().visibility).isEqualTo(View.INVISIBLE)
+        assertThat(view.getDotView().visibility).isEqualTo(View.INVISIBLE)
+
+        ViewUtils.detachView(view)
+    }
+
+    @Test
+    fun isIconVisible_alwaysTrue() {
+        val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel)
+
+        ViewUtils.attachView(view)
+        testableLooper.processAllMessages()
+
+        assertThat(view.isIconVisible).isTrue()
+
+        ViewUtils.detachView(view)
+    }
+
+    @Test
+    fun onDarkChanged_iconHasNewColor() {
+        whenever(statusBarPipelineFlags.useDebugColoring()).thenReturn(false)
+        val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel)
+        ViewUtils.attachView(view)
+        testableLooper.processAllMessages()
+
+        val color = 0x12345678
+        view.onDarkChanged(arrayListOf(), 1.0f, color)
+        testableLooper.processAllMessages()
+
+        assertThat(view.getIconView().imageTintList).isEqualTo(ColorStateList.valueOf(color))
+
+        ViewUtils.detachView(view)
+    }
+
+    @Test
+    fun setStaticDrawableColor_iconHasNewColor() {
+        whenever(statusBarPipelineFlags.useDebugColoring()).thenReturn(false)
+        val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel)
+        ViewUtils.attachView(view)
+        testableLooper.processAllMessages()
+
+        val color = 0x23456789
+        view.setStaticDrawableColor(color)
+        testableLooper.processAllMessages()
+
+        assertThat(view.getIconView().imageTintList).isEqualTo(ColorStateList.valueOf(color))
+
+        ViewUtils.detachView(view)
+    }
+
+    private fun View.getGroupView(): View {
+        return this.requireViewById(R.id.mobile_group)
+    }
+
+    private fun View.getIconView(): ImageView {
+        return this.requireViewById(R.id.mobile_signal)
+    }
+
+    private fun View.getDotView(): View {
+        return this.requireViewById(R.id.status_bar_dot)
+    }
+}
+
+private const val SLOT_NAME = "TestSlotName"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt
index 043d55a..c960a06 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt
@@ -20,6 +20,7 @@
 import com.android.settingslib.mobile.TelephonyIcons
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
 import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconInteractor
 import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconViewModelTest.Companion.defaultSignal
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
@@ -45,6 +46,7 @@
     private lateinit var qsIcon: QsMobileIconViewModel
     private lateinit var keyguardIcon: KeyguardMobileIconViewModel
     private lateinit var interactor: FakeMobileIconInteractor
+    @Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags
     @Mock private lateinit var logger: ConnectivityPipelineLogger
     @Mock private lateinit var constants: ConnectivityConstants
     @Mock private lateinit var tableLogBuffer: TableLogBuffer
@@ -68,9 +70,9 @@
         commonImpl =
             MobileIconViewModel(SUB_1_ID, interactor, logger, constants, testScope.backgroundScope)
 
-        homeIcon = HomeMobileIconViewModel(commonImpl, logger)
-        qsIcon = QsMobileIconViewModel(commonImpl, logger)
-        keyguardIcon = KeyguardMobileIconViewModel(commonImpl, logger)
+        homeIcon = HomeMobileIconViewModel(commonImpl, statusBarPipelineFlags)
+        qsIcon = QsMobileIconViewModel(commonImpl, statusBarPipelineFlags)
+        keyguardIcon = KeyguardMobileIconViewModel(commonImpl, statusBarPipelineFlags)
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
index 50221bc..a24e29ae 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
@@ -98,6 +98,30 @@
         }
 
     @Test
+    fun `icon - uses empty state - when not in service`() =
+        testScope.runTest {
+            var latest: Int? = null
+            val job = underTest.iconId.onEach { latest = it }.launchIn(this)
+
+            interactor.isInService.value = false
+
+            var expected = emptySignal()
+
+            assertThat(latest).isEqualTo(expected)
+
+            // Changing the level doesn't overwrite the disabled state
+            interactor.level.value = 2
+            assertThat(latest).isEqualTo(expected)
+
+            // Once back in service, the regular icon appears
+            interactor.isInService.value = true
+            expected = defaultSignal(level = 2)
+            assertThat(latest).isEqualTo(expected)
+
+            job.cancel()
+        }
+
+    @Test
     fun networkType_dataEnabled_groupIsRepresented() =
         testScope.runTest {
             val expected =
@@ -250,6 +274,41 @@
         }
 
     @Test
+    fun `network type - alwaysShow - shown when not connected`() =
+        testScope.runTest {
+            interactor.setIconGroup(THREE_G)
+            interactor.isConnected.value = false
+            interactor.alwaysShowDataRatIcon.value = true
+
+            var latest: Icon? = null
+            val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
+
+            val expected =
+                Icon.Resource(
+                    THREE_G.dataType,
+                    ContentDescription.Resource(THREE_G.dataContentDescription)
+                )
+            assertThat(latest).isEqualTo(expected)
+
+            job.cancel()
+        }
+
+    @Test
+    fun `network type - not shown when not connected`() =
+        testScope.runTest {
+            interactor.setIconGroup(THREE_G)
+            interactor.isDataConnected.value = true
+            interactor.isConnected.value = false
+
+            var latest: Icon? = null
+            val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
+
+            assertThat(latest).isNull()
+
+            job.cancel()
+        }
+
+    @Test
     fun roaming() =
         testScope.runTest {
             interactor.isRoaming.value = true
@@ -375,5 +434,7 @@
         ): Int {
             return SignalDrawable.getState(level, /* numLevels */ 4, !connected)
         }
+
+        fun emptySignal(): Int = SignalDrawable.getEmptyState(4)
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt
index d6cb762..58b50c7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt
@@ -19,6 +19,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.phone.StatusBarLocation
+import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
 import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconsInteractor
 import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
@@ -45,6 +46,7 @@
     private lateinit var underTest: MobileIconsViewModel
     private val interactor = FakeMobileIconsInteractor(FakeMobileMappingsProxy(), mock())
 
+    @Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags
     @Mock private lateinit var logger: ConnectivityPipelineLogger
     @Mock private lateinit var constants: ConnectivityConstants
 
@@ -67,6 +69,7 @@
                 logger,
                 constants,
                 testScope.backgroundScope,
+                statusBarPipelineFlags,
             )
 
         interactor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt
new file mode 100644
index 0000000..3fe6983
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.shared.ui.view
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.StatusBarIconView.STATE_DOT
+import com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN
+import com.android.systemui.statusbar.StatusBarIconView.STATE_ICON
+import com.android.systemui.statusbar.pipeline.shared.ui.binder.ModernStatusBarViewBinding
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper(setAsMainLooper = true)
+class ModernStatusBarViewTest : SysuiTestCase() {
+
+    private lateinit var binding: TestBinding
+
+    @Test
+    fun initView_hasCorrectSlot() {
+        val view = ModernStatusBarView(context, null)
+        val binding = TestBinding()
+
+        view.initView("slotName") { binding }
+
+        assertThat(view.slot).isEqualTo("slotName")
+    }
+
+    @Test
+    fun getVisibleState_icon_returnsIcon() {
+        val view = createAndInitView()
+
+        view.setVisibleState(STATE_ICON, /* animate= */ false)
+
+        assertThat(view.visibleState).isEqualTo(STATE_ICON)
+    }
+
+    @Test
+    fun getVisibleState_dot_returnsDot() {
+        val view = createAndInitView()
+
+        view.setVisibleState(STATE_DOT, /* animate= */ false)
+
+        assertThat(view.visibleState).isEqualTo(STATE_DOT)
+    }
+
+    @Test
+    fun getVisibleState_hidden_returnsHidden() {
+        val view = createAndInitView()
+
+        view.setVisibleState(STATE_HIDDEN, /* animate= */ false)
+
+        assertThat(view.visibleState).isEqualTo(STATE_HIDDEN)
+    }
+
+    @Test
+    fun onDarkChanged_bindingReceivesIconAndDecorTint() {
+        val view = createAndInitView()
+
+        view.onDarkChanged(arrayListOf(), 1.0f, 0x12345678)
+
+        assertThat(binding.iconTint).isEqualTo(0x12345678)
+        assertThat(binding.decorTint).isEqualTo(0x12345678)
+    }
+
+    @Test
+    fun setStaticDrawableColor_bindingReceivesIconTint() {
+        val view = createAndInitView()
+
+        view.setStaticDrawableColor(0x12345678)
+
+        assertThat(binding.iconTint).isEqualTo(0x12345678)
+    }
+
+    @Test
+    fun setDecorColor_bindingReceivesDecorColor() {
+        val view = createAndInitView()
+
+        view.setDecorColor(0x23456789)
+
+        assertThat(binding.decorTint).isEqualTo(0x23456789)
+    }
+
+    @Test
+    fun isIconVisible_usesBinding_true() {
+        val view = createAndInitView()
+
+        binding.shouldIconBeVisibleInternal = true
+
+        assertThat(view.isIconVisible).isEqualTo(true)
+    }
+
+    @Test
+    fun isIconVisible_usesBinding_false() {
+        val view = createAndInitView()
+
+        binding.shouldIconBeVisibleInternal = false
+
+        assertThat(view.isIconVisible).isEqualTo(false)
+    }
+
+    private fun createAndInitView(): ModernStatusBarView {
+        val view = ModernStatusBarView(context, null)
+        binding = TestBinding()
+        view.initView(SLOT_NAME) { binding }
+        return view
+    }
+
+    inner class TestBinding : ModernStatusBarViewBinding {
+        var iconTint: Int? = null
+        var decorTint: Int? = null
+        var onVisibilityStateChangedCalled: Boolean = false
+
+        var shouldIconBeVisibleInternal: Boolean = true
+
+        override fun onIconTintChanged(newTint: Int) {
+            iconTint = newTint
+        }
+
+        override fun onDecorTintChanged(newTint: Int) {
+            decorTint = newTint
+        }
+
+        override fun onVisibilityStateChanged(state: Int) {
+            onVisibilityStateChangedCalled = true
+        }
+
+        override fun getShouldIconBeVisible(): Boolean {
+            return shouldIconBeVisibleInternal
+        }
+    }
+}
+
+private const val SLOT_NAME = "TestSlotName"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModelTest.kt
index 30fd308..824cebd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModelTest.kt
@@ -16,11 +16,12 @@
 
 package com.android.systemui.statusbar.pipeline.wifi.data.model
 
+import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.log.table.TableRowLogger
 import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel.Active.Companion.MAX_VALID_LEVEL
-import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel.Active.Companion.MIN_VALID_LEVEL
+import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel.Companion.MIN_VALID_LEVEL
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 
@@ -34,12 +35,6 @@
         }
     }
 
-    @Test
-    fun active_levelNull_noException() {
-        WifiNetworkModel.Active(NETWORK_ID, level = null)
-        // No assert, just need no crash
-    }
-
     @Test(expected = IllegalArgumentException::class)
     fun active_levelNegative_exceptionThrown() {
         WifiNetworkModel.Active(NETWORK_ID, level = MIN_VALID_LEVEL - 1)
@@ -50,9 +45,53 @@
         WifiNetworkModel.Active(NETWORK_ID, level = MAX_VALID_LEVEL + 1)
     }
 
+    @Test(expected = IllegalArgumentException::class)
+    fun carrierMerged_invalidSubId_exceptionThrown() {
+        WifiNetworkModel.CarrierMerged(NETWORK_ID, INVALID_SUBSCRIPTION_ID, 1)
+    }
+
     // Non-exhaustive logDiffs test -- just want to make sure the logging logic isn't totally broken
 
     @Test
+    fun logDiffs_carrierMergedToInactive_resetsAllFields() {
+        val logger = TestLogger()
+        val prevVal =
+            WifiNetworkModel.CarrierMerged(
+                networkId = 5,
+                subscriptionId = 3,
+                level = 1,
+            )
+
+        WifiNetworkModel.Inactive.logDiffs(prevVal, logger)
+
+        assertThat(logger.changes).contains(Pair(COL_NETWORK_TYPE, TYPE_INACTIVE))
+        assertThat(logger.changes).contains(Pair(COL_NETWORK_ID, NETWORK_ID_DEFAULT.toString()))
+        assertThat(logger.changes).contains(Pair(COL_VALIDATED, "false"))
+        assertThat(logger.changes).contains(Pair(COL_LEVEL, LEVEL_DEFAULT.toString()))
+        assertThat(logger.changes).contains(Pair(COL_SSID, "null"))
+    }
+
+    @Test
+    fun logDiffs_inactiveToCarrierMerged_logsAllFields() {
+        val logger = TestLogger()
+        val carrierMerged =
+            WifiNetworkModel.CarrierMerged(
+                networkId = 6,
+                subscriptionId = 3,
+                level = 2,
+            )
+
+        carrierMerged.logDiffs(prevVal = WifiNetworkModel.Inactive, logger)
+
+        assertThat(logger.changes).contains(Pair(COL_NETWORK_TYPE, TYPE_CARRIER_MERGED))
+        assertThat(logger.changes).contains(Pair(COL_NETWORK_ID, "6"))
+        assertThat(logger.changes).contains(Pair(COL_SUB_ID, "3"))
+        assertThat(logger.changes).contains(Pair(COL_VALIDATED, "true"))
+        assertThat(logger.changes).contains(Pair(COL_LEVEL, "2"))
+        assertThat(logger.changes).contains(Pair(COL_SSID, "null"))
+    }
+
+    @Test
     fun logDiffs_inactiveToActive_logsAllActiveFields() {
         val logger = TestLogger()
         val activeNetwork =
@@ -101,8 +140,14 @@
                 level = 3,
                 ssid = "Test SSID"
             )
+        val prevVal =
+            WifiNetworkModel.CarrierMerged(
+                networkId = 5,
+                subscriptionId = 3,
+                level = 1,
+            )
 
-        activeNetwork.logDiffs(prevVal = WifiNetworkModel.CarrierMerged, logger)
+        activeNetwork.logDiffs(prevVal, logger)
 
         assertThat(logger.changes).contains(Pair(COL_NETWORK_TYPE, TYPE_ACTIVE))
         assertThat(logger.changes).contains(Pair(COL_NETWORK_ID, "5"))
@@ -111,7 +156,7 @@
         assertThat(logger.changes).contains(Pair(COL_SSID, "Test SSID"))
     }
     @Test
-    fun logDiffs_activeToCarrierMerged_resetsAllActiveFields() {
+    fun logDiffs_activeToCarrierMerged_logsAllFields() {
         val logger = TestLogger()
         val activeNetwork =
             WifiNetworkModel.Active(
@@ -120,13 +165,20 @@
                 level = 3,
                 ssid = "Test SSID"
             )
+        val carrierMerged =
+            WifiNetworkModel.CarrierMerged(
+                networkId = 6,
+                subscriptionId = 3,
+                level = 2,
+            )
 
-        WifiNetworkModel.CarrierMerged.logDiffs(prevVal = activeNetwork, logger)
+        carrierMerged.logDiffs(prevVal = activeNetwork, logger)
 
         assertThat(logger.changes).contains(Pair(COL_NETWORK_TYPE, TYPE_CARRIER_MERGED))
-        assertThat(logger.changes).contains(Pair(COL_NETWORK_ID, NETWORK_ID_DEFAULT.toString()))
-        assertThat(logger.changes).contains(Pair(COL_VALIDATED, "false"))
-        assertThat(logger.changes).contains(Pair(COL_LEVEL, LEVEL_DEFAULT.toString()))
+        assertThat(logger.changes).contains(Pair(COL_NETWORK_ID, "6"))
+        assertThat(logger.changes).contains(Pair(COL_SUB_ID, "3"))
+        assertThat(logger.changes).contains(Pair(COL_VALIDATED, "true"))
+        assertThat(logger.changes).contains(Pair(COL_LEVEL, "2"))
         assertThat(logger.changes).contains(Pair(COL_SSID, "null"))
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt
index 4e15b4a..f5837d6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt
@@ -18,7 +18,7 @@
 
 import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
 import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
-import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositoryImpl.Companion.ACTIVITY_DEFAULT
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl.Companion.ACTIVITY_DEFAULT
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
 
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 b935442..1085c2b 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
@@ -27,6 +27,7 @@
 import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.DemoModeWifiDataSource
 import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.DemoWifiRepository
 import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.model.FakeWifiEventModel
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.kotlinArgumentCaptor
 import com.android.systemui.util.mockito.whenever
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt
new file mode 100644
index 0000000..3c4e85b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.wifi.data.repository.prod
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
+import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+
+@SmallTest
+class DisabledWifiRepositoryTest : SysuiTestCase() {
+
+    private lateinit var underTest: DisabledWifiRepository
+
+    @Before
+    fun setUp() {
+        underTest = DisabledWifiRepository()
+    }
+
+    @Test
+    fun enabled_alwaysFalse() {
+        assertThat(underTest.isWifiEnabled.value).isEqualTo(false)
+    }
+
+    @Test
+    fun default_alwaysFalse() {
+        assertThat(underTest.isWifiDefault.value).isEqualTo(false)
+    }
+
+    @Test
+    fun network_alwaysUnavailable() {
+        assertThat(underTest.wifiNetwork.value).isEqualTo(WifiNetworkModel.Unavailable)
+    }
+
+    @Test
+    fun activity_alwaysFalse() {
+        assertThat(underTest.wifiActivity.value)
+            .isEqualTo(DataActivityModel(hasActivityIn = false, hasActivityOut = false))
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
similarity index 92%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
index 5d0d87b..87ce8fa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.pipeline.wifi.data.repository
+package com.android.systemui.statusbar.pipeline.wifi.data.repository.prod
 
 import android.net.ConnectivityManager
 import android.net.Network
@@ -26,6 +26,7 @@
 import android.net.wifi.WifiInfo
 import android.net.wifi.WifiManager
 import android.net.wifi.WifiManager.TrafficStateCallback
+import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.broadcast.BroadcastDispatcher
@@ -33,8 +34,7 @@
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
 import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
 import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
-import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositoryImpl.Companion.ACTIVITY_DEFAULT
-import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositoryImpl.Companion.WIFI_NETWORK_DEFAULT
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl.Companion.WIFI_NETWORK_DEFAULT
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.argumentCaptor
@@ -98,13 +98,6 @@
     }
 
     @Test
-    fun isWifiEnabled_nullWifiManager_getsFalse() = runBlocking(IMMEDIATE) {
-        underTest = createRepo(wifiManagerToUse = null)
-
-        assertThat(underTest.isWifiEnabled.value).isFalse()
-    }
-
-    @Test
     fun isWifiEnabled_initiallyGetsWifiManagerValue() = runBlocking(IMMEDIATE) {
         whenever(wifiManager.isWifiEnabled).thenReturn(true)
 
@@ -348,7 +341,6 @@
             .launchIn(this)
 
         val wifiInfo = mock<WifiInfo>().apply {
-            whenever(this.ssid).thenReturn(SSID)
             whenever(this.isPrimary).thenReturn(true)
             whenever(this.isCarrierMerged).thenReturn(true)
         }
@@ -361,6 +353,67 @@
     }
 
     @Test
+    fun wifiNetwork_carrierMergedButInvalidSubId_flowHasInvalid() =
+        runBlocking(IMMEDIATE) {
+            var latest: WifiNetworkModel? = null
+            val job = underTest
+                .wifiNetwork
+                .onEach { latest = it }
+                .launchIn(this)
+
+            val wifiInfo = mock<WifiInfo>().apply {
+                whenever(this.isPrimary).thenReturn(true)
+                whenever(this.isCarrierMerged).thenReturn(true)
+                whenever(this.subscriptionId).thenReturn(INVALID_SUBSCRIPTION_ID)
+            }
+
+            getNetworkCallback().onCapabilitiesChanged(
+                NETWORK,
+                createWifiNetworkCapabilities(wifiInfo),
+            )
+
+            assertThat(latest).isInstanceOf(WifiNetworkModel.Invalid::class.java)
+
+            job.cancel()
+        }
+
+    @Test
+    fun wifiNetwork_isCarrierMerged_getsCorrectValues() =
+        runBlocking(IMMEDIATE) {
+            var latest: WifiNetworkModel? = null
+            val job = underTest
+                .wifiNetwork
+                .onEach { latest = it }
+                .launchIn(this)
+
+            val rssi = -57
+            val wifiInfo = mock<WifiInfo>().apply {
+                whenever(this.isPrimary).thenReturn(true)
+                whenever(this.isCarrierMerged).thenReturn(true)
+                whenever(this.rssi).thenReturn(rssi)
+                whenever(this.subscriptionId).thenReturn(567)
+            }
+
+            whenever(wifiManager.calculateSignalLevel(rssi)).thenReturn(2)
+            whenever(wifiManager.maxSignalLevel).thenReturn(5)
+
+            getNetworkCallback().onCapabilitiesChanged(
+                NETWORK,
+                createWifiNetworkCapabilities(wifiInfo),
+            )
+
+            assertThat(latest is WifiNetworkModel.CarrierMerged).isTrue()
+            val latestCarrierMerged = latest as WifiNetworkModel.CarrierMerged
+            assertThat(latestCarrierMerged.networkId).isEqualTo(NETWORK_ID)
+            assertThat(latestCarrierMerged.subscriptionId).isEqualTo(567)
+            assertThat(latestCarrierMerged.level).isEqualTo(2)
+            // numberOfLevels = maxSignalLevel + 1
+            assertThat(latestCarrierMerged.numberOfLevels).isEqualTo(6)
+
+            job.cancel()
+        }
+
+    @Test
     fun wifiNetwork_notValidated_networkNotValidated() = runBlocking(IMMEDIATE) {
         var latest: WifiNetworkModel? = null
         val job = underTest
@@ -721,21 +774,6 @@
     }
 
     @Test
-    fun wifiActivity_nullWifiManager_receivesDefault() = runBlocking(IMMEDIATE) {
-        underTest = createRepo(wifiManagerToUse = null)
-
-        var latest: DataActivityModel? = null
-        val job = underTest
-                .wifiActivity
-                .onEach { latest = it }
-                .launchIn(this)
-
-        assertThat(latest).isEqualTo(ACTIVITY_DEFAULT)
-
-        job.cancel()
-    }
-
-    @Test
     fun wifiActivity_callbackGivesNone_activityFlowHasNone() = runBlocking(IMMEDIATE) {
         var latest: DataActivityModel? = null
         val job = underTest
@@ -801,7 +839,7 @@
         job.cancel()
     }
 
-    private fun createRepo(wifiManagerToUse: WifiManager? = wifiManager): WifiRepositoryImpl {
+    private fun createRepo(): WifiRepositoryImpl {
         return WifiRepositoryImpl(
             broadcastDispatcher,
             connectivityManager,
@@ -809,7 +847,7 @@
             tableLogger,
             executor,
             scope,
-            wifiManagerToUse,
+            wifiManager,
         )
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt
index 2ecb17b..089a170 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt
@@ -52,6 +52,22 @@
     }
 
     @Test
+    fun ssid_unavailableNetwork_outputsNull() =
+        runBlocking(IMMEDIATE) {
+            wifiRepository.setWifiNetwork(WifiNetworkModel.Unavailable)
+
+            var latest: String? = "default"
+            val job = underTest
+                .ssid
+                .onEach { latest = it }
+                .launchIn(this)
+
+            assertThat(latest).isNull()
+
+            job.cancel()
+        }
+
+    @Test
     fun ssid_inactiveNetwork_outputsNull() = runBlocking(IMMEDIATE) {
         wifiRepository.setWifiNetwork(WifiNetworkModel.Inactive)
 
@@ -68,7 +84,9 @@
 
     @Test
     fun ssid_carrierMergedNetwork_outputsNull() = runBlocking(IMMEDIATE) {
-        wifiRepository.setWifiNetwork(WifiNetworkModel.CarrierMerged)
+        wifiRepository.setWifiNetwork(
+            WifiNetworkModel.CarrierMerged(networkId = 1, subscriptionId = 2, level = 1)
+        )
 
         var latest: String? = "default"
         val job = underTest
@@ -85,6 +103,7 @@
     fun ssid_isPasspointAccessPoint_outputsPasspointName() = runBlocking(IMMEDIATE) {
         wifiRepository.setWifiNetwork(WifiNetworkModel.Active(
             networkId = 1,
+            level = 1,
             isPasspointAccessPoint = true,
             passpointProviderFriendlyName = "friendly",
         ))
@@ -104,6 +123,7 @@
     fun ssid_isOnlineSignUpForPasspoint_outputsPasspointName() = runBlocking(IMMEDIATE) {
         wifiRepository.setWifiNetwork(WifiNetworkModel.Active(
             networkId = 1,
+            level = 1,
             isOnlineSignUpForPasspointAccessPoint = true,
             passpointProviderFriendlyName = "friendly",
         ))
@@ -123,6 +143,7 @@
     fun ssid_unknownSsid_outputsNull() = runBlocking(IMMEDIATE) {
         wifiRepository.setWifiNetwork(WifiNetworkModel.Active(
             networkId = 1,
+            level = 1,
             ssid = WifiManager.UNKNOWN_SSID,
         ))
 
@@ -141,6 +162,7 @@
     fun ssid_validSsid_outputsSsid() = runBlocking(IMMEDIATE) {
         wifiRepository.setWifiNetwork(WifiNetworkModel.Active(
             networkId = 1,
+            level = 1,
             ssid = "MyAwesomeWifiNetwork",
         ))
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
index 59c10cd..b8ace2f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
@@ -17,7 +17,6 @@
 package com.android.systemui.statusbar.pipeline.wifi.ui.view
 
 import android.content.res.ColorStateList
-import android.graphics.Rect
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.testing.TestableLooper.RunWithLooper
@@ -27,7 +26,6 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.lifecycle.InstantTaskExecutorRule
 import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.statusbar.StatusBarIconView.STATE_DOT
 import com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN
@@ -52,8 +50,6 @@
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import org.junit.Before
-import org.junit.Ignore
-import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
@@ -70,7 +66,8 @@
     private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags
     @Mock
     private lateinit var logger: ConnectivityPipelineLogger
-    @Mock private lateinit var tableLogBuffer: TableLogBuffer
+    @Mock
+    private lateinit var tableLogBuffer: TableLogBuffer
     @Mock
     private lateinit var connectivityConstants: ConnectivityConstants
     @Mock
@@ -83,9 +80,6 @@
     private lateinit var scope: CoroutineScope
     private lateinit var airplaneModeViewModel: AirplaneModeViewModel
 
-    @JvmField @Rule
-    val instantTaskExecutor = InstantTaskExecutorRule()
-
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
@@ -118,40 +112,6 @@
         ).home
     }
 
-    @Test
-    fun constructAndBind_hasCorrectSlot() {
-        val view = ModernStatusBarWifiView.constructAndBind(context, "slotName", viewModel)
-
-        assertThat(view.slot).isEqualTo("slotName")
-    }
-
-    @Test
-    fun getVisibleState_icon_returnsIcon() {
-        val view = ModernStatusBarWifiView.constructAndBind(context, SLOT_NAME, viewModel)
-
-        view.setVisibleState(STATE_ICON, /* animate= */ false)
-
-        assertThat(view.visibleState).isEqualTo(STATE_ICON)
-    }
-
-    @Test
-    fun getVisibleState_dot_returnsDot() {
-        val view = ModernStatusBarWifiView.constructAndBind(context, SLOT_NAME, viewModel)
-
-        view.setVisibleState(STATE_DOT, /* animate= */ false)
-
-        assertThat(view.visibleState).isEqualTo(STATE_DOT)
-    }
-
-    @Test
-    fun getVisibleState_hidden_returnsHidden() {
-        val view = ModernStatusBarWifiView.constructAndBind(context, SLOT_NAME, viewModel)
-
-        view.setVisibleState(STATE_HIDDEN, /* animate= */ false)
-
-        assertThat(view.visibleState).isEqualTo(STATE_HIDDEN)
-    }
-
     // Note: The following tests are more like integration tests, since they stand up a full
     // [WifiViewModel] and test the interactions between the view, view-binder, and view-model.
 
@@ -235,24 +195,24 @@
     }
 
     @Test
-    @Ignore("b/262660044")
     fun onDarkChanged_iconHasNewColor() {
-        whenever(statusBarPipelineFlags.useWifiDebugColoring()).thenReturn(false)
+        whenever(statusBarPipelineFlags.useDebugColoring()).thenReturn(false)
         val view = ModernStatusBarWifiView.constructAndBind(context, SLOT_NAME, viewModel)
         ViewUtils.attachView(view)
         testableLooper.processAllMessages()
 
-        val areas = ArrayList(listOf(Rect(0, 0, 1000, 1000)))
         val color = 0x12345678
-        view.onDarkChanged(areas, 1.0f, color)
+        view.onDarkChanged(arrayListOf(), 1.0f, color)
         testableLooper.processAllMessages()
 
         assertThat(view.getIconView().imageTintList).isEqualTo(ColorStateList.valueOf(color))
+
+        ViewUtils.detachView(view)
     }
 
     @Test
     fun setStaticDrawableColor_iconHasNewColor() {
-        whenever(statusBarPipelineFlags.useWifiDebugColoring()).thenReturn(false)
+        whenever(statusBarPipelineFlags.useDebugColoring()).thenReturn(false)
         val view = ModernStatusBarWifiView.constructAndBind(context, SLOT_NAME, viewModel)
         ViewUtils.attachView(view)
         testableLooper.processAllMessages()
@@ -262,6 +222,8 @@
         testableLooper.processAllMessages()
 
         assertThat(view.getIconView().imageTintList).isEqualTo(ColorStateList.valueOf(color))
+
+        ViewUtils.detachView(view)
     }
 
     private fun View.getIconGroupView(): View {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt
index 12b93819..b932837 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt
@@ -206,7 +206,8 @@
                 // Enabled = false => no networks shown
                 TestCase(
                     enabled = false,
-                    network = WifiNetworkModel.CarrierMerged,
+                    network =
+                        WifiNetworkModel.CarrierMerged(NETWORK_ID, subscriptionId = 1, level = 1),
                     expected = null,
                 ),
                 TestCase(
@@ -228,7 +229,8 @@
                 // forceHidden = true => no networks shown
                 TestCase(
                     forceHidden = true,
-                    network = WifiNetworkModel.CarrierMerged,
+                    network =
+                        WifiNetworkModel.CarrierMerged(NETWORK_ID, subscriptionId = 1, level = 1),
                     expected = null,
                 ),
                 TestCase(
@@ -369,7 +371,8 @@
 
                 // network = CarrierMerged => not shown
                 TestCase(
-                    network = WifiNetworkModel.CarrierMerged,
+                    network =
+                        WifiNetworkModel.CarrierMerged(NETWORK_ID, subscriptionId = 1, level = 1),
                     expected = null,
                 ),
 
@@ -379,6 +382,12 @@
                     expected = null,
                 ),
 
+                // network = Unavailable => not shown
+                TestCase(
+                    network = WifiNetworkModel.Unavailable,
+                    expected = null,
+                ),
+
                 // network = Active & validated = false => not shown
                 TestCase(
                     network = WifiNetworkModel.Active(NETWORK_ID, isValidated = false, level = 3),
@@ -397,12 +406,6 @@
                             description = "Full internet level 4 icon",
                         ),
                 ),
-
-                // network has null level => not shown
-                TestCase(
-                    network = WifiNetworkModel.Active(NETWORK_ID, isValidated = true, level = null),
-                    expected = null,
-                ),
             )
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
index 4158434..e5cfec9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
@@ -228,7 +228,7 @@
         whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true)
         createAndSetViewModel()
 
-        wifiRepository.setWifiNetwork(WifiNetworkModel.Active(NETWORK_ID, ssid = null))
+        wifiRepository.setWifiNetwork(WifiNetworkModel.Active(NETWORK_ID, ssid = null, level = 1))
 
         var activityIn: Boolean? = null
         val activityInJob = underTest
@@ -553,7 +553,8 @@
 
     companion object {
         private const val NETWORK_ID = 2
-        private val ACTIVE_VALID_WIFI_NETWORK = WifiNetworkModel.Active(NETWORK_ID, ssid = "AB")
+        private val ACTIVE_VALID_WIFI_NETWORK =
+            WifiNetworkModel.Active(NETWORK_ID, ssid = "AB", level = 1)
     }
 }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
index 4b32ee2..0cca7b2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
@@ -390,19 +390,27 @@
         bindController(view, row.getEntry());
         view.setVisibility(View.GONE);
 
-        View crossFadeView = new View(mContext);
+        View fadeOutView = new View(mContext);
+        fadeOutView.setId(com.android.internal.R.id.actions_container_layout);
+
+        FrameLayout parent = new FrameLayout(mContext);
+        parent.addView(view);
+        parent.addView(fadeOutView);
 
         // Start focus animation
-        view.focusAnimated(crossFadeView);
-
+        view.focusAnimated();
         assertTrue(view.isAnimatingAppearance());
 
-        // fast forward to end of animation
-        mAnimatorTestRule.advanceTimeBy(ANIMATION_DURATION_STANDARD);
+        // fast forward to 1 ms before end of animation and verify fadeOutView has alpha set to 0f
+        mAnimatorTestRule.advanceTimeBy(ANIMATION_DURATION_STANDARD - 1);
+        assertEquals(0f, fadeOutView.getAlpha());
 
-        // assert that crossFadeView's alpha is reset to 1f after the animation (hidden behind
+        // fast forward to end of animation
+        mAnimatorTestRule.advanceTimeBy(1);
+
+        // assert that fadeOutView's alpha is reset to 1f after the animation (hidden behind
         // RemoteInputView)
-        assertEquals(1f, crossFadeView.getAlpha());
+        assertEquals(1f, fadeOutView.getAlpha());
         assertFalse(view.isAnimatingAppearance());
         assertEquals(View.VISIBLE, view.getVisibility());
         assertEquals(1f, view.getAlpha());
@@ -415,20 +423,27 @@
                 mDependency,
                 TestableLooper.get(this));
         ExpandableNotificationRow row = helper.createRow();
-        FrameLayout remoteInputViewParent = new FrameLayout(mContext);
         RemoteInputView view = RemoteInputView.inflate(mContext, null, row.getEntry(), mController);
-        remoteInputViewParent.addView(view);
         bindController(view, row.getEntry());
 
+        View fadeInView = new View(mContext);
+        fadeInView.setId(com.android.internal.R.id.actions_container_layout);
+
+        FrameLayout parent = new FrameLayout(mContext);
+        parent.addView(view);
+        parent.addView(fadeInView);
+
         // Start defocus animation
-        view.onDefocus(true, false);
+        view.onDefocus(true /* animate */, false /* logClose */, null /* doAfterDefocus */);
         assertEquals(View.VISIBLE, view.getVisibility());
+        assertEquals(0f, fadeInView.getAlpha());
 
         // fast forward to end of animation
         mAnimatorTestRule.advanceTimeBy(ANIMATION_DURATION_STANDARD);
 
         // assert that RemoteInputView is no longer visible
         assertEquals(View.GONE, view.getVisibility());
+        assertEquals(1f, fadeInView.getAlpha());
     }
 
     // NOTE: because we're refactoring the RemoteInputView and moving logic into the
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/FixedCapacityBatteryState.kt b/packages/SystemUI/tests/src/com/android/systemui/stylus/FixedCapacityBatteryState.kt
new file mode 100644
index 0000000..7e01088
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/stylus/FixedCapacityBatteryState.kt
@@ -0,0 +1,25 @@
+/*
+ * 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.stylus
+
+import android.hardware.BatteryState
+
+class FixedCapacityBatteryState(private val capacity: Float) : BatteryState() {
+    override fun getCapacity() = capacity
+    override fun getStatus() = 0
+    override fun isPresent() = true
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusFirstUsageListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusFirstUsageListenerTest.kt
deleted file mode 100644
index 8dd088f..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusFirstUsageListenerTest.kt
+++ /dev/null
@@ -1,289 +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.stylus
-
-import android.content.Context
-import android.hardware.BatteryState
-import android.hardware.input.InputManager
-import android.os.Handler
-import android.testing.AndroidTestingRunner
-import android.view.InputDevice
-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.util.concurrency.FakeExecutor
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.whenever
-import com.android.systemui.util.time.FakeSystemClock
-import org.junit.Before
-import org.junit.Ignore
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.Mockito.never
-import org.mockito.Mockito.times
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.verifyNoMoreInteractions
-import org.mockito.Mockito.verifyZeroInteractions
-import org.mockito.MockitoAnnotations
-
-@RunWith(AndroidTestingRunner::class)
-@SmallTest
-@Ignore("TODO(b/20579491): unignore on main")
-class StylusFirstUsageListenerTest : SysuiTestCase() {
-    @Mock lateinit var context: Context
-    @Mock lateinit var inputManager: InputManager
-    @Mock lateinit var stylusManager: StylusManager
-    @Mock lateinit var featureFlags: FeatureFlags
-    @Mock lateinit var internalStylusDevice: InputDevice
-    @Mock lateinit var otherDevice: InputDevice
-    @Mock lateinit var externalStylusDevice: InputDevice
-    @Mock lateinit var batteryState: BatteryState
-    @Mock lateinit var handler: Handler
-
-    private lateinit var stylusListener: StylusFirstUsageListener
-
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-        whenever(featureFlags.isEnabled(Flags.TRACK_STYLUS_EVER_USED)).thenReturn(true)
-        whenever(inputManager.isStylusEverUsed(context)).thenReturn(false)
-
-        stylusListener =
-            StylusFirstUsageListener(
-                context,
-                inputManager,
-                stylusManager,
-                featureFlags,
-                EXECUTOR,
-                handler
-            )
-        stylusListener.hasStarted = false
-
-        whenever(handler.post(any())).thenAnswer {
-            (it.arguments[0] as Runnable).run()
-            true
-        }
-
-        whenever(otherDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(false)
-        whenever(internalStylusDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(true)
-        whenever(internalStylusDevice.isExternal).thenReturn(false)
-        whenever(externalStylusDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(true)
-        whenever(externalStylusDevice.isExternal).thenReturn(true)
-
-        whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf())
-        whenever(inputManager.getInputDevice(OTHER_DEVICE_ID)).thenReturn(otherDevice)
-        whenever(inputManager.getInputDevice(INTERNAL_STYLUS_DEVICE_ID))
-            .thenReturn(internalStylusDevice)
-        whenever(inputManager.getInputDevice(EXTERNAL_STYLUS_DEVICE_ID))
-            .thenReturn(externalStylusDevice)
-    }
-
-    @Test
-    fun start_flagDisabled_doesNotRegister() {
-        whenever(featureFlags.isEnabled(Flags.TRACK_STYLUS_EVER_USED)).thenReturn(false)
-
-        stylusListener.start()
-
-        verify(stylusManager, never()).registerCallback(any())
-        verify(inputManager, never()).setStylusEverUsed(context, true)
-    }
-
-    @Test
-    fun start_toggleHasStarted() {
-        stylusListener.start()
-
-        assert(stylusListener.hasStarted)
-    }
-
-    @Test
-    fun start_hasStarted_doesNotRegister() {
-        stylusListener.hasStarted = true
-
-        stylusListener.start()
-
-        verify(stylusManager, never()).registerCallback(any())
-    }
-
-    @Test
-    fun start_hostDeviceDoesNotSupportStylus_doesNotRegister() {
-        whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf(OTHER_DEVICE_ID))
-
-        stylusListener.start()
-
-        verify(stylusManager, never()).registerCallback(any())
-        verify(inputManager, never()).setStylusEverUsed(context, true)
-    }
-
-    @Test
-    fun start_stylusEverUsed_doesNotRegister() {
-        whenever(inputManager.inputDeviceIds)
-            .thenReturn(intArrayOf(OTHER_DEVICE_ID, INTERNAL_STYLUS_DEVICE_ID))
-        whenever(inputManager.isStylusEverUsed(context)).thenReturn(true)
-
-        stylusListener.start()
-
-        verify(stylusManager, never()).registerCallback(any())
-        verify(inputManager, never()).setStylusEverUsed(context, true)
-    }
-
-    @Test
-    fun start_hostDeviceSupportsStylus_registersListener() {
-        whenever(inputManager.inputDeviceIds)
-            .thenReturn(intArrayOf(OTHER_DEVICE_ID, INTERNAL_STYLUS_DEVICE_ID))
-
-        stylusListener.start()
-
-        verify(stylusManager).registerCallback(any())
-        verify(inputManager, never()).setStylusEverUsed(context, true)
-    }
-
-    @Test
-    fun onStylusAdded_hasNotStarted_doesNotRegisterListener() {
-        stylusListener.hasStarted = false
-
-        stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
-
-        verifyZeroInteractions(inputManager)
-    }
-
-    @Test
-    fun onStylusAdded_internalStylus_registersListener() {
-        stylusListener.hasStarted = true
-
-        stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
-
-        verify(inputManager, times(1))
-            .addInputDeviceBatteryListener(INTERNAL_STYLUS_DEVICE_ID, EXECUTOR, stylusListener)
-    }
-
-    @Test
-    fun onStylusAdded_externalStylus_doesNotRegisterListener() {
-        stylusListener.hasStarted = true
-
-        stylusListener.onStylusAdded(EXTERNAL_STYLUS_DEVICE_ID)
-
-        verify(inputManager, never()).addInputDeviceBatteryListener(any(), any(), any())
-    }
-
-    @Test
-    fun onStylusAdded_otherDevice_doesNotRegisterListener() {
-        stylusListener.onStylusAdded(OTHER_DEVICE_ID)
-
-        verify(inputManager, never()).addInputDeviceBatteryListener(any(), any(), any())
-    }
-
-    @Test
-    fun onStylusRemoved_registeredDevice_unregistersListener() {
-        stylusListener.hasStarted = true
-        stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
-
-        stylusListener.onStylusRemoved(INTERNAL_STYLUS_DEVICE_ID)
-
-        verify(inputManager, times(1))
-            .removeInputDeviceBatteryListener(INTERNAL_STYLUS_DEVICE_ID, stylusListener)
-    }
-
-    @Test
-    fun onStylusRemoved_hasNotStarted_doesNotUnregisterListener() {
-        stylusListener.hasStarted = false
-        stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
-
-        stylusListener.onStylusRemoved(INTERNAL_STYLUS_DEVICE_ID)
-
-        verifyZeroInteractions(inputManager)
-    }
-
-    @Test
-    fun onStylusRemoved_unregisteredDevice_doesNotUnregisterListener() {
-        stylusListener.hasStarted = true
-
-        stylusListener.onStylusRemoved(INTERNAL_STYLUS_DEVICE_ID)
-
-        verifyNoMoreInteractions(inputManager)
-    }
-
-    @Test
-    fun onStylusBluetoothConnected_updateStylusFlagAndUnregisters() {
-        stylusListener.hasStarted = true
-        stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
-
-        stylusListener.onStylusBluetoothConnected(EXTERNAL_STYLUS_DEVICE_ID, "ANY")
-
-        verify(inputManager).setStylusEverUsed(context, true)
-        verify(inputManager, times(1))
-            .removeInputDeviceBatteryListener(INTERNAL_STYLUS_DEVICE_ID, stylusListener)
-        verify(stylusManager).unregisterCallback(stylusListener)
-    }
-
-    @Test
-    fun onStylusBluetoothConnected_hasNotStarted_doesNoting() {
-        stylusListener.hasStarted = false
-        stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
-
-        stylusListener.onStylusBluetoothConnected(EXTERNAL_STYLUS_DEVICE_ID, "ANY")
-
-        verifyZeroInteractions(inputManager)
-        verifyZeroInteractions(stylusManager)
-    }
-
-    @Test
-    fun onBatteryStateChanged_batteryPresent_updateStylusFlagAndUnregisters() {
-        stylusListener.hasStarted = true
-        stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
-        whenever(batteryState.isPresent).thenReturn(true)
-
-        stylusListener.onBatteryStateChanged(0, 1, batteryState)
-
-        verify(inputManager).setStylusEverUsed(context, true)
-        verify(inputManager, times(1))
-            .removeInputDeviceBatteryListener(INTERNAL_STYLUS_DEVICE_ID, stylusListener)
-        verify(stylusManager).unregisterCallback(stylusListener)
-    }
-
-    @Test
-    fun onBatteryStateChanged_batteryNotPresent_doesNotUpdateFlagOrUnregister() {
-        stylusListener.hasStarted = true
-        stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
-        whenever(batteryState.isPresent).thenReturn(false)
-
-        stylusListener.onBatteryStateChanged(0, 1, batteryState)
-
-        verifyZeroInteractions(stylusManager)
-        verify(inputManager, never())
-            .removeInputDeviceBatteryListener(INTERNAL_STYLUS_DEVICE_ID, stylusListener)
-    }
-
-    @Test
-    fun onBatteryStateChanged_hasNotStarted_doesNothing() {
-        stylusListener.hasStarted = false
-        stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
-        whenever(batteryState.isPresent).thenReturn(false)
-
-        stylusListener.onBatteryStateChanged(0, 1, batteryState)
-
-        verifyZeroInteractions(inputManager)
-        verifyZeroInteractions(stylusManager)
-    }
-
-    companion object {
-        private const val OTHER_DEVICE_ID = 0
-        private const val INTERNAL_STYLUS_DEVICE_ID = 1
-        private const val EXTERNAL_STYLUS_DEVICE_ID = 2
-        private val EXECUTOR = FakeExecutor(FakeSystemClock())
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt
index 58b5560..6d6e40a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt
@@ -17,12 +17,15 @@
 
 import android.bluetooth.BluetoothAdapter
 import android.bluetooth.BluetoothDevice
+import android.hardware.BatteryState
 import android.hardware.input.InputManager
 import android.os.Handler
 import android.testing.AndroidTestingRunner
 import android.view.InputDevice
 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.util.mockito.any
 import com.android.systemui.util.mockito.whenever
 import java.util.concurrent.Executor
@@ -31,30 +34,27 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
+import org.mockito.Mockito.clearInvocations
 import org.mockito.Mockito.inOrder
 import org.mockito.Mockito.never
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.Mockito.verifyZeroInteractions
 import org.mockito.MockitoAnnotations
 
 @RunWith(AndroidTestingRunner::class)
 @SmallTest
-@Ignore("b/257936830 until bt APIs")
 class StylusManagerTest : SysuiTestCase() {
     @Mock lateinit var inputManager: InputManager
-
     @Mock lateinit var stylusDevice: InputDevice
-
     @Mock lateinit var btStylusDevice: InputDevice
-
     @Mock lateinit var otherDevice: InputDevice
-
+    @Mock lateinit var batteryState: BatteryState
     @Mock lateinit var bluetoothAdapter: BluetoothAdapter
-
     @Mock lateinit var bluetoothDevice: BluetoothDevice
-
     @Mock lateinit var handler: Handler
+    @Mock lateinit var featureFlags: FeatureFlags
 
     @Mock lateinit var stylusCallback: StylusManager.StylusCallback
 
@@ -75,11 +75,8 @@
             true
         }
 
-        stylusManager = StylusManager(inputManager, bluetoothAdapter, handler, EXECUTOR)
-
-        stylusManager.registerCallback(stylusCallback)
-
-        stylusManager.registerBatteryCallback(stylusBatteryCallback)
+        stylusManager =
+            StylusManager(mContext, inputManager, bluetoothAdapter, handler, EXECUTOR, featureFlags)
 
         whenever(otherDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(false)
         whenever(stylusDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(true)
@@ -92,19 +89,47 @@
         whenever(inputManager.getInputDevice(STYLUS_DEVICE_ID)).thenReturn(stylusDevice)
         whenever(inputManager.getInputDevice(BT_STYLUS_DEVICE_ID)).thenReturn(btStylusDevice)
         whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf(STYLUS_DEVICE_ID))
+        whenever(inputManager.isStylusEverUsed(mContext)).thenReturn(false)
 
         whenever(bluetoothAdapter.getRemoteDevice(STYLUS_BT_ADDRESS)).thenReturn(bluetoothDevice)
         whenever(bluetoothDevice.address).thenReturn(STYLUS_BT_ADDRESS)
+
+        whenever(featureFlags.isEnabled(Flags.TRACK_STYLUS_EVER_USED)).thenReturn(true)
+
+        stylusManager.startListener()
+        stylusManager.registerCallback(stylusCallback)
+        stylusManager.registerBatteryCallback(stylusBatteryCallback)
+        clearInvocations(inputManager)
     }
 
     @Test
-    fun startListener_registersInputDeviceListener() {
+    fun startListener_hasNotStarted_registersInputDeviceListener() {
+        stylusManager =
+            StylusManager(mContext, inputManager, bluetoothAdapter, handler, EXECUTOR, featureFlags)
+
         stylusManager.startListener()
 
         verify(inputManager, times(1)).registerInputDeviceListener(any(), any())
     }
 
     @Test
+    fun startListener_hasStarted_doesNothing() {
+        stylusManager.startListener()
+
+        verifyZeroInteractions(inputManager)
+    }
+
+    @Test
+    fun onInputDeviceAdded_hasNotStarted_doesNothing() {
+        stylusManager =
+            StylusManager(mContext, inputManager, bluetoothAdapter, handler, EXECUTOR, featureFlags)
+
+        stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
+
+        verifyZeroInteractions(stylusCallback)
+    }
+
+    @Test
     fun onInputDeviceAdded_multipleRegisteredCallbacks_callsAll() {
         stylusManager.registerCallback(otherStylusCallback)
 
@@ -117,6 +142,26 @@
     }
 
     @Test
+    fun onInputDeviceAdded_internalStylus_registersBatteryListener() {
+        whenever(stylusDevice.isExternal).thenReturn(false)
+
+        stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
+
+        verify(inputManager, times(1))
+            .addInputDeviceBatteryListener(STYLUS_DEVICE_ID, EXECUTOR, stylusManager)
+    }
+
+    @Test
+    fun onInputDeviceAdded_externalStylus_doesNotRegisterbatteryListener() {
+        whenever(stylusDevice.isExternal).thenReturn(true)
+
+        stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
+
+        verify(inputManager, never())
+            .addInputDeviceBatteryListener(STYLUS_DEVICE_ID, EXECUTOR, stylusManager)
+    }
+
+    @Test
     fun onInputDeviceAdded_stylus_callsCallbacksOnStylusAdded() {
         stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
 
@@ -125,6 +170,23 @@
     }
 
     @Test
+    @Ignore("b/257936830 until bt APIs")
+    fun onInputDeviceAdded_btStylus_firstUsed_callsCallbacksOnStylusFirstUsed() {
+        stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
+
+        verify(stylusCallback, times(1)).onStylusFirstUsed()
+    }
+
+    @Test
+    @Ignore("b/257936830 until bt APIs")
+    fun onInputDeviceAdded_btStylus_firstUsed_setsFlag() {
+        stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
+
+        verify(inputManager, times(1)).setStylusEverUsed(mContext, true)
+    }
+
+    @Test
+    @Ignore("b/257936830 until bt APIs")
     fun onInputDeviceAdded_btStylus_callsCallbacksWithAddress() {
         stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
 
@@ -143,6 +205,17 @@
     }
 
     @Test
+    fun onInputDeviceChanged_hasNotStarted_doesNothing() {
+        stylusManager =
+            StylusManager(mContext, inputManager, bluetoothAdapter, handler, EXECUTOR, featureFlags)
+
+        stylusManager.onInputDeviceChanged(STYLUS_DEVICE_ID)
+
+        verifyZeroInteractions(stylusCallback)
+    }
+
+    @Test
+    @Ignore("b/257936830 until bt APIs")
     fun onInputDeviceChanged_multipleRegisteredCallbacks_callsAll() {
         stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
         // whenever(stylusDevice.bluetoothAddress).thenReturn(STYLUS_BT_ADDRESS)
@@ -157,6 +230,7 @@
     }
 
     @Test
+    @Ignore("b/257936830 until bt APIs")
     fun onInputDeviceChanged_stylusNewBtConnection_callsCallbacks() {
         stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
         // whenever(stylusDevice.bluetoothAddress).thenReturn(STYLUS_BT_ADDRESS)
@@ -168,6 +242,7 @@
     }
 
     @Test
+    @Ignore("b/257936830 until bt APIs")
     fun onInputDeviceChanged_stylusLostBtConnection_callsCallbacks() {
         stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
         // whenever(btStylusDevice.bluetoothAddress).thenReturn(null)
@@ -179,6 +254,7 @@
     }
 
     @Test
+    @Ignore("b/257936830 until bt APIs")
     fun onInputDeviceChanged_btConnection_stylusAlreadyBtConnected_onlyCallsListenersOnce() {
         stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
 
@@ -189,6 +265,7 @@
     }
 
     @Test
+    @Ignore("b/257936830 until bt APIs")
     fun onInputDeviceChanged_noBtConnection_stylusNeverBtConnected_doesNotCallCallbacks() {
         stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
 
@@ -198,11 +275,22 @@
     }
 
     @Test
+    fun onInputDeviceRemoved_hasNotStarted_doesNothing() {
+        stylusManager =
+            StylusManager(mContext, inputManager, bluetoothAdapter, handler, EXECUTOR, featureFlags)
+        stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
+
+        stylusManager.onInputDeviceRemoved(STYLUS_DEVICE_ID)
+
+        verifyZeroInteractions(stylusCallback)
+    }
+
+    @Test
     fun onInputDeviceRemoved_multipleRegisteredCallbacks_callsAll() {
         stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
         stylusManager.registerCallback(otherStylusCallback)
 
-        stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
+        stylusManager.onInputDeviceRemoved(STYLUS_DEVICE_ID)
 
         verify(stylusCallback, times(1)).onStylusRemoved(STYLUS_DEVICE_ID)
         verify(otherStylusCallback, times(1)).onStylusRemoved(STYLUS_DEVICE_ID)
@@ -219,6 +307,17 @@
     }
 
     @Test
+    fun onInputDeviceRemoved_unregistersBatteryListener() {
+        stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
+
+        stylusManager.onInputDeviceRemoved(STYLUS_DEVICE_ID)
+
+        verify(inputManager, times(1))
+            .removeInputDeviceBatteryListener(STYLUS_DEVICE_ID, stylusManager)
+    }
+
+    @Test
+    @Ignore("b/257936830 until bt APIs")
     fun onInputDeviceRemoved_btStylus_callsCallbacks() {
         stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
 
@@ -232,6 +331,7 @@
     }
 
     @Test
+    @Ignore("b/257936830 until bt APIs")
     fun onStylusBluetoothConnected_registersMetadataListener() {
         stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
 
@@ -239,6 +339,7 @@
     }
 
     @Test
+    @Ignore("b/257936830 until bt APIs")
     fun onStylusBluetoothConnected_noBluetoothDevice_doesNotRegisterMetadataListener() {
         whenever(bluetoothAdapter.getRemoteDevice(STYLUS_BT_ADDRESS)).thenReturn(null)
 
@@ -248,6 +349,7 @@
     }
 
     @Test
+    @Ignore("b/257936830 until bt APIs")
     fun onStylusBluetoothDisconnected_unregistersMetadataListener() {
         stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
 
@@ -257,6 +359,7 @@
     }
 
     @Test
+    @Ignore("b/257936830 until bt APIs")
     fun onMetadataChanged_multipleRegisteredBatteryCallbacks_executesAll() {
         stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
         stylusManager.registerBatteryCallback(otherStylusBatteryCallback)
@@ -274,6 +377,7 @@
     }
 
     @Test
+    @Ignore("b/257936830 until bt APIs")
     fun onMetadataChanged_chargingStateTrue_executesBatteryCallbacks() {
         stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
 
@@ -288,6 +392,7 @@
     }
 
     @Test
+    @Ignore("b/257936830 until bt APIs")
     fun onMetadataChanged_chargingStateFalse_executesBatteryCallbacks() {
         stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
 
@@ -302,6 +407,7 @@
     }
 
     @Test
+    @Ignore("b/257936830 until bt APIs")
     fun onMetadataChanged_chargingStateNoDevice_doesNotExecuteBatteryCallbacks() {
         stylusManager.onMetadataChanged(
             bluetoothDevice,
@@ -313,6 +419,7 @@
     }
 
     @Test
+    @Ignore("b/257936830 until bt APIs")
     fun onMetadataChanged_notChargingState_doesNotExecuteBatteryCallbacks() {
         stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
 
@@ -326,6 +433,63 @@
             .onStylusBluetoothChargingStateChanged(any(), any(), any())
     }
 
+    @Test
+    @Ignore("TODO(b/261826950): remove on main")
+    fun onBatteryStateChanged_batteryPresent_stylusNeverUsed_updateEverUsedFlag() {
+        whenever(batteryState.isPresent).thenReturn(true)
+
+        stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
+
+        verify(inputManager).setStylusEverUsed(mContext, true)
+    }
+
+    @Test
+    @Ignore("TODO(b/261826950): remove on main")
+    fun onBatteryStateChanged_batteryPresent_stylusNeverUsed_executesStylusFirstUsed() {
+        whenever(batteryState.isPresent).thenReturn(true)
+
+        stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
+
+        verify(stylusCallback, times(1)).onStylusFirstUsed()
+    }
+
+    @Test
+    @Ignore("TODO(b/261826950): remove on main")
+    fun onBatteryStateChanged_batteryPresent_stylusUsed_doesNotUpdateEverUsedFlag() {
+        whenever(inputManager.isStylusEverUsed(mContext)).thenReturn(true)
+        whenever(batteryState.isPresent).thenReturn(true)
+
+        stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
+
+        verify(inputManager, never()).setStylusEverUsed(mContext, true)
+    }
+
+    @Test
+    @Ignore("TODO(b/261826950): remove on main")
+    fun onBatteryStateChanged_batteryNotPresent_doesNotUpdateEverUsedFlag() {
+        whenever(batteryState.isPresent).thenReturn(false)
+
+        stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
+
+        verify(inputManager, never())
+            .removeInputDeviceBatteryListener(STYLUS_DEVICE_ID, stylusManager)
+    }
+
+    @Test
+    fun onBatteryStateChanged_hasNotStarted_doesNothing() {
+        stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
+
+        verifyZeroInteractions(inputManager)
+    }
+
+    @Test
+    fun onBatteryStateChanged_executesBatteryCallbacks() {
+        stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
+
+        verify(stylusBatteryCallback, times(1))
+            .onStylusUsiBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
+    }
+
     companion object {
         private val EXECUTOR = Executor { r -> r.run() }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerStartableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerStartableTest.kt
index ff382a3..1cccd65c8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerStartableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerStartableTest.kt
@@ -25,17 +25,15 @@
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.util.mockito.whenever
-import java.util.concurrent.Executor
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
-import org.mockito.Mockito.inOrder
 import org.mockito.Mockito.mock
-import org.mockito.Mockito.never
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.Mockito.verifyZeroInteractions
 import org.mockito.MockitoAnnotations
 
 @RunWith(AndroidTestingRunner::class)
@@ -60,7 +58,6 @@
                 inputManager,
                 stylusUsiPowerUi,
                 featureFlags,
-                DIRECT_EXECUTOR,
             )
 
         whenever(featureFlags.isEnabled(Flags.ENABLE_USI_BATTERY_NOTIFICATIONS)).thenReturn(true)
@@ -79,40 +76,19 @@
     }
 
     @Test
-    fun start_addsBatteryListenerForInternalStylus() {
+    fun start_hostDeviceDoesNotSupportStylus_doesNotRegister() {
+        whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf(EXTERNAL_DEVICE_ID))
+
         startable.start()
 
-        verify(inputManager, times(1))
-            .addInputDeviceBatteryListener(STYLUS_DEVICE_ID, DIRECT_EXECUTOR, startable)
+        verifyZeroInteractions(stylusManager)
     }
 
     @Test
-    fun onStylusAdded_internalStylus_addsBatteryListener() {
-        startable.onStylusAdded(STYLUS_DEVICE_ID)
+    fun start_initStylusUsiPowerUi() {
+        startable.start()
 
-        verify(inputManager, times(1))
-            .addInputDeviceBatteryListener(STYLUS_DEVICE_ID, DIRECT_EXECUTOR, startable)
-    }
-
-    @Test
-    fun onStylusAdded_externalStylus_doesNotAddBatteryListener() {
-        startable.onStylusAdded(EXTERNAL_DEVICE_ID)
-
-        verify(inputManager, never())
-            .addInputDeviceBatteryListener(EXTERNAL_DEVICE_ID, DIRECT_EXECUTOR, startable)
-    }
-
-    @Test
-    fun onStylusRemoved_registeredStylus_removesBatteryListener() {
-        startable.onStylusAdded(STYLUS_DEVICE_ID)
-        startable.onStylusRemoved(STYLUS_DEVICE_ID)
-
-        inOrder(inputManager).let {
-            it.verify(inputManager, times(1))
-                .addInputDeviceBatteryListener(STYLUS_DEVICE_ID, DIRECT_EXECUTOR, startable)
-            it.verify(inputManager, times(1))
-                .removeInputDeviceBatteryListener(STYLUS_DEVICE_ID, startable)
-        }
+        verify(stylusUsiPowerUi, times(1)).init()
     }
 
     @Test
@@ -130,28 +106,34 @@
     }
 
     @Test
-    fun onBatteryStateChanged_batteryPresent_refreshesNotification() {
-        val batteryState = mock(BatteryState::class.java)
-        whenever(batteryState.isPresent).thenReturn(true)
+    fun onStylusUsiBatteryStateChanged_batteryPresentValidCapacity_refreshesNotification() {
+        val batteryState = FixedCapacityBatteryState(0.1f)
 
-        startable.onBatteryStateChanged(STYLUS_DEVICE_ID, 123, batteryState)
+        startable.onStylusUsiBatteryStateChanged(STYLUS_DEVICE_ID, 123, batteryState)
 
-        verify(stylusUsiPowerUi, times(1)).updateBatteryState(batteryState)
+        verify(stylusUsiPowerUi, times(1)).updateBatteryState(STYLUS_DEVICE_ID, batteryState)
     }
 
     @Test
-    fun onBatteryStateChanged_batteryNotPresent_noop() {
+    fun onStylusUsiBatteryStateChanged_batteryPresentInvalidCapacity_noop() {
+        val batteryState = FixedCapacityBatteryState(0f)
+
+        startable.onStylusUsiBatteryStateChanged(STYLUS_DEVICE_ID, 123, batteryState)
+
+        verifyNoMoreInteractions(stylusUsiPowerUi)
+    }
+
+    @Test
+    fun onStylusUsiBatteryStateChanged_batteryNotPresent_noop() {
         val batteryState = mock(BatteryState::class.java)
         whenever(batteryState.isPresent).thenReturn(false)
 
-        startable.onBatteryStateChanged(STYLUS_DEVICE_ID, 123, batteryState)
+        startable.onStylusUsiBatteryStateChanged(STYLUS_DEVICE_ID, 123, batteryState)
 
         verifyNoMoreInteractions(stylusUsiPowerUi)
     }
 
     companion object {
-        private val DIRECT_EXECUTOR = Executor { r -> r.run() }
-
         private const val EXTERNAL_DEVICE_ID = 0
         private const val STYLUS_DEVICE_ID = 1
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt
index 5987550..1e81dc7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt
@@ -16,8 +16,12 @@
 
 package com.android.systemui.stylus
 
-import android.hardware.BatteryState
+import android.app.Notification
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
 import android.hardware.input.InputManager
+import android.os.Bundle
 import android.os.Handler
 import android.testing.AndroidTestingRunner
 import android.view.InputDevice
@@ -26,14 +30,22 @@
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import junit.framework.Assert.assertEquals
 import org.junit.Before
 import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
 import org.mockito.Mock
+import org.mockito.Mockito.doNothing
 import org.mockito.Mockito.inOrder
+import org.mockito.Mockito.never
+import org.mockito.Mockito.spy
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyNoMoreInteractions
@@ -46,13 +58,19 @@
     @Mock lateinit var inputManager: InputManager
     @Mock lateinit var handler: Handler
     @Mock lateinit var btStylusDevice: InputDevice
+    @Captor lateinit var notificationCaptor: ArgumentCaptor<Notification>
 
     private lateinit var stylusUsiPowerUi: StylusUsiPowerUI
+    private lateinit var broadcastReceiver: BroadcastReceiver
+    private lateinit var contextSpy: Context
 
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
 
+        contextSpy = spy(mContext)
+        doNothing().whenever(contextSpy).startActivity(any())
+
         whenever(handler.post(any())).thenAnswer {
             (it.arguments[0] as Runnable).run()
             true
@@ -63,56 +81,77 @@
         whenever(btStylusDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(true)
         // whenever(btStylusDevice.bluetoothAddress).thenReturn("SO:ME:AD:DR:ES")
 
-        stylusUsiPowerUi = StylusUsiPowerUI(mContext, notificationManager, inputManager, handler)
+        stylusUsiPowerUi = StylusUsiPowerUI(contextSpy, notificationManager, inputManager, handler)
+        broadcastReceiver = stylusUsiPowerUi.receiver
+    }
+
+    @Test
+    fun updateBatteryState_capacityZero_noop() {
+        stylusUsiPowerUi.updateBatteryState(0, FixedCapacityBatteryState(0f))
+
+        verifyNoMoreInteractions(notificationManager)
     }
 
     @Test
     fun updateBatteryState_capacityBelowThreshold_notifies() {
-        stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.1f))
+        stylusUsiPowerUi.updateBatteryState(0, FixedCapacityBatteryState(0.1f))
 
-        verify(notificationManager, times(1)).notify(eq(R.string.stylus_battery_low), any())
+        verify(notificationManager, times(1))
+            .notify(eq(R.string.stylus_battery_low_percentage), any())
         verifyNoMoreInteractions(notificationManager)
     }
 
     @Test
     fun updateBatteryState_capacityAboveThreshold_cancelsNotificattion() {
-        stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.8f))
+        stylusUsiPowerUi.updateBatteryState(0, FixedCapacityBatteryState(0.8f))
 
-        verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low)
+        verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low_percentage)
         verifyNoMoreInteractions(notificationManager)
     }
 
     @Test
     fun updateBatteryState_existingNotification_capacityAboveThreshold_cancelsNotification() {
-        stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.1f))
-        stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.8f))
+        stylusUsiPowerUi.updateBatteryState(0, FixedCapacityBatteryState(0.1f))
+        stylusUsiPowerUi.updateBatteryState(0, FixedCapacityBatteryState(0.8f))
 
         inOrder(notificationManager).let {
-            it.verify(notificationManager, times(1)).notify(eq(R.string.stylus_battery_low), any())
-            it.verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low)
+            it.verify(notificationManager, times(1))
+                .notify(eq(R.string.stylus_battery_low_percentage), any())
+            it.verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low_percentage)
             it.verifyNoMoreInteractions()
         }
     }
 
     @Test
     fun updateBatteryState_existingNotification_capacityBelowThreshold_updatesNotification() {
-        stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.1f))
-        stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.15f))
+        stylusUsiPowerUi.updateBatteryState(0, FixedCapacityBatteryState(0.1f))
+        stylusUsiPowerUi.updateBatteryState(0, FixedCapacityBatteryState(0.15f))
 
-        verify(notificationManager, times(2)).notify(eq(R.string.stylus_battery_low), any())
+        verify(notificationManager, times(2))
+            .notify(eq(R.string.stylus_battery_low_percentage), notificationCaptor.capture())
+        assertEquals(
+            notificationCaptor.value.extras.getString(Notification.EXTRA_TITLE),
+            context.getString(R.string.stylus_battery_low_percentage, "15%")
+        )
+        assertEquals(
+            notificationCaptor.value.extras.getString(Notification.EXTRA_TEXT),
+            context.getString(R.string.stylus_battery_low_subtitle)
+        )
         verifyNoMoreInteractions(notificationManager)
     }
 
     @Test
     fun updateBatteryState_capacityAboveThenBelowThreshold_hidesThenShowsNotification() {
-        stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.1f))
-        stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.5f))
-        stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.1f))
+        stylusUsiPowerUi.updateBatteryState(0, FixedCapacityBatteryState(0.1f))
+        stylusUsiPowerUi.updateBatteryState(0, FixedCapacityBatteryState(0.5f))
+        stylusUsiPowerUi.updateBatteryState(0, FixedCapacityBatteryState(0.1f))
 
         inOrder(notificationManager).let {
-            it.verify(notificationManager, times(1)).notify(eq(R.string.stylus_battery_low), any())
-            it.verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low)
-            it.verify(notificationManager, times(1)).notify(eq(R.string.stylus_battery_low), any())
+            it.verify(notificationManager, times(1))
+                .notify(eq(R.string.stylus_battery_low_percentage), any())
+            it.verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low_percentage)
+            it.verify(notificationManager, times(1))
+                .notify(eq(R.string.stylus_battery_low_percentage), any())
             it.verifyNoMoreInteractions()
         }
     }
@@ -121,47 +160,66 @@
     fun updateSuppression_noExistingNotification_cancelsNotification() {
         stylusUsiPowerUi.updateSuppression(true)
 
-        verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low)
+        verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low_percentage)
         verifyNoMoreInteractions(notificationManager)
     }
 
     @Test
     fun updateSuppression_existingNotification_cancelsNotification() {
-        stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.1f))
+        stylusUsiPowerUi.updateBatteryState(0, FixedCapacityBatteryState(0.1f))
 
         stylusUsiPowerUi.updateSuppression(true)
 
         inOrder(notificationManager).let {
-            it.verify(notificationManager, times(1)).notify(eq(R.string.stylus_battery_low), any())
-            it.verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low)
+            it.verify(notificationManager, times(1))
+                .notify(eq(R.string.stylus_battery_low_percentage), any())
+            it.verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low_percentage)
             it.verifyNoMoreInteractions()
         }
     }
 
     @Test
     @Ignore("TODO(b/257936830): get bt address once input api available")
-    fun refresh_hasConnectedBluetoothStylus_doesNotNotify() {
+    fun refresh_hasConnectedBluetoothStylus_cancelsNotification() {
         whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf(0))
 
         stylusUsiPowerUi.refresh()
 
-        verifyNoMoreInteractions(notificationManager)
+        verify(notificationManager).cancel(R.string.stylus_battery_low_percentage)
     }
 
     @Test
     @Ignore("TODO(b/257936830): get bt address once input api available")
     fun refresh_hasConnectedBluetoothStylus_existingNotification_cancelsNotification() {
-        stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.1f))
+        stylusUsiPowerUi.updateBatteryState(0, FixedCapacityBatteryState(0.1f))
         whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf(0))
 
         stylusUsiPowerUi.refresh()
 
-        verify(notificationManager).cancel(R.string.stylus_battery_low)
+        verify(notificationManager).cancel(R.string.stylus_battery_low_percentage)
     }
 
-    class FixedCapacityBatteryState(private val capacity: Float) : BatteryState() {
-        override fun getCapacity() = capacity
-        override fun getStatus() = 0
-        override fun isPresent() = true
+    @Test
+    fun broadcastReceiver_clicked_hasInputDeviceId_startsUsiDetailsActivity() {
+        val intent = Intent(StylusUsiPowerUI.ACTION_CLICKED_LOW_BATTERY)
+        val activityIntentCaptor = argumentCaptor<Intent>()
+        stylusUsiPowerUi.updateBatteryState(1, FixedCapacityBatteryState(0.15f))
+        broadcastReceiver.onReceive(contextSpy, intent)
+
+        verify(contextSpy, times(1)).startActivity(activityIntentCaptor.capture())
+        assertThat(activityIntentCaptor.value.action)
+            .isEqualTo(StylusUsiPowerUI.ACTION_STYLUS_USI_DETAILS)
+        val args =
+            activityIntentCaptor.value.getExtra(StylusUsiPowerUI.KEY_SETTINGS_FRAGMENT_ARGS)
+                as Bundle
+        assertThat(args.getInt(StylusUsiPowerUI.KEY_DEVICE_INPUT_ID)).isEqualTo(1)
+    }
+
+    @Test
+    fun broadcastReceiver_clicked_nullInputDeviceId_doesNotStartActivity() {
+        val intent = Intent(StylusUsiPowerUI.ACTION_CLICKED_LOW_BATTERY)
+        broadcastReceiver.onReceive(contextSpy, intent)
+
+        verify(contextSpy, never()).startActivity(any())
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseControllerTest.kt
index d25c8c1..614261d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseControllerTest.kt
@@ -17,8 +17,14 @@
 
 import android.graphics.Color
 import android.testing.AndroidTestingRunner
+import android.view.View.INVISIBLE
+import android.view.View.VISIBLE
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseController.Companion.AnimationState.EASE_IN
+import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseController.Companion.AnimationState.EASE_OUT
+import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseController.Companion.AnimationState.MAIN
+import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseController.Companion.AnimationState.NOT_PLAYING
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
@@ -33,26 +39,117 @@
     private val fakeExecutor = FakeExecutor(fakeSystemClock)
 
     @Test
-    fun play_playsTurbulenceNoise() {
-        val config = TurbulenceNoiseAnimationConfig(duration = 1000f)
+    fun play_playsTurbulenceNoiseInOrder() {
+        val config = TurbulenceNoiseAnimationConfig(maxDuration = 1000f)
         val turbulenceNoiseView = TurbulenceNoiseView(context, null)
-
         val turbulenceNoiseController = TurbulenceNoiseController(turbulenceNoiseView)
 
+        assertThat(turbulenceNoiseController.state).isEqualTo(NOT_PLAYING)
+
         fakeExecutor.execute {
             turbulenceNoiseController.play(config)
 
-            assertThat(turbulenceNoiseView.isPlaying).isTrue()
+            assertThat(turbulenceNoiseController.state).isEqualTo(EASE_IN)
 
-            fakeSystemClock.advanceTime(config.duration.toLong())
+            fakeSystemClock.advanceTime(config.easeInDuration.toLong())
 
-            assertThat(turbulenceNoiseView.isPlaying).isFalse()
+            assertThat(turbulenceNoiseController.state).isEqualTo(MAIN)
+
+            fakeSystemClock.advanceTime(config.maxDuration.toLong())
+
+            assertThat(turbulenceNoiseController.state).isEqualTo(EASE_OUT)
+
+            fakeSystemClock.advanceTime(config.easeOutDuration.toLong())
+
+            assertThat(turbulenceNoiseController.state).isEqualTo(NOT_PLAYING)
+        }
+    }
+
+    @Test
+    fun play_alreadyPlaying_ignoresNewAnimationRequest() {
+        val config = TurbulenceNoiseAnimationConfig(maxDuration = 1000f)
+        val turbulenceNoiseView = TurbulenceNoiseView(context, null)
+        // Currently playing the main animation.
+        val turbulenceNoiseController =
+            TurbulenceNoiseController(turbulenceNoiseView).also { it.state = MAIN }
+
+        fakeExecutor.execute {
+            // Request another animation
+            turbulenceNoiseController.play(config)
+
+            assertThat(turbulenceNoiseController.state).isEqualTo(MAIN)
+        }
+    }
+
+    @Test
+    fun finish_mainAnimationPlaying_playsEaseOutAnimation() {
+        val config = TurbulenceNoiseAnimationConfig(maxDuration = 1000f)
+        val turbulenceNoiseView = TurbulenceNoiseView(context, null)
+        val turbulenceNoiseController =
+            TurbulenceNoiseController(turbulenceNoiseView).also { it.state = MAIN }
+
+        fakeExecutor.execute {
+            turbulenceNoiseController.play(config)
+
+            fakeSystemClock.advanceTime(config.maxDuration.toLong() / 2)
+
+            turbulenceNoiseController.finish()
+
+            assertThat(turbulenceNoiseController.state).isEqualTo(EASE_OUT)
+        }
+    }
+
+    @Test
+    fun finish_nonMainAnimationPlaying_doesNotFinishAnimation() {
+        val config = TurbulenceNoiseAnimationConfig(maxDuration = 1000f)
+        val turbulenceNoiseView = TurbulenceNoiseView(context, null)
+        val turbulenceNoiseController =
+            TurbulenceNoiseController(turbulenceNoiseView).also { it.state = EASE_IN }
+
+        fakeExecutor.execute {
+            turbulenceNoiseController.play(config)
+
+            fakeSystemClock.advanceTime(config.maxDuration.toLong() / 2)
+
+            turbulenceNoiseController.finish()
+
+            assertThat(turbulenceNoiseController.state).isEqualTo(EASE_IN)
+        }
+    }
+
+    @Test
+    fun onAnimationFinished_resetsStateCorrectly() {
+        val config = TurbulenceNoiseAnimationConfig(maxDuration = 1000f)
+        val turbulenceNoiseView = TurbulenceNoiseView(context, null)
+        val turbulenceNoiseController = TurbulenceNoiseController(turbulenceNoiseView)
+
+        assertThat(turbulenceNoiseController.state).isEqualTo(NOT_PLAYING)
+        assertThat(turbulenceNoiseView.visibility).isEqualTo(INVISIBLE)
+        assertThat(turbulenceNoiseView.noiseConfig).isNull()
+
+        fakeExecutor.execute {
+            turbulenceNoiseController.play(config)
+
+            assertThat(turbulenceNoiseController.state).isEqualTo(EASE_IN)
+            assertThat(turbulenceNoiseView.visibility).isEqualTo(VISIBLE)
+            assertThat(turbulenceNoiseView.noiseConfig).isEqualTo(config)
+
+            // Play all the animations.
+            fakeSystemClock.advanceTime(
+                config.easeInDuration.toLong() +
+                    config.maxDuration.toLong() +
+                    config.easeOutDuration.toLong()
+            )
+
+            assertThat(turbulenceNoiseController.state).isEqualTo(NOT_PLAYING)
+            assertThat(turbulenceNoiseView.visibility).isEqualTo(INVISIBLE)
+            assertThat(turbulenceNoiseView.noiseConfig).isNull()
         }
     }
 
     @Test
     fun updateColor_updatesCorrectColor() {
-        val config = TurbulenceNoiseAnimationConfig(duration = 1000f, color = Color.WHITE)
+        val config = TurbulenceNoiseAnimationConfig(maxDuration = 1000f, color = Color.WHITE)
         val turbulenceNoiseView = TurbulenceNoiseView(context, null)
         val expectedColor = Color.RED
 
@@ -61,9 +158,9 @@
         fakeExecutor.execute {
             turbulenceNoiseController.play(config)
 
-            turbulenceNoiseView.updateColor(expectedColor)
+            turbulenceNoiseController.updateNoiseColor(expectedColor)
 
-            fakeSystemClock.advanceTime(config.duration.toLong())
+            fakeSystemClock.advanceTime(config.maxDuration.toLong())
 
             assertThat(config.color).isEqualTo(expectedColor)
         }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseViewTest.kt
index 633aac0..ce7f2f4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseViewTest.kt
@@ -16,7 +16,6 @@
 package com.android.systemui.surfaceeffects.turbulencenoise
 
 import android.testing.AndroidTestingRunner
-import android.view.View
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.concurrency.FakeExecutor
@@ -34,53 +33,65 @@
     private val fakeExecutor = FakeExecutor(fakeSystemClock)
 
     @Test
-    fun play_viewHasCorrectVisibility() {
-        val config = TurbulenceNoiseAnimationConfig(duration = 1000f)
-        val turbulenceNoiseView = TurbulenceNoiseView(context, null)
-
-        assertThat(turbulenceNoiseView.visibility).isEqualTo(View.INVISIBLE)
-
-        fakeExecutor.execute {
-            turbulenceNoiseView.play(config)
-
-            assertThat(turbulenceNoiseView.visibility).isEqualTo(View.VISIBLE)
-
-            fakeSystemClock.advanceTime(config.duration.toLong())
-
-            assertThat(turbulenceNoiseView.visibility).isEqualTo(View.INVISIBLE)
-        }
-    }
-
-    @Test
     fun play_playsAnimation() {
-        val config = TurbulenceNoiseAnimationConfig(duration = 1000f)
-        val turbulenceNoiseView = TurbulenceNoiseView(context, null)
+        val config = TurbulenceNoiseAnimationConfig()
+        val turbulenceNoiseView = TurbulenceNoiseView(context, null).also { it.applyConfig(config) }
+        var onAnimationEndCalled = false
 
         fakeExecutor.execute {
-            turbulenceNoiseView.play(config)
+            turbulenceNoiseView.play(onAnimationEnd = { onAnimationEndCalled = true })
 
-            assertThat(turbulenceNoiseView.isPlaying).isTrue()
+            fakeSystemClock.advanceTime(config.maxDuration.toLong())
+
+            assertThat(onAnimationEndCalled).isTrue()
         }
     }
 
     @Test
-    fun play_onEnd_triggersOnAnimationEnd() {
-        var animationEnd = false
-        val config =
-            TurbulenceNoiseAnimationConfig(
-                duration = 1000f,
-                onAnimationEnd = { animationEnd = true }
-            )
-        val turbulenceNoiseView = TurbulenceNoiseView(context, null)
+    fun playEaseIn_playsEaseInAnimation() {
+        val config = TurbulenceNoiseAnimationConfig()
+        val turbulenceNoiseView = TurbulenceNoiseView(context, null).also { it.applyConfig(config) }
+        var onAnimationEndCalled = false
 
         fakeExecutor.execute {
-            turbulenceNoiseView.play(config)
+            turbulenceNoiseView.playEaseIn(onAnimationEnd = { onAnimationEndCalled = true })
 
-            assertThat(turbulenceNoiseView.isPlaying).isTrue()
+            fakeSystemClock.advanceTime(config.easeInDuration.toLong())
 
-            fakeSystemClock.advanceTime(config.duration.toLong())
+            assertThat(onAnimationEndCalled).isTrue()
+        }
+    }
 
-            assertThat(animationEnd).isTrue()
+    @Test
+    fun playEaseOut_playsEaseOutAnimation() {
+        val config = TurbulenceNoiseAnimationConfig()
+        val turbulenceNoiseView = TurbulenceNoiseView(context, null).also { it.applyConfig(config) }
+        var onAnimationEndCalled = false
+
+        fakeExecutor.execute {
+            turbulenceNoiseView.playEaseOut(onAnimationEnd = { onAnimationEndCalled = true })
+
+            fakeSystemClock.advanceTime(config.easeOutDuration.toLong())
+
+            assertThat(onAnimationEndCalled).isTrue()
+        }
+    }
+
+    @Test
+    fun finish_animationPlaying_finishesAnimation() {
+        val config = TurbulenceNoiseAnimationConfig()
+        val turbulenceNoiseView = TurbulenceNoiseView(context, null).also { it.applyConfig(config) }
+        var onAnimationEndCalled = false
+
+        fakeExecutor.execute {
+            turbulenceNoiseView.play(onAnimationEnd = { onAnimationEndCalled = true })
+
+            assertThat(turbulenceNoiseView.currentAnimator).isNotNull()
+
+            turbulenceNoiseView.finish()
+
+            assertThat(onAnimationEndCalled).isTrue()
+            assertThat(turbulenceNoiseView.currentAnimator).isNull()
         }
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
index 99e2012..45f7df3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
@@ -159,7 +159,7 @@
         underTest.displayView(getState())
         assertThat(fakeWakeLock.isHeld).isTrue()
 
-        underTest.removeView("id", "test reason")
+        underTest.removeView(DEFAULT_ID, "test reason")
 
         assertThat(fakeWakeLock.isHeld).isFalse()
     }
@@ -175,6 +175,8 @@
 
     @Test
     fun displayView_twiceWithDifferentIds_oldViewRemovedNewViewAdded() {
+        val listener = registerListener()
+
         underTest.displayView(
             ViewInfo(
                 name = "name",
@@ -199,10 +201,15 @@
         assertThat(windowParamsCaptor.allValues[0].title).isEqualTo("First Fake Window Title")
         assertThat(windowParamsCaptor.allValues[1].title).isEqualTo("Second Fake Window Title")
         verify(windowManager).removeView(viewCaptor.allValues[0])
+        // Since the controller is still storing the older view in case it'll get re-displayed
+        // later, the listener shouldn't be notified
+        assertThat(listener.permanentlyRemovedIds).isEmpty()
     }
 
     @Test
     fun displayView_viewDoesNotDisappearsBeforeTimeout() {
+        val listener = registerListener()
+
         val state = getState()
         underTest.displayView(state)
         reset(windowManager)
@@ -210,10 +217,13 @@
         fakeClock.advanceTime(TIMEOUT_MS - 1)
 
         verify(windowManager, never()).removeView(any())
+        assertThat(listener.permanentlyRemovedIds).isEmpty()
     }
 
     @Test
     fun displayView_viewDisappearsAfterTimeout() {
+        val listener = registerListener()
+
         val state = getState()
         underTest.displayView(state)
         reset(windowManager)
@@ -221,10 +231,13 @@
         fakeClock.advanceTime(TIMEOUT_MS + 1)
 
         verify(windowManager).removeView(any())
+        assertThat(listener.permanentlyRemovedIds).containsExactly(DEFAULT_ID)
     }
 
     @Test
     fun displayView_calledAgainBeforeTimeout_timeoutReset() {
+        val listener = registerListener()
+
         // First, display the view
         val state = getState()
         underTest.displayView(state)
@@ -239,10 +252,13 @@
 
         // Verify we didn't hide the view
         verify(windowManager, never()).removeView(any())
+        assertThat(listener.permanentlyRemovedIds).isEmpty()
     }
 
     @Test
     fun displayView_calledAgainBeforeTimeout_eventuallyTimesOut() {
+        val listener = registerListener()
+
         // First, display the view
         val state = getState()
         underTest.displayView(state)
@@ -255,6 +271,7 @@
         fakeClock.advanceTime(TIMEOUT_MS + 1)
 
         verify(windowManager).removeView(any())
+        assertThat(listener.permanentlyRemovedIds).containsExactly(DEFAULT_ID)
     }
 
     @Test
@@ -271,25 +288,9 @@
     }
 
     @Test
-    fun viewUpdatedWithNewOnViewTimeoutRunnable_newRunnableUsed() {
-        var runnable1Run = false
-        underTest.displayView(ViewInfo(name = "name", id = "id1", windowTitle = "1")) {
-            runnable1Run = true
-        }
-
-        var runnable2Run = false
-        underTest.displayView(ViewInfo(name = "name", id = "id1", windowTitle = "1")) {
-            runnable2Run = true
-        }
-
-        fakeClock.advanceTime(TIMEOUT_MS + 1)
-
-        assertThat(runnable1Run).isFalse()
-        assertThat(runnable2Run).isTrue()
-    }
-
-    @Test
     fun multipleViewsWithDifferentIds_moreRecentReplacesOlder() {
+        val listener = registerListener()
+
         underTest.displayView(
             ViewInfo(
                 name = "name",
@@ -315,10 +316,16 @@
         assertThat(windowParamsCaptor.allValues[1].title).isEqualTo("Second Fake Window Title")
         verify(windowManager).removeView(viewCaptor.allValues[0])
         verify(configurationController, never()).removeCallback(any())
+
+        // Since the controller is still storing the older view in case it'll get re-displayed
+        // later, the listener shouldn't be notified
+        assertThat(listener.permanentlyRemovedIds).isEmpty()
     }
 
     @Test
-    fun multipleViewsWithDifferentIds_recentActiveViewIsDisplayed() {
+    fun multipleViewsWithDifferentIds_newViewRemoved_previousViewIsDisplayed() {
+        val listener = registerListener()
+
         underTest.displayView(ViewInfo("First name", id = "id1"))
 
         verify(windowManager).addView(any(), any())
@@ -329,24 +336,35 @@
         verify(windowManager).removeView(any())
         verify(windowManager).addView(any(), any())
         reset(windowManager)
+        assertThat(listener.permanentlyRemovedIds).isEmpty()
 
+        // WHEN the current view is removed
         underTest.removeView("id2", "test reason")
 
+        // THEN it's correctly removed
         verify(windowManager).removeView(any())
+        assertThat(listener.permanentlyRemovedIds).containsExactly("id2")
+
+        // And the previous view is correctly added
         verify(windowManager).addView(any(), any())
         assertThat(underTest.mostRecentViewInfo?.id).isEqualTo("id1")
         assertThat(underTest.mostRecentViewInfo?.name).isEqualTo("First name")
 
+        // WHEN the previous view times out
         reset(windowManager)
         fakeClock.advanceTime(TIMEOUT_MS + 1)
 
+        // THEN it is also removed
         verify(windowManager).removeView(any())
         assertThat(underTest.activeViews.size).isEqualTo(0)
         verify(configurationController).removeCallback(any())
+        assertThat(listener.permanentlyRemovedIds).isEqualTo(listOf("id2", "id1"))
     }
 
     @Test
     fun multipleViewsWithDifferentIds_oldViewRemoved_recentViewIsDisplayed() {
+        val listener = registerListener()
+
         underTest.displayView(ViewInfo("First name", id = "id1"))
 
         verify(windowManager).addView(any(), any())
@@ -361,7 +379,8 @@
         // WHEN an old view is removed
         underTest.removeView("id1", "test reason")
 
-        // THEN we don't update anything
+        // THEN we don't update anything except the listener
+        assertThat(listener.permanentlyRemovedIds).containsExactly("id1")
         verify(windowManager, never()).removeView(any())
         assertThat(underTest.mostRecentViewInfo?.id).isEqualTo("id2")
         assertThat(underTest.mostRecentViewInfo?.name).isEqualTo("Second name")
@@ -372,10 +391,13 @@
         verify(windowManager).removeView(any())
         assertThat(underTest.activeViews.size).isEqualTo(0)
         verify(configurationController).removeCallback(any())
+        assertThat(listener.permanentlyRemovedIds).isEqualTo(listOf("id1", "id2"))
     }
 
     @Test
     fun multipleViewsWithDifferentIds_threeDifferentViews_recentActiveViewIsDisplayed() {
+        val listener = registerListener()
+
         underTest.displayView(ViewInfo("First name", id = "id1"))
         underTest.displayView(ViewInfo("Second name", id = "id2"))
         underTest.displayView(ViewInfo("Third name", id = "id3"))
@@ -387,6 +409,7 @@
         underTest.removeView("id3", "test reason")
 
         verify(windowManager).removeView(any())
+        assertThat(listener.permanentlyRemovedIds).isEqualTo(listOf("id3"))
         assertThat(underTest.mostRecentViewInfo?.id).isEqualTo("id2")
         assertThat(underTest.mostRecentViewInfo?.name).isEqualTo("Second name")
         verify(configurationController, never()).removeCallback(any())
@@ -395,6 +418,7 @@
         underTest.removeView("id2", "test reason")
 
         verify(windowManager).removeView(any())
+        assertThat(listener.permanentlyRemovedIds).isEqualTo(listOf("id3", "id2"))
         assertThat(underTest.mostRecentViewInfo?.id).isEqualTo("id1")
         assertThat(underTest.mostRecentViewInfo?.name).isEqualTo("First name")
         verify(configurationController, never()).removeCallback(any())
@@ -403,6 +427,7 @@
         fakeClock.advanceTime(TIMEOUT_MS + 1)
 
         verify(windowManager).removeView(any())
+        assertThat(listener.permanentlyRemovedIds).isEqualTo(listOf("id3", "id2", "id1"))
         assertThat(underTest.activeViews.size).isEqualTo(0)
         verify(configurationController).removeCallback(any())
     }
@@ -438,6 +463,8 @@
 
     @Test
     fun multipleViews_mostRecentViewRemoved_otherViewsTimedOutAndNotDisplayed() {
+        val listener = registerListener()
+
         underTest.displayView(ViewInfo("First name", id = "id1", timeoutMs = 4000))
         fakeClock.advanceTime(1000)
         underTest.displayView(ViewInfo("Second name", id = "id2", timeoutMs = 4000))
@@ -451,10 +478,13 @@
         verify(windowManager, never()).addView(any(), any())
         assertThat(underTest.activeViews.size).isEqualTo(0)
         verify(configurationController).removeCallback(any())
+        assertThat(listener.permanentlyRemovedIds).containsExactly("id1", "id2", "id3")
     }
 
     @Test
     fun multipleViews_mostRecentViewRemoved_viewWithShortTimeLeftNotDisplayed() {
+        val listener = registerListener()
+
         underTest.displayView(ViewInfo("First name", id = "id1", timeoutMs = 4000))
         fakeClock.advanceTime(1000)
         underTest.displayView(ViewInfo("Second name", id = "id2", timeoutMs = 2500))
@@ -467,10 +497,13 @@
         verify(windowManager, never()).addView(any(), any())
         assertThat(underTest.activeViews.size).isEqualTo(0)
         verify(configurationController).removeCallback(any())
+        assertThat(listener.permanentlyRemovedIds).containsExactly("id1", "id2")
     }
 
     @Test
     fun lowerThenHigherPriority_higherReplacesLower() {
+        val listener = registerListener()
+
         underTest.displayView(
             ViewInfo(
                 name = "normal",
@@ -499,10 +532,15 @@
         verify(windowManager).addView(capture(viewCaptor), capture(windowParamsCaptor))
         assertThat(windowParamsCaptor.value.title).isEqualTo("Critical Window Title")
         verify(configurationController, never()).removeCallback(any())
+        // Since the controller is still storing the older view in case it'll get re-displayed
+        // later, the listener shouldn't be notified
+        assertThat(listener.permanentlyRemovedIds).isEmpty()
     }
 
     @Test
     fun lowerThenHigherPriority_lowerPriorityRedisplayed() {
+        val listener = registerListener()
+
         underTest.displayView(
             ViewInfo(
                 name = "normal",
@@ -537,6 +575,7 @@
 
         // THEN the normal view is re-displayed
         verify(windowManager).removeView(viewCaptor.allValues[1])
+        assertThat(listener.permanentlyRemovedIds).containsExactly("critical")
         verify(windowManager).addView(any(), capture(windowParamsCaptor))
         assertThat(windowParamsCaptor.value.title).isEqualTo("Normal Window Title")
         verify(configurationController, never()).removeCallback(any())
@@ -544,6 +583,8 @@
 
     @Test
     fun lowerThenHigherPriority_lowerPriorityNotRedisplayedBecauseTimedOut() {
+        val listener = registerListener()
+
         underTest.displayView(
             ViewInfo(
                 name = "normal",
@@ -573,6 +614,7 @@
         verify(windowManager, never()).addView(any(), any())
         assertThat(underTest.activeViews).isEmpty()
         verify(configurationController).removeCallback(any())
+        assertThat(listener.permanentlyRemovedIds).containsExactly("critical", "normal")
     }
 
     @Test
@@ -609,6 +651,8 @@
 
     @Test
     fun higherThenLowerPriority_lowerEventuallyDisplayed() {
+        val listener = registerListener()
+
         underTest.displayView(
             ViewInfo(
                 name = "critical",
@@ -644,6 +688,7 @@
 
         // THEN the second normal view is displayed
         verify(windowManager).removeView(viewCaptor.value)
+        assertThat(listener.permanentlyRemovedIds).containsExactly("critical")
         verify(windowManager).addView(capture(viewCaptor), capture(windowParamsCaptor))
         assertThat(windowParamsCaptor.value.title).isEqualTo("Normal Window Title")
         assertThat(underTest.activeViews.size).isEqualTo(1)
@@ -652,6 +697,8 @@
 
     @Test
     fun higherThenLowerPriority_lowerNotDisplayedBecauseTimedOut() {
+        val listener = registerListener()
+
         underTest.displayView(
             ViewInfo(
                 name = "critical",
@@ -691,10 +738,13 @@
         verify(windowManager, never()).addView(any(), any())
         assertThat(underTest.activeViews).isEmpty()
         verify(configurationController).removeCallback(any())
+        assertThat(listener.permanentlyRemovedIds).containsExactly("critical", "normal")
     }
 
     @Test
     fun criticalThenNewCritical_newCriticalDisplayed() {
+        val listener = registerListener()
+
         underTest.displayView(
             ViewInfo(
                 name = "critical 1",
@@ -724,10 +774,15 @@
         assertThat(windowParamsCaptor.value.title).isEqualTo("Critical Window Title 2")
         assertThat(underTest.activeViews.size).isEqualTo(2)
         verify(configurationController, never()).removeCallback(any())
+        // Since the controller is still storing the older view in case it'll get re-displayed
+        // later, the listener shouldn't be notified
+        assertThat(listener.permanentlyRemovedIds).isEmpty()
     }
 
     @Test
     fun normalThenNewNormal_newNormalDisplayed() {
+        val listener = registerListener()
+
         underTest.displayView(
             ViewInfo(
                 name = "normal 1",
@@ -757,6 +812,9 @@
         assertThat(windowParamsCaptor.value.title).isEqualTo("Normal Window Title 2")
         assertThat(underTest.activeViews.size).isEqualTo(2)
         verify(configurationController, never()).removeCallback(any())
+        // Since the controller is still storing the older view in case it'll get re-displayed
+        // later, the listener shouldn't be notified
+        assertThat(listener.permanentlyRemovedIds).isEmpty()
     }
 
     @Test
@@ -957,25 +1015,103 @@
     }
 
     @Test
-    fun removeView_viewRemovedAndRemovalLogged() {
+    fun removeView_viewRemovedAndRemovalLoggedAndListenerNotified() {
+        val listener = registerListener()
+
         // First, add the view
         underTest.displayView(getState())
 
         // Then, remove it
         val reason = "test reason"
-        val deviceId = "id"
-        underTest.removeView(deviceId, reason)
+        underTest.removeView(DEFAULT_ID, reason)
 
         verify(windowManager).removeView(any())
-        verify(logger).logViewRemoval(deviceId, reason)
+        verify(logger).logViewRemoval(DEFAULT_ID, reason)
         verify(configurationController).removeCallback(any())
+        assertThat(listener.permanentlyRemovedIds).containsExactly(DEFAULT_ID)
     }
 
     @Test
-    fun removeView_noAdd_viewNotRemoved() {
+    fun removeView_noAdd_viewNotRemovedAndListenerNotNotified() {
+        val listener = registerListener()
+
         underTest.removeView("id", "reason")
 
         verify(windowManager, never()).removeView(any())
+        assertThat(listener.permanentlyRemovedIds).isEmpty()
+    }
+
+    @Test
+    fun listenerRegistered_notifiedOnRemoval() {
+        val listener = registerListener()
+        underTest.displayView(getState())
+
+        underTest.removeView(DEFAULT_ID, "reason")
+
+        assertThat(listener.permanentlyRemovedIds).containsExactly(DEFAULT_ID)
+    }
+
+    @Test
+    fun listenerRegistered_notifiedOnTimedOutEvenWhenNotDisplayed() {
+        val listener = registerListener()
+        underTest.displayView(
+            ViewInfo(
+                id = "id1",
+                name = "name1",
+                timeoutMs = 3000,
+            ),
+        )
+
+        // Display a second view
+        underTest.displayView(
+            ViewInfo(
+                id = "id2",
+                name = "name2",
+                timeoutMs = 2500,
+            ),
+        )
+
+        // WHEN the second view times out
+        fakeClock.advanceTime(2501)
+
+        // THEN the listener is notified of both IDs, since id2 timed out and id1 doesn't have
+        // enough time left to be redisplayed
+        assertThat(listener.permanentlyRemovedIds).containsExactly("id1", "id2")
+    }
+
+    @Test
+    fun multipleListeners_allNotified() {
+        val listener1 = registerListener()
+        val listener2 = registerListener()
+        val listener3 = registerListener()
+
+        underTest.displayView(getState())
+
+        underTest.removeView(DEFAULT_ID, "reason")
+
+        assertThat(listener1.permanentlyRemovedIds).containsExactly(DEFAULT_ID)
+        assertThat(listener2.permanentlyRemovedIds).containsExactly(DEFAULT_ID)
+        assertThat(listener3.permanentlyRemovedIds).containsExactly(DEFAULT_ID)
+    }
+
+    @Test
+    fun sameListenerRegisteredMultipleTimes_onlyNotifiedOnce() {
+        val listener = registerListener()
+        underTest.registerListener(listener)
+        underTest.registerListener(listener)
+
+        underTest.displayView(getState())
+
+        underTest.removeView(DEFAULT_ID, "reason")
+
+        assertThat(listener.permanentlyRemovedIds).hasSize(1)
+        assertThat(listener.permanentlyRemovedIds).containsExactly(DEFAULT_ID)
+    }
+
+    private fun registerListener(): Listener {
+        return Listener().also {
+            underTest.registerListener(it)
+        }
     }
 
     private fun getState(name: String = "name") = ViewInfo(name)
@@ -1030,9 +1166,17 @@
         override val windowTitle: String = "Window Title",
         override val wakeReason: String = "WAKE_REASON",
         override val timeoutMs: Int = TIMEOUT_MS.toInt(),
-        override val id: String = "id",
+        override val id: String = DEFAULT_ID,
         override val priority: ViewPriority = ViewPriority.NORMAL,
     ) : TemporaryViewInfo()
+
+    inner class Listener : TemporaryViewDisplayController.Listener {
+        val permanentlyRemovedIds = mutableListOf<String>()
+        override fun onInfoPermanentlyRemoved(id: String) {
+            permanentlyRemovedIds.add(id)
+        }
+    }
 }
 
 private const val TIMEOUT_MS = 10000L
+private const val DEFAULT_ID = "defaultId"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
index d3411c2..45eb1f9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
@@ -20,6 +20,7 @@
 import android.os.VibrationEffect
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
+import android.view.MotionEvent
 import android.view.View
 import android.view.ViewGroup
 import android.view.WindowManager
@@ -43,6 +44,8 @@
 import com.android.systemui.temporarydisplay.ViewPriority
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.capture
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.time.FakeSystemClock
 import com.android.systemui.util.view.ViewUtil
@@ -54,6 +57,7 @@
 import org.mockito.ArgumentCaptor
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mock
+import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
@@ -74,6 +78,7 @@
     @Mock private lateinit var falsingCollector: FalsingCollector
     @Mock private lateinit var viewUtil: ViewUtil
     @Mock private lateinit var vibratorHelper: VibratorHelper
+    @Mock private lateinit var swipeGestureHandler: SwipeChipbarAwayGestureHandler
     private lateinit var fakeWakeLockBuilder: WakeLockFake.Builder
     private lateinit var fakeWakeLock: WakeLockFake
     private lateinit var fakeClock: FakeSystemClock
@@ -106,6 +111,7 @@
                 powerManager,
                 falsingManager,
                 falsingCollector,
+                swipeGestureHandler,
                 viewUtil,
                 vibratorHelper,
                 fakeWakeLockBuilder,
@@ -124,7 +130,7 @@
             )
         )
 
-        val contentDescView = getChipbarView().requireViewById<ViewGroup>(R.id.chipbar_inner)
+        val contentDescView = getChipbarView().getInnerView()
         assertThat(contentDescView.contentDescription.toString()).contains("loadedCD")
         assertThat(contentDescView.contentDescription.toString()).contains("text")
     }
@@ -139,11 +145,43 @@
             )
         )
 
-        val contentDescView = getChipbarView().requireViewById<ViewGroup>(R.id.chipbar_inner)
+        val contentDescView = getChipbarView().getInnerView()
         assertThat(contentDescView.contentDescription.toString()).isEqualTo("text")
     }
 
     @Test
+    fun displayView_contentDescription_endIsLoading() {
+        underTest.displayView(
+            createChipbarInfo(
+                Icon.Resource(R.drawable.ic_cake, ContentDescription.Loaded("loadedCD")),
+                Text.Loaded("text"),
+                endItem = ChipbarEndItem.Loading,
+            )
+        )
+
+        val contentDescView = getChipbarView().getInnerView()
+        val loadingDesc = context.resources.getString(R.string.media_transfer_loading)
+        assertThat(contentDescView.contentDescription.toString()).contains("text")
+        assertThat(contentDescView.contentDescription.toString()).contains(loadingDesc)
+    }
+
+    @Test
+    fun displayView_contentDescription_endNotLoading() {
+        underTest.displayView(
+            createChipbarInfo(
+                Icon.Resource(R.drawable.ic_cake, ContentDescription.Loaded("loadedCD")),
+                Text.Loaded("text"),
+                endItem = ChipbarEndItem.Error,
+            )
+        )
+
+        val contentDescView = getChipbarView().getInnerView()
+        val loadingDesc = context.resources.getString(R.string.media_transfer_loading)
+        assertThat(contentDescView.contentDescription.toString()).contains("text")
+        assertThat(contentDescView.contentDescription.toString()).doesNotContain(loadingDesc)
+    }
+
+    @Test
     fun displayView_loadedIcon_correctlyRendered() {
         val drawable = context.getDrawable(R.drawable.ic_celebration)!!
 
@@ -398,17 +436,101 @@
         verify(logger).logViewUpdate(eq(WINDOW_TITLE), eq("new title text"), any())
     }
 
+    @Test
+    fun swipeToDismiss_false_neverListensForGesture() {
+        underTest.displayView(
+            createChipbarInfo(
+                Icon.Resource(R.drawable.ic_cake, contentDescription = null),
+                Text.Loaded("title text"),
+                endItem = ChipbarEndItem.Loading,
+                allowSwipeToDismiss = false,
+            )
+        )
+
+        verify(swipeGestureHandler, never()).addOnGestureDetectedCallback(any(), any())
+    }
+
+    @Test
+    fun swipeToDismiss_true_listensForGesture() {
+        underTest.displayView(
+            createChipbarInfo(
+                Icon.Resource(R.drawable.ic_cake, contentDescription = null),
+                Text.Loaded("title text"),
+                endItem = ChipbarEndItem.Loading,
+                allowSwipeToDismiss = true,
+            )
+        )
+
+        verify(swipeGestureHandler).addOnGestureDetectedCallback(any(), any())
+    }
+
+    @Test
+    fun swipeToDismiss_swipeOccurs_viewDismissed() {
+        underTest.displayView(
+            createChipbarInfo(
+                Icon.Resource(R.drawable.ic_cake, contentDescription = null),
+                Text.Loaded("title text"),
+                endItem = ChipbarEndItem.Loading,
+                allowSwipeToDismiss = true,
+            )
+        )
+        val view = getChipbarView()
+
+        val callbackCaptor = argumentCaptor<(MotionEvent) -> Unit>()
+        verify(swipeGestureHandler).addOnGestureDetectedCallback(any(), capture(callbackCaptor))
+
+        callbackCaptor.value.invoke(MotionEvent.obtain(0L, 0L, 0, 0f, 0f, 0))
+
+        verify(windowManager).removeView(view)
+    }
+
+    @Test
+    fun swipeToDismiss_viewUpdatedToFalse_swipeOccurs_viewNotDismissed() {
+        underTest.displayView(
+            createChipbarInfo(
+                Icon.Resource(R.drawable.ic_cake, contentDescription = null),
+                Text.Loaded("title text"),
+                endItem = ChipbarEndItem.Loading,
+                allowSwipeToDismiss = true,
+            )
+        )
+        val view = getChipbarView()
+        val callbackCaptor = argumentCaptor<(MotionEvent) -> Unit>()
+        verify(swipeGestureHandler).addOnGestureDetectedCallback(any(), capture(callbackCaptor))
+
+        // WHEN the view is updated to not allow swipe-to-dismiss
+        underTest.displayView(
+            createChipbarInfo(
+                Icon.Resource(R.drawable.ic_cake, contentDescription = null),
+                Text.Loaded("title text"),
+                endItem = ChipbarEndItem.Loading,
+                allowSwipeToDismiss = false,
+            )
+        )
+
+        // THEN the callback is removed
+        verify(swipeGestureHandler).removeOnGestureDetectedCallback(any())
+
+        // And WHEN the old callback is invoked
+        callbackCaptor.value.invoke(MotionEvent.obtain(0L, 0L, 0, 0f, 0f, 0))
+
+        // THEN it is ignored and view isn't removed
+        verify(windowManager, never()).removeView(view)
+    }
+
     private fun createChipbarInfo(
         startIcon: Icon,
         text: Text,
         endItem: ChipbarEndItem?,
         vibrationEffect: VibrationEffect? = null,
+        allowSwipeToDismiss: Boolean = false,
     ): ChipbarInfo {
         return ChipbarInfo(
             TintedIcon(startIcon, tintAttr = null),
             text,
             endItem,
             vibrationEffect,
+            allowSwipeToDismiss,
             windowTitle = WINDOW_TITLE,
             wakeReason = WAKE_REASON,
             timeoutMs = TIMEOUT,
@@ -417,6 +539,8 @@
         )
     }
 
+    private fun ViewGroup.getInnerView() = this.requireViewById<ViewGroup>(R.id.chipbar_inner)
+
     private fun ViewGroup.getStartIconView() = this.requireViewById<ImageView>(R.id.start_icon)
 
     private fun ViewGroup.getChipText(): String =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/FakeChipbarCoordinator.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/FakeChipbarCoordinator.kt
index 4ef4e6c..ffac8f6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/FakeChipbarCoordinator.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/FakeChipbarCoordinator.kt
@@ -43,6 +43,7 @@
     powerManager: PowerManager,
     falsingManager: FalsingManager,
     falsingCollector: FalsingCollector,
+    swipeChipbarAwayGestureHandler: SwipeChipbarAwayGestureHandler,
     viewUtil: ViewUtil,
     vibratorHelper: VibratorHelper,
     wakeLockBuilder: WakeLock.Builder,
@@ -59,6 +60,7 @@
         powerManager,
         falsingManager,
         falsingCollector,
+        swipeChipbarAwayGestureHandler,
         viewUtil,
         vibratorHelper,
         wakeLockBuilder,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/SwipeChipbarAwayGestureHandlerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/SwipeChipbarAwayGestureHandlerTest.kt
new file mode 100644
index 0000000..a87a950
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/SwipeChipbarAwayGestureHandlerTest.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.temporarydisplay.chipbar
+
+import android.graphics.Rect
+import android.view.MotionEvent
+import android.view.View
+import androidx.test.filters.SmallTest
+import com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+
+@SmallTest
+class SwipeChipbarAwayGestureHandlerTest : SysuiTestCase() {
+
+    private lateinit var underTest: SwipeChipbarAwayGestureHandler
+
+    @Before
+    fun setUp() {
+        underTest = SwipeChipbarAwayGestureHandler(context, mock())
+    }
+
+    @Test
+    fun startOfGestureIsWithinBounds_noViewFetcher_returnsFalse() {
+        assertThat(underTest.startOfGestureIsWithinBounds(createMotionEvent())).isFalse()
+    }
+
+    @Test
+    fun startOfGestureIsWithinBounds_usesViewFetcher_aboveBottom_returnsTrue() {
+        val view = createMockView()
+
+        underTest.setViewFetcher { view }
+
+        val motionEvent = createMotionEvent(y = VIEW_BOTTOM - 100f)
+        assertThat(underTest.startOfGestureIsWithinBounds(motionEvent)).isTrue()
+    }
+
+    @Test
+    fun startOfGestureIsWithinBounds_usesViewFetcher_slightlyBelowBottom_returnsTrue() {
+        val view = createMockView()
+
+        underTest.setViewFetcher { view }
+
+        val motionEvent = createMotionEvent(y = VIEW_BOTTOM + 20f)
+        assertThat(underTest.startOfGestureIsWithinBounds(motionEvent)).isTrue()
+    }
+
+    @Test
+    fun startOfGestureIsWithinBounds_usesViewFetcher_tooFarDown_returnsFalse() {
+        val view = createMockView()
+
+        underTest.setViewFetcher { view }
+
+        val motionEvent = createMotionEvent(y = VIEW_BOTTOM * 4f)
+        assertThat(underTest.startOfGestureIsWithinBounds(motionEvent)).isFalse()
+    }
+
+    @Test
+    fun startOfGestureIsWithinBounds_viewFetcherReset_returnsFalse() {
+        val view = createMockView()
+
+        underTest.setViewFetcher { view }
+
+        val motionEvent = createMotionEvent(y = VIEW_BOTTOM - 100f)
+        assertThat(underTest.startOfGestureIsWithinBounds(motionEvent)).isTrue()
+
+        underTest.resetViewFetcher()
+        assertThat(underTest.startOfGestureIsWithinBounds(motionEvent)).isFalse()
+    }
+
+    private fun createMotionEvent(y: Float = 0f): MotionEvent {
+        return MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0f, y, 0)
+    }
+
+    private fun createMockView(): View {
+        return mock<View>().also {
+            doAnswer { invocation ->
+                    val out: Rect = invocation.getArgument(0)
+                    out.set(0, 0, 0, VIEW_BOTTOM)
+                    null
+                }
+                .whenever(it)
+                .getBoundsOnScreen(any())
+        }
+    }
+
+    private companion object {
+        const val VIEW_BOTTOM = 455
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
index 2a93fff..1710709 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
@@ -172,7 +172,7 @@
         verify(mDumpManager).registerDumpable(any(), any());
         verify(mDeviceProvisionedController).addCallback(mDeviceProvisionedListener.capture());
         verify(mSecureSettings).registerContentObserverForUser(
-                eq(Settings.Secure.getUriFor(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES)),
+                eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES),
                 eq(false), mSettingsObserver.capture(), eq(UserHandle.USER_ALL)
         );
     }
@@ -790,15 +790,15 @@
 
         reset(mResources);
         when(mResources.getColor(eq(android.R.color.system_accent1_500), any()))
-                .thenReturn(mThemeOverlayController.mColorScheme.getAccent1().get(6));
+                .thenReturn(mThemeOverlayController.mColorScheme.getAccent1().getS500());
         when(mResources.getColor(eq(android.R.color.system_accent2_500), any()))
-                .thenReturn(mThemeOverlayController.mColorScheme.getAccent2().get(6));
+                .thenReturn(mThemeOverlayController.mColorScheme.getAccent2().getS500());
         when(mResources.getColor(eq(android.R.color.system_accent3_500), any()))
-                .thenReturn(mThemeOverlayController.mColorScheme.getAccent3().get(6));
+                .thenReturn(mThemeOverlayController.mColorScheme.getAccent3().getS500());
         when(mResources.getColor(eq(android.R.color.system_neutral1_500), any()))
-                .thenReturn(mThemeOverlayController.mColorScheme.getNeutral1().get(6));
+                .thenReturn(mThemeOverlayController.mColorScheme.getNeutral1().getS500());
         when(mResources.getColor(eq(android.R.color.system_neutral2_500), any()))
-                .thenReturn(mThemeOverlayController.mColorScheme.getNeutral2().get(6));
+                .thenReturn(mThemeOverlayController.mColorScheme.getNeutral2().getS500());
 
         // Defers event because we already have initial colors.
         verify(mThemeOverlayApplier, never())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt
index 89402de..f4226bc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt
@@ -29,6 +29,7 @@
 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
 import com.android.systemui.shade.NotificationPanelViewController
+import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.LightRevealScrim
 import com.android.systemui.statusbar.phone.CentralSurfaces
 import com.android.systemui.unfold.util.FoldableDeviceStates
@@ -73,6 +74,8 @@
 
     @Mock lateinit var viewTreeObserver: ViewTreeObserver
 
+    @Mock private lateinit var commandQueue: CommandQueue
+
     @Captor private lateinit var foldStateListenerCaptor: ArgumentCaptor<FoldStateListener>
 
     private lateinit var deviceStates: FoldableDeviceStates
@@ -102,7 +105,8 @@
             }
 
         keyguardRepository = FakeKeyguardRepository()
-        val keyguardInteractor = KeyguardInteractor(repository = keyguardRepository)
+        val keyguardInteractor =
+            KeyguardInteractor(repository = keyguardRepository, commandQueue = commandQueue)
 
         // Needs to be run on the main thread
         runBlocking(IMMEDIATE) {
@@ -171,8 +175,10 @@
 
             fold()
             underTest.onScreenTurningOn({})
-            underTest.onStartedWakingUp()
+            // The body of onScreenTurningOn is executed on fakeExecutor,
+            // run all pending tasks before calling the next method
             fakeExecutor.runAllReady()
+            underTest.onStartedWakingUp()
 
             verify(latencyTracker).onActionStart(any())
             verify(latencyTracker).onActionCancel(any())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/TestUnfoldTransitionProvider.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/TestUnfoldTransitionProvider.kt
index c316402..4a28cd1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/TestUnfoldTransitionProvider.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/TestUnfoldTransitionProvider.kt
@@ -26,6 +26,10 @@
         listeners.forEach { it.onTransitionFinished() }
     }
 
+    override fun onTransitionFinishing() {
+        listeners.forEach { it.onTransitionFinishing() }
+    }
+
     override fun onTransitionProgress(progress: Float) {
         listeners.forEach { it.onTransitionProgress(progress) }
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt
new file mode 100644
index 0000000..d3fdbd9
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt
@@ -0,0 +1,134 @@
+/*
+ * 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.unfold
+
+import android.os.VibrationEffect
+import android.os.Vibrator
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.unfold.updates.FoldProvider
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.mock
+import java.util.concurrent.Executor
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class UnfoldHapticsPlayerTest : SysuiTestCase() {
+
+    private val progressProvider = TestUnfoldTransitionProvider()
+    private val vibrator: Vibrator = mock()
+    private val testFoldProvider = TestFoldProvider()
+
+    private lateinit var player: UnfoldHapticsPlayer
+
+    @Before
+    fun before() {
+        player = UnfoldHapticsPlayer(progressProvider, testFoldProvider, Runnable::run, vibrator)
+    }
+
+    @Test
+    fun testUnfoldingTransitionFinishingEarly_playsHaptics() {
+        testFoldProvider.onFoldUpdate(isFolded = true)
+        testFoldProvider.onFoldUpdate(isFolded = false)
+        progressProvider.onTransitionStarted()
+        progressProvider.onTransitionProgress(0.5f)
+        progressProvider.onTransitionFinishing()
+
+        verify(vibrator).vibrate(any<VibrationEffect>())
+    }
+
+    @Test
+    fun testUnfoldingTransitionFinishingLate_doesNotPlayHaptics() {
+        testFoldProvider.onFoldUpdate(isFolded = true)
+        testFoldProvider.onFoldUpdate(isFolded = false)
+        progressProvider.onTransitionStarted()
+        progressProvider.onTransitionProgress(0.99f)
+        progressProvider.onTransitionFinishing()
+
+        verify(vibrator, never()).vibrate(any<VibrationEffect>())
+    }
+
+    @Test
+    fun testFoldingAfterUnfolding_doesNotPlayHaptics() {
+        // Unfold
+        testFoldProvider.onFoldUpdate(isFolded = true)
+        testFoldProvider.onFoldUpdate(isFolded = false)
+        progressProvider.onTransitionStarted()
+        progressProvider.onTransitionProgress(0.5f)
+        progressProvider.onTransitionFinishing()
+        progressProvider.onTransitionFinished()
+        clearInvocations(vibrator)
+
+        // Fold
+        progressProvider.onTransitionStarted()
+        progressProvider.onTransitionProgress(0.5f)
+        progressProvider.onTransitionFinished()
+        testFoldProvider.onFoldUpdate(isFolded = true)
+
+        verify(vibrator, never()).vibrate(any<VibrationEffect>())
+    }
+
+    @Test
+    fun testUnfoldingAfterFoldingAndUnfolding_playsHaptics() {
+        // Unfold
+        testFoldProvider.onFoldUpdate(isFolded = true)
+        testFoldProvider.onFoldUpdate(isFolded = false)
+        progressProvider.onTransitionStarted()
+        progressProvider.onTransitionProgress(0.5f)
+        progressProvider.onTransitionFinishing()
+        progressProvider.onTransitionFinished()
+
+        // Fold
+        progressProvider.onTransitionStarted()
+        progressProvider.onTransitionProgress(0.5f)
+        progressProvider.onTransitionFinished()
+        testFoldProvider.onFoldUpdate(isFolded = true)
+        clearInvocations(vibrator)
+
+        // Unfold again
+        testFoldProvider.onFoldUpdate(isFolded = true)
+        testFoldProvider.onFoldUpdate(isFolded = false)
+        progressProvider.onTransitionStarted()
+        progressProvider.onTransitionProgress(0.5f)
+        progressProvider.onTransitionFinishing()
+        progressProvider.onTransitionFinished()
+
+        verify(vibrator).vibrate(any<VibrationEffect>())
+    }
+
+    private class TestFoldProvider : FoldProvider {
+        private val listeners = arrayListOf<FoldProvider.FoldCallback>()
+
+        override fun registerCallback(callback: FoldProvider.FoldCallback, executor: Executor) {
+            listeners += callback
+        }
+
+        override fun unregisterCallback(callback: FoldProvider.FoldCallback) {
+            listeners -= callback
+        }
+
+        fun onFoldUpdate(isFolded: Boolean) {
+            listeners.forEach { it.onFoldUpdated(isFolded) }
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
index 7d5f06c..6086e16 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
@@ -29,6 +29,7 @@
 import com.android.systemui.unfold.updates.hinge.HingeAngleProvider
 import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
 import com.android.systemui.unfold.updates.screen.ScreenStatusProvider.ScreenListener
+import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityProvider
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.capture
 import com.google.common.truth.Truth.assertThat
@@ -56,6 +57,9 @@
     @Mock
     private lateinit var rotationChangeProvider: RotationChangeProvider
 
+    @Mock
+    private lateinit var unfoldKeyguardVisibilityProvider: UnfoldKeyguardVisibilityProvider
+
     @Captor
     private lateinit var rotationListener: ArgumentCaptor<RotationListener>
 
@@ -87,6 +91,7 @@
                 screenOnStatusProvider,
                 foldProvider,
                 activityTypeProvider,
+                unfoldKeyguardVisibilityProvider,
                 rotationChangeProvider,
                 context.mainExecutor,
                 handler
@@ -380,6 +385,47 @@
     }
 
     @Test
+    fun startClosingEvent_whileNotOnKeyguardAndNotOnLauncher_doesNotTriggerBeforeThreshold() {
+        setKeyguardVisibility(visible = false)
+        setupForegroundActivityType(isHomeActivity = false)
+        sendHingeAngleEvent(180)
+
+        sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES + 1)
+
+        assertThat(foldUpdates).isEmpty()
+    }
+
+    @Test
+    fun startClosingEvent_whileKeyguardStateNotAvailable_triggerBeforeThreshold() {
+        setKeyguardVisibility(visible = null)
+        sendHingeAngleEvent(180)
+
+        sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES + 1)
+
+        assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
+    }
+
+    @Test
+    fun startClosingEvent_whileonKeyguard_doesTriggerBeforeThreshold() {
+        setKeyguardVisibility(visible = true)
+        sendHingeAngleEvent(180)
+
+        sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES + 1)
+
+        assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
+    }
+
+    @Test
+    fun startClosingEvent_whileNotOnKeyguard_triggersAfterThreshold() {
+        setKeyguardVisibility(visible = false)
+        sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES)
+
+        sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES - 1)
+
+        assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
+    }
+
+    @Test
     fun screenOff_whileFolded_hingeAngleProviderRemainsOff() {
         setFoldState(folded = true)
         assertThat(testHingeAngleProvider.isStarted).isFalse()
@@ -445,6 +491,10 @@
         whenever(activityTypeProvider.isHomeActivity).thenReturn(isHomeActivity)
     }
 
+    private fun setKeyguardVisibility(visible: Boolean?) {
+        whenever(unfoldKeyguardVisibilityProvider.isKeyguardVisible).thenReturn(visible)
+    }
+
     private fun simulateTimeout(waitTime: Long = HALF_OPENED_TIMEOUT_MILLIS) {
         val runnableDelay = scheduledRunnableDelay ?: throw Exception("No runnable scheduled.")
         if (waitTime >= runnableDelay) {
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 78b0cbe..9bb52be 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
@@ -36,12 +36,14 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.shared.model.Text
+import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.flags.FakeFeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.qs.user.UserSwitchDialogController
+import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.policy.DeviceProvisionedController
 import com.android.systemui.telephony.data.repository.FakeTelephonyRepository
 import com.android.systemui.telephony.domain.interactor.TelephonyInteractor
@@ -60,12 +62,12 @@
 import com.android.systemui.util.mockito.nullable
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.test.TestCoroutineScope
-import kotlinx.coroutines.test.advanceUntilIdle
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -73,10 +75,12 @@
 import org.mockito.ArgumentMatchers.anyBoolean
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mock
+import org.mockito.Mockito.atLeastOnce
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(JUnit4::class)
 class UserInteractorTest : SysuiTestCase() {
@@ -90,10 +94,11 @@
     @Mock private lateinit var dialogShower: UserSwitchDialogController.DialogShower
     @Mock private lateinit var resumeSessionReceiver: GuestResumeSessionReceiver
     @Mock private lateinit var resetOrExitSessionReceiver: GuestResetOrExitSessionReceiver
+    @Mock private lateinit var commandQueue: CommandQueue
 
     private lateinit var underTest: UserInteractor
 
-    private lateinit var testCoroutineScope: TestCoroutineScope
+    private lateinit var testScope: TestScope
     private lateinit var userRepository: FakeUserRepository
     private lateinit var keyguardRepository: FakeKeyguardRepository
     private lateinit var telephonyRepository: FakeTelephonyRepository
@@ -117,11 +122,12 @@
         userRepository = FakeUserRepository()
         keyguardRepository = FakeKeyguardRepository()
         telephonyRepository = FakeTelephonyRepository()
-        testCoroutineScope = TestCoroutineScope()
+        val testDispatcher = StandardTestDispatcher()
+        testScope = TestScope(testDispatcher)
         val refreshUsersScheduler =
             RefreshUsersScheduler(
-                applicationScope = testCoroutineScope,
-                mainDispatcher = IMMEDIATE,
+                applicationScope = testScope.backgroundScope,
+                mainDispatcher = testDispatcher,
                 repository = userRepository,
             )
         underTest =
@@ -132,23 +138,24 @@
                 keyguardInteractor =
                     KeyguardInteractor(
                         repository = keyguardRepository,
+                        commandQueue = commandQueue,
                     ),
                 manager = manager,
-                applicationScope = testCoroutineScope,
+                applicationScope = testScope.backgroundScope,
                 telephonyInteractor =
                     TelephonyInteractor(
                         repository = telephonyRepository,
                     ),
                 broadcastDispatcher = fakeBroadcastDispatcher,
-                backgroundDispatcher = IMMEDIATE,
+                backgroundDispatcher = testDispatcher,
                 activityManager = activityManager,
                 refreshUsersScheduler = refreshUsersScheduler,
                 guestUserInteractor =
                     GuestUserInteractor(
                         applicationContext = context,
-                        applicationScope = testCoroutineScope,
-                        mainDispatcher = IMMEDIATE,
-                        backgroundDispatcher = IMMEDIATE,
+                        applicationScope = testScope.backgroundScope,
+                        mainDispatcher = testDispatcher,
+                        backgroundDispatcher = testDispatcher,
                         manager = manager,
                         repository = userRepository,
                         deviceProvisionedController = deviceProvisionedController,
@@ -164,7 +171,7 @@
 
     @Test
     fun `onRecordSelected - user`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 3, includeGuest = false)
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[0])
@@ -179,7 +186,7 @@
 
     @Test
     fun `onRecordSelected - switch to guest user`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 3, includeGuest = true)
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[0])
@@ -193,7 +200,7 @@
 
     @Test
     fun `onRecordSelected - enter guest mode`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 3, includeGuest = false)
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[0])
@@ -202,6 +209,7 @@
             whenever(manager.createGuest(any())).thenReturn(guestUserInfo)
 
             underTest.onRecordSelected(UserRecord(isGuest = true), dialogShower)
+            runCurrent()
 
             verify(dialogShower).dismiss()
             verify(manager).createGuest(any())
@@ -210,7 +218,7 @@
 
     @Test
     fun `onRecordSelected - action`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 3, includeGuest = true)
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[0])
@@ -224,81 +232,72 @@
 
     @Test
     fun `users - switcher enabled`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 3, includeGuest = true)
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[0])
             userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
 
-            var value: List<UserModel>? = null
-            val job = underTest.users.onEach { value = it }.launchIn(this)
-            assertUsers(models = value, count = 3, includeGuest = true)
+            val value = collectLastValue(underTest.users)
 
-            job.cancel()
+            assertUsers(models = value(), count = 3, includeGuest = true)
         }
 
     @Test
     fun `users - switches to second user`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[0])
             userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
 
-            var value: List<UserModel>? = null
-            val job = underTest.users.onEach { value = it }.launchIn(this)
+            val value = collectLastValue(underTest.users)
             userRepository.setSelectedUserInfo(userInfos[1])
 
-            assertUsers(models = value, count = 2, selectedIndex = 1)
-            job.cancel()
+            assertUsers(models = value(), count = 2, selectedIndex = 1)
         }
 
     @Test
     fun `users - switcher not enabled`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[0])
             userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = false))
 
-            var value: List<UserModel>? = null
-            val job = underTest.users.onEach { value = it }.launchIn(this)
-            assertUsers(models = value, count = 1)
-
-            job.cancel()
+            val value = collectLastValue(underTest.users)
+            assertUsers(models = value(), count = 1)
         }
 
     @Test
     fun selectedUser() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[0])
             userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
 
-            var value: UserModel? = null
-            val job = underTest.selectedUser.onEach { value = it }.launchIn(this)
-            assertUser(value, id = 0, isSelected = true)
+            val value = collectLastValue(underTest.selectedUser)
+            assertUser(value(), id = 0, isSelected = true)
 
             userRepository.setSelectedUserInfo(userInfos[1])
-            assertUser(value, id = 1, isSelected = true)
-
-            job.cancel()
+            assertUser(value(), id = 1, isSelected = true)
         }
 
     @Test
     fun `actions - device unlocked`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
 
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[0])
             userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
             keyguardRepository.setKeyguardShowing(false)
-            var value: List<UserActionModel>? = null
-            val job = underTest.actions.onEach { value = it }.launchIn(this)
+            val value = collectLastValue(underTest.actions)
 
-            assertThat(value)
+            runCurrent()
+
+            assertThat(value())
                 .isEqualTo(
                     listOf(
                         UserActionModel.ENTER_GUEST_MODE,
@@ -307,13 +306,11 @@
                         UserActionModel.NAVIGATE_TO_USER_MANAGEMENT,
                     )
                 )
-
-            job.cancel()
         }
 
     @Test
     fun `actions - device unlocked - full screen`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, true)
             val userInfos = createUserInfos(count = 2, includeGuest = false)
 
@@ -321,10 +318,9 @@
             userRepository.setSelectedUserInfo(userInfos[0])
             userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
             keyguardRepository.setKeyguardShowing(false)
-            var value: List<UserActionModel>? = null
-            val job = underTest.actions.onEach { value = it }.launchIn(this)
+            val value = collectLastValue(underTest.actions)
 
-            assertThat(value)
+            assertThat(value())
                 .isEqualTo(
                     listOf(
                         UserActionModel.ADD_USER,
@@ -333,46 +329,38 @@
                         UserActionModel.NAVIGATE_TO_USER_MANAGEMENT,
                     )
                 )
-
-            job.cancel()
         }
 
     @Test
     fun `actions - device unlocked user not primary - empty list`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[1])
             userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
             keyguardRepository.setKeyguardShowing(false)
-            var value: List<UserActionModel>? = null
-            val job = underTest.actions.onEach { value = it }.launchIn(this)
+            val value = collectLastValue(underTest.actions)
 
-            assertThat(value).isEqualTo(emptyList<UserActionModel>())
-
-            job.cancel()
+            assertThat(value()).isEqualTo(emptyList<UserActionModel>())
         }
 
     @Test
     fun `actions - device unlocked user is guest - empty list`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = true)
             assertThat(userInfos[1].isGuest).isTrue()
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[1])
             userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
             keyguardRepository.setKeyguardShowing(false)
-            var value: List<UserActionModel>? = null
-            val job = underTest.actions.onEach { value = it }.launchIn(this)
+            val value = collectLastValue(underTest.actions)
 
-            assertThat(value).isEqualTo(emptyList<UserActionModel>())
-
-            job.cancel()
+            assertThat(value()).isEqualTo(emptyList<UserActionModel>())
         }
 
     @Test
     fun `actions - device locked add from lockscreen set - full list`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[0])
@@ -383,10 +371,9 @@
                 )
             )
             keyguardRepository.setKeyguardShowing(false)
-            var value: List<UserActionModel>? = null
-            val job = underTest.actions.onEach { value = it }.launchIn(this)
+            val value = collectLastValue(underTest.actions)
 
-            assertThat(value)
+            assertThat(value())
                 .isEqualTo(
                     listOf(
                         UserActionModel.ENTER_GUEST_MODE,
@@ -395,13 +382,11 @@
                         UserActionModel.NAVIGATE_TO_USER_MANAGEMENT,
                     )
                 )
-
-            job.cancel()
         }
 
     @Test
     fun `actions - device locked add from lockscreen set - full list - full screen`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, true)
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
@@ -413,10 +398,9 @@
                 )
             )
             keyguardRepository.setKeyguardShowing(false)
-            var value: List<UserActionModel>? = null
-            val job = underTest.actions.onEach { value = it }.launchIn(this)
+            val value = collectLastValue(underTest.actions)
 
-            assertThat(value)
+            assertThat(value())
                 .isEqualTo(
                     listOf(
                         UserActionModel.ADD_USER,
@@ -425,39 +409,33 @@
                         UserActionModel.NAVIGATE_TO_USER_MANAGEMENT,
                     )
                 )
-
-            job.cancel()
         }
 
     @Test
     fun `actions - device locked - only  manage user is shown`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[0])
             userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
             keyguardRepository.setKeyguardShowing(true)
-            var value: List<UserActionModel>? = null
-            val job = underTest.actions.onEach { value = it }.launchIn(this)
+            val value = collectLastValue(underTest.actions)
 
-            assertThat(value).isEqualTo(listOf(UserActionModel.NAVIGATE_TO_USER_MANAGEMENT))
-
-            job.cancel()
+            assertThat(value()).isEqualTo(listOf(UserActionModel.NAVIGATE_TO_USER_MANAGEMENT))
         }
 
     @Test
     fun `executeAction - add user - dialog shown`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[0])
             keyguardRepository.setKeyguardShowing(false)
-            var dialogRequest: ShowDialogRequestModel? = null
-            val job = underTest.dialogShowRequests.onEach { dialogRequest = it }.launchIn(this)
+            val dialogRequest = collectLastValue(underTest.dialogShowRequests)
             val dialogShower: UserSwitchDialogController.DialogShower = mock()
 
             underTest.executeAction(UserActionModel.ADD_USER, dialogShower)
-            assertThat(dialogRequest)
+            assertThat(dialogRequest())
                 .isEqualTo(
                     ShowDialogRequestModel.ShowAddUserDialog(
                         userHandle = userInfos[0].userHandle,
@@ -468,14 +446,12 @@
                 )
 
             underTest.onDialogShown()
-            assertThat(dialogRequest).isNull()
-
-            job.cancel()
+            assertThat(dialogRequest()).isNull()
         }
 
     @Test
-    fun `executeAction - add supervised user - starts activity`() =
-        runBlocking(IMMEDIATE) {
+    fun `executeAction - add supervised user - dismisses dialog and starts activity`() =
+        testScope.runTest {
             underTest.executeAction(UserActionModel.ADD_SUPERVISED_USER)
 
             val intentCaptor = kotlinArgumentCaptor<Intent>()
@@ -487,7 +463,7 @@
 
     @Test
     fun `executeAction - navigate to manage users`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             underTest.executeAction(UserActionModel.NAVIGATE_TO_USER_MANAGEMENT)
 
             val intentCaptor = kotlinArgumentCaptor<Intent>()
@@ -497,7 +473,7 @@
 
     @Test
     fun `executeAction - guest mode`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[0])
@@ -505,110 +481,103 @@
             val guestUserInfo = createUserInfo(id = 1337, name = "guest", isGuest = true)
             whenever(manager.createGuest(any())).thenReturn(guestUserInfo)
             val dialogRequests = mutableListOf<ShowDialogRequestModel?>()
-            val showDialogsJob =
-                underTest.dialogShowRequests
-                    .onEach {
-                        dialogRequests.add(it)
-                        if (it != null) {
-                            underTest.onDialogShown()
-                        }
+            backgroundScope.launch {
+                underTest.dialogShowRequests.collect {
+                    dialogRequests.add(it)
+                    if (it != null) {
+                        underTest.onDialogShown()
                     }
-                    .launchIn(this)
-            val dismissDialogsJob =
-                underTest.dialogDismissRequests
-                    .onEach {
-                        if (it != null) {
-                            underTest.onDialogDismissed()
-                        }
+                }
+            }
+            backgroundScope.launch {
+                underTest.dialogDismissRequests.collect {
+                    if (it != null) {
+                        underTest.onDialogDismissed()
                     }
-                    .launchIn(this)
+                }
+            }
 
             underTest.executeAction(UserActionModel.ENTER_GUEST_MODE)
+            runCurrent()
 
             assertThat(dialogRequests)
                 .contains(
                     ShowDialogRequestModel.ShowUserCreationDialog(isGuest = true),
                 )
             verify(activityManager).switchUser(guestUserInfo.id)
-
-            showDialogsJob.cancel()
-            dismissDialogsJob.cancel()
         }
 
     @Test
     fun `selectUser - already selected guest re-selected - exit guest dialog`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = true)
             val guestUserInfo = userInfos[1]
             assertThat(guestUserInfo.isGuest).isTrue()
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(guestUserInfo)
             userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
-            var dialogRequest: ShowDialogRequestModel? = null
-            val job = underTest.dialogShowRequests.onEach { dialogRequest = it }.launchIn(this)
+            val dialogRequest = collectLastValue(underTest.dialogShowRequests)
 
             underTest.selectUser(
                 newlySelectedUserId = guestUserInfo.id,
                 dialogShower = dialogShower,
             )
 
-            assertThat(dialogRequest)
+            assertThat(dialogRequest())
                 .isInstanceOf(ShowDialogRequestModel.ShowExitGuestDialog::class.java)
             verify(dialogShower, never()).dismiss()
-            job.cancel()
         }
 
     @Test
     fun `selectUser - currently guest non-guest selected - exit guest dialog`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = true)
             val guestUserInfo = userInfos[1]
             assertThat(guestUserInfo.isGuest).isTrue()
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(guestUserInfo)
             userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
-            var dialogRequest: ShowDialogRequestModel? = null
-            val job = underTest.dialogShowRequests.onEach { dialogRequest = it }.launchIn(this)
+            val dialogRequest = collectLastValue(underTest.dialogShowRequests)
 
             underTest.selectUser(newlySelectedUserId = userInfos[0].id, dialogShower = dialogShower)
 
-            assertThat(dialogRequest)
+            assertThat(dialogRequest())
                 .isInstanceOf(ShowDialogRequestModel.ShowExitGuestDialog::class.java)
             verify(dialogShower, never()).dismiss()
-            job.cancel()
         }
 
     @Test
     fun `selectUser - not currently guest - switches users`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[0])
             userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
-            var dialogRequest: ShowDialogRequestModel? = null
-            val job = underTest.dialogShowRequests.onEach { dialogRequest = it }.launchIn(this)
+            val dialogRequest = collectLastValue(underTest.dialogShowRequests)
 
             underTest.selectUser(newlySelectedUserId = userInfos[1].id, dialogShower = dialogShower)
 
-            assertThat(dialogRequest).isNull()
+            assertThat(dialogRequest()).isNull()
             verify(activityManager).switchUser(userInfos[1].id)
             verify(dialogShower).dismiss()
-            job.cancel()
         }
 
     @Test
     fun `Telephony call state changes - refreshes users`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
+            runCurrent()
+
             val refreshUsersCallCount = userRepository.refreshUsersCallCount
 
             telephonyRepository.setCallState(1)
+            runCurrent()
 
             assertThat(userRepository.refreshUsersCallCount).isEqualTo(refreshUsersCallCount + 1)
         }
 
     @Test
     fun `User switched broadcast`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[0])
@@ -617,9 +586,11 @@
             val callback2: UserInteractor.UserCallback = mock()
             underTest.addCallback(callback1)
             underTest.addCallback(callback2)
+            runCurrent()
             val refreshUsersCallCount = userRepository.refreshUsersCallCount
 
             userRepository.setSelectedUserInfo(userInfos[1])
+            runCurrent()
             fakeBroadcastDispatcher.registeredReceivers.forEach {
                 it.onReceive(
                     context,
@@ -627,16 +598,17 @@
                         .putExtra(Intent.EXTRA_USER_HANDLE, userInfos[1].id),
                 )
             }
+            runCurrent()
 
-            verify(callback1).onUserStateChanged()
-            verify(callback2).onUserStateChanged()
+            verify(callback1, atLeastOnce()).onUserStateChanged()
+            verify(callback2, atLeastOnce()).onUserStateChanged()
             assertThat(userRepository.secondaryUserId).isEqualTo(userInfos[1].id)
             assertThat(userRepository.refreshUsersCallCount).isEqualTo(refreshUsersCallCount + 1)
         }
 
     @Test
     fun `User info changed broadcast`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[0])
@@ -649,12 +621,14 @@
                 )
             }
 
+            runCurrent()
+
             assertThat(userRepository.refreshUsersCallCount).isEqualTo(refreshUsersCallCount + 1)
         }
 
     @Test
     fun `System user unlocked broadcast - refresh users`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[0])
@@ -667,13 +641,14 @@
                         .putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_SYSTEM),
                 )
             }
+            runCurrent()
 
             assertThat(userRepository.refreshUsersCallCount).isEqualTo(refreshUsersCallCount + 1)
         }
 
     @Test
     fun `Non-system user unlocked broadcast - do not refresh users`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[0])
@@ -691,14 +666,14 @@
 
     @Test
     fun userRecords() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 3, includeGuest = false)
             userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[0])
             keyguardRepository.setKeyguardShowing(false)
 
-            testCoroutineScope.advanceUntilIdle()
+            runCurrent()
 
             assertRecords(
                 records = underTest.userRecords.value,
@@ -717,7 +692,7 @@
 
     @Test
     fun userRecordsFullScreen() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, true)
             val userInfos = createUserInfos(count = 3, includeGuest = false)
             userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
@@ -725,7 +700,7 @@
             userRepository.setSelectedUserInfo(userInfos[0])
             keyguardRepository.setKeyguardShowing(false)
 
-            testCoroutineScope.advanceUntilIdle()
+            runCurrent()
 
             assertRecords(
                 records = underTest.userRecords.value,
@@ -744,7 +719,7 @@
 
     @Test
     fun selectedUserRecord() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 3, includeGuest = true)
             userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
             userRepository.setUserInfos(userInfos)
@@ -762,63 +737,54 @@
 
     @Test
     fun `users - secondary user - guest user can be switched to`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 3, includeGuest = true)
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[1])
             userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
 
-            var res: List<UserModel>? = null
-            val job = underTest.users.onEach { res = it }.launchIn(this)
-            assertThat(res?.size == 3).isTrue()
-            assertThat(res?.find { it.isGuest }).isNotNull()
-            job.cancel()
+            val res = collectLastValue(underTest.users)
+            assertThat(res()?.size == 3).isTrue()
+            assertThat(res()?.find { it.isGuest }).isNotNull()
         }
 
     @Test
     fun `users - secondary user - no guest action`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 3, includeGuest = true)
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[1])
             userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
 
-            var res: List<UserActionModel>? = null
-            val job = underTest.actions.onEach { res = it }.launchIn(this)
-            assertThat(res?.find { it == UserActionModel.ENTER_GUEST_MODE }).isNull()
-            job.cancel()
+            val res = collectLastValue(underTest.actions)
+            assertThat(res()?.find { it == UserActionModel.ENTER_GUEST_MODE }).isNull()
         }
 
     @Test
     fun `users - secondary user - no guest user record`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 3, includeGuest = true)
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[1])
             userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
 
-            var res: List<UserRecord>? = null
-            val job = underTest.userRecords.onEach { res = it }.launchIn(this)
-            assertThat(res?.find { it.isGuest }).isNull()
-            job.cancel()
+            assertThat(underTest.userRecords.value.find { it.isGuest }).isNull()
         }
 
     @Test
     fun `show user switcher - full screen disabled - shows dialog switcher`() =
-        runBlocking(IMMEDIATE) {
-            var dialogRequest: ShowDialogRequestModel? = null
+        testScope.runTest {
             val expandable = mock<Expandable>()
             underTest.showUserSwitcher(context, expandable)
 
-            val job = underTest.dialogShowRequests.onEach { dialogRequest = it }.launchIn(this)
+            val dialogRequest = collectLastValue(underTest.dialogShowRequests)
 
             // Dialog is shown.
-            assertThat(dialogRequest).isEqualTo(ShowDialogRequestModel.ShowUserSwitcherDialog)
+            assertThat(dialogRequest())
+                .isEqualTo(ShowDialogRequestModel.ShowUserSwitcherDialog(expandable))
 
             underTest.onDialogShown()
-            assertThat(dialogRequest).isNull()
-
-            job.cancel()
+            assertThat(dialogRequest()).isNull()
         }
 
     @Test
@@ -849,8 +815,8 @@
 
     @Test
     fun `users - secondary user - managed profile is not included`() =
-        runBlocking(IMMEDIATE) {
-            var userInfos = createUserInfos(count = 3, includeGuest = false).toMutableList()
+        testScope.runTest {
+            val userInfos = createUserInfos(count = 3, includeGuest = false).toMutableList()
             userInfos.add(
                 UserInfo(
                     50,
@@ -863,23 +829,19 @@
             userRepository.setSelectedUserInfo(userInfos[1])
             userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
 
-            var res: List<UserModel>? = null
-            val job = underTest.users.onEach { res = it }.launchIn(this)
-            assertThat(res?.size == 3).isTrue()
-            job.cancel()
+            val res = collectLastValue(underTest.users)
+            assertThat(res()?.size == 3).isTrue()
         }
 
     @Test
     fun `current user is not primary and user switcher is disabled`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[1])
             userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = false))
-            var selectedUser: UserModel? = null
-            val job = underTest.selectedUser.onEach { selectedUser = it }.launchIn(this)
-            assertThat(selectedUser).isNotNull()
-            job.cancel()
+            val selectedUser = collectLastValue(underTest.selectedUser)
+            assertThat(selectedUser()).isNotNull()
         }
 
     private fun assertUsers(
@@ -1017,7 +979,6 @@
     }
 
     companion object {
-        private val IMMEDIATE = Dispatchers.Main.immediate
         private val ICON = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)
         private val GUEST_ICON: Drawable = mock()
         private const val SUPERVISED_USER_CREATION_APP_PACKAGE = "supervisedUserCreation"
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 108fa62..9a4ca56 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
@@ -34,6 +34,7 @@
 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
 import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.policy.DeviceProvisionedController
 import com.android.systemui.telephony.data.repository.FakeTelephonyRepository
 import com.android.systemui.telephony.domain.interactor.TelephonyInteractor
@@ -75,6 +76,7 @@
     @Mock private lateinit var uiEventLogger: UiEventLogger
     @Mock private lateinit var resumeSessionReceiver: GuestResumeSessionReceiver
     @Mock private lateinit var resetOrExitSessionReceiver: GuestResetOrExitSessionReceiver
+    @Mock private lateinit var commandQueue: CommandQueue
 
     private lateinit var underTest: StatusBarUserChipViewModel
 
@@ -241,6 +243,7 @@
                     keyguardInteractor =
                         KeyguardInteractor(
                             repository = keyguardRepository,
+                            commandQueue = commandQueue,
                         ),
                     featureFlags =
                         FakeFeatureFlags().apply { set(Flags.FULL_SCREEN_USER_SWITCHER, false) },
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 784a26b..3d4bbdb 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
@@ -34,6 +34,7 @@
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.power.data.repository.FakePowerRepository
 import com.android.systemui.power.domain.interactor.PowerInteractor
+import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.policy.DeviceProvisionedController
 import com.android.systemui.telephony.data.repository.FakeTelephonyRepository
 import com.android.systemui.telephony.domain.interactor.TelephonyInteractor
@@ -76,6 +77,7 @@
     @Mock private lateinit var uiEventLogger: UiEventLogger
     @Mock private lateinit var resumeSessionReceiver: GuestResumeSessionReceiver
     @Mock private lateinit var resetOrExitSessionReceiver: GuestResetOrExitSessionReceiver
+    @Mock private lateinit var commandQueue: CommandQueue
 
     private lateinit var underTest: UserSwitcherViewModel
 
@@ -142,6 +144,7 @@
                             keyguardInteractor =
                                 KeyguardInteractor(
                                     repository = keyguardRepository,
+                                    commandQueue = commandQueue,
                                 ),
                             featureFlags =
                                 FakeFeatureFlags().apply {
@@ -169,273 +172,295 @@
     }
 
     @Test
-    fun users() = testScope.runTest {
-        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,
-                ),
-                UserInfo(
-                    /* id= */ 1,
-                    /* name= */ "one",
-                    /* iconPath= */ "",
-                    /* flags= */ UserInfo.FLAG_FULL,
-                    UserManager.USER_TYPE_FULL_SYSTEM,
-                ),
-                UserInfo(
-                    /* id= */ 2,
-                    /* name= */ "two",
-                    /* iconPath= */ "",
-                    /* flags= */ UserInfo.FLAG_FULL,
-                    UserManager.USER_TYPE_FULL_SYSTEM,
-                ),
-            )
-        userRepository.setUserInfos(userInfos)
-        userRepository.setSelectedUserInfo(userInfos[0])
-
-        val userViewModels = mutableListOf<List<UserViewModel>>()
-        val job = launch(testDispatcher) { underTest.users.toList(userViewModels) }
-
-        assertThat(userViewModels.last()).hasSize(3)
-        assertUserViewModel(
-            viewModel = userViewModels.last()[0],
-            viewKey = 0,
-            name = Text.Loaded("zero"),
-            isSelectionMarkerVisible = true,
-        )
-        assertUserViewModel(
-            viewModel = userViewModels.last()[1],
-            viewKey = 1,
-            name = Text.Loaded("one"),
-            isSelectionMarkerVisible = false,
-        )
-        assertUserViewModel(
-            viewModel = userViewModels.last()[2],
-            viewKey = 2,
-            name = Text.Loaded("two"),
-            isSelectionMarkerVisible = false,
-        )
-        job.cancel()
-    }
-
-    @Test
-    fun `maximumUserColumns - few users`() = testScope.runTest {
-        setUsers(count = 2)
-        val values = mutableListOf<Int>()
-        val job = launch(testDispatcher) { underTest.maximumUserColumns.toList(values) }
-
-        assertThat(values.last()).isEqualTo(4)
-
-        job.cancel()
-    }
-
-    @Test
-    fun `maximumUserColumns - many users`() = testScope.runTest {
-        setUsers(count = 5)
-        val values = mutableListOf<Int>()
-        val job = launch(testDispatcher) { underTest.maximumUserColumns.toList(values) }
-
-        assertThat(values.last()).isEqualTo(3)
-        job.cancel()
-    }
-
-    @Test
-    fun `isOpenMenuButtonVisible - has actions - true`() = testScope.runTest {
-        setUsers(2)
-
-        val isVisible = mutableListOf<Boolean>()
-        val job = launch(testDispatcher) { underTest.isOpenMenuButtonVisible.toList(isVisible) }
-
-        assertThat(isVisible.last()).isTrue()
-        job.cancel()
-    }
-
-    @Test
-    fun `isOpenMenuButtonVisible - no actions - false`() = testScope.runTest {
-        val userInfos = setUsers(2)
-        userRepository.setSelectedUserInfo(userInfos[1])
-        keyguardRepository.setKeyguardShowing(true)
-        whenever(manager.canAddMoreUsers(any())).thenReturn(false)
-
-        val isVisible = mutableListOf<Boolean>()
-        val job = launch(testDispatcher) { underTest.isOpenMenuButtonVisible.toList(isVisible) }
-
-        assertThat(isVisible.last()).isFalse()
-        job.cancel()
-    }
-
-    @Test
-    fun menu() = testScope.runTest {
-        val isMenuVisible = mutableListOf<Boolean>()
-        val job = launch(testDispatcher) { underTest.isMenuVisible.toList(isMenuVisible) }
-        assertThat(isMenuVisible.last()).isFalse()
-
-        underTest.onOpenMenuButtonClicked()
-        assertThat(isMenuVisible.last()).isTrue()
-
-        underTest.onMenuClosed()
-        assertThat(isMenuVisible.last()).isFalse()
-
-        job.cancel()
-    }
-
-    @Test
-    fun `menu actions`() = testScope.runTest {
-        setUsers(2)
-        val actions = mutableListOf<List<UserActionViewModel>>()
-        val job = launch(testDispatcher) { underTest.menu.toList(actions) }
-
-        assertThat(actions.last().map { it.viewKey })
-            .isEqualTo(
+    fun users() =
+        testScope.runTest {
+            val userInfos =
                 listOf(
-                    UserActionModel.ENTER_GUEST_MODE.ordinal.toLong(),
-                    UserActionModel.ADD_USER.ordinal.toLong(),
-                    UserActionModel.ADD_SUPERVISED_USER.ordinal.toLong(),
-                    UserActionModel.NAVIGATE_TO_USER_MANAGEMENT.ordinal.toLong(),
+                    UserInfo(
+                        /* id= */ 0,
+                        /* name= */ "zero",
+                        /* iconPath= */ "",
+                        /* flags= */ UserInfo.FLAG_PRIMARY or
+                            UserInfo.FLAG_ADMIN or
+                            UserInfo.FLAG_FULL,
+                        UserManager.USER_TYPE_FULL_SYSTEM,
+                    ),
+                    UserInfo(
+                        /* id= */ 1,
+                        /* name= */ "one",
+                        /* iconPath= */ "",
+                        /* flags= */ UserInfo.FLAG_FULL,
+                        UserManager.USER_TYPE_FULL_SYSTEM,
+                    ),
+                    UserInfo(
+                        /* id= */ 2,
+                        /* name= */ "two",
+                        /* iconPath= */ "",
+                        /* flags= */ UserInfo.FLAG_FULL,
+                        UserManager.USER_TYPE_FULL_SYSTEM,
+                    ),
                 )
-            )
+            userRepository.setUserInfos(userInfos)
+            userRepository.setSelectedUserInfo(userInfos[0])
 
-        job.cancel()
-    }
+            val userViewModels = mutableListOf<List<UserViewModel>>()
+            val job = launch(testDispatcher) { underTest.users.toList(userViewModels) }
 
-    @Test
-    fun `isFinishRequested - finishes when user is switched`() = testScope.runTest {
-        val userInfos = setUsers(count = 2)
-        val isFinishRequested = mutableListOf<Boolean>()
-        val job = launch(testDispatcher) { underTest.isFinishRequested.toList(isFinishRequested) }
-        assertThat(isFinishRequested.last()).isFalse()
-
-        userRepository.setSelectedUserInfo(userInfos[1])
-
-        assertThat(isFinishRequested.last()).isTrue()
-
-        job.cancel()
-    }
-
-    @Test
-    fun `isFinishRequested - finishes when the screen turns off`() = testScope.runTest {
-        setUsers(count = 2)
-        powerRepository.setInteractive(true)
-        val isFinishRequested = mutableListOf<Boolean>()
-        val job = launch(testDispatcher) { underTest.isFinishRequested.toList(isFinishRequested) }
-        assertThat(isFinishRequested.last()).isFalse()
-
-        powerRepository.setInteractive(false)
-
-        assertThat(isFinishRequested.last()).isTrue()
-
-        job.cancel()
-    }
-
-    @Test
-    fun `isFinishRequested - finishes when cancel button is clicked`() = testScope.runTest {
-        setUsers(count = 2)
-        powerRepository.setInteractive(true)
-        val isFinishRequested = mutableListOf<Boolean>()
-        val job = launch(testDispatcher) { underTest.isFinishRequested.toList(isFinishRequested) }
-        assertThat(isFinishRequested.last()).isFalse()
-
-        underTest.onCancelButtonClicked()
-
-        assertThat(isFinishRequested.last()).isTrue()
-
-        underTest.onFinished()
-
-        assertThat(isFinishRequested.last()).isFalse()
-
-        job.cancel()
-    }
-
-    @Test
-    fun `guest selected -- name is exit guest`() = testScope.runTest {
-        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,
-                        ),
-                        UserInfo(
-                                /* id= */ 1,
-                                /* name= */ "one",
-                                /* iconPath= */ "",
-                                /* flags= */ UserInfo.FLAG_FULL,
-                                UserManager.USER_TYPE_FULL_GUEST,
-                        ),
-                )
-
-        userRepository.setUserInfos(userInfos)
-        userRepository.setSelectedUserInfo(userInfos[1])
-
-        val userViewModels = mutableListOf<List<UserViewModel>>()
-        val job = launch(testDispatcher) { underTest.users.toList(userViewModels) }
-
-        assertThat(userViewModels.last()).hasSize(2)
-        assertUserViewModel(
-                viewModel = userViewModels.last()[0],
-                viewKey = 0,
-                name = Text.Loaded("zero"),
-                isSelectionMarkerVisible = false,
-        )
-        assertUserViewModel(
-                viewModel = userViewModels.last()[1],
-                viewKey = 1,
-                name = Text.Resource(
-                    com.android.settingslib.R.string.guest_exit_quick_settings_button
-                ),
-                isSelectionMarkerVisible = true,
-        )
-        job.cancel()
-    }
-
-    @Test
-    fun `guest not selected -- name is guest`() = testScope.runTest {
-        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,
-                        ),
-                        UserInfo(
-                                /* id= */ 1,
-                                /* name= */ "one",
-                                /* iconPath= */ "",
-                                /* flags= */ UserInfo.FLAG_FULL,
-                                UserManager.USER_TYPE_FULL_GUEST,
-                        ),
-                )
-
-        userRepository.setUserInfos(userInfos)
-        userRepository.setSelectedUserInfo(userInfos[0])
-        runCurrent()
-
-        val userViewModels = mutableListOf<List<UserViewModel>>()
-        val job = launch(testDispatcher) { underTest.users.toList(userViewModels) }
-
-        assertThat(userViewModels.last()).hasSize(2)
-        assertUserViewModel(
+            assertThat(userViewModels.last()).hasSize(3)
+            assertUserViewModel(
                 viewModel = userViewModels.last()[0],
                 viewKey = 0,
                 name = Text.Loaded("zero"),
                 isSelectionMarkerVisible = true,
-        )
-        assertUserViewModel(
+            )
+            assertUserViewModel(
                 viewModel = userViewModels.last()[1],
                 viewKey = 1,
                 name = Text.Loaded("one"),
                 isSelectionMarkerVisible = false,
-        )
-        job.cancel()
-    }
+            )
+            assertUserViewModel(
+                viewModel = userViewModels.last()[2],
+                viewKey = 2,
+                name = Text.Loaded("two"),
+                isSelectionMarkerVisible = false,
+            )
+            job.cancel()
+        }
+
+    @Test
+    fun `maximumUserColumns - few users`() =
+        testScope.runTest {
+            setUsers(count = 2)
+            val values = mutableListOf<Int>()
+            val job = launch(testDispatcher) { underTest.maximumUserColumns.toList(values) }
+
+            assertThat(values.last()).isEqualTo(4)
+
+            job.cancel()
+        }
+
+    @Test
+    fun `maximumUserColumns - many users`() =
+        testScope.runTest {
+            setUsers(count = 5)
+            val values = mutableListOf<Int>()
+            val job = launch(testDispatcher) { underTest.maximumUserColumns.toList(values) }
+
+            assertThat(values.last()).isEqualTo(3)
+            job.cancel()
+        }
+
+    @Test
+    fun `isOpenMenuButtonVisible - has actions - true`() =
+        testScope.runTest {
+            setUsers(2)
+
+            val isVisible = mutableListOf<Boolean>()
+            val job = launch(testDispatcher) { underTest.isOpenMenuButtonVisible.toList(isVisible) }
+
+            assertThat(isVisible.last()).isTrue()
+            job.cancel()
+        }
+
+    @Test
+    fun `isOpenMenuButtonVisible - no actions - false`() =
+        testScope.runTest {
+            val userInfos = setUsers(2)
+            userRepository.setSelectedUserInfo(userInfos[1])
+            keyguardRepository.setKeyguardShowing(true)
+            whenever(manager.canAddMoreUsers(any())).thenReturn(false)
+
+            val isVisible = mutableListOf<Boolean>()
+            val job = launch(testDispatcher) { underTest.isOpenMenuButtonVisible.toList(isVisible) }
+
+            assertThat(isVisible.last()).isFalse()
+            job.cancel()
+        }
+
+    @Test
+    fun menu() =
+        testScope.runTest {
+            val isMenuVisible = mutableListOf<Boolean>()
+            val job = launch(testDispatcher) { underTest.isMenuVisible.toList(isMenuVisible) }
+            assertThat(isMenuVisible.last()).isFalse()
+
+            underTest.onOpenMenuButtonClicked()
+            assertThat(isMenuVisible.last()).isTrue()
+
+            underTest.onMenuClosed()
+            assertThat(isMenuVisible.last()).isFalse()
+
+            job.cancel()
+        }
+
+    @Test
+    fun `menu actions`() =
+        testScope.runTest {
+            setUsers(2)
+            val actions = mutableListOf<List<UserActionViewModel>>()
+            val job = launch(testDispatcher) { underTest.menu.toList(actions) }
+
+            assertThat(actions.last().map { it.viewKey })
+                .isEqualTo(
+                    listOf(
+                        UserActionModel.ENTER_GUEST_MODE.ordinal.toLong(),
+                        UserActionModel.ADD_USER.ordinal.toLong(),
+                        UserActionModel.ADD_SUPERVISED_USER.ordinal.toLong(),
+                        UserActionModel.NAVIGATE_TO_USER_MANAGEMENT.ordinal.toLong(),
+                    )
+                )
+
+            job.cancel()
+        }
+
+    @Test
+    fun `isFinishRequested - finishes when user is switched`() =
+        testScope.runTest {
+            val userInfos = setUsers(count = 2)
+            val isFinishRequested = mutableListOf<Boolean>()
+            val job =
+                launch(testDispatcher) { underTest.isFinishRequested.toList(isFinishRequested) }
+            assertThat(isFinishRequested.last()).isFalse()
+
+            userRepository.setSelectedUserInfo(userInfos[1])
+
+            assertThat(isFinishRequested.last()).isTrue()
+
+            job.cancel()
+        }
+
+    @Test
+    fun `isFinishRequested - finishes when the screen turns off`() =
+        testScope.runTest {
+            setUsers(count = 2)
+            powerRepository.setInteractive(true)
+            val isFinishRequested = mutableListOf<Boolean>()
+            val job =
+                launch(testDispatcher) { underTest.isFinishRequested.toList(isFinishRequested) }
+            assertThat(isFinishRequested.last()).isFalse()
+
+            powerRepository.setInteractive(false)
+
+            assertThat(isFinishRequested.last()).isTrue()
+
+            job.cancel()
+        }
+
+    @Test
+    fun `isFinishRequested - finishes when cancel button is clicked`() =
+        testScope.runTest {
+            setUsers(count = 2)
+            powerRepository.setInteractive(true)
+            val isFinishRequested = mutableListOf<Boolean>()
+            val job =
+                launch(testDispatcher) { underTest.isFinishRequested.toList(isFinishRequested) }
+            assertThat(isFinishRequested.last()).isFalse()
+
+            underTest.onCancelButtonClicked()
+
+            assertThat(isFinishRequested.last()).isTrue()
+
+            underTest.onFinished()
+
+            assertThat(isFinishRequested.last()).isFalse()
+
+            job.cancel()
+        }
+
+    @Test
+    fun `guest selected -- name is exit guest`() =
+        testScope.runTest {
+            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,
+                    ),
+                    UserInfo(
+                        /* id= */ 1,
+                        /* name= */ "one",
+                        /* iconPath= */ "",
+                        /* flags= */ UserInfo.FLAG_FULL,
+                        UserManager.USER_TYPE_FULL_GUEST,
+                    ),
+                )
+
+            userRepository.setUserInfos(userInfos)
+            userRepository.setSelectedUserInfo(userInfos[1])
+
+            val userViewModels = mutableListOf<List<UserViewModel>>()
+            val job = launch(testDispatcher) { underTest.users.toList(userViewModels) }
+
+            assertThat(userViewModels.last()).hasSize(2)
+            assertUserViewModel(
+                viewModel = userViewModels.last()[0],
+                viewKey = 0,
+                name = Text.Loaded("zero"),
+                isSelectionMarkerVisible = false,
+            )
+            assertUserViewModel(
+                viewModel = userViewModels.last()[1],
+                viewKey = 1,
+                name =
+                    Text.Resource(
+                        com.android.settingslib.R.string.guest_exit_quick_settings_button
+                    ),
+                isSelectionMarkerVisible = true,
+            )
+            job.cancel()
+        }
+
+    @Test
+    fun `guest not selected -- name is guest`() =
+        testScope.runTest {
+            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,
+                    ),
+                    UserInfo(
+                        /* id= */ 1,
+                        /* name= */ "one",
+                        /* iconPath= */ "",
+                        /* flags= */ UserInfo.FLAG_FULL,
+                        UserManager.USER_TYPE_FULL_GUEST,
+                    ),
+                )
+
+            userRepository.setUserInfos(userInfos)
+            userRepository.setSelectedUserInfo(userInfos[0])
+            runCurrent()
+
+            val userViewModels = mutableListOf<List<UserViewModel>>()
+            val job = launch(testDispatcher) { underTest.users.toList(userViewModels) }
+
+            assertThat(userViewModels.last()).hasSize(2)
+            assertUserViewModel(
+                viewModel = userViewModels.last()[0],
+                viewKey = 0,
+                name = Text.Loaded("zero"),
+                isSelectionMarkerVisible = true,
+            )
+            assertUserViewModel(
+                viewModel = userViewModels.last()[1],
+                viewKey = 1,
+                name = Text.Loaded("one"),
+                isSelectionMarkerVisible = false,
+            )
+            job.cancel()
+        }
 
     private suspend fun setUsers(count: Int): List<UserInfo> {
         val userInfos =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt b/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt
index 6bfc2f1..7d0d57b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt
@@ -19,9 +19,12 @@
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.Job
+import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -35,6 +38,10 @@
 import kotlinx.coroutines.flow.toList
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.advanceTimeBy
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
 import kotlinx.coroutines.yield
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -231,6 +238,170 @@
     }
 }
 
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class ThrottleFlowTest : SysuiTestCase() {
+
+    @Test
+    fun doesNotAffectEmissions_whenDelayAtLeastEqualToPeriod() = runTest {
+        // Arrange
+        val choreographer = createChoreographer(this)
+        val output = mutableListOf<Int>()
+        val collectJob = backgroundScope.launch {
+            flow {
+                emit(1)
+                delay(1000)
+                emit(2)
+            }.throttle(1000, choreographer.fakeClock).toList(output)
+        }
+
+        // Act
+        choreographer.advanceAndRun(0)
+
+        // Assert
+        assertThat(output).containsExactly(1)
+
+        // Act
+        choreographer.advanceAndRun(999)
+
+        // Assert
+        assertThat(output).containsExactly(1)
+
+        // Act
+        choreographer.advanceAndRun(1)
+
+        // Assert
+        assertThat(output).containsExactly(1, 2)
+
+        // Cleanup
+        collectJob.cancel()
+    }
+
+    @Test
+    fun delaysEmissions_withShorterThanPeriodDelay_untilPeriodElapses() = runTest {
+        // Arrange
+        val choreographer = createChoreographer(this)
+        val output = mutableListOf<Int>()
+        val collectJob = backgroundScope.launch {
+            flow {
+                emit(1)
+                delay(500)
+                emit(2)
+            }.throttle(1000, choreographer.fakeClock).toList(output)
+        }
+
+        // Act
+        choreographer.advanceAndRun(0)
+
+        // Assert
+        assertThat(output).containsExactly(1)
+
+        // Act
+        choreographer.advanceAndRun(500)
+        choreographer.advanceAndRun(499)
+
+        // Assert
+        assertThat(output).containsExactly(1)
+
+        // Act
+        choreographer.advanceAndRun(1)
+
+        // Assert
+        assertThat(output).containsExactly(1, 2)
+
+        // Cleanup
+        collectJob.cancel()
+    }
+
+    @Test
+    fun filtersAllButLastEmission_whenMultipleEmissionsInPeriod() = runTest {
+        // Arrange
+        val choreographer = createChoreographer(this)
+        val output = mutableListOf<Int>()
+        val collectJob = backgroundScope.launch {
+            flow {
+                emit(1)
+                delay(500)
+                emit(2)
+                delay(500)
+                emit(3)
+            }.throttle(1000, choreographer.fakeClock).toList(output)
+        }
+
+        // Act
+        choreographer.advanceAndRun(0)
+
+        // Assert
+        assertThat(output).containsExactly(1)
+
+        // Act
+        choreographer.advanceAndRun(500)
+        choreographer.advanceAndRun(499)
+
+        // Assert
+        assertThat(output).containsExactly(1)
+
+        // Act
+        choreographer.advanceAndRun(1)
+
+        // Assert
+        assertThat(output).containsExactly(1, 3)
+
+        // Cleanup
+        collectJob.cancel()
+    }
+
+    @Test
+    fun filtersAllButLastEmission_andDelaysIt_whenMultipleEmissionsInShorterThanPeriod() = runTest {
+        // Arrange
+        val choreographer = createChoreographer(this)
+        val output = mutableListOf<Int>()
+        val collectJob = backgroundScope.launch {
+            flow {
+                emit(1)
+                delay(500)
+                emit(2)
+                delay(250)
+                emit(3)
+            }.throttle(1000, choreographer.fakeClock).toList(output)
+        }
+
+        // Act
+        choreographer.advanceAndRun(0)
+
+        // Assert
+        assertThat(output).containsExactly(1)
+
+        // Act
+        choreographer.advanceAndRun(500)
+        choreographer.advanceAndRun(250)
+        choreographer.advanceAndRun(249)
+
+        // Assert
+        assertThat(output).containsExactly(1)
+
+        // Act
+        choreographer.advanceAndRun(1)
+
+        // Assert
+        assertThat(output).containsExactly(1, 3)
+
+        // Cleanup
+        collectJob.cancel()
+    }
+
+    private fun createChoreographer(testScope: TestScope) = object {
+        val fakeClock = FakeSystemClock()
+
+        fun advanceAndRun(millis: Long) {
+            fakeClock.advanceTime(millis)
+            testScope.advanceTimeBy(millis)
+            testScope.runCurrent()
+        }
+    }
+}
+
 private fun <T> assertThatFlow(flow: Flow<T>) =
     object {
         suspend fun emitsExactly(vararg emissions: T) =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/leak/LeakReporterTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/leak/LeakReporterTest.java
index d0420f7..729168a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/leak/LeakReporterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/leak/LeakReporterTest.java
@@ -22,13 +22,17 @@
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
+import android.app.ActivityManager;
 import android.app.NotificationManager;
+import android.os.UserHandle;
 
 import androidx.test.filters.MediumTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.settings.UserTracker;
 
 import org.junit.After;
 import org.junit.Before;
@@ -48,6 +52,7 @@
     private File mLeakDir;
     private File mLeakDump;
     private File mLeakHprof;
+    private UserTracker mUserTracker;
     private NotificationManager mNotificationManager;
 
     @Before
@@ -56,6 +61,9 @@
         mLeakDump = new File(mLeakDir, LeakReporter.LEAK_DUMP);
         mLeakHprof = new File(mLeakDir, LeakReporter.LEAK_HPROF);
 
+        mUserTracker = mock(UserTracker.class);
+        when(mUserTracker.getUserHandle()).thenReturn(
+                UserHandle.of(ActivityManager.getCurrentUser()));
         mNotificationManager = mock(NotificationManager.class);
         mContext.addMockSystemService(NotificationManager.class, mNotificationManager);
 
@@ -65,7 +73,7 @@
             return null;
         }).when(mLeakDetector).dump(any(), any());
 
-        mLeakReporter = new LeakReporter(mContext, mLeakDetector, "test@example.com");
+        mLeakReporter = new LeakReporter(mContext, mUserTracker, mLeakDetector, "test@example.com");
     }
 
     @After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java
index 915ea1a..0663004 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java
@@ -48,6 +48,7 @@
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.VibratorHelper;
 import com.android.systemui.util.RingerModeLiveData;
 import com.android.systemui.util.RingerModeTracker;
@@ -101,6 +102,8 @@
     @Mock
     private ActivityManager mActivityManager;
     @Mock
+    private UserTracker mUserTracker;
+    @Mock
     private DumpManager mDumpManager;
 
 
@@ -113,6 +116,7 @@
         // Initial non-set value
         when(mRingerModeLiveData.getValue()).thenReturn(-1);
         when(mRingerModeInternalLiveData.getValue()).thenReturn(-1);
+        when(mUserTracker.getUserId()).thenReturn(ActivityManager.getCurrentUser());
         // Enable group volume adjustments
         mContext.getOrCreateTestableResources().addOverride(
                 com.android.internal.R.bool.config_volumeAdjustmentForRemoteGroupSessions,
@@ -124,7 +128,7 @@
                 mBroadcastDispatcher, mRingerModeTracker, mThreadFactory, mAudioManager,
                 mNotificationManager, mVibrator, mIAudioService, mAccessibilityManager,
                 mPackageManager, mWakefullnessLifcycle, mCaptioningManager, mKeyguardManager,
-                mActivityManager, mDumpManager, mCallback);
+                mActivityManager, mUserTracker, mDumpManager, mCallback);
         mVolumeController.setEnableDialogs(true, true);
     }
 
@@ -233,12 +237,13 @@
                 CaptioningManager captioningManager,
                 KeyguardManager keyguardManager,
                 ActivityManager activityManager,
+                UserTracker userTracker,
                 DumpManager dumpManager,
                 C callback) {
             super(context, broadcastDispatcher, ringerModeTracker, theadFactory, audioManager,
                     notificationManager, optionalVibrator, iAudioService, accessibilityManager,
                     packageManager, wakefulnessLifecycle, captioningManager, keyguardManager,
-                    activityManager, dumpManager);
+                    activityManager, userTracker, dumpManager);
             mCallbacks = callback;
 
             ArgumentCaptor<WakefulnessLifecycle.Observer> observerCaptor =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
index c3c6975..d419095 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.volume;
 
+import static com.android.systemui.volume.Events.DISMISS_REASON_UNKNOWN;
 import static com.android.systemui.volume.VolumeDialogControllerImpl.STREAMS;
 
 import static junit.framework.Assert.assertEquals;
@@ -342,6 +343,15 @@
         assertEquals(mDialog.mVolumeRingerMuteIconDrawableId, R.drawable.ic_volume_ringer_mute);
     }
 
+    @Test
+    public void testDialogDismissAnimation_notifyVisibleIsNotCalledBeforeAnimation() {
+        mDialog.dismissH(DISMISS_REASON_UNKNOWN);
+        // notifyVisible(false) should not be called immediately but only after the dismiss
+        // animation has ended.
+        verify(mVolumeDialogController, times(0)).notifyVisible(false);
+        mDialog.getDialogView().animate().cancel();
+    }
+
 /*
     @Test
     public void testContentDescriptions() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/WalletContextualSuggestionsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/WalletContextualSuggestionsControllerTest.kt
new file mode 100644
index 0000000..b527861
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/WalletContextualSuggestionsControllerTest.kt
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.wallet.controller
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.service.quickaccesswallet.GetWalletCardsResponse
+import android.service.quickaccesswallet.QuickAccessWalletClient
+import android.service.quickaccesswallet.WalletCard
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.capture
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import java.util.ArrayList
+import kotlinx.coroutines.CoroutineScope
+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.junit.runners.JUnit4
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.isNull
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class WalletContextualSuggestionsControllerTest : SysuiTestCase() {
+
+    @Mock private lateinit var walletController: QuickAccessWalletController
+    @Mock private lateinit var broadcastDispatcher: BroadcastDispatcher
+    @Mock private lateinit var featureFlags: FeatureFlags
+    @Mock private lateinit var mockContext: Context
+    @Captor private lateinit var broadcastReceiver: ArgumentCaptor<BroadcastReceiver>
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+
+        whenever(
+                broadcastDispatcher.broadcastFlow<List<String>?>(
+                    any(),
+                    isNull(),
+                    any(),
+                    any(),
+                    any()
+                )
+            )
+            .thenCallRealMethod()
+
+        whenever(featureFlags.isEnabled(eq(Flags.ENABLE_WALLET_CONTEXTUAL_LOYALTY_CARDS)))
+            .thenReturn(true)
+
+        whenever(CARD_1.cardId).thenReturn(ID_1)
+        whenever(CARD_2.cardId).thenReturn(ID_2)
+        whenever(CARD_3.cardId).thenReturn(ID_3)
+    }
+
+    @Test
+    fun `state - has wallet cards - received contextual cards`() = runTest {
+        setUpWalletClient(listOf(CARD_1, CARD_2))
+        val latest =
+            collectLastValue(
+                createWalletContextualSuggestionsController(backgroundScope)
+                    .contextualSuggestionCards,
+            )
+
+        runCurrent()
+        verifyRegistered()
+        broadcastReceiver.value.onReceive(
+            mockContext,
+            createContextualCardsIntent(listOf(ID_1, ID_2))
+        )
+
+        assertThat(latest()).containsExactly(CARD_1, CARD_2)
+    }
+
+    @Test
+    fun `state - no wallet cards - received contextual cards`() = runTest {
+        setUpWalletClient(emptyList())
+        val latest =
+            collectLastValue(
+                createWalletContextualSuggestionsController(backgroundScope)
+                    .contextualSuggestionCards,
+            )
+
+        runCurrent()
+        verifyRegistered()
+        broadcastReceiver.value.onReceive(
+            mockContext,
+            createContextualCardsIntent(listOf(ID_1, ID_2))
+        )
+
+        assertThat(latest()).isEmpty()
+    }
+
+    @Test
+    fun `state - has wallet cards - no contextual cards`() = runTest {
+        setUpWalletClient(listOf(CARD_1, CARD_2))
+        val latest =
+            collectLastValue(
+                createWalletContextualSuggestionsController(backgroundScope)
+                    .contextualSuggestionCards,
+            )
+
+        runCurrent()
+        verifyRegistered()
+        broadcastReceiver.value.onReceive(mockContext, createContextualCardsIntent(emptyList()))
+
+        assertThat(latest()).isEmpty()
+    }
+
+    @Test
+    fun `state - wallet cards error`() = runTest {
+        setUpWalletClient(shouldFail = true)
+        val latest =
+            collectLastValue(
+                createWalletContextualSuggestionsController(backgroundScope)
+                    .contextualSuggestionCards,
+            )
+
+        runCurrent()
+        verifyRegistered()
+        broadcastReceiver.value.onReceive(
+            mockContext,
+            createContextualCardsIntent(listOf(ID_1, ID_2))
+        )
+
+        assertThat(latest()).isEmpty()
+    }
+
+    @Test
+    fun `state - no contextual cards extra`() = runTest {
+        setUpWalletClient(listOf(CARD_1, CARD_2))
+        val latest =
+            collectLastValue(
+                createWalletContextualSuggestionsController(backgroundScope)
+                    .contextualSuggestionCards,
+            )
+
+        runCurrent()
+        verifyRegistered()
+        broadcastReceiver.value.onReceive(mockContext, Intent(INTENT_NAME))
+
+        assertThat(latest()).isEmpty()
+    }
+
+    @Test
+    fun `state - has wallet cards - received contextual cards - feature disabled`() = runTest {
+        whenever(featureFlags.isEnabled(eq(Flags.ENABLE_WALLET_CONTEXTUAL_LOYALTY_CARDS)))
+            .thenReturn(false)
+        setUpWalletClient(listOf(CARD_1, CARD_2))
+        val latest =
+            collectLastValue(
+                createWalletContextualSuggestionsController(backgroundScope)
+                    .contextualSuggestionCards,
+            )
+
+        runCurrent()
+        verify(broadcastDispatcher, never()).broadcastFlow(any(), isNull(), any(), any())
+        assertThat(latest()).isNull()
+    }
+
+    private fun createWalletContextualSuggestionsController(
+        scope: CoroutineScope
+    ): WalletContextualSuggestionsController {
+        return WalletContextualSuggestionsController(
+            scope,
+            walletController,
+            broadcastDispatcher,
+            featureFlags
+        )
+    }
+
+    private fun verifyRegistered() {
+        verify(broadcastDispatcher)
+            .registerReceiver(capture(broadcastReceiver), any(), isNull(), isNull(), any(), any())
+    }
+
+    private fun createContextualCardsIntent(
+        ids: List<String> = emptyList(),
+    ): Intent {
+        val intent = Intent(INTENT_NAME)
+        intent.putStringArrayListExtra("cardIds", ArrayList(ids))
+        return intent
+    }
+
+    private fun setUpWalletClient(
+        cards: List<WalletCard> = emptyList(),
+        shouldFail: Boolean = false
+    ) {
+        whenever(walletController.queryWalletCards(any())).thenAnswer { invocation ->
+            with(
+                invocation.arguments[0] as QuickAccessWalletClient.OnWalletCardsRetrievedCallback
+            ) {
+                if (shouldFail) {
+                    onWalletCardRetrievalError(mock())
+                } else {
+                    onWalletCardsRetrieved(GetWalletCardsResponse(cards, 0))
+                }
+            }
+        }
+    }
+
+    companion object {
+        private const val ID_1: String = "123"
+        private val CARD_1: WalletCard = mock()
+        private const val ID_2: String = "456"
+        private val CARD_2: WalletCard = mock()
+        private const val ID_3: String = "789"
+        private val CARD_3: WalletCard = mock()
+        private val INTENT_NAME: String = "WalletSuggestionsIntent"
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/ImageWallpaperTest.java b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/ImageWallpaperTest.java
index 0fdcb95..31cce4f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/ImageWallpaperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/ImageWallpaperTest.java
@@ -32,13 +32,13 @@
 import static org.mockito.Mockito.when;
 import static org.mockito.hamcrest.MockitoHamcrest.intThat;
 
+import android.app.ActivityManager;
 import android.app.WallpaperManager;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.ColorSpace;
 import android.graphics.Rect;
 import android.hardware.display.DisplayManager;
-import android.os.UserHandle;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.view.Surface;
@@ -49,6 +49,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.time.FakeSystemClock;
 
@@ -81,6 +82,8 @@
     private Surface mSurface;
     @Mock
     private Context mMockContext;
+    @Mock
+    private UserTracker mUserTracker;
 
     @Mock
     private Bitmap mWallpaperBitmap;
@@ -108,13 +111,16 @@
         when(mWallpaperBitmap.getConfig()).thenReturn(Bitmap.Config.ARGB_8888);
 
         // set up wallpaper manager
-        when(mWallpaperManager.getBitmapAsUser(eq(UserHandle.USER_CURRENT), anyBoolean()))
+        when(mWallpaperManager.getBitmapAsUser(eq(ActivityManager.getCurrentUser()), anyBoolean()))
                 .thenReturn(mWallpaperBitmap);
         when(mMockContext.getSystemService(WallpaperManager.class)).thenReturn(mWallpaperManager);
 
         // set up surface
         when(mSurfaceHolder.getSurface()).thenReturn(mSurface);
         doNothing().when(mSurface).hwuiDestroy();
+
+        // set up UserTracker
+        when(mUserTracker.getUserId()).thenReturn(ActivityManager.getCurrentUser());
     }
 
     @Test
@@ -170,7 +176,7 @@
     }
 
     private ImageWallpaper createImageWallpaper() {
-        return new ImageWallpaper(mFakeBackgroundExecutor) {
+        return new ImageWallpaper(mFakeBackgroundExecutor, mUserTracker) {
             @Override
             public Engine onCreateEngine() {
                 return new CanvasEngine() {
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 2e06cc5..68ccc30 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -24,6 +24,7 @@
 import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.wm.shell.bubbles.Bubble.KEY_APP_BUBBLE;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -90,10 +91,12 @@
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shade.NotificationShadeWindowControllerImpl;
 import com.android.systemui.shade.NotificationShadeWindowView;
 import com.android.systemui.shade.ShadeController;
 import com.android.systemui.shade.ShadeExpansionStateManager;
+import com.android.systemui.shade.ShadeWindowLogger;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.RankingBuilder;
@@ -227,6 +230,8 @@
     private BubbleEntry mBubbleEntryUser11;
     private BubbleEntry mBubbleEntry2User11;
 
+    private Intent mAppBubbleIntent;
+
     @Mock
     private ShellInit mShellInit;
     @Mock
@@ -273,6 +278,8 @@
     private Optional<OneHandedController> mOneHandedOptional;
     @Mock
     private UserManager mUserManager;
+    @Mock
+    private ShadeWindowLogger mShadeWindowLogger;
 
     private TestableBubblePositioner mPositioner;
 
@@ -297,7 +304,8 @@
                 mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController,
                 mConfigurationController, mKeyguardViewMediator, mKeyguardBypassController,
                 mColorExtractor, mDumpManager, mKeyguardStateController,
-                mScreenOffAnimationController, mAuthController, mShadeExpansionStateManager);
+                mScreenOffAnimationController, mAuthController, mShadeExpansionStateManager,
+                mShadeWindowLogger);
         mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView);
         mNotificationShadeWindowController.attach();
 
@@ -319,6 +327,9 @@
         mBubbleEntry2User11 = BubblesManager.notifToBubbleEntry(
                 mNotificationTestHelper.createBubble(handle));
 
+        mAppBubbleIntent = new Intent(mContext, BubblesTestActivity.class);
+        mAppBubbleIntent.setPackage(mContext.getPackageName());
+
         mZenModeConfig.suppressedVisualEffects = 0;
         when(mZenModeController.getConfig()).thenReturn(mZenModeConfig);
 
@@ -351,7 +362,8 @@
                         mock(Handler.class),
                         mock(NotifPipelineFlags.class),
                         mock(KeyguardNotificationVisibilityProvider.class),
-                        mock(UiEventLogger.class)
+                        mock(UiEventLogger.class),
+                        mock(UserTracker.class)
                 );
         when(mShellTaskOrganizer.getExecutor()).thenReturn(syncExecutor);
         mBubbleController = new TestableBubbleController(
@@ -1626,6 +1638,62 @@
                 any(Bubble.class), anyBoolean(), anyBoolean());
     }
 
+    @Test
+    public void testShowOrHideAppBubble_addsAndExpand() {
+        assertThat(mBubbleController.isStackExpanded()).isFalse();
+        assertThat(mBubbleData.getBubbleInStackWithKey(KEY_APP_BUBBLE)).isNull();
+
+        mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
+
+        verify(mBubbleController).inflateAndAdd(any(Bubble.class), /* suppressFlyout= */ eq(true),
+                /* showInShade= */ eq(false));
+        assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
+        assertThat(mBubbleController.isStackExpanded()).isTrue();
+    }
+
+    @Test
+    public void testShowOrHideAppBubble_expandIfCollapsed() {
+        mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
+        mBubbleController.updateBubble(mBubbleEntry);
+        mBubbleController.collapseStack();
+        assertThat(mBubbleController.isStackExpanded()).isFalse();
+
+        // Calling this while collapsed will expand the app bubble
+        mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
+
+        assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
+        assertThat(mBubbleController.isStackExpanded()).isTrue();
+        assertThat(mBubbleData.getBubbles().size()).isEqualTo(2);
+    }
+
+    @Test
+    public void testShowOrHideAppBubble_collapseIfSelected() {
+        mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
+        assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
+        assertThat(mBubbleController.isStackExpanded()).isTrue();
+
+        // Calling this while the app bubble is expanded should collapse the stack
+        mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
+
+        assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
+        assertThat(mBubbleController.isStackExpanded()).isFalse();
+        assertThat(mBubbleData.getBubbles().size()).isEqualTo(1);
+    }
+
+    @Test
+    public void testShowOrHideAppBubble_selectIfNotSelected() {
+        mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
+        mBubbleController.updateBubble(mBubbleEntry);
+        mBubbleController.expandStackAndSelectBubble(mBubbleEntry);
+        assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(mBubbleEntry.getKey());
+        assertThat(mBubbleController.isStackExpanded()).isTrue();
+
+        mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
+        assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
+        assertThat(mBubbleController.isStackExpanded()).isTrue();
+        assertThat(mBubbleData.getBubbles().size()).isEqualTo(2);
+    }
+
     /** Creates a bubble using the userId and package. */
     private Bubble createBubble(int userId, String pkg) {
         final UserHandle userHandle = new UserHandle(userId);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableNotificationInterruptStateProviderImpl.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableNotificationInterruptStateProviderImpl.java
index e5316bc8..ceee0bc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableNotificationInterruptStateProviderImpl.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableNotificationInterruptStateProviderImpl.java
@@ -24,6 +24,7 @@
 
 import com.android.internal.logging.UiEventLogger;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.notification.NotifPipelineFlags;
 import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptLogger;
@@ -48,7 +49,8 @@
             Handler mainHandler,
             NotifPipelineFlags flags,
             KeyguardNotificationVisibilityProvider keyguardNotificationVisibilityProvider,
-            UiEventLogger uiEventLogger) {
+            UiEventLogger uiEventLogger,
+            UserTracker userTracker) {
         super(contentResolver,
                 powerManager,
                 dreamManager,
@@ -61,7 +63,8 @@
                 mainHandler,
                 flags,
                 keyguardNotificationVisibilityProvider,
-                uiEventLogger);
+                uiEventLogger,
+                userTracker);
         mUseHeadsUp = true;
     }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/MemoryTrackingTestCase.java b/packages/SystemUI/tests/utils/src/com/android/systemui/MemoryTrackingTestCase.java
index 3767fbe..3428553 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/MemoryTrackingTestCase.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/MemoryTrackingTestCase.java
@@ -40,24 +40,49 @@
 public class MemoryTrackingTestCase extends SysuiTestCase {
     private static File sFilesDir = null;
     private static String sLatestTestClassName = null;
+    private static int sHeapCount = 0;
+    private static File sLatestBaselineHeapFile = null;
 
-    @Before public void grabFilesDir() {
+    // Ideally, we would do this in @BeforeClass just once, but we need mContext to get the files
+    // dir, and that does not exist until @Before on each test method.
+    @Before
+    public void grabFilesDir() throws IOException {
+        // This should happen only once per suite
         if (sFilesDir == null) {
             sFilesDir = mContext.getFilesDir();
         }
-        sLatestTestClassName = getClass().getName();
+
+        // This will happen before the first test method in each class
+        if (sLatestTestClassName == null) {
+            sLatestTestClassName = getClass().getName();
+            sLatestBaselineHeapFile = dump("baseline" + (++sHeapCount), "before-test");
+        }
     }
 
     @AfterClass
     public static void dumpHeap() throws IOException {
+        File afterTestHeap = dump(sLatestTestClassName, "after-test");
+        if (sLatestBaselineHeapFile != null && afterTestHeap != null) {
+            Log.w("MEMORY", "To compare heap to baseline (use go/ahat):");
+            Log.w("MEMORY", "  adb pull " + sLatestBaselineHeapFile);
+            Log.w("MEMORY", "  adb pull " + afterTestHeap);
+            Log.w("MEMORY",
+                    "  java -jar ahat.jar --baseline " + sLatestBaselineHeapFile.getName() + " "
+                            + afterTestHeap.getName());
+        }
+        sLatestTestClassName = null;
+    }
+
+    private static File dump(String basename, String heapKind) throws IOException {
         if (sFilesDir == null) {
             Log.e("MEMORY", "Somehow no test cases??");
-            return;
+            return null;
         }
         mockitoTearDown();
-        Log.w("MEMORY", "about to dump heap");
-        File path = new File(sFilesDir, sLatestTestClassName + ".ahprof");
+        Log.w("MEMORY", "about to dump " + heapKind + " heap");
+        File path = new File(sFilesDir, basename + ".ahprof");
         Debug.dumpHprofData(path.getPath());
-        Log.w("MEMORY", "did it!  Location: " + path);
+        Log.w("MEMORY", "Success!  Location: " + path);
+        return path;
     }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java
index bf2235a..1bab997 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java
@@ -132,8 +132,10 @@
 
     @After
     public void SysuiTeardown() {
-        InstrumentationRegistry.registerInstance(mRealInstrumentation,
-                InstrumentationRegistry.getArguments());
+        if (mRealInstrumentation != null) {
+            InstrumentationRegistry.registerInstance(mRealInstrumentation,
+                    InstrumentationRegistry.getArguments());
+        }
         if (TestableLooper.get(this) != null) {
             TestableLooper.get(this).processAllMessages();
             // Must remove static reference to this test object to prevent leak (b/261039202)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/udfps/FakeOverlapDetector.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/udfps/FakeOverlapDetector.kt
index 8176dd0..1bdee36 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/udfps/FakeOverlapDetector.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/udfps/FakeOverlapDetector.kt
@@ -19,9 +19,10 @@
 import android.graphics.Rect
 
 class FakeOverlapDetector : OverlapDetector {
-    var shouldReturn: Boolean = false
+    var shouldReturn: Map<Int, Boolean> = mapOf()
 
     override fun isGoodOverlap(touchData: NormalizedTouchData, nativeSensorBounds: Rect): Boolean {
-        return shouldReturn
+        return shouldReturn[touchData.pointerId]
+            ?: error("Unexpected PointerId not declared in TestCase currentPointers")
     }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceProviderClientFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceProviderClientFactory.kt
index d85dd2e..16a1298 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceProviderClientFactory.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceProviderClientFactory.kt
@@ -18,17 +18,17 @@
 package com.android.systemui.keyguard.data.quickaffordance
 
 import com.android.systemui.settings.UserTracker
-import com.android.systemui.shared.quickaffordance.data.content.FakeKeyguardQuickAffordanceProviderClient
-import com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderClient
+import com.android.systemui.shared.customization.data.content.CustomizationProviderClient
+import com.android.systemui.shared.customization.data.content.FakeCustomizationProviderClient
 
 class FakeKeyguardQuickAffordanceProviderClientFactory(
     private val userTracker: UserTracker,
-    private val callback: (Int) -> KeyguardQuickAffordanceProviderClient = {
-        FakeKeyguardQuickAffordanceProviderClient()
+    private val callback: (Int) -> CustomizationProviderClient = {
+        FakeCustomizationProviderClient()
     },
 ) : KeyguardQuickAffordanceProviderClientFactory {
 
-    override fun create(): KeyguardQuickAffordanceProviderClient {
+    override fun create(): CustomizationProviderClient {
         return callback(userTracker.userId)
     }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeBiometricRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeBiometricRepository.kt
new file mode 100644
index 0000000..f3e52de
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeBiometricRepository.kt
@@ -0,0 +1,47 @@
+/*
+ * 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.data.repository
+
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+
+class FakeBiometricRepository : BiometricRepository {
+
+    private val _isFingerprintEnrolled = MutableStateFlow<Boolean>(false)
+    override val isFingerprintEnrolled: StateFlow<Boolean> = _isFingerprintEnrolled.asStateFlow()
+
+    private val _isStrongBiometricAllowed = MutableStateFlow(false)
+    override val isStrongBiometricAllowed = _isStrongBiometricAllowed.asStateFlow()
+
+    private val _isFingerprintEnabledByDevicePolicy = MutableStateFlow(false)
+    override val isFingerprintEnabledByDevicePolicy =
+        _isFingerprintEnabledByDevicePolicy.asStateFlow()
+
+    fun setFingerprintEnrolled(isFingerprintEnrolled: Boolean) {
+        _isFingerprintEnrolled.value = isFingerprintEnrolled
+    }
+
+    fun setStrongBiometricAllowed(isStrongBiometricAllowed: Boolean) {
+        _isStrongBiometricAllowed.value = isStrongBiometricAllowed
+    }
+
+    fun setFingerprintEnabledByDevicePolicy(isFingerprintEnabledByDevicePolicy: Boolean) {
+        _isFingerprintEnabledByDevicePolicy.value = isFingerprintEnabledByDevicePolicy
+    }
+}
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 39d2eca..15b4736 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
@@ -52,6 +52,9 @@
     private val _isDozing = MutableStateFlow(false)
     override val isDozing: Flow<Boolean> = _isDozing
 
+    private val _isAodAvailable = MutableStateFlow(false)
+    override val isAodAvailable: Flow<Boolean> = _isAodAvailable
+
     private val _isDreaming = MutableStateFlow(false)
     override val isDreaming: Flow<Boolean> = _isDreaming
 
@@ -126,6 +129,10 @@
         _isDozing.value = isDozing
     }
 
+    fun setAodAvailable(isAodAvailable: Boolean) {
+        _isAodAvailable.value = isAodAvailable
+    }
+
     fun setDreamingWithOverlay(isDreaming: Boolean) {
         _isDreamingWithOverlay.value = isDreaming
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/RankingBuilder.java b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/RankingBuilder.java
index 045e6f1..7bcad45 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/RankingBuilder.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/RankingBuilder.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar;
 
+import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+
 import android.annotation.NonNull;
 import android.app.Notification;
 import android.app.NotificationChannel;
@@ -57,6 +59,7 @@
     private ShortcutInfo mShortcutInfo = null;
     private int mRankingAdjustment = 0;
     private boolean mIsBubble = false;
+    private int mProposedImportance = IMPORTANCE_UNSPECIFIED;
 
     public RankingBuilder() {
     }
@@ -86,6 +89,7 @@
         mShortcutInfo = ranking.getConversationShortcutInfo();
         mRankingAdjustment = ranking.getRankingAdjustment();
         mIsBubble = ranking.isBubble();
+        mProposedImportance = ranking.getProposedImportance();
     }
 
     public Ranking build() {
@@ -114,7 +118,8 @@
                 mIsConversation,
                 mShortcutInfo,
                 mRankingAdjustment,
-                mIsBubble);
+                mIsBubble,
+                mProposedImportance);
         return ranking;
     }
 
@@ -214,6 +219,11 @@
         return this;
     }
 
+    public RankingBuilder setProposedImportance(@Importance int importance) {
+        mProposedImportance = importance;
+        return this;
+    }
+
     public RankingBuilder setUserSentiment(int userSentiment) {
         mUserSentiment = userSentiment;
         return this;
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java
index e660e1f2..4b97316 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java
@@ -23,6 +23,8 @@
 import android.os.UserHandle;
 import android.util.Pair;
 
+import com.android.systemui.settings.UserTracker;
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -57,6 +59,11 @@
     }
 
     @Override
+    public UserTracker getUserTracker() {
+        return null;
+    }
+
+    @Override
     public void registerContentObserverForUser(Uri uri, boolean notifyDescendents,
             ContentObserver settingsObserver, int userHandle) {
         List<ContentObserver> observers;
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeNetworkController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeNetworkController.java
index 33ef9cf..1baac84 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeNetworkController.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeNetworkController.java
@@ -46,11 +46,6 @@
     }
 
     @Override
-    public boolean hasEmergencyCryptKeeperText() {
-        return false;
-    }
-
-    @Override
     public boolean isRadioOn() {
         return false;
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java
index 2d6d29a..926c6c5 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java
@@ -98,6 +98,10 @@
     }
 
     @Override
+    public void removeAllIconsForExternalSlot(String slot) {
+    }
+
+    @Override
     public void setIconAccessibilityLiveRegion(String slot, int mode) {
     }
 
diff --git a/packages/SystemUI/tools/lint/baseline.xml b/packages/SystemUI/tools/lint/baseline.xml
index 9a2e320..301c9b8 100644
--- a/packages/SystemUI/tools/lint/baseline.xml
+++ b/packages/SystemUI/tools/lint/baseline.xml
@@ -337,17 +337,6 @@
     <issue
         id="Deprecated"
         message="`android:singleLine` is deprecated: Use `maxLines=&quot;1&quot;` instead"
-        errorLine1="        android:singleLine=&quot;true&quot;"
-        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/layout/emergency_cryptkeeper_text.xml"
-            line="25"
-            column="9"/>
-    </issue>
-
-    <issue
-        id="Deprecated"
-        message="`android:singleLine` is deprecated: Use `maxLines=&quot;1&quot;` instead"
         errorLine1="                android:singleLine=&quot;true&quot;"
         errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -88997,17 +88986,6 @@
         errorLine1="        android:paddingStart=&quot;6dp&quot;"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="res/layout/emergency_cryptkeeper_text.xml"
-            line="24"
-            column="9"/>
-    </issue>
-
-    <issue
-        id="RtlSymmetry"
-        message="When you define `paddingStart` you should probably also define `paddingEnd` for right-to-left symmetry"
-        errorLine1="        android:paddingStart=&quot;6dp&quot;"
-        errorLine2="        ~~~~~~~~~~~~~~~~~~~~">
-        <location
             file="res/layout/heads_up_status_bar_layout.xml"
             line="43"
             column="9"/>
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedComponent.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
index 5a868a4..cfb959e 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
@@ -22,8 +22,8 @@
 import android.os.Handler
 import android.view.IWindowManager
 import com.android.systemui.unfold.config.UnfoldTransitionConfig
-import com.android.systemui.unfold.dagger.UnfoldBackground
 import com.android.systemui.unfold.dagger.UnfoldMain
+import com.android.systemui.unfold.dagger.UnfoldSingleThreadBg
 import com.android.systemui.unfold.updates.FoldProvider
 import com.android.systemui.unfold.updates.RotationChangeProvider
 import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
@@ -58,7 +58,7 @@
             @BindsInstance sensorManager: SensorManager,
             @BindsInstance @UnfoldMain handler: Handler,
             @BindsInstance @UnfoldMain executor: Executor,
-            @BindsInstance @UnfoldBackground backgroundExecutor: Executor,
+            @BindsInstance @UnfoldSingleThreadBg singleThreadBgExecutor: Executor,
             @BindsInstance @UnfoldTransitionATracePrefix tracingTagPrefix: String,
             @BindsInstance windowManager: IWindowManager,
             @BindsInstance contentResolver: ContentResolver = context.contentResolver
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
index 8f4ee4d..31616fa 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
@@ -16,9 +16,7 @@
 
 package com.android.systemui.unfold
 
-import android.hardware.SensorManager
 import com.android.systemui.unfold.config.UnfoldTransitionConfig
-import com.android.systemui.unfold.dagger.UnfoldBackground
 import com.android.systemui.unfold.progress.FixedTimingTransitionProgressProvider
 import com.android.systemui.unfold.progress.PhysicsBasedUnfoldTransitionProgressProvider
 import com.android.systemui.unfold.updates.DeviceFoldStateProvider
@@ -28,53 +26,80 @@
 import com.android.systemui.unfold.updates.hinge.HingeSensorAngleProvider
 import com.android.systemui.unfold.util.ATraceLoggerTransitionProgressListener
 import com.android.systemui.unfold.util.ScaleAwareTransitionProgressProvider
+import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityManager
+import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityManagerImpl
+import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityProvider
 import dagger.Module
 import dagger.Provides
 import java.util.Optional
-import java.util.concurrent.Executor
+import javax.inject.Provider
 import javax.inject.Singleton
 
-@Module
+@Module(includes = [UnfoldSharedInternalModule::class])
 class UnfoldSharedModule {
     @Provides
     @Singleton
-    fun unfoldTransitionProgressProvider(
-        config: UnfoldTransitionConfig,
-        scaleAwareProviderFactory: ScaleAwareTransitionProgressProvider.Factory,
-        tracingListener: ATraceLoggerTransitionProgressListener,
-        foldStateProvider: FoldStateProvider
-    ): Optional<UnfoldTransitionProgressProvider> =
-        if (!config.isEnabled) {
-            Optional.empty()
-        } else {
-            val baseProgressProvider =
-                if (config.isHingeAngleEnabled) {
-                    PhysicsBasedUnfoldTransitionProgressProvider(foldStateProvider)
-                } else {
-                    FixedTimingTransitionProgressProvider(foldStateProvider)
-                }
-            Optional.of(
-                scaleAwareProviderFactory.wrap(baseProgressProvider).apply {
-                    // Always present callback that logs animation beginning and end.
-                    addCallback(tracingListener)
-                })
-        }
-
-    @Provides
-    @Singleton
     fun provideFoldStateProvider(
         deviceFoldStateProvider: DeviceFoldStateProvider
     ): FoldStateProvider = deviceFoldStateProvider
 
     @Provides
+    @Singleton
+    fun unfoldKeyguardVisibilityProvider(
+        impl: UnfoldKeyguardVisibilityManagerImpl
+    ): UnfoldKeyguardVisibilityProvider = impl
+
+    @Provides
+    @Singleton
+    fun unfoldKeyguardVisibilityManager(
+        impl: UnfoldKeyguardVisibilityManagerImpl
+    ): UnfoldKeyguardVisibilityManager = impl
+}
+
+/**
+ * Needed as methods inside must be public, but their parameters can be internal (and, a public
+ * method can't have internal parameters). Making the module internal and included in a public one
+ * fixes the issue.
+ */
+@Module
+internal class UnfoldSharedInternalModule {
+    @Provides
+    @Singleton
+    fun unfoldTransitionProgressProvider(
+        config: UnfoldTransitionConfig,
+        scaleAwareProviderFactory: ScaleAwareTransitionProgressProvider.Factory,
+        tracingListener: ATraceLoggerTransitionProgressListener,
+        physicsBasedUnfoldTransitionProgressProvider:
+            Provider<PhysicsBasedUnfoldTransitionProgressProvider>,
+        fixedTimingTransitionProgressProvider: Provider<FixedTimingTransitionProgressProvider>,
+    ): Optional<UnfoldTransitionProgressProvider> {
+        if (!config.isEnabled) {
+            return Optional.empty()
+        }
+        val baseProgressProvider =
+            if (config.isHingeAngleEnabled) {
+                physicsBasedUnfoldTransitionProgressProvider.get()
+            } else {
+                fixedTimingTransitionProgressProvider.get()
+            }
+
+        return Optional.of(
+            scaleAwareProviderFactory.wrap(baseProgressProvider).apply {
+                // Always present callback that logs animation beginning and end.
+                addCallback(tracingListener)
+            }
+        )
+    }
+
+    @Provides
     fun hingeAngleProvider(
         config: UnfoldTransitionConfig,
-        sensorManager: SensorManager,
-        @UnfoldBackground executor: Executor
-    ): HingeAngleProvider =
-        if (config.isHingeAngleEnabled) {
-            HingeSensorAngleProvider(sensorManager, executor)
+        hingeAngleSensorProvider: Provider<HingeSensorAngleProvider>
+    ): HingeAngleProvider {
+        return if (config.isHingeAngleEnabled) {
+            hingeAngleSensorProvider.get()
         } else {
             EmptyHingeAngleProvider
         }
+    }
 }
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
index a1ed178..aa93c629 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
@@ -37,29 +37,29 @@
  * This should **never** be called from sysui, as the object is already provided in that process.
  */
 fun createUnfoldSharedComponent(
-    context: Context,
-    config: UnfoldTransitionConfig,
-    screenStatusProvider: ScreenStatusProvider,
-    foldProvider: FoldProvider,
-    activityTypeProvider: CurrentActivityTypeProvider,
-    sensorManager: SensorManager,
-    mainHandler: Handler,
-    mainExecutor: Executor,
-    backgroundExecutor: Executor,
-    tracingTagPrefix: String,
-    windowManager: IWindowManager,
+        context: Context,
+        config: UnfoldTransitionConfig,
+        screenStatusProvider: ScreenStatusProvider,
+        foldProvider: FoldProvider,
+        activityTypeProvider: CurrentActivityTypeProvider,
+        sensorManager: SensorManager,
+        mainHandler: Handler,
+        mainExecutor: Executor,
+        singleThreadBgExecutor: Executor,
+        tracingTagPrefix: String,
+        windowManager: IWindowManager,
 ): UnfoldSharedComponent =
-    DaggerUnfoldSharedComponent.factory()
-        .create(
-            context,
-            config,
-            screenStatusProvider,
-            foldProvider,
-            activityTypeProvider,
-            sensorManager,
-            mainHandler,
-            mainExecutor,
-            backgroundExecutor,
-            tracingTagPrefix,
-            windowManager,
-        )
+        DaggerUnfoldSharedComponent.factory()
+                .create(
+                        context,
+                        config,
+                        screenStatusProvider,
+                        foldProvider,
+                        activityTypeProvider,
+                        sensorManager,
+                        mainHandler,
+                        mainExecutor,
+                        singleThreadBgExecutor,
+                        tracingTagPrefix,
+                        windowManager,
+                )
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldBackground.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldSingleThreadBg.kt
similarity index 89%
rename from packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldBackground.kt
rename to packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldSingleThreadBg.kt
index 6074795..dcac531 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldBackground.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldSingleThreadBg.kt
@@ -18,8 +18,7 @@
 
 /**
  * Alternative to [UiBackground] qualifier annotation in unfold module.
+ *
  * It is needed as we can't depend on SystemUI code in this module.
  */
-@Qualifier
-@Retention(AnnotationRetention.RUNTIME)
-annotation class UnfoldBackground
+@Qualifier @Retention(AnnotationRetention.RUNTIME) annotation class UnfoldSingleThreadBg
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/FixedTimingTransitionProgressProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/FixedTimingTransitionProgressProvider.kt
index fa59cb4..4622464 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/FixedTimingTransitionProgressProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/FixedTimingTransitionProgressProvider.kt
@@ -24,11 +24,13 @@
 import com.android.systemui.unfold.updates.FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE
 import com.android.systemui.unfold.updates.FoldStateProvider
 import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdate
+import javax.inject.Inject
 
 /** Emits animation progress with fixed timing after unfolding */
-internal class FixedTimingTransitionProgressProvider(
-    private val foldStateProvider: FoldStateProvider
-) : UnfoldTransitionProgressProvider, FoldStateProvider.FoldUpdatesListener {
+internal class FixedTimingTransitionProgressProvider
+@Inject
+constructor(private val foldStateProvider: FoldStateProvider) :
+    UnfoldTransitionProgressProvider, FoldStateProvider.FoldUpdatesListener {
 
     private val animatorListener = AnimatorListener()
     private val animator =
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
index 074b1e1..6ffbe5a 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
@@ -33,9 +33,10 @@
 import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdate
 import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdatesListener
 import com.android.systemui.unfold.updates.name
+import javax.inject.Inject
 
 /** Maps fold updates to unfold transition progress using DynamicAnimation. */
-class PhysicsBasedUnfoldTransitionProgressProvider(
+class PhysicsBasedUnfoldTransitionProgressProvider @Inject constructor(
     private val foldStateProvider: FoldStateProvider
 ) : UnfoldTransitionProgressProvider, FoldUpdatesListener, DynamicAnimation.OnAnimationEndListener {
 
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
index 808128d..97c9ba9 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
@@ -31,6 +31,7 @@
 import com.android.systemui.unfold.updates.hinge.HingeAngleProvider
 import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
 import com.android.systemui.unfold.util.CurrentActivityTypeProvider
+import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityProvider
 import java.util.concurrent.Executor
 import javax.inject.Inject
 
@@ -42,6 +43,7 @@
     private val screenStatusProvider: ScreenStatusProvider,
     private val foldProvider: FoldProvider,
     private val activityTypeProvider: CurrentActivityTypeProvider,
+    private val unfoldKeyguardVisibilityProvider: UnfoldKeyguardVisibilityProvider,
     private val rotationChangeProvider: RotationChangeProvider,
     @UnfoldMain private val mainExecutor: Executor,
     @UnfoldMain private val handler: Handler
@@ -77,6 +79,7 @@
         screenStatusProvider.addCallback(screenListener)
         hingeAngleProvider.addCallback(hingeAngleListener)
         rotationChangeProvider.addCallback(rotationListener)
+        activityTypeProvider.init()
     }
 
     override fun stop() {
@@ -85,6 +88,7 @@
         hingeAngleProvider.removeCallback(hingeAngleListener)
         hingeAngleProvider.stop()
         rotationChangeProvider.removeCallback(rotationListener)
+        activityTypeProvider.uninit()
     }
 
     override fun addCallback(listener: FoldUpdatesListener) {
@@ -113,19 +117,17 @@
         }
 
         val isClosing = angle < lastHingeAngle
-        val closingThreshold = getClosingThreshold()
-        val closingThresholdMet = closingThreshold == null || angle < closingThreshold
         val isFullyOpened = FULLY_OPEN_DEGREES - angle < FULLY_OPEN_THRESHOLD_DEGREES
         val closingEventDispatched = lastFoldUpdate == FOLD_UPDATE_START_CLOSING
         val screenAvailableEventSent = isUnfoldHandled
 
         if (isClosing // hinge angle should be decreasing since last update
-                && closingThresholdMet // hinge angle is below certain threshold
                 && !closingEventDispatched  // we haven't sent closing event already
                 && !isFullyOpened // do not send closing event if we are in fully opened hinge
                                   // angle range as closing threshold could overlap this range
                 && screenAvailableEventSent // do not send closing event if we are still in
                                             // the process of turning on the inner display
+                && isClosingThresholdMet(angle) // hinge angle is below certain threshold.
         ) {
             notifyFoldUpdate(FOLD_UPDATE_START_CLOSING)
         }
@@ -144,6 +146,11 @@
         outputListeners.forEach { it.onHingeAngleUpdate(angle) }
     }
 
+    private fun isClosingThresholdMet(currentAngle: Float) : Boolean {
+        val closingThreshold = getClosingThreshold()
+        return closingThreshold == null || currentAngle < closingThreshold
+    }
+
     /**
      * Fold animation should be started only after the threshold returned here.
      *
@@ -152,12 +159,13 @@
      */
     private fun getClosingThreshold(): Int? {
         val isHomeActivity = activityTypeProvider.isHomeActivity ?: return null
+        val isKeyguardVisible = unfoldKeyguardVisibilityProvider.isKeyguardVisible == true
 
         if (DEBUG) {
-            Log.d(TAG, "isHomeActivity=$isHomeActivity")
+            Log.d(TAG, "isHomeActivity=$isHomeActivity, isOnKeyguard=$isKeyguardVisible")
         }
 
-        return if (isHomeActivity) {
+        return if (isHomeActivity || isKeyguardVisible) {
             null
         } else {
             START_CLOSING_ON_APPS_THRESHOLD_DEGREES
@@ -257,7 +265,7 @@
     }
 
 private const val TAG = "DeviceFoldProvider"
-private const val DEBUG = false
+private val DEBUG = Log.isLoggable(TAG, Log.DEBUG)
 
 /** Threshold after which we consider the device fully unfolded. */
 @VisibleForTesting const val FULLY_OPEN_THRESHOLD_DEGREES = 15f
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt
index 577137c..89fb12e 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt
@@ -20,35 +20,43 @@
 import android.hardware.SensorManager
 import android.os.Trace
 import androidx.core.util.Consumer
+import com.android.systemui.unfold.dagger.UnfoldSingleThreadBg
 import java.util.concurrent.Executor
+import javax.inject.Inject
 
-internal class HingeSensorAngleProvider(
+internal class HingeSensorAngleProvider
+@Inject
+constructor(
     private val sensorManager: SensorManager,
-    private val executor: Executor
-) :
-    HingeAngleProvider {
+    @UnfoldSingleThreadBg private val singleThreadBgExecutor: Executor
+) : HingeAngleProvider {
 
     private val sensorListener = HingeAngleSensorListener()
     private val listeners: MutableList<Consumer<Float>> = arrayListOf()
     var started = false
 
-    override fun start() = executor.execute {
-        if (started) return@execute
-        Trace.beginSection("HingeSensorAngleProvider#start")
-        val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_HINGE_ANGLE)
-        sensorManager.registerListener(
-            sensorListener,
-            sensor,
-            SensorManager.SENSOR_DELAY_FASTEST
-        )
-        Trace.endSection()
-        started = true
+    override fun start() {
+        singleThreadBgExecutor.execute {
+            if (started) return@execute
+            Trace.beginSection("HingeSensorAngleProvider#start")
+            val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_HINGE_ANGLE)
+            sensorManager.registerListener(
+                sensorListener,
+                sensor,
+                SensorManager.SENSOR_DELAY_FASTEST
+            )
+            Trace.endSection()
+
+            started = true
+        }
     }
 
-    override fun stop() = executor.execute {
-        if (!started) return@execute
-        sensorManager.unregisterListener(sensorListener)
-        started = false
+    override fun stop() {
+        singleThreadBgExecutor.execute {
+            if (!started) return@execute
+            sensorManager.unregisterListener(sensorListener)
+            started = false
+        }
     }
 
     override fun removeCallback(listener: Consumer<Float>) {
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/CurrentActivityTypeProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/CurrentActivityTypeProvider.kt
index d0e6cdc..34e7c38 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/CurrentActivityTypeProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/CurrentActivityTypeProvider.kt
@@ -16,6 +16,11 @@
 
 interface CurrentActivityTypeProvider {
     val isHomeActivity: Boolean?
+
+    /** Starts listening for task updates. */
+    fun init() {}
+    /** Stop listening for task updates. */
+    fun uninit() {}
 }
 
 class EmptyCurrentActivityTypeProvider(override val isHomeActivity: Boolean? = null) :
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/UnfoldKeyguardVisibilityProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/UnfoldKeyguardVisibilityProvider.kt
new file mode 100644
index 0000000..9f0efa0
--- /dev/null
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/UnfoldKeyguardVisibilityProvider.kt
@@ -0,0 +1,54 @@
+/*
+ * 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.unfold.util
+
+import java.lang.ref.WeakReference
+import javax.inject.Inject
+import javax.inject.Singleton
+
+interface UnfoldKeyguardVisibilityProvider {
+    /**
+     * True when the keyguard is visible.
+     *
+     * Might be [null] when it is not known.
+     */
+    val isKeyguardVisible: Boolean?
+}
+
+/** Used to notify keyguard visibility. */
+interface UnfoldKeyguardVisibilityManager {
+    /** Sets the delegate. [delegate] should return true when the keyguard is visible. */
+    fun setKeyguardVisibleDelegate(delegate: () -> Boolean)
+}
+
+/**
+ * Keeps a [WeakReference] for the keyguard visibility provider.
+ *
+ * It is a weak reference because this is in the global scope, while the delegate might be set from
+ * another subcomponent (that might have shorter lifespan).
+ */
+@Singleton
+class UnfoldKeyguardVisibilityManagerImpl @Inject constructor() :
+    UnfoldKeyguardVisibilityProvider, UnfoldKeyguardVisibilityManager {
+
+    private var delegatedProvider: WeakReference<() -> Boolean?>? = null
+
+    override fun setKeyguardVisibleDelegate(delegate: () -> Boolean) {
+        delegatedProvider = WeakReference(delegate)
+    }
+
+    override val isKeyguardVisible: Boolean?
+        get() = delegatedProvider?.get()?.invoke()
+}
diff --git a/packages/VpnDialogs/res/values-b+sr+Latn/strings.xml b/packages/VpnDialogs/res/values-b+sr+Latn/strings.xml
index 01bd4df..a1075d2 100644
--- a/packages/VpnDialogs/res/values-b+sr+Latn/strings.xml
+++ b/packages/VpnDialogs/res/values-b+sr+Latn/strings.xml
@@ -16,22 +16,22 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="prompt" msgid="3183836924226407828">"Захтев за повезивање"</string>
-    <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> жели да подеси VPN везу која омогућава праћење саобраћаја на мрежи. Прихватите само ако верујете извору. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; се приказује у врху екрана када је VPN активан."</string>
-    <string name="warning" product="tv" msgid="5188957997628124947">"Апликација <xliff:g id="APP">%s</xliff:g> жели да подеси VPN везу која јој омогућава да прати мрежни саобраћај. Прихватите ово само ако имате поверења у извор. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; се приказује на екрану када је VPN активан."</string>
-    <string name="legacy_title" msgid="192936250066580964">"VPN је повезан"</string>
-    <string name="session" msgid="6470628549473641030">"Сесија:"</string>
-    <string name="duration" msgid="3584782459928719435">"Трајање:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Послато:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Примљенo:"</string>
-    <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> бајт(ов)а / <xliff:g id="NUMBER_1">%2$s</xliff:g> пакета"</string>
-    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Повезивање са увек укљученим VPN-ом није успело"</string>
-    <string name="always_on_disconnected_message" msgid="555634519845992917">"Мрежа <xliff:g id="VPN_APP_0">%1$s</xliff:g> је подешена да буде увек повезана, али тренутно не може да успостави везу. Телефон ће користити јавну мрежу док се поново не повеже са <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
-    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"Мрежа <xliff:g id="VPN_APP">%1$s</xliff:g> је подешена да буде увек повезана, али тренутно не може да успостави везу. Нећете имати везу док се VPN поново не повеже."</string>
+    <string name="prompt" msgid="3183836924226407828">"Zahtev za povezivanje"</string>
+    <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> želi da podesi VPN vezu koja omogućava praćenje saobraćaja na mreži. Prihvatite samo ako verujete izvoru. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; se prikazuje u vrhu ekrana kada je VPN aktivan."</string>
+    <string name="warning" product="tv" msgid="5188957997628124947">"Aplikacija <xliff:g id="APP">%s</xliff:g> želi da podesi VPN vezu koja joj omogućava da prati mrežni saobraćaj. Prihvatite ovo samo ako imate poverenja u izvor. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; se prikazuje na ekranu kada je VPN aktivan."</string>
+    <string name="legacy_title" msgid="192936250066580964">"VPN je povezan"</string>
+    <string name="session" msgid="6470628549473641030">"Sesija:"</string>
+    <string name="duration" msgid="3584782459928719435">"Trajanje:"</string>
+    <string name="data_transmitted" msgid="7988167672982199061">"Poslato:"</string>
+    <string name="data_received" msgid="4062776929376067820">"Primljeno:"</string>
+    <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bajt(ov)a / <xliff:g id="NUMBER_1">%2$s</xliff:g> paketa"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Povezivanje sa uvek uključenim VPN-om nije uspelo"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"Mreža <xliff:g id="VPN_APP_0">%1$s</xliff:g> je podešena da bude uvek povezana, ali trenutno ne može da uspostavi vezu. Telefon će koristiti javnu mrežu dok se ponovo ne poveže sa <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"Mreža <xliff:g id="VPN_APP">%1$s</xliff:g> je podešena da bude uvek povezana, ali trenutno ne može da uspostavi vezu. Nećete imati vezu dok se VPN ponovo ne poveže."</string>
     <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
-    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Промени подешавања VPN-а"</string>
-    <string name="configure" msgid="4905518375574791375">"Конфигуриши"</string>
-    <string name="disconnect" msgid="971412338304200056">"Прекини везу"</string>
-    <string name="open_app" msgid="3717639178595958667">"Отвори апликацију"</string>
-    <string name="dismiss" msgid="6192859333764711227">"Одбаци"</string>
+    <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Promeni podešavanja VPN-a"</string>
+    <string name="configure" msgid="4905518375574791375">"Konfiguriši"</string>
+    <string name="disconnect" msgid="971412338304200056">"Prekini vezu"</string>
+    <string name="open_app" msgid="3717639178595958667">"Otvori aplikaciju"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Odbaci"</string>
 </resources>
diff --git a/packages/overlays/AvoidAppsInCutoutOverlay/res/values-b+sr+Latn/strings.xml b/packages/overlays/AvoidAppsInCutoutOverlay/res/values-b+sr+Latn/strings.xml
index c2b611e..f80fa8d 100644
--- a/packages/overlays/AvoidAppsInCutoutOverlay/res/values-b+sr+Latn/strings.xml
+++ b/packages/overlays/AvoidAppsInCutoutOverlay/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="display_cutout_emulation_overlay" msgid="3814493834951357513">"Приказуј апликације испод области изреза"</string>
+    <string name="display_cutout_emulation_overlay" msgid="3814493834951357513">"Prikazuj aplikacije ispod oblasti izreza"</string>
 </resources>
diff --git a/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-b+sr+Latn/strings.xml b/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-b+sr+Latn/strings.xml
index 0adf1dda..5393410 100644
--- a/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-b+sr+Latn/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="display_cutout_emulation_overlay" msgid="1677693377327336341">"Изрезана слика у углу екрана"</string>
+    <string name="display_cutout_emulation_overlay" msgid="1677693377327336341">"Izrezana slika u uglu ekrana"</string>
 </resources>
diff --git a/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values-b+sr+Latn/strings.xml b/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values-b+sr+Latn/strings.xml
index 99b89a2..d2eb7db 100644
--- a/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values-b+sr+Latn/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="display_cutout_emulation_overlay" msgid="5323179900047630217">"Изрезана слика за дупле екране"</string>
+    <string name="display_cutout_emulation_overlay" msgid="5323179900047630217">"Izrezana slika za duple ekrane"</string>
 </resources>
diff --git a/packages/overlays/DisplayCutoutEmulationHoleOverlay/res/values-b+sr+Latn/strings.xml b/packages/overlays/DisplayCutoutEmulationHoleOverlay/res/values-b+sr+Latn/strings.xml
index 411ab7a..97d544c 100644
--- a/packages/overlays/DisplayCutoutEmulationHoleOverlay/res/values-b+sr+Latn/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationHoleOverlay/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="display_cutout_emulation_overlay" msgid="7305489596221077240">"Изрезана слика у облику рупе"</string>
+    <string name="display_cutout_emulation_overlay" msgid="7305489596221077240">"Izrezana slika u obliku rupe"</string>
 </resources>
diff --git a/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values-b+sr+Latn/strings.xml b/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values-b+sr+Latn/strings.xml
index 9026c36..d78d344 100644
--- a/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values-b+sr+Latn/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values-b+sr+Latn/strings.xml
@@ -19,5 +19,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="display_cutout_emulation_overlay" msgid="3947428012427075896">"Изрезана слика за уске екране"</string>
+    <string name="display_cutout_emulation_overlay" msgid="3947428012427075896">"Izrezana slika za uske ekrane"</string>
 </resources>
diff --git a/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values-b+sr+Latn/strings.xml b/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values-b+sr+Latn/strings.xml
index 8ee39b8..46d30c6 100644
--- a/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values-b+sr+Latn/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="display_cutout_emulation_overlay" msgid="6424539415439220018">"Изрезана слика за високе екране"</string>
+    <string name="display_cutout_emulation_overlay" msgid="6424539415439220018">"Izrezana slika za visoke ekrane"</string>
 </resources>
diff --git a/packages/overlays/DisplayCutoutEmulationWaterfallOverlay/res/values-b+sr+Latn/strings.xml b/packages/overlays/DisplayCutoutEmulationWaterfallOverlay/res/values-b+sr+Latn/strings.xml
index 24e3828..4cb324c 100644
--- a/packages/overlays/DisplayCutoutEmulationWaterfallOverlay/res/values-b+sr+Latn/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationWaterfallOverlay/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="display_cutout_emulation_overlay" msgid="3523556473422419323">"Изрезани слап"</string>
+    <string name="display_cutout_emulation_overlay" msgid="3523556473422419323">"Izrezani slap"</string>
 </resources>
diff --git a/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values-b+sr+Latn/strings.xml b/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values-b+sr+Latn/strings.xml
index 6087dd7..d4160f4 100644
--- a/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values-b+sr+Latn/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="display_cutout_emulation_overlay" msgid="4043478945358357737">"Изрезана слика за широке екране"</string>
+    <string name="display_cutout_emulation_overlay" msgid="4043478945358357737">"Izrezana slika za široke ekrane"</string>
 </resources>
diff --git a/packages/overlays/NoCutoutOverlay/res/values-b+sr+Latn/strings.xml b/packages/overlays/NoCutoutOverlay/res/values-b+sr+Latn/strings.xml
index 26afbf9..082e586 100644
--- a/packages/overlays/NoCutoutOverlay/res/values-b+sr+Latn/strings.xml
+++ b/packages/overlays/NoCutoutOverlay/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="display_cutout_emulation_overlay" msgid="9031691255599853162">"Сакриј"</string>
+    <string name="display_cutout_emulation_overlay" msgid="9031691255599853162">"Sakrij"</string>
 </resources>
diff --git a/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java b/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
index 3fa0ab6..e6abc4c 100644
--- a/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
+++ b/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
@@ -391,7 +391,7 @@
     private boolean takeScreenshot() {
         ScreenshotHelper screenshotHelper = (mScreenshotHelperSupplier != null)
                 ? mScreenshotHelperSupplier.get() : new ScreenshotHelper(mContext);
-        screenshotHelper.takeScreenshot(WindowManager.TAKE_SCREENSHOT_FULLSCREEN,
+        screenshotHelper.takeScreenshot(
                 WindowManager.ScreenshotSource.SCREENSHOT_ACCESSIBILITY_ACTIONS,
                 new Handler(Looper.getMainLooper()), null);
         return true;
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 4430bb4b..9d91b97 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -579,12 +579,6 @@
                 }
             }
 
-            if (onClickIntent != null) {
-                views.setOnClickPendingIntent(android.R.id.background,
-                        PendingIntent.getActivity(mContext, 0, onClickIntent,
-                                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE));
-            }
-
             Icon icon = appInfo.icon != 0
                     ? Icon.createWithResource(appInfo.packageName, appInfo.icon)
                     : Icon.createWithResource(mContext, android.R.drawable.sym_def_app_icon);
@@ -596,6 +590,12 @@
             for (int j = 0; j < widgetCount; j++) {
                 Widget widget = provider.widgets.get(j);
                 if (targetWidget != null && targetWidget != widget) continue;
+                if (onClickIntent != null) {
+                    views.setOnClickPendingIntent(android.R.id.background,
+                            PendingIntent.getActivity(mContext, widget.appWidgetId, onClickIntent,
+                                    PendingIntent.FLAG_UPDATE_CURRENT
+                                       | PendingIntent.FLAG_IMMUTABLE));
+                }
                 if (widget.replaceWithMaskedViewsLocked(views)) {
                     scheduleNotifyUpdateAppWidgetLocked(widget, widget.getEffectiveViewsLocked());
                 }
@@ -817,7 +817,8 @@
             if (host != null) {
                 host.callbacks = null;
                 pruneHostLocked(host);
-                mAppOpsManagerInternal.updateAppWidgetVisibility(host.getWidgetUids(), false);
+                mAppOpsManagerInternal.updateAppWidgetVisibility(host.getWidgetUidsIfBound(),
+                        false);
             }
         }
     }
@@ -888,12 +889,8 @@
             Host host = lookupHostLocked(id);
 
             if (host != null) {
-                try {
-                    mAppOpsManagerInternal.updateAppWidgetVisibility(host.getWidgetUids(), false);
-                } catch (NullPointerException e) {
-                    Slog.e(TAG, "setAppWidgetHidden(): Getting host uids: " + host.toString(), e);
-                    throw e;
-                }
+                mAppOpsManagerInternal.updateAppWidgetVisibility(host.getWidgetUidsIfBound(),
+                        false);
             }
         }
     }
@@ -4345,14 +4342,15 @@
                     PendingHostUpdate.appWidgetRemoved(appWidgetId));
         }
 
-        public SparseArray<String> getWidgetUids() {
+        public SparseArray<String> getWidgetUidsIfBound() {
             final SparseArray<String> uids = new SparseArray<>();
             for (int i = widgets.size() - 1; i >= 0; i--) {
                 final Widget widget = widgets.get(i);
                 if (widget.provider == null) {
                     if (DEBUG) {
-                        Slog.e(TAG, "Widget with no provider " + widget.toString());
+                        Slog.d(TAG, "Widget with no provider " + widget.toString());
                     }
+                    continue;
                 }
                 final ProviderId providerId = widget.provider.id;
                 uids.put(providerId.uid, providerId.componentName.getPackageName());
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 677871f..8c2c964 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -357,6 +357,7 @@
         params.width = WindowManager.LayoutParams.MATCH_PARENT;
         params.accessibilityTitle = context.getString(R.string.autofill_save_accessibility_title);
         params.windowAnimations = R.style.AutofillSaveAnimation;
+        params.setTrustedOverlay();
 
         show();
     }
diff --git a/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java b/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java
index a1e734d..b3fad8c 100644
--- a/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java
+++ b/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java
@@ -281,6 +281,7 @@
         mConnectedBtDevices.remove(id);
         mNearbyBleDevices.remove(id);
         mReportedSelfManagedDevices.remove(id);
+        mSimulated.remove(id);
 
         // Do NOT call mCallback.onDeviceDisappeared()!
         // CompanionDeviceManagerService will know that the association is removed, and will do
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index c4333d9..8a42933 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -3813,6 +3813,13 @@
         final boolean includeSharedProfile =
                 (flags & StorageManager.FLAG_INCLUDE_SHARED_PROFILE) != 0;
 
+        // When the caller is the app actually hosting external storage, we
+        // should never attempt to augment the actual storage volume state,
+        // otherwise we risk confusing it with race conditions as users go
+        // through various unlocked states
+        final boolean callerIsMediaStore = UserHandle.isSameApp(callingUid,
+                mMediaStoreAuthorityAppId);
+
         // Only Apps with MANAGE_EXTERNAL_STORAGE should call the API with includeSharedProfile
         if (includeSharedProfile) {
             try {
@@ -3825,8 +3832,13 @@
                 // Checking first entry in packagesFromUid is enough as using "sharedUserId"
                 // mechanism is rare and discouraged. Also, Apps that share same UID share the same
                 // permissions.
-                if (!mStorageManagerInternal.hasExternalStorageAccess(callingUid,
-                        packagesFromUid[0])) {
+                // Allowing Media Provider is an exception, Media Provider process should be allowed
+                // to query users across profiles, even without MANAGE_EXTERNAL_STORAGE access.
+                // Note that ordinarily Media provider process has the above permission, but if they
+                // are revoked, Storage Volume(s) should still be returned.
+                if (!callerIsMediaStore
+                        && !mStorageManagerInternal.hasExternalStorageAccess(callingUid,
+                                packagesFromUid[0])) {
                     throw new SecurityException("Only File Manager Apps permitted");
                 }
             } catch (RemoteException re) {
@@ -3839,13 +3851,6 @@
         // point
         final boolean systemUserUnlocked = isSystemUnlocked(UserHandle.USER_SYSTEM);
 
-        // When the caller is the app actually hosting external storage, we
-        // should never attempt to augment the actual storage volume state,
-        // otherwise we risk confusing it with race conditions as users go
-        // through various unlocked states
-        final boolean callerIsMediaStore = UserHandle.isSameApp(callingUid,
-                mMediaStoreAuthorityAppId);
-
         final boolean userIsDemo;
         final boolean userKeyUnlocked;
         final boolean storagePermission;
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 4f1efd6..4251581 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -3091,7 +3091,7 @@
                             }
                         }
 
-                        Intent intent = result.getParcelable(AccountManager.KEY_INTENT);
+                        Intent intent = result.getParcelable(AccountManager.KEY_INTENT, Intent.class);
                         if (intent != null && notifyOnAuthFailure && !customTokens) {
                             /*
                              * Make sure that the supplied intent is owned by the authenticator
@@ -3516,8 +3516,7 @@
             Bundle.setDefusable(result, true);
             mNumResults++;
             Intent intent = null;
-            if (result != null
-                    && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) {
+            if (result != null) {
                 if (!checkKeyIntent(
                         Binder.getCallingUid(),
                         result)) {
@@ -4885,8 +4884,10 @@
             	EventLog.writeEvent(0x534e4554, "250588548", authUid, "");
                 return false;
             }
-
             Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT, Intent.class);
+            if (intent == null) {
+                return true;
+            }
             // Explicitly set an empty ClipData to ensure that we don't offer to
             // promote any Uris contained inside for granting purposes
             if (intent.getClipData() == null) {
@@ -4936,8 +4937,12 @@
             Bundle simulateBundle = p.readBundle();
             p.recycle();
             Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT, Intent.class);
-            return (intent.filterEquals(simulateBundle.getParcelable(AccountManager.KEY_INTENT,
-                Intent.class)));
+            Intent simulateIntent = simulateBundle.getParcelable(AccountManager.KEY_INTENT,
+                    Intent.class);
+            if (intent == null) {
+                return (simulateIntent == null);
+            }
+            return intent.filterEquals(simulateIntent);
         }
 
         private boolean isExportedSystemActivity(ActivityInfo activityInfo) {
@@ -5082,8 +5087,7 @@
                     }
                 }
             }
-            if (result != null
-                    && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) {
+            if (result != null) {
                 if (!checkKeyIntent(
                         Binder.getCallingUid(),
                         result)) {
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 9669c06..c36e070 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -3420,6 +3420,11 @@
                             throw new SecurityException("BIND_EXTERNAL_SERVICE failed, "
                                     + className + " is not an isolatedProcess");
                         }
+                        if (!mAm.getPackageManagerInternal().isSameApp(callingPackage, callingUid,
+                                userId)) {
+                            throw new SecurityException("BIND_EXTERNAL_SERVICE failed, "
+                                    + "calling package not owned by calling UID ");
+                        }
                         // Run the service under the calling package's application.
                         ApplicationInfo aInfo = AppGlobals.getPackageManager().getApplicationInfo(
                                 callingPackage, ActivityManagerService.STOCK_PM_FLAGS, userId);
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index 8624ee0..bda60ff 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -379,16 +379,11 @@
                 resolvedType = key.requestResolvedType;
             }
 
-            // Apply any launch flags from the ActivityOptions. This is used only by SystemUI
-            // to ensure that we can launch the pending intent with a consistent launch mode even
-            // if the provided PendingIntent is immutable (ie. to force an activity to launch into
-            // a new task, or to launch multiple instances if supported by the app)
+            // Apply any launch flags from the ActivityOptions. This is to ensure that the caller
+            // can specify a consistent launch mode even if the PendingIntent is immutable
             final ActivityOptions opts = ActivityOptions.fromBundle(options);
             if (opts != null) {
-                // TODO(b/254490217): Move this check into SafeActivityOptions
-                if (controller.mAtmInternal.isCallerRecents(Binder.getCallingUid())) {
-                    finalIntent.addFlags(opts.getPendingIntentLaunchFlags());
-                }
+                finalIntent.addFlags(opts.getPendingIntentLaunchFlags());
             }
 
             // Extract options before clearing calling identity
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 17cd5d1..6562ae7 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -97,7 +97,6 @@
         DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
         DeviceConfig.NAMESPACE_SURFACE_FLINGER_NATIVE_BOOT,
         DeviceConfig.NAMESPACE_SWCODEC_NATIVE,
-        DeviceConfig.NAMESPACE_TETHERING,
         DeviceConfig.NAMESPACE_VENDOR_SYSTEM_NATIVE,
         DeviceConfig.NAMESPACE_VENDOR_SYSTEM_NATIVE_BOOT,
         DeviceConfig.NAMESPACE_VIRTUALIZATION_FRAMEWORK_NATIVE,
diff --git a/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java b/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java
index 4fd739ca..4b0ae1b 100644
--- a/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java
+++ b/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java
@@ -16,6 +16,9 @@
 
 package com.android.server.app;
 
+import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_OTHER;
+import static android.view.WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE;
+
 import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -33,7 +36,6 @@
 import android.graphics.Insets;
 import android.graphics.Rect;
 import android.net.Uri;
-import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.service.games.CreateGameSessionRequest;
@@ -50,7 +52,6 @@
 import android.util.Slog;
 import android.view.SurfaceControl;
 import android.view.SurfaceControlViewHost.SurfacePackage;
-import android.view.WindowManager;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -59,6 +60,7 @@
 import com.android.internal.infra.ServiceConnector.ServiceLifecycleCallbacks;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.ScreenshotHelper;
+import com.android.internal.util.ScreenshotRequest;
 import com.android.server.wm.ActivityTaskManagerInternal;
 import com.android.server.wm.WindowManagerInternal;
 import com.android.server.wm.WindowManagerInternal.TaskSystemBarsListener;
@@ -861,8 +863,6 @@
                 Slog.w(TAG, "Could not get bitmap for id: " + taskId);
                 callback.complete(GameScreenshotResult.createInternalErrorResult());
             } else {
-                final Bundle bundle = ScreenshotHelper.HardwareBitmapBundler.hardwareBitmapToBundle(
-                        bitmap);
                 final RunningTaskInfo runningTaskInfo =
                         mGameTaskInfoProvider.getRunningTaskInfo(taskId);
                 if (runningTaskInfo == null) {
@@ -877,11 +877,17 @@
                         callback.complete(GameScreenshotResult.createSuccessResult());
                     }
                 };
-                mScreenshotHelper.provideScreenshot(bundle, crop, Insets.NONE, taskId,
-                        mUserHandle.getIdentifier(), gameSessionRecord.getComponentName(),
-                        WindowManager.ScreenshotSource.SCREENSHOT_OTHER,
-                        BackgroundThread.getHandler(),
-                        completionConsumer);
+                ScreenshotRequest request = new ScreenshotRequest.Builder(
+                        TAKE_SCREENSHOT_PROVIDED_IMAGE, SCREENSHOT_OTHER)
+                        .setTopComponent(gameSessionRecord.getComponentName())
+                        .setTaskId(taskId)
+                        .setUserId(mUserHandle.getIdentifier())
+                        .setBitmap(bitmap)
+                        .setBoundsOnScreen(crop)
+                        .setInsets(Insets.NONE)
+                        .build();
+                mScreenshotHelper.takeScreenshot(
+                        request, BackgroundThread.getHandler(), completionConsumer);
             }
         });
     }
diff --git a/services/core/java/com/android/server/attention/AttentionManagerService.java b/services/core/java/com/android/server/attention/AttentionManagerService.java
index d4ef638..658e38b 100644
--- a/services/core/java/com/android/server/attention/AttentionManagerService.java
+++ b/services/core/java/com/android/server/attention/AttentionManagerService.java
@@ -668,8 +668,8 @@
             mIProximityUpdateCallback = new IProximityUpdateCallback.Stub() {
                 @Override
                 public void onProximityUpdate(double distance) {
+                    mCallbackInternal.onProximityUpdate(distance);
                     synchronized (mLock) {
-                        mCallbackInternal.onProximityUpdate(distance);
                         freeIfInactiveLocked();
                     }
                 }
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 736914a..278c98f 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -82,6 +82,7 @@
 
     private final @NonNull AudioService mAudioService;
     private final @NonNull Context mContext;
+    private final @NonNull AudioSystemAdapter mAudioSystem;
 
     /** ID for Communication strategy retrieved form audio policy manager */
     private int mCommunicationStrategyId = -1;
@@ -156,12 +157,14 @@
     public static final long USE_SET_COMMUNICATION_DEVICE = 243827847L;
 
     //-------------------------------------------------------------------
-    /*package*/ AudioDeviceBroker(@NonNull Context context, @NonNull AudioService service) {
+    /*package*/ AudioDeviceBroker(@NonNull Context context, @NonNull AudioService service,
+            @NonNull AudioSystemAdapter audioSystem) {
         mContext = context;
         mAudioService = service;
         mBtHelper = new BtHelper(this);
         mDeviceInventory = new AudioDeviceInventory(this);
         mSystemServer = SystemServerAdapter.getDefaultAdapter(mContext);
+        mAudioSystem = audioSystem;
 
         init();
     }
@@ -170,12 +173,14 @@
      *  in system_server */
     AudioDeviceBroker(@NonNull Context context, @NonNull AudioService service,
                       @NonNull AudioDeviceInventory mockDeviceInventory,
-                      @NonNull SystemServerAdapter mockSystemServer) {
+                      @NonNull SystemServerAdapter mockSystemServer,
+                      @NonNull AudioSystemAdapter audioSystem) {
         mContext = context;
         mAudioService = service;
         mBtHelper = new BtHelper(this);
         mDeviceInventory = mockDeviceInventory;
         mSystemServer = mockSystemServer;
+        mAudioSystem = audioSystem;
 
         init();
     }
@@ -450,7 +455,7 @@
             AudioAttributes attr =
                     AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(
                             AudioSystem.STREAM_VOICE_CALL);
-            List<AudioDeviceAttributes> devices = AudioSystem.getDevicesForAttributes(
+            List<AudioDeviceAttributes> devices = mAudioSystem.getDevicesForAttributes(
                     attr, false /* forVolume */);
             if (devices.isEmpty()) {
                 if (mAudioService.isPlatformVoice()) {
@@ -1225,7 +1230,7 @@
             Log.v(TAG, "onSetForceUse(useCase<" + useCase + ">, config<" + config + ">, fromA2dp<"
                     + fromA2dp + ">, eventSource<" + eventSource + ">)");
         }
-        AudioSystem.setForceUse(useCase, config);
+        mAudioSystem.setForceUse(useCase, config);
     }
 
     private void onSendBecomingNoisyIntent() {
@@ -1863,9 +1868,9 @@
 
         if (preferredCommunicationDevice == null
                 || preferredCommunicationDevice.getType() != AudioDeviceInfo.TYPE_BLUETOOTH_SCO) {
-            AudioSystem.setParameters("BT_SCO=off");
+            mAudioSystem.setParameters("BT_SCO=off");
         } else {
-            AudioSystem.setParameters("BT_SCO=on");
+            mAudioSystem.setParameters("BT_SCO=on");
         }
         if (preferredCommunicationDevice == null) {
             AudioDeviceAttributes defaultDevice = getDefaultCommunicationDevice();
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index c804ef2..1bd8f1e 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -183,6 +183,7 @@
 import com.android.server.SystemService;
 import com.android.server.audio.AudioServiceEvents.DeviceVolumeEvent;
 import com.android.server.audio.AudioServiceEvents.PhoneStateEvent;
+import com.android.server.audio.AudioServiceEvents.VolChangedBroadcastEvent;
 import com.android.server.audio.AudioServiceEvents.VolumeEvent;
 import com.android.server.pm.UserManagerInternal;
 import com.android.server.pm.UserManagerInternal.UserRestrictionsListener;
@@ -1205,7 +1206,7 @@
         mUseFixedVolume = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_useFixedVolume);
 
-        mDeviceBroker = new AudioDeviceBroker(mContext, this);
+        mDeviceBroker = new AudioDeviceBroker(mContext, this, mAudioSystem);
 
         mRecordMonitor = new RecordingActivityMonitor(mContext);
         mRecordMonitor.registerRecordingCallback(mVoiceRecordingActivityMonitor, true);
@@ -1637,7 +1638,7 @@
 
         synchronized (mSettingsLock) {
             final int forDock = mDockAudioMediaEnabled ?
-                    AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE;
+                    AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE;
             mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, forDock, "onAudioServerDied");
             sendEncodedSurroundMode(mContentResolver, "onAudioServerDied");
             sendEnabledSurroundFormats(mContentResolver, true);
@@ -2258,9 +2259,10 @@
                 SENDMSG_QUEUE,
                 AudioSystem.FOR_DOCK,
                 mDockAudioMediaEnabled ?
-                        AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE,
+                        AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE,
                 new String("readDockAudioSettings"),
                 0);
+
     }
 
 
@@ -3601,9 +3603,11 @@
             setRingerMode(getNewRingerMode(stream, index, flags),
                     TAG + ".onSetStreamVolume", false /*external*/);
         }
-        // setting non-zero volume for a muted stream unmutes the stream and vice versa,
+        // setting non-zero volume for a muted stream unmutes the stream and vice versa
+        // (only when changing volume for the current device),
         // except for BT SCO stream where only explicit mute is allowed to comply to BT requirements
-        if (streamType != AudioSystem.STREAM_BLUETOOTH_SCO) {
+        if ((streamType != AudioSystem.STREAM_BLUETOOTH_SCO)
+                && (getDeviceForStream(stream) == device)) {
             mStreamStates[stream].mute(index == 0);
         }
     }
@@ -3741,19 +3745,30 @@
         Objects.requireNonNull(ada);
         Objects.requireNonNull(callingPackage);
 
-        AudioService.sVolumeLogger.loglogi("setDeviceVolume" + " from:" + callingPackage + " "
-                + vi + " " + ada, TAG);
-
         if (!vi.hasStreamType()) {
             Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception());
             return;
         }
+
         int index = vi.getVolumeIndex();
         if (index == VolumeInfo.INDEX_NOT_SET && !vi.hasMuteCommand()) {
             throw new IllegalArgumentException(
                     "changing device volume requires a volume index or mute command");
         }
 
+        // force a cache clear to force reevaluating stream type to audio device selection
+        // that can interfere with the sending of the VOLUME_CHANGED_ACTION intent
+        // TODO change cache management to not rely only on invalidation, but on "do not trust"
+        //     moments when routing is in flux.
+        mAudioSystem.clearRoutingCache();
+
+        // log the current device that will be used when evaluating the sending of the
+        // VOLUME_CHANGED_ACTION intent to see if the current device is the one being modified
+        final int currDev = getDeviceForStream(vi.getStreamType());
+
+        AudioService.sVolumeLogger.log(new DeviceVolumeEvent(vi.getStreamType(), index, ada,
+                currDev, callingPackage));
+
         // TODO handle unmuting of current audio device
         // if a stream is not muted but the VolumeInfo is for muting, set the volume index
         // for the device to min volume
@@ -3837,11 +3852,11 @@
             return;
         }
 
-        final AudioEventLogger.Event event = (device == null)
-                ? new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType,
-                    index/*val1*/, flags/*val2*/, callingPackage)
-                : new DeviceVolumeEvent(streamType, index, device, callingPackage);
-        sVolumeLogger.log(event);
+        if (device == null) {
+            // call was already logged in setDeviceVolume()
+            sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType,
+                    index/*val1*/, flags/*val2*/, callingPackage));
+        }
         setStreamVolume(streamType, index, flags, device,
                 callingPackage, callingPackage, attributionTag,
                 Binder.getCallingUid(), callingOrSelfHasAudioSettingsPermission());
@@ -4242,7 +4257,11 @@
                 maybeSendSystemAudioStatusCommand(false);
             }
         }
-        sendVolumeUpdate(streamType, oldIndex, index, flags, device);
+        if (ada == null) {
+            // only non-null when coming here from setDeviceVolume
+            // TODO change test to check early if device is current device or not
+            sendVolumeUpdate(streamType, oldIndex, index, flags, device);
+        }
     }
 
 
@@ -7982,6 +8001,8 @@
                     mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex);
                     mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS,
                             mStreamVolumeAlias[mStreamType]);
+                    AudioService.sVolumeLogger.log(new VolChangedBroadcastEvent(
+                            mStreamType, mStreamVolumeAlias[mStreamType], index));
                     sendBroadcastToAll(mVolumeChanged);
                 }
             }
@@ -10155,7 +10176,7 @@
     static final int LOG_NB_EVENTS_PHONE_STATE = 20;
     static final int LOG_NB_EVENTS_DEVICE_CONNECTION = 50;
     static final int LOG_NB_EVENTS_FORCE_USE = 20;
-    static final int LOG_NB_EVENTS_VOLUME = 40;
+    static final int LOG_NB_EVENTS_VOLUME = 100;
     static final int LOG_NB_EVENTS_DYN_POLICY = 10;
     static final int LOG_NB_EVENTS_SPATIAL = 30;
 
diff --git a/services/core/java/com/android/server/audio/AudioServiceEvents.java b/services/core/java/com/android/server/audio/AudioServiceEvents.java
index 30a9e0a7..c2c3f02 100644
--- a/services/core/java/com/android/server/audio/AudioServiceEvents.java
+++ b/services/core/java/com/android/server/audio/AudioServiceEvents.java
@@ -147,19 +147,42 @@
         }
     }
 
+    static final class VolChangedBroadcastEvent extends AudioEventLogger.Event {
+        final int mStreamType;
+        final int mAliasStreamType;
+        final int mIndex;
+
+        VolChangedBroadcastEvent(int stream, int alias, int index) {
+            mStreamType = stream;
+            mAliasStreamType = alias;
+            mIndex = index;
+        }
+
+        @Override
+        public String eventToString() {
+            return new StringBuilder("sending VOLUME_CHANGED stream:")
+                    .append(AudioSystem.streamToString(mStreamType))
+                    .append(" index:").append(mIndex)
+                    .append(" alias:").append(AudioSystem.streamToString(mAliasStreamType))
+                    .toString();
+        }
+    }
+
     static final class DeviceVolumeEvent extends AudioEventLogger.Event {
         final int mStream;
         final int mVolIndex;
         final String mDeviceNativeType;
         final String mDeviceAddress;
         final String mCaller;
+        final int mDeviceForStream;
 
         DeviceVolumeEvent(int streamType, int index, @NonNull AudioDeviceAttributes device,
-                String callingPackage) {
+                int deviceForStream, String callingPackage) {
             mStream = streamType;
             mVolIndex = index;
             mDeviceNativeType = "0x" + Integer.toHexString(device.getInternalType());
             mDeviceAddress = device.getAddress();
+            mDeviceForStream = deviceForStream;
             mCaller = callingPackage;
             // log metrics
             new MediaMetrics.Item(MediaMetrics.Name.AUDIO_VOLUME_EVENT)
@@ -180,7 +203,9 @@
                     .append(" index:").append(mVolIndex)
                     .append(" device:").append(mDeviceNativeType)
                     .append(" addr:").append(mDeviceAddress)
-                    .append(") from ").append(mCaller).toString();
+                    .append(") from ").append(mCaller)
+                    .append(" currDevForStream:Ox").append(Integer.toHexString(mDeviceForStream))
+                    .toString();
         }
     }
 
diff --git a/services/core/java/com/android/server/audio/AudioSystemAdapter.java b/services/core/java/com/android/server/audio/AudioSystemAdapter.java
index c3754eb..2588371 100644
--- a/services/core/java/com/android/server/audio/AudioSystemAdapter.java
+++ b/services/core/java/com/android/server/audio/AudioSystemAdapter.java
@@ -105,6 +105,13 @@
         }
     }
 
+    public void clearRoutingCache() {
+        if (DEBUG_CACHE) {
+            Log.d(TAG, "---- routing cache clear (from java) ----------");
+        }
+        invalidateRoutingCache();
+    }
+
     /**
      * Implementation of AudioSystem.VolumeRangeInitRequestCallback
      */
@@ -337,6 +344,7 @@
      * @return
      */
     public int setParameters(String keyValuePairs) {
+        invalidateRoutingCache();
         return AudioSystem.setParameters(keyValuePairs);
     }
 
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index 54be4bb..1862942 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -58,13 +58,15 @@
 public final class PlaybackActivityMonitor
         implements AudioPlaybackConfiguration.PlayerDeathMonitor, PlayerFocusEnforcer {
 
-    public static final String TAG = "AudioService.PlaybackActivityMonitor";
+    public static final String TAG = "AS.PlayActivityMonitor";
 
     /*package*/ static final boolean DEBUG = false;
     /*package*/ static final int VOLUME_SHAPER_SYSTEM_DUCK_ID = 1;
     /*package*/ static final int VOLUME_SHAPER_SYSTEM_FADEOUT_ID = 2;
     /*package*/ static final int VOLUME_SHAPER_SYSTEM_MUTE_AWAIT_CONNECTION_ID = 3;
+    /*package*/ static final int VOLUME_SHAPER_SYSTEM_STRONG_DUCK_ID = 4;
 
+    // ducking settings for a "normal duck" at -14dB
     private static final VolumeShaper.Configuration DUCK_VSHAPE =
             new VolumeShaper.Configuration.Builder()
                 .setId(VOLUME_SHAPER_SYSTEM_DUCK_ID)
@@ -78,6 +80,22 @@
                 .build();
     private static final VolumeShaper.Configuration DUCK_ID =
             new VolumeShaper.Configuration(VOLUME_SHAPER_SYSTEM_DUCK_ID);
+
+    // ducking settings for a "strong duck" at -35dB (attenuation factor of 0.017783)
+    private static final VolumeShaper.Configuration STRONG_DUCK_VSHAPE =
+            new VolumeShaper.Configuration.Builder()
+                .setId(VOLUME_SHAPER_SYSTEM_STRONG_DUCK_ID)
+                .setCurve(new float[] { 0.f, 1.f } /* times */,
+                        new float[] { 1.f, 0.017783f } /* volumes */)
+                .setOptionFlags(VolumeShaper.Configuration.OPTION_FLAG_CLOCK_TIME)
+                .setDuration(MediaFocusControl.getFocusRampTimeMs(
+                        AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK,
+                        new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION)
+                                .build()))
+                    .build();
+    private static final VolumeShaper.Configuration STRONG_DUCK_ID =
+            new VolumeShaper.Configuration(VOLUME_SHAPER_SYSTEM_STRONG_DUCK_ID);
+
     private static final VolumeShaper.Operation PLAY_CREATE_IF_NEEDED =
             new VolumeShaper.Operation.Builder(VolumeShaper.Operation.PLAY)
                     .createIfNeeded()
@@ -659,11 +677,23 @@
             // add the players eligible for ducking to the list, and duck them
             // (if apcsToDuck is empty, this will at least mark this uid as ducked, so when
             //  players of the same uid start, they will be ducked by DuckingManager.checkDuck())
-            mDuckingManager.duckUid(loser.getClientUid(), apcsToDuck);
+            mDuckingManager.duckUid(loser.getClientUid(), apcsToDuck, reqCausesStrongDuck(winner));
         }
         return true;
     }
 
+    private boolean reqCausesStrongDuck(FocusRequester requester) {
+        if (requester.getGainRequest() != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) {
+            return false;
+        }
+        final int reqUsage = requester.getAudioAttributes().getUsage();
+        if ((reqUsage == AudioAttributes.USAGE_ASSISTANT)
+                || (reqUsage == AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE)) {
+            return true;
+        }
+        return false;
+    }
+
     @Override
     public void restoreVShapedPlayers(@NonNull FocusRequester winner) {
         if (DEBUG) { Log.v(TAG, "unduckPlayers: uids winner=" + winner.getClientUid()); }
@@ -939,10 +969,11 @@
     private static final class DuckingManager {
         private final HashMap<Integer, DuckedApp> mDuckers = new HashMap<Integer, DuckedApp>();
 
-        synchronized void duckUid(int uid, ArrayList<AudioPlaybackConfiguration> apcsToDuck) {
+        synchronized void duckUid(int uid, ArrayList<AudioPlaybackConfiguration> apcsToDuck,
+                boolean requestCausesStrongDuck) {
             if (DEBUG) {  Log.v(TAG, "DuckingManager: duckUid() uid:"+ uid); }
             if (!mDuckers.containsKey(uid)) {
-                mDuckers.put(uid, new DuckedApp(uid));
+                mDuckers.put(uid, new DuckedApp(uid, requestCausesStrongDuck));
             }
             final DuckedApp da = mDuckers.get(uid);
             for (AudioPlaybackConfiguration apc : apcsToDuck) {
@@ -989,10 +1020,13 @@
 
         private static final class DuckedApp {
             private final int mUid;
+            /** determines whether ducking is done with DUCK_VSHAPE or STRONG_DUCK_VSHAPE */
+            private final boolean mUseStrongDuck;
             private final ArrayList<Integer> mDuckedPlayers = new ArrayList<Integer>();
 
-            DuckedApp(int uid) {
+            DuckedApp(int uid, boolean useStrongDuck) {
                 mUid = uid;
+                mUseStrongDuck = useStrongDuck;
             }
 
             void dump(PrintWriter pw) {
@@ -1013,9 +1047,9 @@
                     return;
                 }
                 try {
-                    sEventLogger.log((new DuckEvent(apc, skipRamp)).printLog(TAG));
+                    sEventLogger.log((new DuckEvent(apc, skipRamp, mUseStrongDuck)).printLog(TAG));
                     apc.getPlayerProxy().applyVolumeShaper(
-                            DUCK_VSHAPE,
+                            mUseStrongDuck ? STRONG_DUCK_VSHAPE : DUCK_VSHAPE,
                             skipRamp ? PLAY_SKIP_RAMP : PLAY_CREATE_IF_NEEDED);
                     mDuckedPlayers.add(piid);
                 } catch (Exception e) {
@@ -1031,7 +1065,7 @@
                             sEventLogger.log((new AudioEventLogger.StringEvent("unducking piid:"
                                     + piid)).printLog(TAG));
                             apc.getPlayerProxy().applyVolumeShaper(
-                                    DUCK_ID,
+                                    mUseStrongDuck ? STRONG_DUCK_ID : DUCK_ID,
                                     VolumeShaper.Operation.REVERSE);
                         } catch (Exception e) {
                             Log.e(TAG, "Error unducking player piid:" + piid + " uid:" + mUid, e);
@@ -1146,13 +1180,17 @@
     }
 
     static final class DuckEvent extends VolumeShaperEvent {
+        final boolean mUseStrongDuck;
+
         @Override
         String getVSAction() {
-            return "ducking";
+            return mUseStrongDuck ? "ducking (strong)" : "ducking";
         }
 
-        DuckEvent(@NonNull AudioPlaybackConfiguration apc, boolean skipRamp) {
+        DuckEvent(@NonNull AudioPlaybackConfiguration apc, boolean skipRamp, boolean useStrongDuck)
+        {
             super(apc, skipRamp);
+            mUseStrongDuck = useStrongDuck;
         }
     }
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/InternalCleanupClient.java b/services/core/java/com/android/server/biometrics/sensors/InternalCleanupClient.java
index 57ea812..1924f3c 100644
--- a/services/core/java/com/android/server/biometrics/sensors/InternalCleanupClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/InternalCleanupClient.java
@@ -96,7 +96,11 @@
         @Override
         public void onClientFinished(@NonNull BaseClientMonitor clientMonitor, boolean success) {
             Slog.d(TAG, "Remove onClientFinished: " + clientMonitor + ", success: " + success);
-            mCallback.onClientFinished(InternalCleanupClient.this, success);
+            if (mUnknownHALTemplates.isEmpty()) {
+                mCallback.onClientFinished(InternalCleanupClient.this, success);
+            } else {
+                startCleanupUnknownHalTemplates();
+            }
         }
     };
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
index 05e83da..787bfb0 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
@@ -16,15 +16,11 @@
 
 package com.android.server.biometrics.sensors.fingerprint.aidl;
 
-import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_START;
-import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR;
-
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.TaskStackListener;
 import android.content.Context;
 import android.hardware.biometrics.BiometricAuthenticator;
-import android.hardware.biometrics.BiometricConstants;
 import android.hardware.biometrics.BiometricFingerprintConstants;
 import android.hardware.biometrics.BiometricFingerprintConstants.FingerprintAcquired;
 import android.hardware.biometrics.common.ICancellationSignal;
@@ -92,7 +88,6 @@
     private long mSideFpsLastAcquireStartTime;
     private Runnable mAuthSuccessRunnable;
     private final Clock mClock;
-    private boolean mDidFinishSfps;
 
     FingerprintAuthenticationClient(
             @NonNull Context context,
@@ -198,9 +193,8 @@
 
     @Override
     protected void handleLifecycleAfterAuth(boolean authenticated) {
-        if (authenticated && !mDidFinishSfps) {
+        if (authenticated) {
             mCallback.onClientFinished(this, true /* success */);
-            mDidFinishSfps = true;
         }
     }
 
@@ -210,13 +204,11 @@
         return false;
     }
 
-    public void handleAuthenticate(
+    @Override
+    public void onAuthenticated(
             BiometricAuthenticator.Identifier identifier,
             boolean authenticated,
             ArrayList<Byte> token) {
-        if (authenticated && mSensorProps.isAnySidefpsType()) {
-            Slog.i(TAG, "(sideFPS): No power press detected, sending auth");
-        }
         super.onAuthenticated(identifier, authenticated, token);
         if (authenticated) {
             mState = STATE_STOPPED;
@@ -227,72 +219,11 @@
     }
 
     @Override
-    public void onAuthenticated(
-            BiometricAuthenticator.Identifier identifier,
-            boolean authenticated,
-            ArrayList<Byte> token) {
-
-        mHandler.post(
-                () -> {
-                    long delay = 0;
-                    if (authenticated && mSensorProps.isAnySidefpsType()) {
-                        delay = isKeyguard() ? mWaitForAuthKeyguard : mWaitForAuthBp;
-
-                        if (mSideFpsLastAcquireStartTime != -1) {
-                            delay = Math.max(0,
-                                    delay - (mClock.millis() - mSideFpsLastAcquireStartTime));
-                        }
-
-                        Slog.i(TAG, "(sideFPS) Auth succeeded, sideFps "
-                                + "waiting for power until: " + delay + "ms");
-                    }
-
-                    if (mHandler.hasMessages(MESSAGE_FINGER_UP)) {
-                        Slog.i(TAG, "Finger up detected, sending auth");
-                        delay = 0;
-                    }
-
-                    mAuthSuccessRunnable =
-                            () -> handleAuthenticate(identifier, authenticated, token);
-                    mHandler.postDelayed(
-                            mAuthSuccessRunnable,
-                            MESSAGE_AUTH_SUCCESS,
-                            delay);
-                });
-    }
-
-    @Override
     public void onAcquired(@FingerprintAcquired int acquiredInfo, int vendorCode) {
         // For UDFPS, notify SysUI with acquiredInfo, so that the illumination can be turned off
         // for most ACQUIRED messages. See BiometricFingerprintConstants#FingerprintAcquired
         mSensorOverlays.ifUdfps(controller -> controller.onAcquired(getSensorId(), acquiredInfo));
         super.onAcquired(acquiredInfo, vendorCode);
-        if (mSensorProps.isAnySidefpsType()) {
-            if (acquiredInfo == FINGERPRINT_ACQUIRED_START) {
-                mSideFpsLastAcquireStartTime = mClock.millis();
-            }
-            final boolean shouldLookForVendor =
-                    mSkipWaitForPowerAcquireMessage == FINGERPRINT_ACQUIRED_VENDOR;
-            final boolean acquireMessageMatch = acquiredInfo == mSkipWaitForPowerAcquireMessage;
-            final boolean vendorMessageMatch = vendorCode == mSkipWaitForPowerVendorAcquireMessage;
-            final boolean ignorePowerPress =
-                    acquireMessageMatch && (!shouldLookForVendor || vendorMessageMatch);
-
-            if (ignorePowerPress) {
-                Slog.d(TAG, "(sideFPS) onFingerUp");
-                mHandler.post(() -> {
-                    if (mHandler.hasMessages(MESSAGE_AUTH_SUCCESS)) {
-                        Slog.d(TAG, "(sideFPS) skipping wait for power");
-                        mHandler.removeMessages(MESSAGE_AUTH_SUCCESS);
-                        mHandler.post(mAuthSuccessRunnable);
-                    } else {
-                        mHandler.postDelayed(() -> {
-                        }, MESSAGE_FINGER_UP, mFingerUpIgnoresPower);
-                    }
-                });
-            }
-        }
-
     }
 
     @Override
@@ -488,22 +419,5 @@
     }
 
     @Override
-    public void onPowerPressed() {
-        if (mSensorProps.isAnySidefpsType()) {
-            Slog.i(TAG, "(sideFPS): onPowerPressed");
-            mHandler.post(() -> {
-                if (mDidFinishSfps) {
-                    return;
-                }
-                Slog.i(TAG, "(sideFPS): finishing auth");
-                // Ignore auths after a power has been detected
-                mHandler.removeMessages(MESSAGE_AUTH_SUCCESS);
-                // Do not call onError() as that will send an additional callback to coex.
-                mDidFinishSfps = true;
-                onErrorInternal(BiometricConstants.BIOMETRIC_ERROR_POWER_PRESSED, 0, true);
-                stopHalOperation();
-                mSensorOverlays.hide(getSensorId());
-            });
-        }
-    }
+    public void onPowerPressed() { }
 }
diff --git a/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java b/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java
index 9dd2f84..b9ca57e 100644
--- a/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java
+++ b/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java
@@ -76,6 +76,10 @@
         return layout;
     }
 
+    int size() {
+        return mLayoutMap.size();
+    }
+
     private Layout createLayout(int state) {
         if (mLayoutMap.contains(state)) {
             Slog.e(TAG, "Attempted to create a second layout for state " + state);
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index 5bdfa70..2b7fbfb 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -402,6 +402,8 @@
     private static final String STABLE_ID_SUFFIX_FORMAT = "id_%d";
     private static final String NO_SUFFIX_FORMAT = "%d";
     private static final long STABLE_FLAG = 1L << 62;
+    private static final int DEFAULT_PEAK_REFRESH_RATE = 0;
+    private static final int DEFAULT_REFRESH_RATE = 60;
     private static final int DEFAULT_LOW_REFRESH_RATE = 60;
     private static final int DEFAULT_HIGH_REFRESH_RATE = 0;
     private static final int[] DEFAULT_BRIGHTNESS_THRESHOLDS = new int[]{};
@@ -570,17 +572,29 @@
      * using higher refresh rates, even if display modes with higher refresh rates are available
      * from hardware composer. Only has an effect if the value is non-zero.
      */
-    private int mDefaultHighRefreshRate = DEFAULT_HIGH_REFRESH_RATE;
+    private int mDefaultPeakRefreshRate = DEFAULT_PEAK_REFRESH_RATE;
 
     /**
      * The default refresh rate for a given device. This value sets the higher default
      * refresh rate. If the hardware composer on the device supports display modes with
      * a higher refresh rate than the default value specified here, the framework may use those
      * higher refresh rate modes if an app chooses one by setting preferredDisplayModeId or calling
-     * setFrameRate(). We have historically allowed fallback to mDefaultHighRefreshRate if
-     * mDefaultLowRefreshRate is set to 0, but this is not supported anymore.
+     * setFrameRate(). We have historically allowed fallback to mDefaultPeakRefreshRate if
+     * mDefaultRefreshRate is set to 0, but this is not supported anymore.
      */
-    private int mDefaultLowRefreshRate = DEFAULT_LOW_REFRESH_RATE;
+    private int mDefaultRefreshRate = DEFAULT_REFRESH_RATE;
+
+    /**
+     * Default refresh rate in the high zone defined by brightness and ambient thresholds.
+     * If non-positive, then the refresh rate is unchanged even if thresholds are configured.
+     */
+    private int mDefaultHighBlockingZoneRefreshRate = DEFAULT_HIGH_REFRESH_RATE;
+
+    /**
+     * Default refresh rate in the zone defined by brightness and ambient thresholds.
+     * If non-positive, then the refresh rate is unchanged even if thresholds are configured.
+     */
+    private int mDefaultLowBlockingZoneRefreshRate = DEFAULT_LOW_REFRESH_RATE;
 
     /**
      * The display uses different gamma curves for different refresh rates. It's hard for panel
@@ -1296,15 +1310,29 @@
     /**
      * @return Default peak refresh rate of the associated display
      */
-    public int getDefaultHighRefreshRate() {
-        return mDefaultHighRefreshRate;
+    public int getDefaultPeakRefreshRate() {
+        return mDefaultPeakRefreshRate;
     }
 
     /**
      * @return Default refresh rate of the associated display
      */
-    public int getDefaultLowRefreshRate() {
-        return mDefaultLowRefreshRate;
+    public int getDefaultRefreshRate() {
+        return mDefaultRefreshRate;
+    }
+
+    /**
+     * @return Default refresh rate in the higher blocking zone of the associated display
+     */
+    public int getDefaultHighBlockingZoneRefreshRate() {
+        return mDefaultHighBlockingZoneRefreshRate;
+    }
+
+    /**
+     * @return Default refresh rate in the lower blocking zone of the associated display
+     */
+    public int getDefaultLowBlockingZoneRefreshRate() {
+        return mDefaultLowBlockingZoneRefreshRate;
     }
 
     /**
@@ -1442,8 +1470,10 @@
                 + ", mDdcAutoBrightnessAvailable= " + mDdcAutoBrightnessAvailable
                 + ", mAutoBrightnessAvailable= " + mAutoBrightnessAvailable
                 + "\n"
-                + ", mDefaultRefreshRate= " + mDefaultLowRefreshRate
-                + ", mDefaultPeakRefreshRate= " + mDefaultHighRefreshRate
+                + ", mDefaultLowBlockingZoneRefreshRate= " + mDefaultLowBlockingZoneRefreshRate
+                + ", mDefaultHighBlockingZoneRefreshRate= " + mDefaultHighBlockingZoneRefreshRate
+                + ", mDefaultPeakRefreshRate= " + mDefaultPeakRefreshRate
+                + ", mDefaultRefreshRate= " + mDefaultRefreshRate
                 + ", mLowDisplayBrightnessThresholds= "
                 + Arrays.toString(mLowDisplayBrightnessThresholds)
                 + ", mLowAmbientBrightnessThresholds= "
@@ -1757,10 +1787,31 @@
         BlockingZoneConfig higherBlockingZoneConfig =
                 (refreshRateConfigs == null) ? null
                         : refreshRateConfigs.getHigherBlockingZoneConfigs();
+        loadPeakDefaultRefreshRate(refreshRateConfigs);
+        loadDefaultRefreshRate(refreshRateConfigs);
         loadLowerRefreshRateBlockingZones(lowerBlockingZoneConfig);
         loadHigherRefreshRateBlockingZones(higherBlockingZoneConfig);
     }
 
+    private void loadPeakDefaultRefreshRate(RefreshRateConfigs refreshRateConfigs) {
+        if (refreshRateConfigs == null || refreshRateConfigs.getDefaultPeakRefreshRate() == null) {
+            mDefaultPeakRefreshRate = mContext.getResources().getInteger(
+                R.integer.config_defaultPeakRefreshRate);
+        } else {
+            mDefaultPeakRefreshRate =
+                refreshRateConfigs.getDefaultPeakRefreshRate().intValue();
+        }
+    }
+
+    private void loadDefaultRefreshRate(RefreshRateConfigs refreshRateConfigs) {
+        if (refreshRateConfigs == null || refreshRateConfigs.getDefaultRefreshRate() == null) {
+            mDefaultRefreshRate = mContext.getResources().getInteger(
+                R.integer.config_defaultRefreshRate);
+        } else {
+            mDefaultRefreshRate =
+                refreshRateConfigs.getDefaultRefreshRate().intValue();
+        }
+    }
 
     /**
      * Loads the refresh rate configurations pertaining to the upper blocking zones.
@@ -1785,10 +1836,10 @@
     private void loadHigherBlockingZoneDefaultRefreshRate(
                 BlockingZoneConfig upperBlockingZoneConfig) {
         if (upperBlockingZoneConfig == null) {
-            mDefaultHighRefreshRate = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_defaultPeakRefreshRate);
+            mDefaultHighBlockingZoneRefreshRate = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_fixedRefreshRateInHighZone);
         } else {
-            mDefaultHighRefreshRate =
+            mDefaultHighBlockingZoneRefreshRate =
                 upperBlockingZoneConfig.getDefaultRefreshRate().intValue();
         }
     }
@@ -1800,10 +1851,10 @@
     private void loadLowerBlockingZoneDefaultRefreshRate(
                 BlockingZoneConfig lowerBlockingZoneConfig) {
         if (lowerBlockingZoneConfig == null) {
-            mDefaultLowRefreshRate = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_defaultRefreshRate);
+            mDefaultLowBlockingZoneRefreshRate = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_defaultRefreshRateInZone);
         } else {
-            mDefaultLowRefreshRate =
+            mDefaultLowBlockingZoneRefreshRate =
                 lowerBlockingZoneConfig.getDefaultRefreshRate().intValue();
         }
     }
@@ -2644,6 +2695,9 @@
         }
     }
 
+    /**
+     * Uniquely identifies a Sensor, with the combination of Type and Name.
+     */
     static class SensorData {
         public String type;
         public String name;
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 8f35924..5cfe65b 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -104,6 +104,7 @@
 import android.provider.Settings;
 import android.sysprop.DisplayProperties;
 import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.EventLog;
 import android.util.IntArray;
@@ -256,6 +257,13 @@
     final SparseArray<Pair<IVirtualDevice, DisplayWindowPolicyController>>
             mDisplayWindowPolicyControllers = new SparseArray<>();
 
+    /**
+     *  Map of every internal primary display device {@link HighBrightnessModeMetadata}s indexed by
+     *  {@link DisplayDevice#mUniqueId}.
+     */
+    public final ArrayMap<String, HighBrightnessModeMetadata> mHighBrightnessModeMetadataMap =
+            new ArrayMap<>();
+
     // List of all currently registered display adapters.
     private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
 
@@ -1570,7 +1578,16 @@
 
         DisplayPowerController dpc = mDisplayPowerControllers.get(displayId);
         if (dpc != null) {
-            dpc.onDisplayChanged();
+            final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
+            if (device == null) {
+                Slog.wtf(TAG, "Display Device is null in DisplayManagerService for display: "
+                        + display.getDisplayIdLocked());
+                return;
+            }
+
+            final String uniqueId = device.getUniqueId();
+            HighBrightnessModeMetadata hbmMetadata = mHighBrightnessModeMetadataMap.get(uniqueId);
+            dpc.onDisplayChanged(hbmMetadata);
         }
     }
 
@@ -1627,7 +1644,15 @@
         final int displayId = display.getDisplayIdLocked();
         final DisplayPowerController dpc = mDisplayPowerControllers.get(displayId);
         if (dpc != null) {
-            dpc.onDisplayChanged();
+            final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
+            if (device == null) {
+                Slog.wtf(TAG, "Display Device is null in DisplayManagerService for display: "
+                        + display.getDisplayIdLocked());
+                return;
+            }
+            final String uniqueId = device.getUniqueId();
+            HighBrightnessModeMetadata hbmMetadata = mHighBrightnessModeMetadataMap.get(uniqueId);
+            dpc.onDisplayChanged(hbmMetadata);
         }
     }
 
@@ -2611,6 +2636,31 @@
         mLogicalDisplayMapper.forEachLocked(this::addDisplayPowerControllerLocked);
     }
 
+    private HighBrightnessModeMetadata getHighBrightnessModeMetadata(LogicalDisplay display) {
+        final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
+        if (device == null) {
+            Slog.wtf(TAG, "Display Device is null in DisplayPowerController for display: "
+                    + display.getDisplayIdLocked());
+            return null;
+        }
+
+        // HBM brightness mode is only applicable to internal physical displays.
+        if (display.getDisplayInfoLocked().type != Display.TYPE_INTERNAL) {
+            return null;
+        }
+
+        final String uniqueId = device.getUniqueId();
+
+        if (mHighBrightnessModeMetadataMap.containsKey(uniqueId)) {
+            return mHighBrightnessModeMetadataMap.get(uniqueId);
+        }
+
+        // HBM Time info not present. Create a new one for this physical display.
+        HighBrightnessModeMetadata hbmInfo = new HighBrightnessModeMetadata();
+        mHighBrightnessModeMetadataMap.put(uniqueId, hbmInfo);
+        return hbmInfo;
+    }
+
     private void addDisplayPowerControllerLocked(LogicalDisplay display) {
         if (mPowerHandler == null) {
             // initPowerManagement has not yet been called.
@@ -2622,10 +2672,18 @@
 
         final BrightnessSetting brightnessSetting = new BrightnessSetting(mPersistentDataStore,
                 display, mSyncRoot);
+
+        // If display is internal and has a HighBrightnessModeMetadata mapping, use that.
+        // Or create a new one and use that.
+        // We also need to pass a mapping of the HighBrightnessModeTimeInfoMap to
+        // displayPowerController, so the hbm info can be correctly associated
+        // with the corresponding displaydevice.
+        HighBrightnessModeMetadata hbmMetadata = getHighBrightnessModeMetadata(display);
+
         final DisplayPowerController displayPowerController = new DisplayPowerController(
                 mContext, mDisplayPowerCallbacks, mPowerHandler, mSensorManager,
                 mDisplayBlanker, display, mBrightnessTracker, brightnessSetting,
-                () -> handleBrightnessChange(display));
+                () -> handleBrightnessChange(display), hbmMetadata);
         mDisplayPowerControllers.append(display.getDisplayIdLocked(), displayPowerController);
     }
 
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index 6331a5d..fdfc20a 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -50,7 +50,6 @@
 import android.provider.DeviceConfig;
 import android.provider.DeviceConfigInterface;
 import android.provider.Settings;
-import android.text.TextUtils;
 import android.util.IndentingPrintWriter;
 import android.util.Pair;
 import android.util.Slog;
@@ -68,6 +67,7 @@
 import com.android.server.LocalServices;
 import com.android.server.display.utils.AmbientFilter;
 import com.android.server.display.utils.AmbientFilterFactory;
+import com.android.server.display.utils.SensorUtils;
 import com.android.server.sensors.SensorManagerInternal;
 import com.android.server.sensors.SensorManagerInternal.ProximityActiveListener;
 import com.android.server.statusbar.StatusBarManagerInternal;
@@ -520,14 +520,20 @@
     }
 
     /**
-     * A utility to make this class aware of the new display configs whenever the default display is
-     * changed
+     * Called when the underlying display device of the default display is changed.
+     * Some data in this class relates to the physical display of the device, and so we need to
+     * reload the configurations based on this.
+     * E.g. the brightness sensors and refresh rate capabilities depend on the physical display
+     * device that is being used, so will be reloaded.
+     *
+     * @param displayDeviceConfig configurations relating to the underlying display device.
      */
     public void defaultDisplayDeviceUpdated(DisplayDeviceConfig displayDeviceConfig) {
         mSettingsObserver.setRefreshRates(displayDeviceConfig,
             /* attemptLoadingFromDeviceConfig= */ true);
         mBrightnessObserver.updateBlockingZoneThresholds(displayDeviceConfig,
             /* attemptLoadingFromDeviceConfig= */ true);
+        mBrightnessObserver.reloadLightSensor(displayDeviceConfig);
     }
 
     /**
@@ -1163,7 +1169,7 @@
             mDefaultRefreshRate =
                     (displayDeviceConfig == null) ? (float) mContext.getResources().getInteger(
                         R.integer.config_defaultRefreshRate)
-                        : (float) displayDeviceConfig.getDefaultLowRefreshRate();
+                        : (float) displayDeviceConfig.getDefaultRefreshRate();
         }
 
         public void observe() {
@@ -1250,7 +1256,7 @@
                 defaultPeakRefreshRate =
                         (displayDeviceConfig == null) ? (float) mContext.getResources().getInteger(
                                 R.integer.config_defaultPeakRefreshRate)
-                                : (float) displayDeviceConfig.getDefaultHighRefreshRate();
+                                : (float) displayDeviceConfig.getDefaultPeakRefreshRate();
             }
             mDefaultPeakRefreshRate = defaultPeakRefreshRate;
         }
@@ -1541,6 +1547,9 @@
 
         private SensorManager mSensorManager;
         private Sensor mLightSensor;
+        private Sensor mRegisteredLightSensor;
+        private String mLightSensorType;
+        private String mLightSensorName;
         private final LightSensorEventListener mLightSensorListener =
                 new LightSensorEventListener();
         // Take it as low brightness before valid sensor data comes
@@ -1603,8 +1612,26 @@
             return mHighAmbientBrightnessThresholds;
         }
 
+        /**
+         * @return the refresh rate to lock to when in a high brightness zone
+         */
+        @VisibleForTesting
+        int getRefreshRateInHighZone() {
+            return mRefreshRateInHighZone;
+        }
+
+        /**
+         * @return the refresh rate to lock to when in a low brightness zone
+         */
+        @VisibleForTesting
+        int getRefreshRateInLowZone() {
+            return mRefreshRateInLowZone;
+        }
+
         private void loadLowBrightnessThresholds(DisplayDeviceConfig displayDeviceConfig,
                 boolean attemptLoadingFromDeviceConfig) {
+            loadRefreshRateInHighZone(displayDeviceConfig, attemptLoadingFromDeviceConfig);
+            loadRefreshRateInLowZone(displayDeviceConfig, attemptLoadingFromDeviceConfig);
             mLowDisplayBrightnessThresholds = loadBrightnessThresholds(
                     () -> mDeviceConfigDisplaySettings.getLowDisplayBrightnessThresholds(),
                     () -> displayDeviceConfig.getLowDisplayBrightnessThresholds(),
@@ -1625,6 +1652,44 @@
             }
         }
 
+        private void loadRefreshRateInLowZone(DisplayDeviceConfig displayDeviceConfig,
+                boolean attemptLoadingFromDeviceConfig) {
+            int refreshRateInLowZone =
+                    (displayDeviceConfig == null) ? mContext.getResources().getInteger(
+                        R.integer.config_defaultRefreshRateInZone)
+                        : displayDeviceConfig.getDefaultLowBlockingZoneRefreshRate();
+            if (attemptLoadingFromDeviceConfig) {
+                try {
+                    refreshRateInLowZone = mDeviceConfig.getInt(
+                        DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
+                        DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_LOW_ZONE,
+                        refreshRateInLowZone);
+                } catch (Exception exception) {
+                    // Do nothing
+                }
+            }
+            mRefreshRateInLowZone = refreshRateInLowZone;
+        }
+
+        private void loadRefreshRateInHighZone(DisplayDeviceConfig displayDeviceConfig,
+                boolean attemptLoadingFromDeviceConfig) {
+            int refreshRateInHighZone =
+                    (displayDeviceConfig == null) ? mContext.getResources().getInteger(
+                        R.integer.config_fixedRefreshRateInHighZone) : displayDeviceConfig
+                        .getDefaultHighBlockingZoneRefreshRate();
+            if (attemptLoadingFromDeviceConfig) {
+                try {
+                    refreshRateInHighZone = mDeviceConfig.getInt(
+                        DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
+                        DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HIGH_ZONE,
+                        refreshRateInHighZone);
+                } catch (Exception exception) {
+                    // Do nothing
+                }
+            }
+            mRefreshRateInHighZone = refreshRateInHighZone;
+        }
+
         private void loadHighBrightnessThresholds(DisplayDeviceConfig displayDeviceConfig,
                 boolean attemptLoadingFromDeviceConfig) {
             mHighDisplayBrightnessThresholds = loadBrightnessThresholds(
@@ -1678,14 +1743,6 @@
         }
 
         /**
-         * @return the refresh to lock to when in a low brightness zone
-         */
-        @VisibleForTesting
-        int getRefreshRateInLowZone() {
-            return mRefreshRateInLowZone;
-        }
-
-        /**
          * @return the display brightness thresholds for the low brightness zones
          */
         @VisibleForTesting
@@ -1701,17 +1758,8 @@
             return mLowAmbientBrightnessThresholds;
         }
 
-        public void registerLightSensor(SensorManager sensorManager, Sensor lightSensor) {
-            mSensorManager = sensorManager;
-            mLightSensor = lightSensor;
-
-            mSensorManager.registerListener(mLightSensorListener,
-                    mLightSensor, LIGHT_SENSOR_RATE_MS * 1000, mHandler);
-        }
-
         public void observe(SensorManager sensorManager) {
             mSensorManager = sensorManager;
-            final ContentResolver cr = mContext.getContentResolver();
             mBrightness = getBrightness(Display.DEFAULT_DISPLAY);
 
             // DeviceConfig is accessible after system ready.
@@ -1739,8 +1787,17 @@
                 mHighAmbientBrightnessThresholds = highAmbientBrightnessThresholds;
             }
 
-            mRefreshRateInLowZone = mDeviceConfigDisplaySettings.getRefreshRateInLowZone();
-            mRefreshRateInHighZone = mDeviceConfigDisplaySettings.getRefreshRateInHighZone();
+            final int refreshRateInLowZone = mDeviceConfigDisplaySettings
+                    .getRefreshRateInLowZone();
+            if (refreshRateInLowZone != -1) {
+                mRefreshRateInLowZone = refreshRateInLowZone;
+            }
+
+            final int refreshRateInHighZone = mDeviceConfigDisplaySettings
+                    .getRefreshRateInHighZone();
+            if (refreshRateInHighZone != -1) {
+                mRefreshRateInHighZone = refreshRateInHighZone;
+            }
 
             restartObserver();
             mDeviceConfigDisplaySettings.startListening();
@@ -1794,6 +1851,10 @@
             restartObserver();
         }
 
+        /**
+         * Used to reload the lower blocking zone refresh rate in case of changes in the
+         * DeviceConfig properties.
+         */
         public void onDeviceConfigRefreshRateInLowZoneChanged(int refreshRate) {
             if (refreshRate != mRefreshRateInLowZone) {
                 mRefreshRateInLowZone = refreshRate;
@@ -1817,6 +1878,10 @@
             restartObserver();
         }
 
+        /**
+         * Used to reload the higher blocking zone refresh rate in case of changes in the
+         * DeviceConfig properties.
+         */
         public void onDeviceConfigRefreshRateInHighZoneChanged(int refreshRate) {
             if (refreshRate != mRefreshRateInHighZone) {
                 mRefreshRateInHighZone = refreshRate;
@@ -1855,6 +1920,10 @@
                 pw.println("    mAmbientHighBrightnessThresholds: " + d);
             }
 
+            pw.println("    mLightSensor: " + mLightSensor);
+            pw.println("    mRegisteredLightSensor: " + mRegisteredLightSensor);
+            pw.println("    mLightSensorName: " + mLightSensorName);
+            pw.println("    mLightSensorType: " + mLightSensorType);
             mLightSensorListener.dumpLocked(pw);
 
             if (mAmbientFilter != null) {
@@ -1908,27 +1977,9 @@
             }
 
             if (mShouldObserveAmbientLowChange || mShouldObserveAmbientHighChange) {
-                Resources resources = mContext.getResources();
-                String lightSensorType = resources.getString(
-                        com.android.internal.R.string.config_displayLightSensorType);
+                Sensor lightSensor = getLightSensor();
 
-                Sensor lightSensor = null;
-                if (!TextUtils.isEmpty(lightSensorType)) {
-                    List<Sensor> sensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);
-                    for (int i = 0; i < sensors.size(); i++) {
-                        Sensor sensor = sensors.get(i);
-                        if (lightSensorType.equals(sensor.getStringType())) {
-                            lightSensor = sensor;
-                            break;
-                        }
-                    }
-                }
-
-                if (lightSensor == null) {
-                    lightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
-                }
-
-                if (lightSensor != null) {
+                if (lightSensor != null && lightSensor != mLightSensor) {
                     final Resources res = mContext.getResources();
 
                     mAmbientFilter = AmbientFilterFactory.createBrightnessFilter(TAG, res);
@@ -1938,15 +1989,40 @@
                 mAmbientFilter = null;
                 mLightSensor = null;
             }
-
+            updateSensorStatus();
             if (mRefreshRateChangeable) {
-                updateSensorStatus();
                 synchronized (mLock) {
                     onBrightnessChangedLocked();
                 }
             }
         }
 
+        private void reloadLightSensor(DisplayDeviceConfig displayDeviceConfig) {
+            reloadLightSensorData(displayDeviceConfig);
+            restartObserver();
+        }
+
+        private void reloadLightSensorData(DisplayDeviceConfig displayDeviceConfig) {
+            // The displayDeviceConfig (ddc) contains display specific preferences. When loaded,
+            // it naturally falls back to the global config.xml.
+            if (displayDeviceConfig != null
+                    && displayDeviceConfig.getAmbientLightSensor() != null) {
+                // This covers both the ddc and the config.xml fallback
+                mLightSensorType = displayDeviceConfig.getAmbientLightSensor().type;
+                mLightSensorName = displayDeviceConfig.getAmbientLightSensor().name;
+            } else if (mLightSensorName == null && mLightSensorType == null) {
+                Resources resources = mContext.getResources();
+                mLightSensorType = resources.getString(
+                        com.android.internal.R.string.config_displayLightSensorType);
+                mLightSensorName = "";
+            }
+        }
+
+        private Sensor getLightSensor() {
+            return SensorUtils.findSensor(mSensorManager, mLightSensorType,
+                    mLightSensorName, Sensor.TYPE_LIGHT);
+        }
+
         /**
          * Checks to see if at least one value is positive, in which case it is necessary to listen
          * to value changes.
@@ -2088,17 +2164,36 @@
 
             if ((mShouldObserveAmbientLowChange || mShouldObserveAmbientHighChange)
                      && isDeviceActive() && !mLowPowerModeEnabled && mRefreshRateChangeable) {
-                mSensorManager.registerListener(mLightSensorListener,
-                        mLightSensor, LIGHT_SENSOR_RATE_MS * 1000, mHandler);
-                if (mLoggingEnabled) {
-                    Slog.d(TAG, "updateSensorStatus: registerListener");
-                }
+                registerLightSensor();
+
             } else {
-                mLightSensorListener.removeCallbacks();
-                mSensorManager.unregisterListener(mLightSensorListener);
-                if (mLoggingEnabled) {
-                    Slog.d(TAG, "updateSensorStatus: unregisterListener");
-                }
+                unregisterSensorListener();
+            }
+        }
+
+        private void registerLightSensor() {
+            if (mRegisteredLightSensor == mLightSensor) {
+                return;
+            }
+
+            if (mRegisteredLightSensor != null) {
+                unregisterSensorListener();
+            }
+
+            mSensorManager.registerListener(mLightSensorListener,
+                    mLightSensor, LIGHT_SENSOR_RATE_MS * 1000, mHandler);
+            mRegisteredLightSensor = mLightSensor;
+            if (mLoggingEnabled) {
+                Slog.d(TAG, "updateSensorStatus: registerListener");
+            }
+        }
+
+        private void unregisterSensorListener() {
+            mLightSensorListener.removeCallbacks();
+            mSensorManager.unregisterListener(mLightSensorListener);
+            mRegisteredLightSensor = null;
+            if (mLoggingEnabled) {
+                Slog.d(TAG, "updateSensorStatus: unregisterListener");
             }
         }
 
@@ -2634,15 +2729,10 @@
         }
 
         public int getRefreshRateInLowZone() {
-            int defaultRefreshRateInZone = mContext.getResources().getInteger(
-                    R.integer.config_defaultRefreshRateInZone);
-
-            int refreshRate = mDeviceConfig.getInt(
+            return mDeviceConfig.getInt(
                     DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
-                    DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_LOW_ZONE,
-                    defaultRefreshRateInZone);
+                    DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_LOW_ZONE, -1);
 
-            return refreshRate;
         }
 
         /*
@@ -2664,15 +2754,10 @@
         }
 
         public int getRefreshRateInHighZone() {
-            int defaultRefreshRateInZone = mContext.getResources().getInteger(
-                    R.integer.config_fixedRefreshRateInHighZone);
-
-            int refreshRate = mDeviceConfig.getInt(
+            return mDeviceConfig.getInt(
                     DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
                     DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HIGH_ZONE,
-                    defaultRefreshRateInZone);
-
-            return refreshRate;
+                    -1);
         }
 
         public int getRefreshRateInHbmSunlight() {
@@ -2720,23 +2805,29 @@
 
             int[] lowDisplayBrightnessThresholds = getLowDisplayBrightnessThresholds();
             int[] lowAmbientBrightnessThresholds = getLowAmbientBrightnessThresholds();
-            int refreshRateInLowZone = getRefreshRateInLowZone();
+            final int refreshRateInLowZone = getRefreshRateInLowZone();
 
             mHandler.obtainMessage(MSG_LOW_BRIGHTNESS_THRESHOLDS_CHANGED,
                     new Pair<>(lowDisplayBrightnessThresholds, lowAmbientBrightnessThresholds))
                     .sendToTarget();
-            mHandler.obtainMessage(MSG_REFRESH_RATE_IN_LOW_ZONE_CHANGED, refreshRateInLowZone, 0)
+
+            if (refreshRateInLowZone != -1) {
+                mHandler.obtainMessage(MSG_REFRESH_RATE_IN_LOW_ZONE_CHANGED, refreshRateInLowZone)
                     .sendToTarget();
+            }
 
             int[] highDisplayBrightnessThresholds = getHighDisplayBrightnessThresholds();
             int[] highAmbientBrightnessThresholds = getHighAmbientBrightnessThresholds();
-            int refreshRateInHighZone = getRefreshRateInHighZone();
+            final int refreshRateInHighZone = getRefreshRateInHighZone();
 
             mHandler.obtainMessage(MSG_HIGH_BRIGHTNESS_THRESHOLDS_CHANGED,
                     new Pair<>(highDisplayBrightnessThresholds, highAmbientBrightnessThresholds))
                     .sendToTarget();
-            mHandler.obtainMessage(MSG_REFRESH_RATE_IN_HIGH_ZONE_CHANGED, refreshRateInHighZone, 0)
+
+            if (refreshRateInHighZone != -1) {
+                mHandler.obtainMessage(MSG_REFRESH_RATE_IN_HIGH_ZONE_CHANGED, refreshRateInHighZone)
                     .sendToTarget();
+            }
 
             final int refreshRateInHbmSunlight = getRefreshRateInHbmSunlight();
             mHandler.obtainMessage(MSG_REFRESH_RATE_IN_HBM_SUNLIGHT_CHANGED,
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index d791c06..b431306 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -391,6 +391,7 @@
     private float[] mNitsRange;
 
     private final HighBrightnessModeController mHbmController;
+    private final HighBrightnessModeMetadata mHighBrightnessModeMetadata;
 
     private final BrightnessThrottler mBrightnessThrottler;
 
@@ -511,7 +512,7 @@
             DisplayPowerCallbacks callbacks, Handler handler,
             SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay,
             BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting,
-            Runnable onBrightnessChangeRunnable) {
+            Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata) {
         mLogicalDisplay = logicalDisplay;
         mDisplayId = mLogicalDisplay.getDisplayIdLocked();
         final String displayIdStr = "[" + mDisplayId + "]";
@@ -521,6 +522,7 @@
         mSuspendBlockerIdProxPositive = displayIdStr + "prox positive";
         mSuspendBlockerIdProxNegative = displayIdStr + "prox negative";
         mSuspendBlockerIdProxDebounce = displayIdStr + "prox debounce";
+        mHighBrightnessModeMetadata = hbmMetadata;
 
         mDisplayDevice = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
         mUniqueDisplayId = logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId();
@@ -793,7 +795,7 @@
      * of each display need to be properly reflected in AutomaticBrightnessController.
      */
     @GuardedBy("DisplayManagerService.mSyncRoot")
-    public void onDisplayChanged() {
+    public void onDisplayChanged(HighBrightnessModeMetadata hbmMetadata) {
         final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
         if (device == null) {
             Slog.wtf(TAG, "Display Device is null in DisplayPowerController for display: "
@@ -815,9 +817,9 @@
                 mUniqueDisplayId = uniqueId;
                 mDisplayStatsId = mUniqueDisplayId.hashCode();
                 mDisplayDeviceConfig = config;
-                loadFromDisplayDeviceConfig(token, info);
+                loadFromDisplayDeviceConfig(token, info, hbmMetadata);
 
-                // Since the underlying display-device changed, we really don't know the
+                /// Since the underlying display-device changed, we really don't know the
                 // last command that was sent to change it's state. Lets assume it is unknown so
                 // that we trigger a change immediately.
                 mPowerState.resetScreenState();
@@ -860,6 +862,10 @@
                 mAutomaticBrightnessController.stop();
             }
 
+            if (mScreenOffBrightnessSensorController != null) {
+                mScreenOffBrightnessSensorController.stop();
+            }
+
             if (mBrightnessSetting != null) {
                 mBrightnessSetting.unregisterListener(mBrightnessSettingListener);
             }
@@ -868,7 +874,8 @@
         }
     }
 
-    private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info) {
+    private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info,
+                                             HighBrightnessModeMetadata hbmMetadata) {
         // All properties that depend on the associated DisplayDevice and the DDC must be
         // updated here.
         loadBrightnessRampRates();
@@ -881,6 +888,7 @@
                     mBrightnessRampIncreaseMaxTimeMillis,
                     mBrightnessRampDecreaseMaxTimeMillis);
         }
+        mHbmController.setHighBrightnessModeMetadata(hbmMetadata);
         mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId,
                 mDisplayDeviceConfig.getHighBrightnessModeData(),
                 new HighBrightnessModeController.HdrBrightnessDeviceConfig() {
@@ -1104,6 +1112,9 @@
             mBrightnessEventRingBuffer =
                     new RingBuffer<>(BrightnessEvent.class, RINGBUFFER_MAX);
 
+            if (mScreenOffBrightnessSensorController != null) {
+                mScreenOffBrightnessSensorController.stop();
+            }
             loadScreenOffBrightnessSensor();
             int[] sensorValueToLux = mDisplayDeviceConfig.getScreenOffBrightnessSensorValueToLux();
             if (mScreenOffBrightnessSensor != null && sensorValueToLux != null) {
@@ -1958,7 +1969,7 @@
                     if (mAutomaticBrightnessController != null) {
                         mAutomaticBrightnessController.update();
                     }
-                }, mContext);
+                }, mHighBrightnessModeMetadata, mContext);
     }
 
     private BrightnessThrottler createBrightnessThrottlerLocked() {
@@ -2746,6 +2757,10 @@
             dumpBrightnessEvents(pw);
         }
 
+        if (mScreenOffBrightnessSensorController != null) {
+            mScreenOffBrightnessSensorController.dump(pw);
+        }
+
         if (mHbmController != null) {
             mHbmController.dump(pw);
         }
diff --git a/services/core/java/com/android/server/display/DisplayPowerState.java b/services/core/java/com/android/server/display/DisplayPowerState.java
index f650b11..2c257a1 100644
--- a/services/core/java/com/android/server/display/DisplayPowerState.java
+++ b/services/core/java/com/android/server/display/DisplayPowerState.java
@@ -506,6 +506,8 @@
                     boolean valid = state != Display.STATE_UNKNOWN && !Float.isNaN(brightnessState);
                     boolean changed = stateChanged || backlightChanged;
                     if (!valid || !changed) {
+                        mStateChangeInProgress = false;
+                        mBacklightChangeInProgress = false;
                         try {
                             mLock.wait();
                         } catch (InterruptedException ex) {
diff --git a/services/core/java/com/android/server/display/HbmEvent.java b/services/core/java/com/android/server/display/HbmEvent.java
new file mode 100644
index 0000000..5675e2f
--- /dev/null
+++ b/services/core/java/com/android/server/display/HbmEvent.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display;
+
+
+/**
+ * Represents an event in which High Brightness Mode was enabled.
+ */
+class HbmEvent {
+    private long mStartTimeMillis;
+    private long mEndTimeMillis;
+
+    HbmEvent(long startTimeMillis, long endTimeMillis) {
+        this.mStartTimeMillis = startTimeMillis;
+        this.mEndTimeMillis = endTimeMillis;
+    }
+
+    public long getStartTimeMillis() {
+        return mStartTimeMillis;
+    }
+
+    public long getEndTimeMillis() {
+        return mEndTimeMillis;
+    }
+
+    @Override
+    public String toString() {
+        return "HbmEvent: {startTimeMillis:" + mStartTimeMillis + ", endTimeMillis: "
+                + mEndTimeMillis + "}, total: "
+                + ((mEndTimeMillis - mStartTimeMillis) / 1000) + "]";
+    }
+}
diff --git a/services/core/java/com/android/server/display/HighBrightnessModeController.java b/services/core/java/com/android/server/display/HighBrightnessModeController.java
index 0b9d4de..ac32d53 100644
--- a/services/core/java/com/android/server/display/HighBrightnessModeController.java
+++ b/services/core/java/com/android/server/display/HighBrightnessModeController.java
@@ -42,8 +42,8 @@
 import com.android.server.display.DisplayManagerService.Clock;
 
 import java.io.PrintWriter;
+import java.util.ArrayDeque;
 import java.util.Iterator;
-import java.util.LinkedList;
 
 /**
  * Controls the status of high-brightness mode for devices that support it. This class assumes that
@@ -105,30 +105,24 @@
     private int mHbmStatsState = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_OFF;
 
     /**
-     * If HBM is currently running, this is the start time for the current HBM session.
+     * If HBM is currently running, this is the start time and set of all events,
+     * for the current HBM session.
      */
-    private long mRunningStartTimeMillis = -1;
-
-    /**
-     * List of previous HBM-events ordered from most recent to least recent.
-     * Meant to store only the events that fall into the most recent
-     * {@link mHbmData.timeWindowMillis}.
-     */
-    private LinkedList<HbmEvent> mEvents = new LinkedList<>();
+    private HighBrightnessModeMetadata mHighBrightnessModeMetadata = null;
 
     HighBrightnessModeController(Handler handler, int width, int height, IBinder displayToken,
             String displayUniqueId, float brightnessMin, float brightnessMax,
             HighBrightnessModeData hbmData, HdrBrightnessDeviceConfig hdrBrightnessCfg,
-            Runnable hbmChangeCallback, Context context) {
+            Runnable hbmChangeCallback, HighBrightnessModeMetadata hbmMetadata, Context context) {
         this(new Injector(), handler, width, height, displayToken, displayUniqueId, brightnessMin,
-            brightnessMax, hbmData, hdrBrightnessCfg, hbmChangeCallback, context);
+            brightnessMax, hbmData, hdrBrightnessCfg, hbmChangeCallback, hbmMetadata, context);
     }
 
     @VisibleForTesting
     HighBrightnessModeController(Injector injector, Handler handler, int width, int height,
             IBinder displayToken, String displayUniqueId, float brightnessMin, float brightnessMax,
             HighBrightnessModeData hbmData, HdrBrightnessDeviceConfig hdrBrightnessCfg,
-            Runnable hbmChangeCallback, Context context) {
+            Runnable hbmChangeCallback, HighBrightnessModeMetadata hbmMetadata, Context context) {
         mInjector = injector;
         mContext = context;
         mClock = injector.getClock();
@@ -137,6 +131,7 @@
         mBrightnessMin = brightnessMin;
         mBrightnessMax = brightnessMax;
         mHbmChangeCallback = hbmChangeCallback;
+        mHighBrightnessModeMetadata = hbmMetadata;
         mSkinThermalStatusObserver = new SkinThermalStatusObserver(mInjector, mHandler);
         mSettingsObserver = new SettingsObserver(mHandler);
         mRecalcRunnable = this::recalculateTimeAllowance;
@@ -222,19 +217,22 @@
 
         // If we are starting or ending a high brightness mode session, store the current
         // session in mRunningStartTimeMillis, or the old one in mEvents.
-        final boolean wasHbmDrainingAvailableTime = mRunningStartTimeMillis != -1;
+        final long runningStartTime = mHighBrightnessModeMetadata.getRunningStartTimeMillis();
+        final boolean wasHbmDrainingAvailableTime = runningStartTime != -1;
         final boolean shouldHbmDrainAvailableTime = mBrightness > mHbmData.transitionPoint
                 && !mIsHdrLayerPresent;
         if (wasHbmDrainingAvailableTime != shouldHbmDrainAvailableTime) {
             final long currentTime = mClock.uptimeMillis();
             if (shouldHbmDrainAvailableTime) {
-                mRunningStartTimeMillis = currentTime;
+                mHighBrightnessModeMetadata.setRunningStartTimeMillis(currentTime);
             } else {
-                mEvents.addFirst(new HbmEvent(mRunningStartTimeMillis, currentTime));
-                mRunningStartTimeMillis = -1;
+                final HbmEvent hbmEvent = new HbmEvent(runningStartTime, currentTime);
+                mHighBrightnessModeMetadata.addHbmEvent(hbmEvent);
+                mHighBrightnessModeMetadata.setRunningStartTimeMillis(-1);
 
                 if (DEBUG) {
-                    Slog.d(TAG, "New HBM event: " + mEvents.getFirst());
+                    Slog.d(TAG, "New HBM event: "
+                            + mHighBrightnessModeMetadata.getHbmEventQueue().peekFirst());
                 }
             }
         }
@@ -260,6 +258,10 @@
         mSettingsObserver.stopObserving();
     }
 
+    void setHighBrightnessModeMetadata(HighBrightnessModeMetadata hbmInfo) {
+        mHighBrightnessModeMetadata = hbmInfo;
+    }
+
     void resetHbmData(int width, int height, IBinder displayToken, String displayUniqueId,
             HighBrightnessModeData hbmData, HdrBrightnessDeviceConfig hdrBrightnessCfg) {
         mWidth = width;
@@ -316,20 +318,22 @@
         pw.println("  mBrightnessMax=" + mBrightnessMax);
         pw.println("  remainingTime=" + calculateRemainingTime(mClock.uptimeMillis()));
         pw.println("  mIsTimeAvailable= " + mIsTimeAvailable);
-        pw.println("  mRunningStartTimeMillis=" + TimeUtils.formatUptime(mRunningStartTimeMillis));
+        pw.println("  mRunningStartTimeMillis="
+                + TimeUtils.formatUptime(mHighBrightnessModeMetadata.getRunningStartTimeMillis()));
         pw.println("  mIsThermalStatusWithinLimit=" + mIsThermalStatusWithinLimit);
         pw.println("  mIsBlockedByLowPowerMode=" + mIsBlockedByLowPowerMode);
         pw.println("  width*height=" + mWidth + "*" + mHeight);
         pw.println("  mEvents=");
         final long currentTime = mClock.uptimeMillis();
         long lastStartTime = currentTime;
-        if (mRunningStartTimeMillis != -1) {
-            lastStartTime = dumpHbmEvent(pw, new HbmEvent(mRunningStartTimeMillis, currentTime));
+        long runningStartTimeMillis = mHighBrightnessModeMetadata.getRunningStartTimeMillis();
+        if (runningStartTimeMillis != -1) {
+            lastStartTime = dumpHbmEvent(pw, new HbmEvent(runningStartTimeMillis, currentTime));
         }
-        for (HbmEvent event : mEvents) {
-            if (lastStartTime > event.endTimeMillis) {
+        for (HbmEvent event : mHighBrightnessModeMetadata.getHbmEventQueue()) {
+            if (lastStartTime > event.getEndTimeMillis()) {
                 pw.println("    event: [normal brightness]: "
-                        + TimeUtils.formatDuration(lastStartTime - event.endTimeMillis));
+                        + TimeUtils.formatDuration(lastStartTime - event.getEndTimeMillis()));
             }
             lastStartTime = dumpHbmEvent(pw, event);
         }
@@ -338,12 +342,12 @@
     }
 
     private long dumpHbmEvent(PrintWriter pw, HbmEvent event) {
-        final long duration = event.endTimeMillis - event.startTimeMillis;
+        final long duration = event.getEndTimeMillis() - event.getStartTimeMillis();
         pw.println("    event: ["
-                + TimeUtils.formatUptime(event.startTimeMillis) + ", "
-                + TimeUtils.formatUptime(event.endTimeMillis) + "] ("
+                + TimeUtils.formatUptime(event.getStartTimeMillis()) + ", "
+                + TimeUtils.formatUptime(event.getEndTimeMillis()) + "] ("
                 + TimeUtils.formatDuration(duration) + ")");
-        return event.startTimeMillis;
+        return event.getStartTimeMillis();
     }
 
     private boolean isCurrentlyAllowed() {
@@ -372,13 +376,15 @@
 
         // First, lets see how much time we've taken for any currently running
         // session of HBM.
-        if (mRunningStartTimeMillis > 0) {
-            if (mRunningStartTimeMillis > currentTime) {
+        long runningStartTimeMillis = mHighBrightnessModeMetadata.getRunningStartTimeMillis();
+        if (runningStartTimeMillis > 0) {
+            if (runningStartTimeMillis > currentTime) {
                 Slog.e(TAG, "Start time set to the future. curr: " + currentTime
-                        + ", start: " + mRunningStartTimeMillis);
-                mRunningStartTimeMillis = currentTime;
+                        + ", start: " + runningStartTimeMillis);
+                mHighBrightnessModeMetadata.setRunningStartTimeMillis(currentTime);
+                runningStartTimeMillis = currentTime;
             }
-            timeAlreadyUsed = currentTime - mRunningStartTimeMillis;
+            timeAlreadyUsed = currentTime - runningStartTimeMillis;
         }
 
         if (DEBUG) {
@@ -387,18 +393,19 @@
 
         // Next, lets iterate through the history of previous sessions and add those times.
         final long windowstartTimeMillis = currentTime - mHbmData.timeWindowMillis;
-        Iterator<HbmEvent> it = mEvents.iterator();
+        Iterator<HbmEvent> it = mHighBrightnessModeMetadata.getHbmEventQueue().iterator();
         while (it.hasNext()) {
             final HbmEvent event = it.next();
 
             // If this event ended before the current Timing window, discard forever and ever.
-            if (event.endTimeMillis < windowstartTimeMillis) {
+            if (event.getEndTimeMillis() < windowstartTimeMillis) {
                 it.remove();
                 continue;
             }
 
-            final long startTimeMillis = Math.max(event.startTimeMillis, windowstartTimeMillis);
-            timeAlreadyUsed += event.endTimeMillis - startTimeMillis;
+            final long startTimeMillis = Math.max(event.getStartTimeMillis(),
+                            windowstartTimeMillis);
+            timeAlreadyUsed += event.getEndTimeMillis() - startTimeMillis;
         }
 
         if (DEBUG) {
@@ -425,17 +432,18 @@
         // Calculate the time at which we want to recalculate mIsTimeAvailable in case a lux or
         // brightness change doesn't happen before then.
         long nextTimeout = -1;
+        final ArrayDeque<HbmEvent> hbmEvents = mHighBrightnessModeMetadata.getHbmEventQueue();
         if (mBrightness > mHbmData.transitionPoint) {
             // if we're in high-lux now, timeout when we run out of allowed time.
             nextTimeout = currentTime + remainingTime;
-        } else if (!mIsTimeAvailable && mEvents.size() > 0) {
+        } else if (!mIsTimeAvailable && hbmEvents.size() > 0) {
             // If we are not allowed...timeout when the oldest event moved outside of the timing
             // window by at least minTime. Basically, we're calculating the soonest time we can
             // get {@code timeMinMillis} back to us.
             final long windowstartTimeMillis = currentTime - mHbmData.timeWindowMillis;
-            final HbmEvent lastEvent = mEvents.getLast();
+            final HbmEvent lastEvent = hbmEvents.peekLast();
             final long startTimePlusMinMillis =
-                    Math.max(windowstartTimeMillis, lastEvent.startTimeMillis)
+                    Math.max(windowstartTimeMillis, lastEvent.getStartTimeMillis())
                     + mHbmData.timeMinMillis;
             final long timeWhenMinIsGainedBack =
                     currentTime + (startTimePlusMinMillis - windowstartTimeMillis) - remainingTime;
@@ -459,9 +467,10 @@
                     + ", mUnthrottledBrightness: " + mUnthrottledBrightness
                     + ", mThrottlingReason: "
                         + BrightnessInfo.briMaxReasonToString(mThrottlingReason)
-                    + ", RunningStartTimeMillis: " + mRunningStartTimeMillis
+                    + ", RunningStartTimeMillis: "
+                        + mHighBrightnessModeMetadata.getRunningStartTimeMillis()
                     + ", nextTimeout: " + (nextTimeout != -1 ? (nextTimeout - currentTime) : -1)
-                    + ", events: " + mEvents);
+                    + ", events: " + hbmEvents);
         }
 
         if (nextTimeout != -1) {
@@ -588,25 +597,6 @@
         }
     }
 
-    /**
-     * Represents an event in which High Brightness Mode was enabled.
-     */
-    private static class HbmEvent {
-        public long startTimeMillis;
-        public long endTimeMillis;
-
-        HbmEvent(long startTimeMillis, long endTimeMillis) {
-            this.startTimeMillis = startTimeMillis;
-            this.endTimeMillis = endTimeMillis;
-        }
-
-        @Override
-        public String toString() {
-            return "[Event: {" + startTimeMillis + ", " + endTimeMillis + "}, total: "
-                    + ((endTimeMillis - startTimeMillis) / 1000) + "]";
-        }
-    }
-
     @VisibleForTesting
     class HdrListener extends SurfaceControlHdrLayerInfoListener {
         @Override
diff --git a/services/core/java/com/android/server/display/HighBrightnessModeMetadata.java b/services/core/java/com/android/server/display/HighBrightnessModeMetadata.java
new file mode 100644
index 0000000..37234ff
--- /dev/null
+++ b/services/core/java/com/android/server/display/HighBrightnessModeMetadata.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display;
+
+import java.util.ArrayDeque;
+
+
+/**
+ * Represents High Brightness Mode metadata associated
+ * with a specific internal physical display.
+ * Required for separately storing data like time information,
+ * and related events when display was in HBM mode per
+ * physical internal display.
+ */
+class HighBrightnessModeMetadata {
+    /**
+     * Queue of previous HBM-events ordered from most recent to least recent.
+     * Meant to store only the events that fall into the most recent
+     * {@link HighBrightnessModeData#timeWindowMillis mHbmData.timeWindowMillis}.
+     */
+    private final ArrayDeque<HbmEvent> mEvents = new ArrayDeque<>();
+
+    /**
+     * If HBM is currently running, this is the start time for the current HBM session.
+     */
+    private long mRunningStartTimeMillis = -1;
+
+    public long getRunningStartTimeMillis() {
+        return mRunningStartTimeMillis;
+    }
+
+    public void setRunningStartTimeMillis(long setTime) {
+        mRunningStartTimeMillis = setTime;
+    }
+
+    public ArrayDeque<HbmEvent> getHbmEventQueue() {
+        return mEvents;
+    }
+
+    public void addHbmEvent(HbmEvent hbmEvent) {
+        mEvents.addFirst(hbmEvent);
+    }
+}
+
diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
index bf576b8..1f7232a 100644
--- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java
+++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
@@ -159,6 +159,7 @@
     private Layout mCurrentLayout = null;
     private int mDeviceState = DeviceStateManager.INVALID_DEVICE_STATE;
     private int mPendingDeviceState = DeviceStateManager.INVALID_DEVICE_STATE;
+    private int mDeviceStateToBeAppliedAfterBoot = DeviceStateManager.INVALID_DEVICE_STATE;
     private boolean mBootCompleted = false;
     private boolean mInteractive;
 
@@ -353,6 +354,12 @@
         ipw.println("mDeviceStatesOnWhichToWakeUp=" + mDeviceStatesOnWhichToWakeUp);
         ipw.println("mDeviceStatesOnWhichToSleep=" + mDeviceStatesOnWhichToSleep);
         ipw.println("mInteractive=" + mInteractive);
+        ipw.println("mBootCompleted=" + mBootCompleted);
+
+        ipw.println();
+        ipw.println("mDeviceState=" + mDeviceState);
+        ipw.println("mPendingDeviceState=" + mPendingDeviceState);
+        ipw.println("mDeviceStateToBeAppliedAfterBoot=" + mDeviceStateToBeAppliedAfterBoot);
 
         final int logicalDisplayCount = mLogicalDisplays.size();
         ipw.println();
@@ -370,6 +377,17 @@
     }
 
     void setDeviceStateLocked(int state, boolean isOverrideActive) {
+        if (!mBootCompleted) {
+            // The boot animation might still be in progress, we do not want to switch states now
+            // as the boot animation would end up with an incorrect size.
+            if (DEBUG) {
+                Slog.d(TAG, "Postponing transition to state: " + mPendingDeviceState
+                        + " until boot is completed");
+            }
+            mDeviceStateToBeAppliedAfterBoot = state;
+            return;
+        }
+
         Slog.i(TAG, "Requesting Transition to state: " + state + ", from state=" + mDeviceState
                 + ", interactive=" + mInteractive + ", mBootCompleted=" + mBootCompleted);
         // As part of a state transition, we may need to turn off some displays temporarily so that
@@ -378,6 +396,7 @@
         // temporarily turned off.
         resetLayoutLocked(mDeviceState, state, /* isStateChangeStarting= */ true);
         mPendingDeviceState = state;
+        mDeviceStateToBeAppliedAfterBoot = DeviceStateManager.INVALID_DEVICE_STATE;
         final boolean wakeDevice = shouldDeviceBeWoken(mPendingDeviceState, mDeviceState,
                 mInteractive, mBootCompleted);
         final boolean sleepDevice = shouldDeviceBePutToSleep(mPendingDeviceState, mDeviceState,
@@ -424,6 +443,10 @@
     void onBootCompleted() {
         synchronized (mSyncRoot) {
             mBootCompleted = true;
+            if (mDeviceStateToBeAppliedAfterBoot != DeviceStateManager.INVALID_DEVICE_STATE) {
+                setDeviceStateLocked(mDeviceStateToBeAppliedAfterBoot,
+                        /* isOverrideActive= */ false);
+            }
         }
     }
 
@@ -477,7 +500,8 @@
     @VisibleForTesting
     boolean shouldDeviceBePutToSleep(int pendingState, int currentState, boolean isOverrideActive,
             boolean isInteractive, boolean isBootCompleted) {
-        return mDeviceStatesOnWhichToSleep.get(pendingState)
+        return currentState != DeviceStateManager.INVALID_DEVICE_STATE
+                && mDeviceStatesOnWhichToSleep.get(pendingState)
                 && !mDeviceStatesOnWhichToSleep.get(currentState)
                 && !isOverrideActive
                 && isInteractive && isBootCompleted;
@@ -926,6 +950,15 @@
         final int layerStack = assignLayerStackLocked(displayId);
         final LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
         display.updateLocked(mDisplayDeviceRepo);
+
+        final DisplayInfo info = display.getDisplayInfoLocked();
+        if (info.type == Display.TYPE_INTERNAL && mDeviceStateToLayoutMap.size() > 1) {
+            // If this is an internal display and the device uses a display layout configuration,
+            // the display should be disabled as later we will receive a device state update, which
+            // will tell us which internal displays should be enabled and which should be disabled.
+            display.setEnabledLocked(false);
+        }
+
         mLogicalDisplays.put(displayId, display);
         return display;
     }
diff --git a/services/core/java/com/android/server/display/ScreenOffBrightnessSensorController.java b/services/core/java/com/android/server/display/ScreenOffBrightnessSensorController.java
index 6f50dac..42defac 100644
--- a/services/core/java/com/android/server/display/ScreenOffBrightnessSensorController.java
+++ b/services/core/java/com/android/server/display/ScreenOffBrightnessSensorController.java
@@ -92,6 +92,10 @@
         }
     }
 
+    void stop() {
+        setLightSensorEnabled(false);
+    }
+
     float getAutomaticScreenBrightness() {
         if (mLastSensorValue < 0 || mLastSensorValue >= mSensorValueToLux.length
                 || (!mRegistered
@@ -109,7 +113,7 @@
 
     /** Dump current state */
     public void dump(PrintWriter pw) {
-        pw.println("ScreenOffBrightnessSensorController:");
+        pw.println("Screen Off Brightness Sensor Controller:");
         IndentingPrintWriter idpw = new IndentingPrintWriter(pw);
         idpw.increaseIndent();
         idpw.println("registered=" + mRegistered);
diff --git a/services/core/java/com/android/server/display/utils/SensorUtils.java b/services/core/java/com/android/server/display/utils/SensorUtils.java
index 4924ad5..48bc46c 100644
--- a/services/core/java/com/android/server/display/utils/SensorUtils.java
+++ b/services/core/java/com/android/server/display/utils/SensorUtils.java
@@ -33,6 +33,10 @@
      */
     public static Sensor findSensor(SensorManager sensorManager, String sensorType,
             String sensorName, int fallbackType) {
+        if (sensorManager == null) {
+            return null;
+        }
+
         if ("".equals(sensorName) && "".equals(sensorType)) {
             return null;
         }
diff --git a/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java b/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
index 9a19031..c5fb527 100644
--- a/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
+++ b/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.BroadcastOptions;
 import android.app.PendingIntent;
 import android.content.ComponentName;
@@ -37,6 +38,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -102,15 +104,19 @@
     }
 
     /**
-     * Creates a new instance.
+     * Creates a new instance from a {@link PendingIntent}.
      *
-     * @param context context
+     * <p>This method assumes the session package name has been validated and effectively belongs to
+     * the media session's owner.
+     *
      * @param userId userId
-     * @param pendingIntent pending intent
-     * @return Can be {@code null} if pending intent was null.
+     * @param pendingIntent pending intent that will receive media button events
+     * @param sessionPackageName package name of media session owner
+     * @return {@link MediaButtonReceiverHolder} instance or {@code null} if pending intent was
+     *     null.
      */
-    public static MediaButtonReceiverHolder create(Context context, int userId,
-            PendingIntent pendingIntent, String sessionPackageName) {
+    public static MediaButtonReceiverHolder create(
+            int userId, @Nullable PendingIntent pendingIntent, String sessionPackageName) {
         if (pendingIntent == null) {
             return null;
         }
@@ -312,7 +318,7 @@
     }
 
     private static ComponentName getComponentName(PendingIntent pendingIntent, int componentType) {
-        List<ResolveInfo> resolveInfos = null;
+        List<ResolveInfo> resolveInfos = Collections.emptyList();
         switch (componentType) {
             case COMPONENT_TYPE_ACTIVITY:
                 resolveInfos = pendingIntent.queryIntentComponents(
@@ -330,32 +336,37 @@
                         PACKAGE_MANAGER_COMMON_FLAGS | PackageManager.GET_RECEIVERS);
                 break;
         }
-        if (resolveInfos != null && !resolveInfos.isEmpty()) {
-            return createComponentName(resolveInfos.get(0));
+
+        for (ResolveInfo resolveInfo : resolveInfos) {
+            ComponentInfo componentInfo = getComponentInfo(resolveInfo);
+            if (componentInfo != null && TextUtils.equals(componentInfo.packageName,
+                    pendingIntent.getCreatorPackage())
+                    && componentInfo.packageName != null && componentInfo.name != null) {
+                return new ComponentName(componentInfo.packageName, componentInfo.name);
+            }
         }
+
         return null;
     }
 
-    private static ComponentName createComponentName(ResolveInfo resolveInfo) {
-        if (resolveInfo == null) {
-            return null;
-        }
-        ComponentInfo componentInfo;
+    /**
+     * Retrieves the {@link ComponentInfo} from a {@link ResolveInfo} instance. Similar to {@link
+     * ResolveInfo#getComponentInfo()}, but returns {@code null} if this {@link ResolveInfo} points
+     * to a content provider.
+     *
+     * @param resolveInfo Where to extract the {@link ComponentInfo} from.
+     * @return Either a non-null {@link ResolveInfo#activityInfo} or {@link
+     *     ResolveInfo#serviceInfo}. Otherwise {@code null} if {@link ResolveInfo#providerInfo} is
+     *     not {@code null}.
+     */
+    private static ComponentInfo getComponentInfo(@NonNull ResolveInfo resolveInfo) {
         // Code borrowed from ResolveInfo#getComponentInfo().
         if (resolveInfo.activityInfo != null) {
-            componentInfo = resolveInfo.activityInfo;
+            return resolveInfo.activityInfo;
         } else if (resolveInfo.serviceInfo != null) {
-            componentInfo = resolveInfo.serviceInfo;
+            return resolveInfo.serviceInfo;
         } else {
-            // We're not interested in content provider.
-            return null;
-        }
-        // Code borrowed from ComponentInfo#getComponentName().
-        try {
-            return new ComponentName(componentInfo.packageName, componentInfo.name);
-        } catch (IllegalArgumentException | NullPointerException e) {
-            // This may be happen if resolveActivity() end up with matching multiple activities.
-            // see PackageManager#resolveActivity().
+            // We're not interested in content providers.
             return null;
         }
     }
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 0785fac..1bd5063 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -938,8 +938,7 @@
         }
 
         @Override
-        public void setMediaButtonReceiver(PendingIntent pi, String sessionPackageName)
-                throws RemoteException {
+        public void setMediaButtonReceiver(PendingIntent pi) throws RemoteException {
             final long token = Binder.clearCallingIdentity();
             try {
                 if ((mPolicies & MediaSessionPolicyProvider.SESSION_POLICY_IGNORE_BUTTON_RECEIVER)
@@ -947,7 +946,7 @@
                     return;
                 }
                 mMediaButtonReceiverHolder =
-                        MediaButtonReceiverHolder.create(mContext, mUserId, pi, sessionPackageName);
+                        MediaButtonReceiverHolder.create(mUserId, pi, mPackageName);
                 mService.onMediaButtonReceiverChanged(MediaSessionRecord.this);
             } finally {
                 Binder.restoreCallingIdentity(token);
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index b89147e..d08150c 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -2285,9 +2285,9 @@
                     PendingIntent pi = mCustomMediaKeyDispatcher.getMediaButtonReceiver(keyEvent,
                             uid, asSystemService);
                     if (pi != null) {
-                        mediaButtonReceiverHolder = MediaButtonReceiverHolder.create(mContext,
-                                mCurrentFullUserRecord.mFullUserId, pi,
-                                /* sessionPackageName= */ "");
+                        mediaButtonReceiverHolder =
+                                MediaButtonReceiverHolder.create(
+                                        mCurrentFullUserRecord.mFullUserId, pi, "");
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 4d44c886..6bc8582 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -239,7 +239,6 @@
 import android.service.notification.NotificationRecordProto;
 import android.service.notification.NotificationServiceDumpProto;
 import android.service.notification.NotificationStats;
-import android.service.notification.SnoozeCriterion;
 import android.service.notification.StatusBarNotification;
 import android.service.notification.ZenModeConfig;
 import android.service.notification.ZenModeProto;
@@ -8526,95 +8525,6 @@
         }
     }
 
-    static class NotificationRecordExtractorData {
-        // Class that stores any field in a NotificationRecord that can change via an extractor.
-        // Used to cache previous data used in a sort.
-        int mPosition;
-        int mVisibility;
-        boolean mShowBadge;
-        boolean mAllowBubble;
-        boolean mIsBubble;
-        NotificationChannel mChannel;
-        String mGroupKey;
-        ArrayList<String> mOverridePeople;
-        ArrayList<SnoozeCriterion> mSnoozeCriteria;
-        Integer mUserSentiment;
-        Integer mSuppressVisually;
-        ArrayList<Notification.Action> mSystemSmartActions;
-        ArrayList<CharSequence> mSmartReplies;
-        int mImportance;
-
-        // These fields may not trigger a reranking but diffs here may be logged.
-        float mRankingScore;
-        boolean mIsConversation;
-
-        NotificationRecordExtractorData(int position, int visibility, boolean showBadge,
-                boolean allowBubble, boolean isBubble, NotificationChannel channel, String groupKey,
-                ArrayList<String> overridePeople, ArrayList<SnoozeCriterion> snoozeCriteria,
-                Integer userSentiment, Integer suppressVisually,
-                ArrayList<Notification.Action> systemSmartActions,
-                ArrayList<CharSequence> smartReplies, int importance, float rankingScore,
-                boolean isConversation) {
-            mPosition = position;
-            mVisibility = visibility;
-            mShowBadge = showBadge;
-            mAllowBubble = allowBubble;
-            mIsBubble = isBubble;
-            mChannel = channel;
-            mGroupKey = groupKey;
-            mOverridePeople = overridePeople;
-            mSnoozeCriteria = snoozeCriteria;
-            mUserSentiment = userSentiment;
-            mSuppressVisually = suppressVisually;
-            mSystemSmartActions = systemSmartActions;
-            mSmartReplies = smartReplies;
-            mImportance = importance;
-            mRankingScore = rankingScore;
-            mIsConversation = isConversation;
-        }
-
-        // Returns whether the provided NotificationRecord differs from the cached data in any way.
-        // Should be guarded by mNotificationLock; not annotated here as this class is static.
-        boolean hasDiffForRankingLocked(NotificationRecord r, int newPosition) {
-            return mPosition != newPosition
-                    || mVisibility != r.getPackageVisibilityOverride()
-                    || mShowBadge != r.canShowBadge()
-                    || mAllowBubble != r.canBubble()
-                    || mIsBubble != r.getNotification().isBubbleNotification()
-                    || !Objects.equals(mChannel, r.getChannel())
-                    || !Objects.equals(mGroupKey, r.getGroupKey())
-                    || !Objects.equals(mOverridePeople, r.getPeopleOverride())
-                    || !Objects.equals(mSnoozeCriteria, r.getSnoozeCriteria())
-                    || !Objects.equals(mUserSentiment, r.getUserSentiment())
-                    || !Objects.equals(mSuppressVisually, r.getSuppressedVisualEffects())
-                    || !Objects.equals(mSystemSmartActions, r.getSystemGeneratedSmartActions())
-                    || !Objects.equals(mSmartReplies, r.getSmartReplies())
-                    || mImportance != r.getImportance();
-        }
-
-        // Returns whether the NotificationRecord has a change from this data for which we should
-        // log an update. This method specifically targets fields that may be changed via
-        // adjustments from the assistant.
-        //
-        // Fields here are the union of things in NotificationRecordLogger.shouldLogReported
-        // and NotificationRecord.applyAdjustments.
-        //
-        // Should be guarded by mNotificationLock; not annotated here as this class is static.
-        boolean hasDiffForLoggingLocked(NotificationRecord r, int newPosition) {
-            return mPosition != newPosition
-                    || !Objects.equals(mChannel, r.getChannel())
-                    || !Objects.equals(mGroupKey, r.getGroupKey())
-                    || !Objects.equals(mOverridePeople, r.getPeopleOverride())
-                    || !Objects.equals(mSnoozeCriteria, r.getSnoozeCriteria())
-                    || !Objects.equals(mUserSentiment, r.getUserSentiment())
-                    || !Objects.equals(mSystemSmartActions, r.getSystemGeneratedSmartActions())
-                    || !Objects.equals(mSmartReplies, r.getSmartReplies())
-                    || mImportance != r.getImportance()
-                    || !r.rankingScoreMatches(mRankingScore)
-                    || mIsConversation != r.isConversation();
-        }
-    }
-
     void handleRankingSort() {
         if (mRankingHelper == null) return;
         synchronized (mNotificationLock) {
@@ -8640,7 +8550,8 @@
                         r.getSmartReplies(),
                         r.getImportance(),
                         r.getRankingScore(),
-                        r.isConversation());
+                        r.isConversation(),
+                        r.getProposedImportance());
                 extractorDataBefore.put(r.getKey(), extractorData);
                 mRankingHelper.extractSignals(r);
             }
@@ -9935,7 +9846,8 @@
                     record.getRankingScore() == 0
                             ? RANKING_UNCHANGED
                             : (record.getRankingScore() > 0 ?  RANKING_PROMOTED : RANKING_DEMOTED),
-                    record.getNotification().isBubbleNotification()
+                    record.getNotification().isBubbleNotification(),
+                    record.getProposedImportance()
             );
             rankings.add(ranking);
         }
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index cbaf485..d344306 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -210,6 +210,7 @@
     // Whether this notification record should have an update logged the next time notifications
     // are sorted.
     private boolean mPendingLogUpdate = false;
+    private int mProposedImportance = IMPORTANCE_UNSPECIFIED;
 
     public NotificationRecord(Context context, StatusBarNotification sbn,
             NotificationChannel channel) {
@@ -499,6 +500,8 @@
         pw.println(prefix + "mImportance="
                 + NotificationListenerService.Ranking.importanceToString(mImportance));
         pw.println(prefix + "mImportanceExplanation=" + getImportanceExplanation());
+        pw.println(prefix + "mProposedImportance="
+                + NotificationListenerService.Ranking.importanceToString(mProposedImportance));
         pw.println(prefix + "mIsAppImportanceLocked=" + mIsAppImportanceLocked);
         pw.println(prefix + "mIntercept=" + mIntercept);
         pw.println(prefix + "mHidden==" + mHidden);
@@ -738,6 +741,12 @@
                             Adjustment.KEY_NOT_CONVERSATION,
                             Boolean.toString(mIsNotConversationOverride));
                 }
+                if (signals.containsKey(Adjustment.KEY_IMPORTANCE_PROPOSAL)) {
+                    mProposedImportance = signals.getInt(Adjustment.KEY_IMPORTANCE_PROPOSAL);
+                    EventLogTags.writeNotificationAdjusted(getKey(),
+                            Adjustment.KEY_IMPORTANCE_PROPOSAL,
+                            Integer.toString(mProposedImportance));
+                }
                 if (!signals.isEmpty() && adjustment.getIssuer() != null) {
                     mAdjustmentIssuer = adjustment.getIssuer();
                 }
@@ -870,6 +879,10 @@
         return stats.naturalImportance;
     }
 
+    public int getProposedImportance() {
+        return mProposedImportance;
+    }
+
     public float getRankingScore() {
         return mRankingScore;
     }
diff --git a/services/core/java/com/android/server/notification/NotificationRecordExtractorData.java b/services/core/java/com/android/server/notification/NotificationRecordExtractorData.java
new file mode 100644
index 0000000..6dc9029
--- /dev/null
+++ b/services/core/java/com/android/server/notification/NotificationRecordExtractorData.java
@@ -0,0 +1,118 @@
+/*
+ * 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.notification;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.service.notification.SnoozeCriterion;
+
+import java.util.ArrayList;
+import java.util.Objects;
+
+/**
+ * Class that stores any field in a NotificationRecord that can change via an extractor.
+ * Used to cache previous data used in a sort.
+ */
+public final class NotificationRecordExtractorData {
+    private final int mPosition;
+    private final int mVisibility;
+    private final boolean mShowBadge;
+    private final boolean mAllowBubble;
+    private final boolean mIsBubble;
+    private final NotificationChannel mChannel;
+    private final String mGroupKey;
+    private final ArrayList<String> mOverridePeople;
+    private final ArrayList<SnoozeCriterion> mSnoozeCriteria;
+    private final Integer mUserSentiment;
+    private final Integer mSuppressVisually;
+    private final ArrayList<Notification.Action> mSystemSmartActions;
+    private final ArrayList<CharSequence> mSmartReplies;
+    private final int mImportance;
+
+    // These fields may not trigger a reranking but diffs here may be logged.
+    private final float mRankingScore;
+    private final boolean mIsConversation;
+    private final int mProposedImportance;
+
+    NotificationRecordExtractorData(int position, int visibility, boolean showBadge,
+            boolean allowBubble, boolean isBubble, NotificationChannel channel, String groupKey,
+            ArrayList<String> overridePeople, ArrayList<SnoozeCriterion> snoozeCriteria,
+            Integer userSentiment, Integer suppressVisually,
+            ArrayList<Notification.Action> systemSmartActions,
+            ArrayList<CharSequence> smartReplies, int importance, float rankingScore,
+            boolean isConversation, int proposedImportance) {
+        mPosition = position;
+        mVisibility = visibility;
+        mShowBadge = showBadge;
+        mAllowBubble = allowBubble;
+        mIsBubble = isBubble;
+        mChannel = channel;
+        mGroupKey = groupKey;
+        mOverridePeople = overridePeople;
+        mSnoozeCriteria = snoozeCriteria;
+        mUserSentiment = userSentiment;
+        mSuppressVisually = suppressVisually;
+        mSystemSmartActions = systemSmartActions;
+        mSmartReplies = smartReplies;
+        mImportance = importance;
+        mRankingScore = rankingScore;
+        mIsConversation = isConversation;
+        mProposedImportance = proposedImportance;
+    }
+
+    // Returns whether the provided NotificationRecord differs from the cached data in any way.
+    // Should be guarded by mNotificationLock; not annotated here as this class is static.
+    boolean hasDiffForRankingLocked(NotificationRecord r, int newPosition) {
+        return mPosition != newPosition
+                || mVisibility != r.getPackageVisibilityOverride()
+                || mShowBadge != r.canShowBadge()
+                || mAllowBubble != r.canBubble()
+                || mIsBubble != r.getNotification().isBubbleNotification()
+                || !Objects.equals(mChannel, r.getChannel())
+                || !Objects.equals(mGroupKey, r.getGroupKey())
+                || !Objects.equals(mOverridePeople, r.getPeopleOverride())
+                || !Objects.equals(mSnoozeCriteria, r.getSnoozeCriteria())
+                || !Objects.equals(mUserSentiment, r.getUserSentiment())
+                || !Objects.equals(mSuppressVisually, r.getSuppressedVisualEffects())
+                || !Objects.equals(mSystemSmartActions, r.getSystemGeneratedSmartActions())
+                || !Objects.equals(mSmartReplies, r.getSmartReplies())
+                || mImportance != r.getImportance()
+                || mProposedImportance != r.getProposedImportance();
+    }
+
+    // Returns whether the NotificationRecord has a change from this data for which we should
+    // log an update. This method specifically targets fields that may be changed via
+    // adjustments from the assistant.
+    //
+    // Fields here are the union of things in NotificationRecordLogger.shouldLogReported
+    // and NotificationRecord.applyAdjustments.
+    //
+    // Should be guarded by mNotificationLock; not annotated here as this class is static.
+    boolean hasDiffForLoggingLocked(NotificationRecord r, int newPosition) {
+        return mPosition != newPosition
+                || !Objects.equals(mChannel, r.getChannel())
+                || !Objects.equals(mGroupKey, r.getGroupKey())
+                || !Objects.equals(mOverridePeople, r.getPeopleOverride())
+                || !Objects.equals(mSnoozeCriteria, r.getSnoozeCriteria())
+                || !Objects.equals(mUserSentiment, r.getUserSentiment())
+                || !Objects.equals(mSystemSmartActions, r.getSystemGeneratedSmartActions())
+                || !Objects.equals(mSmartReplies, r.getSmartReplies())
+                || mImportance != r.getImportance()
+                || !r.rankingScoreMatches(mRankingScore)
+                || mIsConversation != r.isConversation()
+                || mProposedImportance != r.getProposedImportance();
+    }
+}
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index d8aa469..662db78 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -108,7 +108,7 @@
     @VisibleForTesting
     static final int NOTIFICATION_CHANNEL_COUNT_LIMIT = 5000;
     @VisibleForTesting
-    static final int NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT = 50000;
+    static final int NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT = 6000;
 
     private static final int NOTIFICATION_PREFERENCES_PULL_LIMIT = 1000;
     private static final int NOTIFICATION_CHANNEL_PULL_LIMIT = 2000;
@@ -1005,6 +1005,7 @@
                     channel.setAllowBubbles(existing != null
                             ? existing.getAllowBubbles()
                             : NotificationChannel.DEFAULT_ALLOW_BUBBLE);
+                    channel.setImportantConversation(false);
                 }
                 clearLockedFieldsLocked(channel);
 
diff --git a/services/core/java/com/android/server/notification/SnoozeHelper.java b/services/core/java/com/android/server/notification/SnoozeHelper.java
index babe4ea..12c16fc 100644
--- a/services/core/java/com/android/server/notification/SnoozeHelper.java
+++ b/services/core/java/com/android/server/notification/SnoozeHelper.java
@@ -129,7 +129,7 @@
     protected Long getSnoozeTimeForUnpostedNotification(int userId, String pkg, String key) {
         Long time = null;
         synchronized (mLock) {
-            time = mPersistedSnoozedNotifications.get(key);
+            time = mPersistedSnoozedNotifications.get(getTrimmedString(key));
         }
         if (time == null) {
             time = 0L;
@@ -139,7 +139,7 @@
 
     protected String getSnoozeContextForUnpostedNotification(int userId, String pkg, String key) {
         synchronized (mLock) {
-            return mPersistedSnoozedNotificationsWithContext.get(key);
+            return mPersistedSnoozedNotificationsWithContext.get(getTrimmedString(key));
         }
     }
 
@@ -364,8 +364,9 @@
                 final NotificationRecord record = mSnoozedNotifications.valueAt(i);
                 if (record.getUserId() == userId && record.getSbn().getPackageName().equals(pkg)) {
                     mSnoozedNotifications.removeAt(i);
-                    mPersistedSnoozedNotificationsWithContext.remove(record.getKey());
-                    mPersistedSnoozedNotifications.remove(record.getKey());
+                    String trimmedKey = getTrimmedString(record.getKey());
+                    mPersistedSnoozedNotificationsWithContext.remove(trimmedKey);
+                    mPersistedSnoozedNotifications.remove(trimmedKey);
                     Runnable runnable = () -> {
                         final PendingIntent pi = createPendingIntent(record.getKey());
                         mAm.cancel(pi);
@@ -386,8 +387,9 @@
                 final NotificationRecord record = mSnoozedNotifications.valueAt(i);
                 if (record.getUserId() == userId) {
                     mSnoozedNotifications.removeAt(i);
-                    mPersistedSnoozedNotificationsWithContext.remove(record.getKey());
-                    mPersistedSnoozedNotifications.remove(record.getKey());
+                    String trimmedKey = getTrimmedString(record.getKey());
+                    mPersistedSnoozedNotificationsWithContext.remove(trimmedKey);
+                    mPersistedSnoozedNotifications.remove(trimmedKey);
 
                     Runnable runnable = () -> {
                         final PendingIntent pi = createPendingIntent(record.getKey());
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 00fb065..866a995 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -91,6 +91,7 @@
 import android.service.gatekeeper.IGateKeeperService;
 import android.service.voice.VoiceInteractionManagerInternal;
 import android.stats.devicepolicy.DevicePolicyEnums;
+import android.telecom.TelecomManager;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -1760,6 +1761,63 @@
         }
     }
 
+    /**
+     * Returns whether switching users is currently allowed for the provided user.
+     * <p>
+     * Switching users is not allowed in the following cases:
+     * <li>the user is in a phone call</li>
+     * <li>{@link UserManager#DISALLOW_USER_SWITCH} is set</li>
+     * <li>system user hasn't been unlocked yet</li>
+     *
+     * @return A {@link UserManager.UserSwitchabilityResult} flag indicating if the user is
+     * switchable.
+     */
+    public @UserManager.UserSwitchabilityResult int getUserSwitchability(int userId) {
+        checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, "getUserSwitchability");
+
+        final TimingsTraceAndSlog t = new TimingsTraceAndSlog();
+        t.traceBegin("getUserSwitchability-" + userId);
+
+        int flags = UserManager.SWITCHABILITY_STATUS_OK;
+
+        t.traceBegin("TM.isInCall");
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            final TelecomManager telecomManager = mContext.getSystemService(TelecomManager.class);
+            if (telecomManager != null && telecomManager.isInCall()) {
+                flags |= UserManager.SWITCHABILITY_STATUS_USER_IN_CALL;
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+        t.traceEnd();
+
+        t.traceBegin("hasUserRestriction-DISALLOW_USER_SWITCH");
+        if (mLocalService.hasUserRestriction(DISALLOW_USER_SWITCH, userId)) {
+            flags |= UserManager.SWITCHABILITY_STATUS_USER_SWITCH_DISALLOWED;
+        }
+        t.traceEnd();
+
+        // System User is always unlocked in Headless System User Mode, so ignore this flag
+        if (!UserManager.isHeadlessSystemUserMode()) {
+            t.traceBegin("getInt-ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED");
+            final boolean allowUserSwitchingWhenSystemUserLocked = Settings.Global.getInt(
+                    mContext.getContentResolver(),
+                    Settings.Global.ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED, 0) != 0;
+            t.traceEnd();
+            t.traceBegin("isUserUnlocked-USER_SYSTEM");
+            final boolean systemUserUnlocked = mLocalService.isUserUnlocked(UserHandle.USER_SYSTEM);
+            t.traceEnd();
+
+            if (!allowUserSwitchingWhenSystemUserLocked && !systemUserUnlocked) {
+                flags |= UserManager.SWITCHABILITY_STATUS_SYSTEM_USER_LOCKED;
+            }
+        }
+        t.traceEnd();
+
+        return flags;
+    }
+
     @Override
     public boolean isUserSwitcherEnabled(@UserIdInt int mUserId) {
         boolean multiUserSettingOn = Settings.Global.getInt(mContext.getContentResolver(),
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
index 554e269..20c9a21 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -4215,7 +4215,6 @@
         }
         boolean changed = false;
 
-        Set<Permission> needsUpdate = null;
         synchronized (mLock) {
             final Iterator<Permission> it = mRegistry.getPermissionTrees().iterator();
             while (it.hasNext()) {
@@ -4234,26 +4233,6 @@
                             + " that used to be declared by " + bp.getPackageName());
                     it.remove();
                 }
-                if (needsUpdate == null) {
-                    needsUpdate = new ArraySet<>();
-                }
-                needsUpdate.add(bp);
-            }
-        }
-        if (needsUpdate != null) {
-            for (final Permission bp : needsUpdate) {
-                final AndroidPackage sourcePkg =
-                        mPackageManagerInt.getPackage(bp.getPackageName());
-                final PackageStateInternal sourcePs =
-                        mPackageManagerInt.getPackageStateInternal(bp.getPackageName());
-                synchronized (mLock) {
-                    if (sourcePkg != null && sourcePs != null) {
-                        continue;
-                    }
-                    Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
-                            + " from package " + bp.getPackageName());
-                    mRegistry.removePermission(bp.getName());
-                }
             }
         }
         return changed;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index de0d1f8..b380d84 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -566,6 +566,9 @@
     // What we do when the user double-taps on home
     private int mDoubleTapOnHomeBehavior;
 
+    // Whether to lock the device after the next app transition has finished.
+    private boolean mLockAfterAppTransitionFinished;
+
     // Allowed theater mode wake actions
     private boolean mAllowTheaterModeWakeFromKey;
     private boolean mAllowTheaterModeWakeFromPowerKey;
@@ -709,7 +712,7 @@
                     handleRingerChordGesture();
                     break;
                 case MSG_SCREENSHOT_CHORD:
-                    handleScreenShot(msg.arg1, msg.arg2);
+                    handleScreenShot(msg.arg1);
                     break;
             }
         }
@@ -1055,11 +1058,10 @@
             return;
         }
 
-        // Make sure the device locks. Unfortunately, this has the side-effect of briefly revealing
-        // the lock screen before the dream appears. Note that locking is a side-effect of the no
-        // dream action that is executed if we early return above.
-        // TODO(b/261662912): Find a better way to lock the device that doesn't result in jank.
-        lockNow(null);
+        synchronized (mLock) {
+            // Lock the device after the dream transition has finished.
+            mLockAfterAppTransitionFinished = true;
+        }
 
         dreamManagerInternal.requestDream();
     }
@@ -1077,10 +1079,9 @@
         // a tendency to hit the power button immediately when they pick up their device, and we
         // don't want to put the device back to sleep in those cases.
         final PowerManager.WakeData lastWakeUp = mPowerManagerInternal.getLastWakeup();
-        if (lastWakeUp != null && lastWakeUp.wakeReason == PowerManager.WAKE_REASON_GESTURE) {
-            final int gestureDelayMillis = Settings.Global.getInt(mContext.getContentResolver(),
-                    Settings.Global.POWER_BUTTON_SUPPRESSION_DELAY_AFTER_GESTURE_WAKE,
-                    POWER_BUTTON_SUPPRESSION_DELAY_DEFAULT_MILLIS);
+        if (lastWakeUp != null && (lastWakeUp.wakeReason == PowerManager.WAKE_REASON_GESTURE
+                || lastWakeUp.wakeReason == PowerManager.WAKE_REASON_LIFT
+                || lastWakeUp.wakeReason == PowerManager.WAKE_REASON_BIOMETRIC)) {
             final long now = SystemClock.uptimeMillis();
             if (mPowerButtonSuppressionDelayMillis > 0
                     && (now < lastWakeUp.wakeTime + mPowerButtonSuppressionDelayMillis)) {
@@ -1501,9 +1502,9 @@
                 || mShortPressOnStemPrimaryBehavior != SHORT_PRESS_PRIMARY_NOTHING;
     }
 
-    private void interceptScreenshotChord(int type, int source, long pressDelay) {
+    private void interceptScreenshotChord(int source, long pressDelay) {
         mHandler.removeMessages(MSG_SCREENSHOT_CHORD);
-        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SCREENSHOT_CHORD, type, source),
+        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SCREENSHOT_CHORD, source),
                 pressDelay);
     }
 
@@ -1573,9 +1574,8 @@
         }
     };
 
-    private void handleScreenShot(@WindowManager.ScreenshotType int type,
-            @WindowManager.ScreenshotSource int source) {
-        mDefaultDisplayPolicy.takeScreenshot(type, source);
+    private void handleScreenShot(@WindowManager.ScreenshotSource int source) {
+        mDefaultDisplayPolicy.takeScreenshot(TAKE_SCREENSHOT_FULLSCREEN, source);
     }
 
     @Override
@@ -2140,6 +2140,22 @@
                 handleStartTransitionForKeyguardLw(
                         keyguardGoingAway, false /* keyguardOccludingStarted */,
                         0 /* duration */);
+
+                synchronized (mLock) {
+                    mLockAfterAppTransitionFinished = false;
+                }
+            }
+
+            @Override
+            public void onAppTransitionFinishedLocked(IBinder token) {
+                synchronized (mLock) {
+                    if (!mLockAfterAppTransitionFinished) {
+                        return;
+                    }
+                    mLockAfterAppTransitionFinished = false;
+                }
+
+                lockNow(null);
             }
         });
 
@@ -2171,7 +2187,7 @@
                         @Override
                         void execute() {
                             mPowerKeyHandled = true;
-                            interceptScreenshotChord(TAKE_SCREENSHOT_FULLSCREEN,
+                            interceptScreenshotChord(
                                     SCREENSHOT_KEY_CHORD, getScreenshotChordLongPressDelay());
                         }
                         @Override
@@ -2865,8 +2881,7 @@
                 break;
             case KeyEvent.KEYCODE_S:
                 if (down && event.isMetaPressed() && event.isCtrlPressed() && repeatCount == 0) {
-                    interceptScreenshotChord(
-                            TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_OTHER, 0 /*pressDelay*/);
+                    interceptScreenshotChord(SCREENSHOT_KEY_OTHER, 0 /*pressDelay*/);
                     return key_consumed;
                 }
                 break;
@@ -3240,8 +3255,7 @@
                 break;
             case KeyEvent.KEYCODE_SYSRQ:
                 if (down && repeatCount == 0) {
-                    interceptScreenshotChord(
-                            TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_OTHER, 0 /*pressDelay*/);
+                    interceptScreenshotChord(SCREENSHOT_KEY_OTHER, 0 /*pressDelay*/);
                 }
                 return true;
         }
@@ -4130,9 +4144,6 @@
             case KeyEvent.KEYCODE_DEMO_APP_2:
             case KeyEvent.KEYCODE_DEMO_APP_3:
             case KeyEvent.KEYCODE_DEMO_APP_4: {
-                // TODO(b/254604589): Dispatch KeyEvent to System UI.
-                sendSystemKeyToStatusBarAsync(keyCode);
-
                 // Just drop if keys are not intercepted for direct key.
                 result &= ~ACTION_PASS_TO_USER;
                 break;
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index e7221c8..fde0b34 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -191,4 +191,12 @@
      * @see com.android.internal.statusbar.IStatusBar#enterStageSplitFromRunningApp
      */
     void enterStageSplitFromRunningApp(boolean leftOrTop);
+
+    /**
+     * Shows the media output switcher dialog.
+     *
+     * @param packageName of the session for which the output switcher is shown.
+     * @see com.android.internal.statusbar.IStatusBar#showMediaOutputSwitcher
+     */
+    void showMediaOutputSwitcher(String packageName);
 }
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 45748e6..ab7292d 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -714,6 +714,16 @@
                 } catch (RemoteException ex) { }
             }
         }
+
+        @Override
+        public void showMediaOutputSwitcher(String packageName) {
+            if (mBar != null) {
+                try {
+                    mBar.showMediaOutputSwitcher(packageName);
+                } catch (RemoteException ex) {
+                }
+            }
+        }
     };
 
     private final GlobalActionsProvider mGlobalActionsProvider = new GlobalActionsProvider() {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index f38633f..6b01a77 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1456,8 +1456,7 @@
                 updatePictureInPictureMode(null, false);
             } else {
                 mLastReportedMultiWindowMode = inMultiWindowMode;
-                ensureActivityConfiguration(0 /* globalChanges */, PRESERVE_WINDOWS,
-                        false /* ignoreVisibility */);
+                ensureActivityConfiguration(0 /* globalChanges */, PRESERVE_WINDOWS);
             }
         }
     }
@@ -3988,6 +3987,7 @@
     }
 
     void finishRelaunching() {
+        mLetterboxUiController.setRelauchingAfterRequestedOrientationChanged(false);
         mTaskSupervisor.getActivityMetricsLogger().notifyActivityRelaunched(this);
 
         if (mPendingRelaunchCount > 0) {
@@ -7745,13 +7745,17 @@
     }
 
     void setRequestedOrientation(int requestedOrientation) {
+        if (mLetterboxUiController.shouldIgnoreRequestedOrientation(requestedOrientation)) {
+            return;
+        }
         setOrientation(requestedOrientation, this);
 
         // Push the new configuration to the requested app in case where it's not pushed, e.g. when
         // the request is handled at task level with letterbox.
         if (!getMergedOverrideConfiguration().equals(
                 mLastReportedConfiguration.getMergedConfiguration())) {
-            ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */);
+            ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */,
+                    false /* ignoreVisibility */, true /* isRequestedOrientationChanged */);
         }
 
         mAtmService.getTaskChangeNotificationController().notifyActivityRequestedOrientationChanged(
@@ -7934,6 +7938,8 @@
         // The smallest screen width is the short side of screen bounds. Because the bounds
         // and density won't be changed, smallestScreenWidthDp is also fixed.
         overrideConfig.smallestScreenWidthDp = fullConfig.smallestScreenWidthDp;
+        // TODO(b/264276741): Check whether the runtime orietnation request is fixed rather than
+        // the manifest orientation which may be obsolete.
         if (info.isFixedOrientation()) {
             // lock rotation too. When in size-compat, onConfigurationChanged will watch for and
             // apply runtime rotation changes.
@@ -8047,8 +8053,24 @@
             updateResolvedBoundsPosition(newParentConfiguration);
         }
 
-        if (mVisibleRequested) {
-            updateCompatDisplayInsets();
+        boolean isIgnoreOrientationRequest = mDisplayContent != null
+                && mDisplayContent.getIgnoreOrientationRequest();
+        if (mCompatDisplayInsets == null // for size compat mode set in updateCompatDisplayInsets
+                // Fixed orientation letterboxing is possible on both large screen devices
+                // with ignoreOrientationRequest enabled and on phones in split screen even with
+                // ignoreOrientationRequest disabled.
+                && (mLetterboxBoundsForFixedOrientationAndAspectRatio != null
+                        // Limiting check for aspect ratio letterboxing to devices with enabled
+                        // ignoreOrientationRequest. This avoids affecting phones where apps may
+                        // not expect the change of smallestScreenWidthDp after rotation which is
+                        // possible with this logic. Not having smallestScreenWidthDp completely
+                        // accurate on phones shouldn't make the big difference and is expected
+                        // to be already well-tested by apps.
+                        || (isIgnoreOrientationRequest && mIsAspectRatioApplied))) {
+            // TODO(b/264034555): Use mDisplayContent to calculate smallestScreenWidthDp from all
+            // rotations and only re-calculate if parent bounds have non-orientation size change.
+            resolvedConfig.smallestScreenWidthDp =
+                    Math.min(resolvedConfig.screenWidthDp, resolvedConfig.screenHeightDp);
         }
 
         // Assign configuration sequence number into hierarchy because there is a different way than
@@ -8436,7 +8458,7 @@
         // Calculate app bounds using fixed orientation bounds because they will be needed later
         // for comparison with size compat app bounds in {@link resolveSizeCompatModeConfiguration}.
         getTaskFragment().computeConfigResourceOverrides(getResolvedOverrideConfiguration(),
-                newParentConfig);
+                newParentConfig, mCompatDisplayInsets);
         mLetterboxBoundsForFixedOrientationAndAspectRatio = new Rect(resolvedBounds);
     }
 
@@ -9052,7 +9074,13 @@
 
     boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow) {
         return ensureActivityConfiguration(globalChanges, preserveWindow,
-                false /* ignoreVisibility */);
+                false /* ignoreVisibility */, false /* isRequestedOrientationChanged */);
+    }
+
+    boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow,
+            boolean ignoreVisibility) {
+        return ensureActivityConfiguration(globalChanges, preserveWindow, ignoreVisibility,
+                false /* isRequestedOrientationChanged */);
     }
 
     /**
@@ -9066,11 +9094,13 @@
      *                         (stopped state). This is useful for the case where we know the
      *                         activity will be visible soon and we want to ensure its configuration
      *                         before we make it visible.
+     * @param isRequestedOrientationChanged whether this is triggered in response to an app calling
+     *                                      {@link android.app.Activity#setRequestedOrientation}.
      * @return False if the activity was relaunched and true if it wasn't relaunched because we
      *         can't or the app handles the specific configuration that is changing.
      */
     boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow,
-            boolean ignoreVisibility) {
+            boolean ignoreVisibility, boolean isRequestedOrientationChanged) {
         final Task rootTask = getRootTask();
         if (rootTask.mConfigWillChange) {
             ProtoLog.v(WM_DEBUG_CONFIGURATION, "Skipping config check "
@@ -9107,6 +9137,18 @@
             mLastReportedDisplayId = newDisplayId;
         }
 
+        // Calling from here rather than from onConfigurationChanged because it's possible that
+        // onConfigurationChanged was called before mVisibleRequested became true and
+        // mCompatDisplayInsets may not be called again when mVisibleRequested changes. And we
+        // don't want to save mCompatDisplayInsets in onConfigurationChanged without visibility
+        // check to avoid remembering obsolete configuration which can lead to unnecessary
+        // size-compat mode.
+        if (mVisibleRequested) {
+            // Calling from here rather than resolveOverrideConfiguration to ensure that this is
+            // called after full config is updated in ConfigurationContainer#onConfigurationChanged.
+            updateCompatDisplayInsets();
+        }
+
         // Short circuit: if the two full configurations are equal (the common case), then there is
         // nothing to do.  We test the full configuration instead of the global and merged override
         // configurations because there are cases (like moving a task to the root pinned task) where
@@ -9115,12 +9157,6 @@
         if (getConfiguration().equals(mTmpConfig) && !forceNewConfig && !displayChanged) {
             ProtoLog.v(WM_DEBUG_CONFIGURATION, "Configuration & display "
                     + "unchanged in %s", this);
-            // It's possible that resolveOverrideConfiguration was called before mVisibleRequested
-            // became true and mCompatDisplayInsets may not have been created so ensure
-            // that mCompatDisplayInsets is created here.
-            if (mVisibleRequested) {
-                updateCompatDisplayInsets();
-            }
             return true;
         }
 
@@ -9194,6 +9230,9 @@
             } else {
                 mRelaunchReason = RELAUNCH_REASON_NONE;
             }
+            if (isRequestedOrientationChanged) {
+                mLetterboxUiController.setRelauchingAfterRequestedOrientationChanged(true);
+            }
             if (mState == PAUSING) {
                 // A little annoying: we are waiting for this activity to finish pausing. Let's not
                 // do anything now, but just flag that it needs to be restarted when done pausing.
@@ -10127,8 +10166,8 @@
     // TODO(b/263592337): Explore enabling compat fake focus for fullscreen, e.g. for when
     // covered with bubbles.
     boolean shouldSendCompatFakeFocus() {
-        return mWmService.mLetterboxConfiguration.isCompatFakeFocusEnabled() && inMultiWindowMode()
-                && !inPinnedWindowingMode() && !inFreeformWindowingMode();
+        return mWmService.mLetterboxConfiguration.isCompatFakeFocusEnabled(info)
+                && inMultiWindowMode() && !inPinnedWindowingMode() && !inFreeformWindowingMode();
     }
 
     static class Builder {
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index c6e0cd2..aad89b4 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -2867,9 +2867,9 @@
 
         if (differentTopTask && !mAvoidMoveToFront) {
             mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
-            if (mSourceRecord == null || (mSourceRootTask.getTopNonFinishingActivity() != null
-                    && mSourceRootTask.getTopNonFinishingActivity().getTask()
-                            == mSourceRecord.getTask())) {
+            // TODO(b/264487981): Consider using BackgroundActivityStartController to determine
+            //  whether to bring the launching activity to the front.
+            if (mSourceRecord == null || inTopNonFinishingTask(mSourceRecord)) {
                 // We really do want to push this one into the user's face, right now.
                 if (mLaunchTaskBehind && mSourceRecord != null) {
                     intentActivity.setTaskToAffiliateWith(mSourceRecord.getTask());
@@ -2928,6 +2928,20 @@
                 mRootWindowContainer.getDefaultTaskDisplayArea(), mTargetRootTask);
     }
 
+    private boolean inTopNonFinishingTask(ActivityRecord r) {
+        if (r == null || r.getTask() == null) {
+            return false;
+        }
+
+        final Task rTask = r.getTask();
+        final Task parent = rTask.getCreatedByOrganizerTask() != null
+                ? rTask.getCreatedByOrganizerTask() : r.getRootTask();
+        final ActivityRecord topNonFinishingActivity = parent != null
+                ? parent.getTopNonFinishingActivity() : null;
+
+        return topNonFinishingActivity != null && topNonFinishingActivity.getTask() == rTask;
+    }
+
     private void resumeTargetRootTaskIfNeeded() {
         if (mDoResume) {
             final ActivityRecord next = mTargetRootTask.topRunningActivity(
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 1ba7e68..8619615 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -4715,6 +4715,7 @@
                 mTaskChangeNotificationController.notifyTaskFocusChanged(prevTask.mTaskId, false);
             }
             mTaskChangeNotificationController.notifyTaskFocusChanged(task.mTaskId, true);
+            mTaskSupervisor.mRecentTasks.add(task);
         }
 
         applyUpdateLockStateLocked(r);
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index abaa363..0ea6157 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -892,7 +892,7 @@
      *
      * TODO(b/213312721): Remove this predicate and its callers once ShellTransition is enabled.
      */
-    private static boolean isTaskViewTask(WindowContainer wc) {
+    static boolean isTaskViewTask(WindowContainer wc) {
         // We use Task#mRemoveWithTaskOrganizer to identify an embedded Task, but this is a hack and
         // it is not guaranteed to work this logic in the future version.
         return wc instanceof Task && ((Task) wc).mRemoveWithTaskOrganizer;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 36f86d1..9af1b2b 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -2974,7 +2974,7 @@
         if (density == mInitialDisplayDensity) {
             density = 0;
         }
-        mWmService.mDisplayWindowSettings.setForcedDensity(this, density, userId);
+        mWmService.mDisplayWindowSettings.setForcedDensity(getDisplayInfo(), density, userId);
     }
 
     /** @param mode {@link #FORCE_SCALING_MODE_AUTO} or {@link #FORCE_SCALING_MODE_DISABLED}. */
@@ -5948,6 +5948,7 @@
         }
     }
 
+    @Nullable
     ActivityRecord topRunningActivity() {
         return topRunningActivity(false /* considerKeyguardState */);
     }
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 0bb4022..f8fd2b9 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -142,6 +142,7 @@
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.internal.statusbar.LetterboxDetails;
 import com.android.internal.util.ScreenshotHelper;
+import com.android.internal.util.ScreenshotRequest;
 import com.android.internal.util.function.TriConsumer;
 import com.android.internal.view.AppearanceRegion;
 import com.android.internal.widget.PointerLocationView;
@@ -2666,8 +2667,9 @@
      */
     public void takeScreenshot(int screenshotType, int source) {
         if (mScreenshotHelper != null) {
-            mScreenshotHelper.takeScreenshot(screenshotType,
-                    source, mHandler, null /* completionConsumer */);
+            ScreenshotRequest request =
+                    new ScreenshotRequest.Builder(screenshotType, source).build();
+            mScreenshotHelper.takeScreenshot(request, mHandler, null /* completionConsumer */);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index cf3a688..e6d8b3d 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -100,6 +100,8 @@
     private final DisplayWindowSettings mDisplayWindowSettings;
     private final Context mContext;
     private final Object mLock;
+    @Nullable
+    private final DisplayRotationImmersiveAppCompatPolicy mCompatPolicyForImmersiveApps;
 
     public final boolean isDefaultDisplay;
     private final boolean mSupportAutoRotation;
@@ -205,7 +207,7 @@
 
     /**
      * A flag to indicate if the display rotation should be fixed to user specified rotation
-     * regardless of all other states (including app requrested orientation). {@code true} the
+     * regardless of all other states (including app requested orientation). {@code true} the
      * display rotation should be fixed to user specified rotation, {@code false} otherwise.
      */
     private int mFixedToUserRotation = IWindowManager.FIXED_TO_USER_ROTATION_DEFAULT;
@@ -232,6 +234,7 @@
         mContext = context;
         mLock = lock;
         isDefaultDisplay = displayContent.isDefaultDisplay;
+        mCompatPolicyForImmersiveApps = initImmersiveAppCompatPolicy(service, displayContent);
 
         mSupportAutoRotation =
                 mContext.getResources().getBoolean(R.bool.config_supportAutoRotation);
@@ -255,6 +258,14 @@
         }
     }
 
+    @VisibleForTesting
+    @Nullable
+    DisplayRotationImmersiveAppCompatPolicy initImmersiveAppCompatPolicy(
+                WindowManagerService service, DisplayContent displayContent) {
+        return DisplayRotationImmersiveAppCompatPolicy.createIfNeeded(
+                service.mLetterboxConfiguration, this, displayContent);
+    }
+
     // Change the default value to the value specified in the sysprop
     // ro.bootanim.set_orientation_<display_id>. Four values are supported: ORIENTATION_0,
     // ORIENTATION_90, ORIENTATION_180 and ORIENTATION_270.
@@ -1305,11 +1316,11 @@
         return mAllowAllRotations;
     }
 
-    private boolean isLandscapeOrSeascape(int rotation) {
+    boolean isLandscapeOrSeascape(@Surface.Rotation final int rotation) {
         return rotation == mLandscapeRotation || rotation == mSeascapeRotation;
     }
 
-    private boolean isAnyPortrait(int rotation) {
+    boolean isAnyPortrait(@Surface.Rotation final int rotation) {
         return rotation == mPortraitRotation || rotation == mUpsideDownRotation;
     }
 
@@ -1348,9 +1359,16 @@
         return mFoldController != null && mFoldController.overrideFrozenRotation();
     }
 
-    private boolean isRotationChoicePossible(int orientation) {
-        // Rotation choice is only shown when the user is in locked mode.
-        if (mUserRotationMode != WindowManagerPolicy.USER_ROTATION_LOCKED) return false;
+    private boolean isRotationChoiceAllowed(@Surface.Rotation final int proposedRotation) {
+        final boolean isRotationLockEnforced = mCompatPolicyForImmersiveApps != null
+                && mCompatPolicyForImmersiveApps.isRotationLockEnforced(proposedRotation);
+
+        // Don't show rotation choice button if
+        if (!isRotationLockEnforced // not enforcing locked rotation
+                // and the screen rotation is not locked by the user.
+                && mUserRotationMode != WindowManagerPolicy.USER_ROTATION_LOCKED) {
+            return false;
+        }
 
         // Don't show rotation choice if we are in tabletop or book modes.
         if (isTabletopAutoRotateOverrideEnabled()) return false;
@@ -1402,7 +1420,7 @@
         }
 
         // Ensure that some rotation choice is possible for the given orientation.
-        switch (orientation) {
+        switch (mCurrentAppOrientation) {
             case ActivityInfo.SCREEN_ORIENTATION_FULL_USER:
             case ActivityInfo.SCREEN_ORIENTATION_USER:
             case ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED:
@@ -1719,11 +1737,11 @@
 
 
         @Override
-        public void onProposedRotationChanged(int rotation) {
+        public void onProposedRotationChanged(@Surface.Rotation int rotation) {
             ProtoLog.v(WM_DEBUG_ORIENTATION, "onProposedRotationChanged, rotation=%d", rotation);
             // Send interaction power boost to improve redraw performance.
             mService.mPowerManagerInternal.setPowerBoost(Boost.INTERACTION, 0);
-            if (isRotationChoicePossible(mCurrentAppOrientation)) {
+            if (isRotationChoiceAllowed(rotation)) {
                 final boolean isValid = isValidRotationChoice(rotation);
                 sendProposedRotationChangeToStatusBarInternal(rotation, isValid);
             } else {
diff --git a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
index 7266d21..c6037da 100644
--- a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
@@ -203,8 +203,11 @@
                 || !shouldRefreshActivity(activity, newConfig, lastReportedConfig)) {
             return;
         }
-        boolean cycleThroughStop = mWmService.mLetterboxConfiguration
-                .isCameraCompatRefreshCycleThroughStopEnabled();
+        boolean cycleThroughStop =
+                mWmService.mLetterboxConfiguration
+                        .isCameraCompatRefreshCycleThroughStopEnabled()
+                && !activity.mLetterboxUiController
+                        .shouldRefreshActivityViaPauseForCameraCompat();
         try {
             activity.mLetterboxUiController.setIsRefreshAfterRotationRequested(true);
             ProtoLog.v(WM_DEBUG_STATES,
@@ -255,7 +258,8 @@
             Configuration lastReportedConfig) {
         return newConfig.windowConfiguration.getDisplayRotation()
                         != lastReportedConfig.windowConfiguration.getDisplayRotation()
-                && isTreatmentEnabledForActivity(activity);
+                && isTreatmentEnabledForActivity(activity)
+                && activity.mLetterboxUiController.shouldRefreshActivityForCameraCompat();
     }
 
     /**
@@ -287,14 +291,15 @@
      *     <li>The activity has fixed orientation but not "locked" or "nosensor" one.
      * </ul>
      */
-    private boolean isTreatmentEnabledForActivity(@Nullable ActivityRecord activity) {
+    boolean isTreatmentEnabledForActivity(@Nullable ActivityRecord activity) {
         return activity != null && !activity.inMultiWindowMode()
                 && activity.getRequestedConfigurationOrientation() != ORIENTATION_UNDEFINED
                 // "locked" and "nosensor" values are often used by camera apps that can't
                 // handle dynamic changes so we shouldn't force rotate them.
                 && activity.getRequestedOrientation() != SCREEN_ORIENTATION_NOSENSOR
                 && activity.getRequestedOrientation() != SCREEN_ORIENTATION_LOCKED
-                && mCameraIdPackageBiMap.containsPackageName(activity.packageName);
+                && mCameraIdPackageBiMap.containsPackageName(activity.packageName)
+                && activity.mLetterboxUiController.shouldForceRotateForCameraCompat();
     }
 
     private synchronized void notifyCameraOpened(
diff --git a/services/core/java/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicy.java b/services/core/java/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicy.java
new file mode 100644
index 0000000..4dad2b2
--- /dev/null
+++ b/services/core/java/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicy.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
+import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.res.Configuration.Orientation;
+import android.view.InsetsVisibilities;
+import android.view.Surface;
+
+/**
+ * Policy to decide whether to enforce screen rotation lock for optimisation of the screen rotation
+ * user experience for immersive applications for compatibility when ignoring orientation request.
+ *
+ * <p>This is needed because immersive apps, such as games, are often not optimized for all
+ * orientations and can have a poor UX when rotated (e.g., state loss or entering size-compat mode).
+ * Additionally, some games rely on sensors for the gameplay so users can trigger such rotations
+ * accidentally when auto rotation is on.
+ */
+final class DisplayRotationImmersiveAppCompatPolicy {
+
+    @Nullable
+    static DisplayRotationImmersiveAppCompatPolicy createIfNeeded(
+            @NonNull final LetterboxConfiguration letterboxConfiguration,
+            @NonNull final DisplayRotation displayRotation,
+            @NonNull final DisplayContent displayContent) {
+        if (!letterboxConfiguration
+                .isDisplayRotationImmersiveAppCompatPolicyEnabled(/* checkDeviceConfig */ false)) {
+            return null;
+        }
+
+        return new DisplayRotationImmersiveAppCompatPolicy(
+                letterboxConfiguration, displayRotation, displayContent);
+    }
+
+    private final DisplayRotation mDisplayRotation;
+    private final LetterboxConfiguration mLetterboxConfiguration;
+    private final DisplayContent mDisplayContent;
+
+    private DisplayRotationImmersiveAppCompatPolicy(
+            @NonNull final LetterboxConfiguration letterboxConfiguration,
+            @NonNull final DisplayRotation displayRotation,
+            @NonNull final DisplayContent displayContent) {
+        mDisplayRotation = displayRotation;
+        mLetterboxConfiguration = letterboxConfiguration;
+        mDisplayContent = displayContent;
+    }
+
+    /**
+     * Decides whether it is necessary to lock screen rotation, preventing auto rotation, based on
+     * the top activity configuration and proposed screen rotation.
+     *
+     * <p>This is needed because immersive apps, such as games, are often not optimized for all
+     * orientations and can have a poor UX when rotated. Additionally, some games rely on sensors
+     * for the gameplay so users can trigger such rotations accidentally when auto rotation is on.
+     *
+     * <p>Screen rotation is locked when the following conditions are met:
+     * <ul>
+     *   <li>Top activity requests to hide status and navigation bars
+     *   <li>Top activity is fullscreen and in optimal orientation (without letterboxing)
+     *   <li>Rotation will lead to letterboxing due to fixed orientation.
+     *   <li>{@link DisplayContent#getIgnoreOrientationRequest} is {@code true}
+     *   <li>This policy is enabled on the device, for details see
+     *   {@link LetterboxConfiguration#isDisplayRotationImmersiveAppCompatPolicyEnabled}
+     * </ul>
+     *
+     * @param proposedRotation new proposed {@link Surface.Rotation} for the screen.
+     * @return {@code true}, if there is a need to lock screen rotation, {@code false} otherwise.
+     */
+    boolean isRotationLockEnforced(@Surface.Rotation final int proposedRotation) {
+        if (!mLetterboxConfiguration.isDisplayRotationImmersiveAppCompatPolicyEnabled(
+                /* checkDeviceConfig */ true)) {
+            return false;
+        }
+        synchronized (mDisplayContent.mWmService.mGlobalLock) {
+            return isRotationLockEnforcedLocked(proposedRotation);
+        }
+    }
+
+    private boolean isRotationLockEnforcedLocked(@Surface.Rotation final int proposedRotation) {
+        if (!mDisplayContent.getIgnoreOrientationRequest()) {
+            return false;
+        }
+
+        final ActivityRecord activityRecord = mDisplayContent.topRunningActivity();
+        if (activityRecord == null) {
+            return false;
+        }
+
+        // Don't lock screen rotation if an activity hasn't requested to hide system bars.
+        if (!hasRequestedToHideStatusAndNavBars(activityRecord)) {
+            return false;
+        }
+
+        // Don't lock screen rotation if activity is not in fullscreen. Checking windowing mode
+        // for a task rather than an activity to exclude activity embedding scenario.
+        if (activityRecord.getTask() == null
+                || activityRecord.getTask().getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
+            return false;
+        }
+
+        // Don't lock screen rotation if activity is letterboxed.
+        if (activityRecord.areBoundsLetterboxed()) {
+            return false;
+        }
+
+        if (activityRecord.getRequestedConfigurationOrientation() == ORIENTATION_UNDEFINED) {
+            return false;
+        }
+
+        // Lock screen rotation only if, after rotation the activity's orientation won't match
+        // the screen orientation, forcing the activity to enter letterbox mode after rotation.
+        return activityRecord.getRequestedConfigurationOrientation()
+                != surfaceRotationToConfigurationOrientation(proposedRotation);
+    }
+
+    /**
+     * Checks whether activity has requested to hide status and navigation bars.
+     */
+    private boolean hasRequestedToHideStatusAndNavBars(@NonNull ActivityRecord activity) {
+        WindowState mainWindow = activity.findMainWindow();
+        if (mainWindow == null) {
+            return false;
+        }
+        InsetsVisibilities insetsVisibilities = mainWindow.getRequestedVisibilities();
+        return !insetsVisibilities.getVisibility(ITYPE_STATUS_BAR)
+                && !insetsVisibilities.getVisibility(ITYPE_NAVIGATION_BAR);
+    }
+
+    @Orientation
+    private int surfaceRotationToConfigurationOrientation(@Surface.Rotation final int rotation) {
+        if (mDisplayRotation.isAnyPortrait(rotation)) {
+            return ORIENTATION_PORTRAIT;
+        } else if (mDisplayRotation.isLandscapeOrSeascape(rotation)) {
+            return ORIENTATION_LANDSCAPE;
+        } else {
+            return ORIENTATION_UNDEFINED;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettings.java b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
index c1b6496..d87532a 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowSettings.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
@@ -77,14 +77,14 @@
         mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
     }
 
-    void setForcedDensity(DisplayContent displayContent, int density, int userId) {
-        if (displayContent.isDefaultDisplay) {
+    void setForcedDensity(DisplayInfo info, int density, int userId) {
+        if (info.displayId == Display.DEFAULT_DISPLAY) {
             final String densityString = density == 0 ? "" : Integer.toString(density);
             Settings.Secure.putStringForUser(mService.mContext.getContentResolver(),
                     Settings.Secure.DISPLAY_DENSITY_FORCED, densityString, userId);
         }
 
-        final DisplayInfo displayInfo = displayContent.getDisplayInfo();
+        final DisplayInfo displayInfo = info;
         final SettingsProvider.SettingsEntry overrideSettings =
                 mSettingsProvider.getOverrideSettings(displayInfo);
         overrideSettings.mForcedDensity = density;
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index 506396a..f578fe0 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -454,8 +454,7 @@
             final InsetsSource originalImeSource = originalState.peekSource(ITYPE_IME);
 
             if (originalImeSource != null) {
-                final boolean imeVisibility =
-                        w.mActivityRecord.mLastImeShown || w.getRequestedVisibility(ITYPE_IME);
+                final boolean imeVisibility = w.getRequestedVisibility(ITYPE_IME);
                 final InsetsState state = copyState ? new InsetsState(originalState)
                         : originalState;
                 final InsetsSource imeSource = new InsetsSource(originalImeSource);
diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
index 03c5589..800fe09 100644
--- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java
+++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
@@ -18,11 +18,14 @@
 
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.LetterboxConfigurationDeviceConfig.KEY_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
 import android.graphics.Color;
 import android.provider.DeviceConfig;
 import android.util.Slog;
@@ -39,6 +42,10 @@
 
     private static final String TAG = TAG_WITH_CLASS_NAME ? "LetterboxConfiguration" : TAG_ATM;
 
+    @VisibleForTesting
+    static final String DEVICE_CONFIG_KEY_ENABLE_COMPAT_FAKE_FOCUS =
+            "enable_compat_fake_focus";
+
     /**
      * Override of aspect ratio for fixed orientation letterboxing that is set via ADB with
      * set-fixed-orientation-letterbox-aspect-ratio or via {@link
@@ -108,6 +115,12 @@
     /** Letterboxed app window is aligned to the right side. */
     static final int LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM = 2;
 
+    @VisibleForTesting
+    static final String PROPERTY_COMPAT_FAKE_FOCUS_OPT_IN = "com.android.COMPAT_FAKE_FOCUS_OPT_IN";
+    @VisibleForTesting
+    static final String PROPERTY_COMPAT_FAKE_FOCUS_OPT_OUT =
+            "com.android.COMPAT_FAKE_FOCUS_OPT_OUT";
+
     final Context mContext;
 
     // Responsible for the persistence of letterbox[Horizontal|Vertical]PositionMultiplier
@@ -184,6 +197,12 @@
     // Whether using split screen aspect ratio as a default aspect ratio for unresizable apps.
     private boolean mIsSplitScreenAspectRatioForUnresizableAppsEnabled;
 
+    // Whether using display aspect ratio as a default aspect ratio for all letterboxed apps.
+    // mIsSplitScreenAspectRatioForUnresizableAppsEnabled and
+    // config_letterboxDefaultMinAspectRatioForUnresizableApps take priority over this for
+    // unresizable apps
+    private boolean mIsDisplayAspectRatioEnabledForFixedOrientationLetterbox;
+
     // Whether letterboxing strategy is enabled for translucent activities. If {@value false}
     // all the feature is disabled
     private boolean mTranslucentLetterboxingEnabled;
@@ -210,23 +229,40 @@
     // See RefreshCallbackItem for context.
     private boolean mIsCameraCompatRefreshCycleThroughStopEnabled = true;
 
-    LetterboxConfiguration(Context systemUiContext) {
-        this(systemUiContext, new LetterboxConfigurationPersister(systemUiContext,
-                () -> readLetterboxHorizontalReachabilityPositionFromConfig(systemUiContext,
-                        /* forBookMode */ false),
-                () -> readLetterboxVerticalReachabilityPositionFromConfig(systemUiContext,
-                        /* forTabletopMode */ false),
-                () -> readLetterboxHorizontalReachabilityPositionFromConfig(systemUiContext,
-                        /* forBookMode */ true),
-                () -> readLetterboxVerticalReachabilityPositionFromConfig(systemUiContext,
-                        /* forTabletopMode */ true)
-        ));
+    // Whether should ignore app requested orientation in response to an app
+    // calling Activity#setRequestedOrientation. See
+    // LetterboxUiController#shouldIgnoreRequestedOrientation for details.
+    private final boolean mIsPolicyForIgnoringRequestedOrientationEnabled;
+
+    // Whether enabling rotation compat policy for immersive apps that prevents auto rotation
+    // into non-optimal screen orientation while in fullscreen. This is needed because immersive
+    // apps, such as games, are often not optimized for all orientations and can have a poor UX
+    // when rotated. Additionally, some games rely on sensors for the gameplay so users can trigger
+    // such rotations accidentally when auto rotation is on.
+    private final boolean mIsDisplayRotationImmersiveAppCompatPolicyEnabled;
+
+    // Flags dynamically updated with {@link android.provider.DeviceConfig}.
+    @NonNull private final LetterboxConfigurationDeviceConfig mDeviceConfig;
+
+    LetterboxConfiguration(@NonNull final Context systemUiContext) {
+        this(systemUiContext,
+                new LetterboxConfigurationPersister(systemUiContext,
+                        () -> readLetterboxHorizontalReachabilityPositionFromConfig(
+                                systemUiContext, /* forBookMode */ false),
+                        () -> readLetterboxVerticalReachabilityPositionFromConfig(
+                                systemUiContext, /* forTabletopMode */ false),
+                        () -> readLetterboxHorizontalReachabilityPositionFromConfig(
+                                systemUiContext, /* forBookMode */ true),
+                        () -> readLetterboxVerticalReachabilityPositionFromConfig(
+                                systemUiContext, /* forTabletopMode */ true)));
     }
 
     @VisibleForTesting
-    LetterboxConfiguration(Context systemUiContext,
-            LetterboxConfigurationPersister letterboxConfigurationPersister) {
+    LetterboxConfiguration(@NonNull final Context systemUiContext,
+            @NonNull final LetterboxConfigurationPersister letterboxConfigurationPersister) {
         mContext = systemUiContext;
+        mDeviceConfig = new LetterboxConfigurationDeviceConfig(systemUiContext.getMainExecutor());
+
         mFixedOrientationLetterboxAspectRatio = mContext.getResources().getFloat(
                 R.dimen.config_fixedOrientationLetterboxAspectRatio);
         mLetterboxActivityCornersRadius = mContext.getResources().getInteger(
@@ -258,14 +294,26 @@
                 R.dimen.config_letterboxDefaultMinAspectRatioForUnresizableApps));
         mIsSplitScreenAspectRatioForUnresizableAppsEnabled = mContext.getResources().getBoolean(
                 R.bool.config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled);
+        mIsDisplayAspectRatioEnabledForFixedOrientationLetterbox = mContext.getResources()
+                .getBoolean(R.bool
+                        .config_letterboxIsDisplayAspectRatioForFixedOrientationLetterboxEnabled);
         mTranslucentLetterboxingEnabled = mContext.getResources().getBoolean(
                 R.bool.config_letterboxIsEnabledForTranslucentActivities);
         mIsCameraCompatTreatmentEnabled = mContext.getResources().getBoolean(
                 R.bool.config_isWindowManagerCameraCompatTreatmentEnabled);
+        mIsCompatFakeFocusEnabled = mContext.getResources().getBoolean(
+                R.bool.config_isCompatFakeFocusEnabled);
+        mIsPolicyForIgnoringRequestedOrientationEnabled = mContext.getResources().getBoolean(
+                R.bool.config_letterboxIsPolicyForIgnoringRequestedOrientationEnabled);
+
+        mIsDisplayRotationImmersiveAppCompatPolicyEnabled = mContext.getResources().getBoolean(
+                R.bool.config_letterboxIsDisplayRotationImmersiveAppCompatPolicyEnabled);
+        mDeviceConfig.updateFlagActiveStatus(
+                /* isActive */ mIsDisplayRotationImmersiveAppCompatPolicyEnabled,
+                /* key */ KEY_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY);
+
         mLetterboxConfigurationPersister = letterboxConfigurationPersister;
         mLetterboxConfigurationPersister.start();
-        mIsCompatFakeFocusEnabled = mContext.getResources()
-                .getBoolean(R.bool.config_isCompatFakeFocusEnabled);
     }
 
     /**
@@ -904,6 +952,13 @@
     }
 
     /**
+     * Whether using display aspect ratio as a default aspect ratio for all letterboxed apps.
+     */
+    boolean getIsDisplayAspectRatioEnabledForFixedOrientationLetterbox() {
+        return mIsDisplayAspectRatioEnabledForFixedOrientationLetterbox;
+    }
+
+    /**
      * Overrides whether using split screen aspect ratio as a default aspect ratio for unresizable
      * apps.
      */
@@ -912,6 +967,14 @@
     }
 
     /**
+     * Overrides whether using display aspect ratio as a default aspect ratio for all letterboxed
+     * apps.
+     */
+    void setIsDisplayAspectRatioEnabledForFixedOrientationLetterbox(boolean enabled) {
+        mIsDisplayAspectRatioEnabledForFixedOrientationLetterbox = enabled;
+    }
+
+    /**
      * Resets whether using split screen aspect ratio as a default aspect ratio for unresizable
      * apps {@link R.bool.config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled}.
      */
@@ -920,6 +983,16 @@
                 R.bool.config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled);
     }
 
+    /**
+     * Resets whether using display aspect ratio as a default aspect ratio for all letterboxed
+     * apps {@link R.bool.config_letterboxIsDisplayAspectRatioForFixedOrientationLetterboxEnabled}.
+     */
+    void resetIsDisplayAspectRatioEnabledForFixedOrientationLetterbox() {
+        mIsDisplayAspectRatioEnabledForFixedOrientationLetterbox = mContext.getResources()
+                .getBoolean(R.bool
+                        .config_letterboxIsDisplayAspectRatioForFixedOrientationLetterboxEnabled);
+    }
+
     boolean isTranslucentLetterboxingEnabled() {
         return mTranslucentLetterboxingOverrideEnabled || (mTranslucentLetterboxingEnabled
                 && isTranslucentLetterboxingAllowed());
@@ -977,11 +1050,58 @@
                 "enable_translucent_activity_letterbox", false);
     }
 
-    // TODO(b/262866240): Add listener to check for device config property
+    @VisibleForTesting
+    boolean getPackageManagerProperty(PackageManager pm, String property) {
+        boolean enabled = false;
+        try {
+            final PackageManager.Property p = pm.getProperty(property, mContext.getPackageName());
+            enabled = p.getBoolean();
+        } catch (PackageManager.NameNotFoundException e) {
+            // Property not found
+        }
+        return enabled;
+    }
+
+    @VisibleForTesting
+    boolean isCompatFakeFocusEnabled(ActivityInfo info) {
+        if (!isCompatFakeFocusEnabledOnDevice()) {
+            return false;
+        }
+        // See if the developer has chosen to opt in / out of treatment
+        PackageManager pm = mContext.getPackageManager();
+        if (getPackageManagerProperty(pm, PROPERTY_COMPAT_FAKE_FOCUS_OPT_OUT)) {
+            return false;
+        } else if (getPackageManagerProperty(pm, PROPERTY_COMPAT_FAKE_FOCUS_OPT_IN)) {
+            return true;
+        }
+        if (info.isChangeEnabled(ActivityInfo.OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS)) {
+            return true;
+        }
+        return false;
+    }
+
     /** Whether fake sending focus is enabled for unfocused apps in splitscreen */
-    boolean isCompatFakeFocusEnabled() {
-        return mIsCompatFakeFocusEnabled && DeviceConfig.getBoolean(
-                DeviceConfig.NAMESPACE_WINDOW_MANAGER, "enable_compat_fake_focus", true);
+    boolean isCompatFakeFocusEnabledOnDevice() {
+        return mIsCompatFakeFocusEnabled
+                && DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+                        DEVICE_CONFIG_KEY_ENABLE_COMPAT_FAKE_FOCUS, true);
+    }
+
+    /**
+     * Overrides whether fake sending focus is enabled for unfocused apps in splitscreen
+     */
+    @VisibleForTesting
+    void setIsCompatFakeFocusEnabled(boolean enabled) {
+        mIsCompatFakeFocusEnabled = enabled;
+    }
+
+    /**
+     * Whether should ignore app requested orientation in response to an app calling
+     * {@link android.app.Activity#setRequestedOrientation}. See {@link
+     * LetterboxUiController#shouldIgnoreRequestedOrientation} for details.
+     */
+    boolean isPolicyForIgnoringRequestedOrientationEnabled() {
+        return mIsPolicyForIgnoringRequestedOrientationEnabled;
     }
 
     /** Whether camera compatibility treatment is enabled. */
@@ -994,7 +1114,7 @@
     // DeviceConfig.OnPropertiesChangedListener
     private static boolean isCameraCompatTreatmentAllowed() {
         return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
-                "enable_camera_compat_treatment", false);
+                "enable_compat_camera_treatment", true);
     }
 
     /** Whether camera compatibility refresh is enabled. */
@@ -1038,4 +1158,20 @@
         mIsCameraCompatRefreshCycleThroughStopEnabled = true;
     }
 
+    /**
+     * Checks whether rotation compat policy for immersive apps that prevents auto rotation
+     * into non-optimal screen orientation while in fullscreen is enabled.
+     *
+     * <p>This is needed because immersive apps, such as games, are often not optimized for all
+     * orientations and can have a poor UX when rotated. Additionally, some games rely on sensors
+     * for the gameplay so users can trigger such rotations accidentally when auto rotation is on.
+     *
+     * @param checkDeviceConfig whether should check both static config and a dynamic property
+     *        from {@link DeviceConfig} or only static value.
+     */
+    boolean isDisplayRotationImmersiveAppCompatPolicyEnabled(final boolean checkDeviceConfig) {
+        return mIsDisplayRotationImmersiveAppCompatPolicyEnabled && (!checkDeviceConfig
+                || mDeviceConfig.getFlag(KEY_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY));
+    }
+
 }
diff --git a/services/core/java/com/android/server/wm/LetterboxConfigurationDeviceConfig.java b/services/core/java/com/android/server/wm/LetterboxConfigurationDeviceConfig.java
new file mode 100644
index 0000000..cf123a1
--- /dev/null
+++ b/services/core/java/com/android/server/wm/LetterboxConfigurationDeviceConfig.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.annotation.NonNull;
+import android.provider.DeviceConfig;
+import android.util.ArraySet;
+
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+/**
+ * Utility class that caches {@link DeviceConfig} flags for app compat features and listens
+ * to updates by implementing {@link DeviceConfig.OnPropertiesChangedListener}.
+ */
+final class LetterboxConfigurationDeviceConfig
+        implements DeviceConfig.OnPropertiesChangedListener {
+
+    static final String KEY_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY =
+            "enable_display_rotation_immersive_app_compat_policy";
+    private static final boolean DEFAULT_VALUE_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY =
+            true;
+
+    @VisibleForTesting
+    static final Map<String, Boolean> sKeyToDefaultValueMap = Map.of(
+            KEY_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY,
+            DEFAULT_VALUE_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY
+    );
+
+    // Whether enabling rotation compat policy for immersive apps that prevents auto rotation
+    // into non-optimal screen orientation while in fullscreen. This is needed because immersive
+    // apps, such as games, are often not optimized for all orientations and can have a poor UX
+    // when rotated. Additionally, some games rely on sensors for the gameplay so users can trigger
+    // such rotations accidentally when auto rotation is on.
+    private boolean mIsDisplayRotationImmersiveAppCompatPolicyEnabled =
+            DEFAULT_VALUE_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY;
+
+    // Set of active device configs that need to be updated in
+    // DeviceConfig.OnPropertiesChangedListener#onPropertiesChanged.
+    private final ArraySet<String> mActiveDeviceConfigsSet = new ArraySet<>();
+
+    LetterboxConfigurationDeviceConfig(@NonNull final Executor executor) {
+        DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+                executor, /* onPropertiesChangedListener */ this);
+    }
+
+    @Override
+    public void onPropertiesChanged(@NonNull final DeviceConfig.Properties properties) {
+        for (int i = mActiveDeviceConfigsSet.size() - 1; i >= 0; i--) {
+            String key = mActiveDeviceConfigsSet.valueAt(i);
+            // Reads the new configuration, if the device config properties contain the key.
+            if (properties.getKeyset().contains(key)) {
+                readAndSaveValueFromDeviceConfig(key);
+            }
+        }
+    }
+
+    /**
+     * Adds {@code key} to a set of flags that can be updated from the server if
+     * {@code isActive} is {@code true} and read it's current value from {@link DeviceConfig}.
+     */
+    void updateFlagActiveStatus(boolean isActive, String key) {
+        if (!isActive) {
+            return;
+        }
+        mActiveDeviceConfigsSet.add(key);
+        readAndSaveValueFromDeviceConfig(key);
+    }
+
+    /**
+     * Returns values of the {@code key} flag.
+     *
+     * @throws AssertionError {@code key} isn't recognised.
+     */
+    boolean getFlag(String key) {
+        switch (key) {
+            case KEY_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY:
+                return mIsDisplayRotationImmersiveAppCompatPolicyEnabled;
+            default:
+                throw new AssertionError("Unexpected flag name: " + key);
+        }
+    }
+
+    private void readAndSaveValueFromDeviceConfig(String key) {
+        Boolean defaultValue = sKeyToDefaultValueMap.get(key);
+        if (defaultValue == null) {
+            throw new AssertionError("Haven't found default value for flag: " + key);
+        }
+        switch (key) {
+            case KEY_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY:
+                mIsDisplayRotationImmersiveAppCompatPolicyEnabled =
+                        getDeviceConfig(key, defaultValue);
+                break;
+            default:
+                throw new AssertionError("Unexpected flag name: " + key);
+        }
+    }
+
+    private boolean getDeviceConfig(String key, boolean defaultValue) {
+        return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+                key, defaultValue);
+    }
+}
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index fd7e082..67e188f 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -17,10 +17,19 @@
 package com.android.server.wm;
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
+import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.content.pm.ActivityInfo.screenOrientationToString;
 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION;
+import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH;
+import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
+import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION;
 
 import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__BOTTOM;
 import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__CENTER;
@@ -55,6 +64,8 @@
 
 import android.annotation.Nullable;
 import android.app.ActivityManager.TaskDescription;
+import android.content.pm.ActivityInfo.ScreenOrientation;
+import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Color;
@@ -74,6 +85,7 @@
 import com.android.server.wm.LetterboxConfiguration.LetterboxBackgroundType;
 
 import java.io.PrintWriter;
+import java.util.function.BooleanSupplier;
 
 /** Controls behaviour of the letterbox UI for {@link mActivityRecord}. */
 // TODO(b/185262487): Improve test coverage of this class. Parts of it are tested in
@@ -126,17 +138,76 @@
     @Nullable
     private Letterbox mLetterbox;
 
+    @Nullable
+    private final Boolean mBooleanPropertyCameraCompatAllowForceRotation;
+
+    @Nullable
+    private final Boolean mBooleanPropertyCameraCompatAllowRefresh;
+
+    @Nullable
+    private final Boolean mBooleanPropertyCameraCompatEnableRefreshViaPause;
+
     // Whether activity "refresh" was requested but not finished in
     // ActivityRecord#activityResumedLocked following the camera compat force rotation in
     // DisplayRotationCompatPolicy.
     private boolean mIsRefreshAfterRotationRequested;
 
+    @Nullable
+    private final Boolean mBooleanPropertyIgnoreRequestedOrientation;
+
+    private boolean mIsRelauchingAfterRequestedOrientationChanged;
+
     LetterboxUiController(WindowManagerService wmService, ActivityRecord activityRecord) {
         mLetterboxConfiguration = wmService.mLetterboxConfiguration;
         // Given activityRecord may not be fully constructed since LetterboxUiController
         // is created in its constructor. It shouldn't be used in this constructor but it's safe
         // to use it after since controller is only used in ActivityRecord.
         mActivityRecord = activityRecord;
+
+        PackageManager packageManager = wmService.mContext.getPackageManager();
+        mBooleanPropertyIgnoreRequestedOrientation =
+                readComponentProperty(packageManager, mActivityRecord.packageName,
+                        mLetterboxConfiguration::isPolicyForIgnoringRequestedOrientationEnabled,
+                        PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION);
+        mBooleanPropertyCameraCompatAllowForceRotation =
+                readComponentProperty(packageManager, mActivityRecord.packageName,
+                        () -> mLetterboxConfiguration.isCameraCompatTreatmentEnabled(
+                                /* checkDeviceConfig */ true),
+                        PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION);
+        mBooleanPropertyCameraCompatAllowRefresh =
+                readComponentProperty(packageManager, mActivityRecord.packageName,
+                        () -> mLetterboxConfiguration.isCameraCompatTreatmentEnabled(
+                                /* checkDeviceConfig */ true),
+                        PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH);
+        mBooleanPropertyCameraCompatEnableRefreshViaPause =
+                readComponentProperty(packageManager, mActivityRecord.packageName,
+                        () -> mLetterboxConfiguration.isCameraCompatTreatmentEnabled(
+                                /* checkDeviceConfig */ true),
+                        PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE);
+    }
+
+    /**
+     * Reads a {@link Boolean} component property fot a given {@code packageName} and a {@code
+     * propertyName}. Returns {@code null} if {@code gatingCondition} is {@code false} or if the
+     * property isn't specified for the package.
+     *
+     * <p>Return value is {@link Boolean} rather than {@code boolean} so we can know when the
+     * property is unset. Particularly, when this returns {@code null}, {@link
+     * #shouldEnableWithOverrideAndProperty} will check the value of override for the final
+     * decision.
+     */
+    @Nullable
+    private static Boolean readComponentProperty(PackageManager packageManager, String packageName,
+            BooleanSupplier gatingCondition, String propertyName) {
+        if (!gatingCondition.getAsBoolean()) {
+            return null;
+        }
+        try {
+            return packageManager.getProperty(propertyName, packageName).getBoolean();
+        } catch (PackageManager.NameNotFoundException e) {
+            // No such property name.
+        }
+        return null;
     }
 
     /** Cleans up {@link Letterbox} if it exists.*/
@@ -154,6 +225,68 @@
     }
 
     /**
+     * Whether should ignore app requested orientation in response to an app
+     * calling {@link android.app.Activity#setRequestedOrientation}.
+     *
+     * <p>This is needed to avoid getting into {@link android.app.Activity#setRequestedOrientation}
+     * loop when {@link DisplayContent#getIgnoreOrientationRequest} is enabled or device has
+     * landscape natural orientation which app developers don't expect. For example, the loop can
+     * look like this:
+     * <ol>
+     *     <li>App sets default orientation to "unspecified" at runtime
+     *     <li>App requests to "portrait" after checking some condition (e.g. display rotation).
+     *     <li>(2) leads to fullscreen -> letterboxed bounds change and activity relaunch because
+     *     app can't handle the corresponding config changes.
+     *     <li>Loop goes back to (1)
+     * </ol>
+     *
+     * <p>This treatment is enabled when the following conditions are met:
+     * <ul>
+     *     <li>Flag gating the treatment is enabled
+     *     <li>Opt-out component property isn't enabled
+     *     <li>Opt-in component property or per-app override are enabled
+     *     <li>Activity is relaunched after {@link android.app.Activity#setRequestedOrientation}
+     *     call from an app or camera compat force rotation treatment is active for the activity.
+     * </ul>
+     */
+    boolean shouldIgnoreRequestedOrientation(@ScreenOrientation int requestedOrientation) {
+        if (!shouldEnableWithOverrideAndProperty(
+                /* gatingCondition */ mLetterboxConfiguration
+                        ::isPolicyForIgnoringRequestedOrientationEnabled,
+                OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION,
+                mBooleanPropertyIgnoreRequestedOrientation)) {
+            return false;
+        }
+        if (mIsRelauchingAfterRequestedOrientationChanged) {
+            Slog.w(TAG, "Ignoring orientation update to "
+                    + screenOrientationToString(requestedOrientation)
+                    + " due to relaunching after setRequestedOrientation for " + mActivityRecord);
+            return true;
+        }
+        DisplayContent displayContent = mActivityRecord.mDisplayContent;
+        if (displayContent == null) {
+            return false;
+        }
+        if (displayContent.mDisplayRotationCompatPolicy != null
+                && displayContent.mDisplayRotationCompatPolicy
+                        .isTreatmentEnabledForActivity(mActivityRecord)) {
+            Slog.w(TAG, "Ignoring orientation update to "
+                    + screenOrientationToString(requestedOrientation)
+                    + " due to camera compat treatment for " + mActivityRecord);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Sets whether an activity is relaunching after the app has called {@link
+     * android.app.Activity#setRequestedOrientation}.
+     */
+    void setRelauchingAfterRequestedOrientationChanged(boolean isRelaunching) {
+        mIsRelauchingAfterRequestedOrientationChanged = isRelaunching;
+    }
+
+    /**
      * Whether activity "refresh" was requested but not finished in {@link #activityResumedLocked}
      * following the camera compat force rotation in {@link DisplayRotationCompatPolicy}.
      */
@@ -165,6 +298,109 @@
         mIsRefreshAfterRotationRequested = isRequested;
     }
 
+    /**
+     * Whether activity is eligible for activity "refresh" after camera compat force rotation
+     * treatment. See {@link DisplayRotationCompatPolicy} for context.
+     *
+     * <p>This treatment is enabled when the following conditions are met:
+     * <ul>
+     *     <li>Flag gating the camera compat treatment is enabled.
+     *     <li>Activity isn't opted out by the device manufacturer with override or by the app
+     *     developers with the component property.
+     * </ul>
+     */
+    boolean shouldRefreshActivityForCameraCompat() {
+        return shouldEnableWithOptOutOverrideAndProperty(
+                /* gatingCondition */ () -> mLetterboxConfiguration
+                        .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true),
+                OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH,
+                mBooleanPropertyCameraCompatAllowRefresh);
+    }
+
+    /**
+     * Whether activity should be "refreshed" after the camera compat force rotation treatment
+     * using the "resumed -> paused -> resumed" cycle rather than the "resumed -> ... -> stopped
+     * -> ... -> resumed" cycle. See {@link DisplayRotationCompatPolicy} for context.
+     *
+     * <p>This treatment is enabled when the following conditions are met:
+     * <ul>
+     *     <li>Flag gating the camera compat treatment is enabled.
+     *     <li>Activity "refresh" via "resumed -> paused -> resumed" cycle isn't disabled with the
+     *     component property by the app developers.
+     *     <li>Activity "refresh" via "resumed -> paused -> resumed" cycle is enabled by the device
+     *     manufacturer with override / by the app developers with the component property.
+     * </ul>
+     */
+    boolean shouldRefreshActivityViaPauseForCameraCompat() {
+        return shouldEnableWithOverrideAndProperty(
+                /* gatingCondition */ () -> mLetterboxConfiguration
+                        .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true),
+                OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE,
+                mBooleanPropertyCameraCompatEnableRefreshViaPause);
+    }
+
+    /**
+     * Whether activity is eligible for camera compat force rotation treatment. See {@link
+     * DisplayRotationCompatPolicy} for context.
+     *
+     * <p>This treatment is enabled when the following conditions are met:
+     * <ul>
+     *     <li>Flag gating the camera compat treatment is enabled.
+     *     <li>Activity isn't opted out by the device manufacturer with override or by the app
+     *     developers with the component property.
+     * </ul>
+     */
+    boolean shouldForceRotateForCameraCompat() {
+        return shouldEnableWithOptOutOverrideAndProperty(
+                /* gatingCondition */ () -> mLetterboxConfiguration
+                        .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true),
+                OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION,
+                mBooleanPropertyCameraCompatAllowForceRotation);
+    }
+
+    /**
+     * Returns {@code true} when the following conditions are met:
+     * <ul>
+     *     <li>{@code gatingCondition} isn't {@code false}
+     *     <li>OEM didn't opt out with a {@code overrideChangeId} override
+     *     <li>App developers didn't opt out with a component {@code property}
+     * </ul>
+     *
+     * <p>This is used for the treatments that are enabled based with the heuristic but can be
+     * disabled on per-app basis by OEMs or app developers.
+     */
+    private boolean shouldEnableWithOptOutOverrideAndProperty(BooleanSupplier gatingCondition,
+            long overrideChangeId, Boolean property) {
+        if (!gatingCondition.getAsBoolean()) {
+            return false;
+        }
+        return !Boolean.FALSE.equals(property)
+                && !mActivityRecord.info.isChangeEnabled(overrideChangeId);
+    }
+
+    /**
+     * Returns {@code true} when the following conditions are met:
+     * <ul>
+     *     <li>{@code gatingCondition} isn't {@code false}
+     *     <li>App developers didn't opt out with a component {@code property}
+     *     <li>App developers opted in with a component {@code property} or an OEM opted in with a
+     *     component {@code property}
+     * </ul>
+     *
+     * <p>This is used for the treatments that are enabled only on per-app basis.
+     */
+    private boolean shouldEnableWithOverrideAndProperty(BooleanSupplier gatingCondition,
+            long overrideChangeId, Boolean property) {
+        if (!gatingCondition.getAsBoolean()) {
+            return false;
+        }
+        if (Boolean.FALSE.equals(property)) {
+            return false;
+        }
+        return Boolean.TRUE.equals(property)
+                || mActivityRecord.info.isChangeEnabled(overrideChangeId);
+    }
+
     boolean hasWallpaperBackgroundForLetterbox() {
         return mShowWallpaperForLetterboxBackground;
     }
@@ -348,7 +584,7 @@
                 ? getSplitScreenAspectRatio()
                 : mActivityRecord.shouldCreateCompatDisplayInsets()
                     ? getDefaultMinAspectRatioForUnresizableApps()
-                    : mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio();
+                    : getDefaultMinAspectRatio();
     }
 
     private float getDefaultMinAspectRatioForUnresizableApps() {
@@ -357,7 +593,7 @@
             return mLetterboxConfiguration.getDefaultMinAspectRatioForUnresizableApps()
                     > MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO
                             ? mLetterboxConfiguration.getDefaultMinAspectRatioForUnresizableApps()
-                            : mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio();
+                            : getDefaultMinAspectRatio();
         }
 
         return getSplitScreenAspectRatio();
@@ -385,6 +621,16 @@
         return computeAspectRatio(bounds);
     }
 
+    private float getDefaultMinAspectRatio() {
+        final DisplayContent displayContent = mActivityRecord.getDisplayContent();
+        if (displayContent == null
+                || !mLetterboxConfiguration
+                    .getIsDisplayAspectRatioEnabledForFixedOrientationLetterbox()) {
+            return mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio();
+        }
+        return computeAspectRatio(new Rect(displayContent.getBounds()));
+    }
+
     Resources getResources() {
         return mActivityRecord.mWmService.mContext.getResources();
     }
@@ -778,6 +1024,9 @@
                 + mLetterboxConfiguration.getDefaultMinAspectRatioForUnresizableApps());
         pw.println(prefix + "  isSplitScreenAspectRatioForUnresizableAppsEnabled="
                 + mLetterboxConfiguration.getIsSplitScreenAspectRatioForUnresizableAppsEnabled());
+        pw.println(prefix + "  isDisplayAspectRatioEnabledForFixedOrientationLetterbox="
+                + mLetterboxConfiguration
+                .getIsDisplayAspectRatioEnabledForFixedOrientationLetterbox());
     }
 
     /**
@@ -910,10 +1159,9 @@
         final ActivityRecord firstOpaqueActivityBeneath = mActivityRecord.getTask().getActivity(
                 ActivityRecord::fillsParent, mActivityRecord, false /* includeBoundary */,
                 true /* traverseTopToBottom */);
-        if (firstOpaqueActivityBeneath == null
-                || mActivityRecord.launchedFromUid != firstOpaqueActivityBeneath.getUid()) {
+        if (firstOpaqueActivityBeneath == null) {
             // We skip letterboxing if the translucent activity doesn't have any opaque
-            // activities beneath of if it's launched from a different user (e.g. notification)
+            // activities beneath
             return;
         }
         inheritConfiguration(firstOpaqueActivityBeneath);
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index ea6f244..3aa80c4 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -609,7 +609,7 @@
      */
     ActivityRecord mChildPipActivity;
 
-    boolean mLastSurfaceShowing = true;
+    boolean mLastSurfaceShowing;
 
     /**
      * Tracks if a back gesture is in progress.
@@ -3327,12 +3327,17 @@
         // We intend to let organizer manage task visibility but it doesn't
         // have enough information until we finish shell transitions.
         // In the mean time we do an easy fix here.
-        final boolean show = isVisible() || isAnimating(TRANSITION | PARENTS | CHILDREN);
+        final boolean visible = isVisible();
+        final boolean show = visible || isAnimating(TRANSITION | PARENTS | CHILDREN);
         if (mSurfaceControl != null) {
             if (show != mLastSurfaceShowing) {
                 t.setVisibility(mSurfaceControl, show);
             }
         }
+        // Only show the overlay if the task has other visible children
+        if (mOverlayHost != null) {
+            mOverlayHost.setVisibility(t, visible);
+        }
         mLastSurfaceShowing = show;
     }
 
@@ -3479,12 +3484,39 @@
 
         if (info.topActivityInfo != null
                 && task.effectiveUid != info.topActivityInfo.applicationInfo.uid) {
-            info.topActivity = null;
-            info.topActivityInfo = null;
+            // Making a copy to prevent eliminating the info in the original ActivityRecord.
+            info.topActivityInfo = new ActivityInfo(info.topActivityInfo);
+            info.topActivityInfo.applicationInfo =
+                    new ApplicationInfo(info.topActivityInfo.applicationInfo);
+
+            // Strip the sensitive info.
+            info.topActivity = new ComponentName("", "");
+            info.topActivityInfo.packageName = "";
+            info.topActivityInfo.taskAffinity = "";
+            info.topActivityInfo.processName = "";
+            info.topActivityInfo.name = "";
+            info.topActivityInfo.parentActivityName = "";
+            info.topActivityInfo.targetActivity = "";
+            info.topActivityInfo.splitName = "";
+            info.topActivityInfo.applicationInfo.className = "";
+            info.topActivityInfo.applicationInfo.credentialProtectedDataDir = "";
+            info.topActivityInfo.applicationInfo.dataDir = "";
+            info.topActivityInfo.applicationInfo.deviceProtectedDataDir = "";
+            info.topActivityInfo.applicationInfo.manageSpaceActivityName = "";
+            info.topActivityInfo.applicationInfo.nativeLibraryDir = "";
+            info.topActivityInfo.applicationInfo.nativeLibraryRootDir = "";
+            info.topActivityInfo.applicationInfo.processName = "";
+            info.topActivityInfo.applicationInfo.publicSourceDir = "";
+            info.topActivityInfo.applicationInfo.scanPublicSourceDir = "";
+            info.topActivityInfo.applicationInfo.scanSourceDir = "";
+            info.topActivityInfo.applicationInfo.sourceDir = "";
+            info.topActivityInfo.applicationInfo.taskAffinity = "";
+            info.topActivityInfo.applicationInfo.name = "";
+            info.topActivityInfo.applicationInfo.packageName = "";
         }
 
         if (task.effectiveUid != baseActivityUid) {
-            info.baseActivity = null;
+            info.baseActivity = new ComponentName("", "");
         }
     }
 
@@ -4170,13 +4202,7 @@
 
     @Override
     boolean showSurfaceOnCreation() {
-        if (mCreatedByOrganizer) {
-            // Tasks created by the organizer are default visible because they can synchronously
-            // update the leash before new children are added to the task.
-            return true;
-        }
-        // Organized tasks handle their own surface visibility
-        return !canBeOrganized();
+        return false;
     }
 
     @Override
@@ -6384,6 +6410,11 @@
             return this;
         }
 
+        Builder setRemoveWithTaskOrganizer(boolean removeWithTaskOrganizer) {
+            mRemoveWithTaskOrganizer = removeWithTaskOrganizer;
+            return this;
+        }
+
         private Builder setUserId(int userId) {
             mUserId = userId;
             return this;
@@ -6581,7 +6612,7 @@
             mCallingPackage = mActivityInfo.packageName;
             mResizeMode = mActivityInfo.resizeMode;
             mSupportsPictureInPicture = mActivityInfo.supportsPictureInPicture();
-            if (mActivityOptions != null) {
+            if (!mRemoveWithTaskOrganizer && mActivityOptions != null) {
                 mRemoveWithTaskOrganizer = mActivityOptions.getRemoveWithTaskOranizer();
             }
 
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 8ad76a3..79be946 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -1074,10 +1074,14 @@
         // Use launch-adjacent-flag-root if launching with launch-adjacent flag.
         if ((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0
                 && mLaunchAdjacentFlagRootTask != null) {
-            // If the adjacent launch is coming from the same root, launch to adjacent root instead.
-            if (sourceTask != null && mLaunchAdjacentFlagRootTask.getAdjacentTaskFragment() != null
+            if (sourceTask != null && sourceTask == candidateTask) {
+                // Do nothing when task that is getting opened is same as the source.
+            } else if (sourceTask != null
+                    && mLaunchAdjacentFlagRootTask.getAdjacentTaskFragment() != null
                     && (sourceTask == mLaunchAdjacentFlagRootTask
                     || sourceTask.isDescendantOf(mLaunchAdjacentFlagRootTask))) {
+                // If the adjacent launch is coming from the same root, launch to
+                // adjacent root instead.
                 return mLaunchAdjacentFlagRootTask.getAdjacentTaskFragment().asTask();
             } else {
                 return mLaunchAdjacentFlagRootTask;
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index be541ae..22da56a 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -94,6 +94,7 @@
 import android.view.RemoteAnimationTarget;
 import android.view.SurfaceControl;
 import android.window.ITaskFragmentOrganizer;
+import android.window.TaskFragmentAnimationParams;
 import android.window.TaskFragmentInfo;
 import android.window.TaskFragmentOrganizerToken;
 
@@ -304,6 +305,10 @@
     @Nullable
     private final IBinder mFragmentToken;
 
+    /** The animation override params for animation running on this TaskFragment. */
+    @NonNull
+    private TaskFragmentAnimationParams mAnimationParams = TaskFragmentAnimationParams.DEFAULT;
+
     /**
      * The bounds of the embedded TaskFragment relative to the parent Task.
      * {@code null} if it is not {@link #mIsEmbedded}
@@ -454,6 +459,15 @@
                 && organizer.asBinder().equals(mTaskFragmentOrganizer.asBinder());
     }
 
+    void setAnimationParams(@NonNull TaskFragmentAnimationParams animationParams) {
+        mAnimationParams = animationParams;
+    }
+
+    @NonNull
+    TaskFragmentAnimationParams getAnimationParams() {
+        return mAnimationParams;
+    }
+
     TaskFragment getAdjacentTaskFragment() {
         return mAdjacentTaskFragment;
     }
@@ -2124,7 +2138,7 @@
 
         final Rect parentBounds = parentConfig.windowConfiguration.getBounds();
         final Rect resolvedBounds = inOutConfig.windowConfiguration.getBounds();
-        if (resolvedBounds == null || resolvedBounds.isEmpty()) {
+        if (resolvedBounds.isEmpty()) {
             mTmpFullBounds.set(parentBounds);
             insideParentBounds = true;
         } else {
@@ -2213,6 +2227,7 @@
                         : overrideScreenHeightDp;
             }
 
+            // TODO(b/238331848): Consider simplifying logic that computes smallestScreenWidthDp.
             if (inOutConfig.smallestScreenWidthDp
                     == Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
                 // When entering to or exiting from Pip, the PipTaskOrganizer will set the
diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
index 90a0dff..49b2a4ef 100644
--- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
@@ -540,9 +540,12 @@
         synchronized (mGlobalLock) {
             final TaskFragmentOrganizerState organizerState =
                     mTaskFragmentOrganizerState.get(organizer.asBinder());
-            return organizerState != null
-                    ? organizerState.mRemoteAnimationDefinition
-                    : null;
+            if (organizerState == null) {
+                Slog.e(TAG, "TaskFragmentOrganizer has been unregistered or died when trying"
+                        + " to play animation on its organized windows.");
+                return null;
+            }
+            return organizerState.mRemoteAnimationDefinition;
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index d619547..d780cae 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -783,7 +783,8 @@
     }
 
     @Override
-    public void createRootTask(int displayId, int windowingMode, @Nullable IBinder launchCookie) {
+    public void createRootTask(int displayId, int windowingMode, @Nullable IBinder launchCookie,
+            boolean removeWithTaskOrganizer) {
         enforceTaskPermission("createRootTask()");
         final long origId = Binder.clearCallingIdentity();
         try {
@@ -795,7 +796,7 @@
                     return;
                 }
 
-                createRootTask(display, windowingMode, launchCookie);
+                createRootTask(display, windowingMode, launchCookie, removeWithTaskOrganizer);
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
@@ -804,6 +805,12 @@
 
     @VisibleForTesting
     Task createRootTask(DisplayContent display, int windowingMode, @Nullable IBinder launchCookie) {
+        return createRootTask(display, windowingMode, launchCookie,
+                false /* removeWithTaskOrganizer */);
+    }
+
+    Task createRootTask(DisplayContent display, int windowingMode, @Nullable IBinder launchCookie,
+            boolean removeWithTaskOrganizer) {
         ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Create root task displayId=%d winMode=%d",
                 display.mDisplayId, windowingMode);
         // We want to defer the task appear signal until the task is fully created and attached to
@@ -816,6 +823,7 @@
                 .setDeferTaskAppear(true)
                 .setLaunchCookie(launchCookie)
                 .setParent(display.getDefaultTaskDisplayArea())
+                .setRemoveWithTaskOrganizer(removeWithTaskOrganizer)
                 .build();
         task.setDeferTaskAppear(false /* deferTaskAppear */);
         return task;
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index c874747..00e3188 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -653,6 +653,7 @@
                 t.setCornerRadius(targetLeash, 0);
                 t.setShadowRadius(targetLeash, 0);
                 t.setMatrix(targetLeash, 1, 0, 0, 1);
+                t.setAlpha(targetLeash, 1);
                 // The bounds sent to the transition is always a real bounds. This means we lose
                 // information about "null" bounds (inheriting from parent). Core will fix-up
                 // non-organized window surface bounds; however, since Core can't touch organized
@@ -1730,13 +1731,26 @@
             }
 
             if (activityRecord != null || (taskFragment != null && taskFragment.isEmbedded())) {
-                // Set background color to Task theme color for activity and embedded TaskFragment
-                // in case we want to show background during the animation.
-                final Task parentTask = activityRecord != null
-                        ? activityRecord.getTask()
-                        : taskFragment.getTask();
-                final int backgroundColor = ColorUtils.setAlphaComponent(
-                        parentTask.getTaskDescription().getBackgroundColor(), 255);
+                final int backgroundColor;
+                final TaskFragment organizedTf = activityRecord != null
+                        ? activityRecord.getOrganizedTaskFragment()
+                        : taskFragment.getOrganizedTaskFragment();
+                if (organizedTf != null && organizedTf.getAnimationParams()
+                        .getAnimationBackgroundColor() != 0) {
+                    // This window is embedded and has an animation background color set on the
+                    // TaskFragment. Pass this color with this window, so the handler can use it as
+                    // the animation background color if needed,
+                    backgroundColor = organizedTf.getAnimationParams()
+                            .getAnimationBackgroundColor();
+                } else {
+                    // Set background color to Task theme color for activity and embedded
+                    // TaskFragment in case we want to show background during the animation.
+                    final Task parentTask = activityRecord != null
+                            ? activityRecord.getTask()
+                            : taskFragment.getTask();
+                    backgroundColor = ColorUtils.setAlphaComponent(
+                            parentTask.getTaskDescription().getBackgroundColor(), 255);
+                }
                 change.setBackgroundColor(backgroundColor);
             }
 
diff --git a/services/core/java/com/android/server/wm/TrustedOverlayHost.java b/services/core/java/com/android/server/wm/TrustedOverlayHost.java
index 975b21c..88c410b 100644
--- a/services/core/java/com/android/server/wm/TrustedOverlayHost.java
+++ b/services/core/java/com/android/server/wm/TrustedOverlayHost.java
@@ -80,6 +80,12 @@
         }
     }
 
+    void setVisibility(SurfaceControl.Transaction t, boolean visible) {
+        if (mSurfaceControl != null) {
+            t.setVisibility(mSurfaceControl, visible);
+        }
+    }
+
     void addOverlay(SurfaceControlViewHost.SurfacePackage p, SurfaceControl currentParent) {
         requireOverlaySurfaceControl();
         mOverlays.add(p);
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 1d25dbc..b2dab78b 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -371,7 +371,7 @@
 
     boolean updateWallpaperOffset(WindowState wallpaperWin, boolean sync) {
         // Size of the display the wallpaper is rendered on.
-        final Rect lastWallpaperBounds = wallpaperWin.getLastReportedBounds();
+        final Rect lastWallpaperBounds = wallpaperWin.getParentFrame();
         // Full size of the wallpaper (usually larger than bounds above to parallax scroll when
         // swiping through Launcher pages).
         final Rect wallpaperFrame = wallpaperWin.getFrame();
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index cb5a433..8bdab9c 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -3145,14 +3145,26 @@
                     // which if set originates from a call to overridePendingAppTransition.
                     backgroundColorForTransition = adapter.getBackgroundColor();
                 } else {
-                    // Otherwise default to the window's background color if provided through
-                    // the theme as the background color for the animation - the top most window
-                    // with a valid background color and showBackground set takes precedence.
-                    final Task parentTask = activityRecord != null
-                            ? activityRecord.getTask()
-                            : taskFragment.getTask();
-                    backgroundColorForTransition = ColorUtils.setAlphaComponent(
-                            parentTask.getTaskDescription().getBackgroundColor(), 255);
+                    final TaskFragment organizedTf = activityRecord != null
+                            ? activityRecord.getOrganizedTaskFragment()
+                            : taskFragment.getOrganizedTaskFragment();
+                    if (organizedTf != null && organizedTf.getAnimationParams()
+                            .getAnimationBackgroundColor() != 0) {
+                        // This window is embedded and has an animation background color set on the
+                        // TaskFragment. Pass this color with this window, so the handler can use it
+                        // as the animation background color if needed,
+                        backgroundColorForTransition = organizedTf.getAnimationParams()
+                                .getAnimationBackgroundColor();
+                    } else {
+                        // Otherwise default to the window's background color if provided through
+                        // the theme as the background color for the animation - the top most window
+                        // with a valid background color and showBackground set takes precedence.
+                        final Task parentTask = activityRecord != null
+                                ? activityRecord.getTask()
+                                : taskFragment.getTask();
+                        backgroundColorForTransition = ColorUtils.setAlphaComponent(
+                                parentTask.getTaskDescription().getBackgroundColor(), 255);
+                    }
                 }
                 animationRunnerBuilder.setTaskBackgroundColor(backgroundColorForTransition);
             }
@@ -3185,11 +3197,11 @@
 
     private Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
                                     boolean isVoiceInteraction) {
-        if (isOrganized()
+        if (AppTransitionController.isTaskViewTask(this) || (isOrganized()
                 // TODO(b/161711458): Clean-up when moved to shell.
                 && getWindowingMode() != WINDOWING_MODE_FULLSCREEN
                 && getWindowingMode() != WINDOWING_MODE_FREEFORM
-                && getWindowingMode() != WINDOWING_MODE_MULTI_WINDOW) {
+                && getWindowingMode() != WINDOWING_MODE_MULTI_WINDOW)) {
             return null;
         }
 
@@ -3747,7 +3759,6 @@
         if (mSyncState == SYNC_STATE_NONE) return false;
         mSyncState = SYNC_STATE_READY;
         mSyncMethodOverride = BLASTSyncEngine.METHOD_UNDEFINED;
-        mWmService.mWindowPlacerLocked.requestTraversal();
         ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "onSyncFinishedDrawing %s", this);
         return true;
     }
@@ -3817,8 +3828,8 @@
 
     /**
      * Checks if the subtree rooted at this container is finished syncing (everything is ready or
-     * not visible). NOTE, this is not const: it will cancel/prepare itself depending on its state
-     * in the hierarchy.
+     * not visible). NOTE, this is not const: it may cancel/prepare/complete itself depending on
+     * its state in the hierarchy.
      *
      * @return {@code true} if this subtree is finished waiting for sync participants.
      */
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index b3a7754..5065014 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -167,7 +167,6 @@
 import android.app.IAssistDataReceiver;
 import android.app.WindowConfiguration;
 import android.content.BroadcastReceiver;
-import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
@@ -177,7 +176,6 @@
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.TestUtilityService;
 import android.content.res.Configuration;
-import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.database.ContentObserver;
 import android.graphics.Bitmap;
@@ -2587,12 +2585,6 @@
                         && win.mSyncSeqId > lastSyncSeqId) {
                     maybeSyncSeqId = win.shouldSyncWithBuffers() ? win.mSyncSeqId : -1;
                     win.markRedrawForSyncReported();
-                    if (win.mSyncState == WindowContainer.SYNC_STATE_WAITING_FOR_DRAW
-                            && winAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN
-                            && maybeSyncSeqId < 0) {
-                        // Do not wait for a drawn window which won't report draw.
-                        win.onSyncFinishedDrawing();
-                    }
                 } else {
                     maybeSyncSeqId = -1;
                 }
@@ -5845,6 +5837,11 @@
             if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
                 return displayContent.mInitialDisplayDensity;
             }
+
+            DisplayInfo info = mDisplayManagerInternal.getDisplayInfo(displayId);
+            if (info != null && info.hasAccess(Binder.getCallingUid())) {
+                return info.logicalDensityDpi;
+            }
         }
         return -1;
     }
@@ -5876,6 +5873,11 @@
                 final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
                 if (displayContent != null) {
                     displayContent.setForcedDensity(density, targetUserId);
+                } else {
+                    DisplayInfo info = mDisplayManagerInternal.getDisplayInfo(displayId);
+                    if (info != null) {
+                        mDisplayWindowSettings.setForcedDensity(info, density, userId);
+                    }
                 }
             }
         } finally {
@@ -5900,6 +5902,12 @@
                 if (displayContent != null) {
                     displayContent.setForcedDensity(displayContent.mInitialDisplayDensity,
                             callingUserId);
+                } else {
+                    DisplayInfo info = mDisplayManagerInternal.getDisplayInfo(displayId);
+                    if (info != null) {
+                        mDisplayWindowSettings.setForcedDensity(info, info.logicalDensityDpi,
+                                userId);
+                    }
                 }
             }
         } finally {
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index aef6d1d..a06d84c 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -955,6 +955,10 @@
                     runSetBooleanFlag(pw, mLetterboxConfiguration
                             ::setIsSplitScreenAspectRatioForUnresizableAppsEnabled);
                     break;
+                case "--isDisplayAspectRatioEnabledForFixedOrientationLetterbox":
+                    runSetBooleanFlag(pw, mLetterboxConfiguration
+                            ::setIsDisplayAspectRatioEnabledForFixedOrientationLetterbox);
+                    break;
                 case "--isTranslucentLetterboxingEnabled":
                     runSetBooleanFlag(pw, mLetterboxConfiguration
                             ::setTranslucentLetterboxingOverrideEnabled);
@@ -1030,6 +1034,10 @@
                         mLetterboxConfiguration
                                 .resetIsSplitScreenAspectRatioForUnresizableAppsEnabled();
                         break;
+                    case "IsDisplayAspectRatioEnabledForFixedOrientationLetterbox":
+                        mLetterboxConfiguration
+                                .resetIsDisplayAspectRatioEnabledForFixedOrientationLetterbox();
+                        break;
                     case "isTranslucentLetterboxingEnabled":
                         mLetterboxConfiguration.resetTranslucentLetterboxingEnabled();
                         break;
@@ -1140,6 +1148,7 @@
             mLetterboxConfiguration.resetDefaultPositionForVerticalReachability();
             mLetterboxConfiguration.resetIsEducationEnabled();
             mLetterboxConfiguration.resetIsSplitScreenAspectRatioForUnresizableAppsEnabled();
+            mLetterboxConfiguration.resetIsDisplayAspectRatioEnabledForFixedOrientationLetterbox();
             mLetterboxConfiguration.resetTranslucentLetterboxingEnabled();
             mLetterboxConfiguration.resetCameraCompatRefreshEnabled();
             mLetterboxConfiguration.resetCameraCompatRefreshCycleThroughStopEnabled();
@@ -1187,7 +1196,9 @@
             pw.println("Is using split screen aspect ratio as aspect ratio for unresizable apps: "
                     + mLetterboxConfiguration
                             .getIsSplitScreenAspectRatioForUnresizableAppsEnabled());
-
+            pw.println("Is using display aspect ratio as aspect ratio for all letterboxed apps: "
+                    + mLetterboxConfiguration
+                            .getIsDisplayAspectRatioEnabledForFixedOrientationLetterbox());
             pw.println("    Is activity \"refresh\" in camera compatibility treatment enabled: "
                     + mLetterboxConfiguration.isCameraCompatRefreshEnabled());
             pw.println("    Refresh using \"stopped -> resumed\" cycle: "
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index eba3ea4..fd47753 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -21,6 +21,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.app.WindowConfiguration.WINDOW_CONFIG_BOUNDS;
 import static android.view.Display.DEFAULT_DISPLAY;
+import static android.window.TaskFragmentOperation.OP_TYPE_SET_ANIMATION_PARAMS;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_ADD_RECT_INSETS_PROVIDER;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT;
@@ -43,6 +44,7 @@
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_REPARENT_LEAF_TASK_IF_RELAUNCH;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_TASK_FRAGMENT_OPERATION;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_SHORTCUT;
 
@@ -88,7 +90,9 @@
 import android.window.ITransitionPlayer;
 import android.window.IWindowContainerTransactionCallback;
 import android.window.IWindowOrganizerController;
+import android.window.TaskFragmentAnimationParams;
 import android.window.TaskFragmentCreationParams;
+import android.window.TaskFragmentOperation;
 import android.window.WindowContainerTransaction;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -1142,6 +1146,10 @@
                 fragment.setCompanionTaskFragment(companion);
                 break;
             }
+            case HIERARCHY_OP_TYPE_SET_TASK_FRAGMENT_OPERATION: {
+                effects |= applyTaskFragmentOperation(hop, errorCallbackToken, organizer);
+                break;
+            }
             default: {
                 // The other operations may change task order so they are skipped while in lock
                 // task mode. The above operations are still allowed because they don't move
@@ -1274,6 +1282,47 @@
         return effects;
     }
 
+    /** Applies change set through {@link WindowContainerTransaction#setTaskFragmentOperation}. */
+    private int applyTaskFragmentOperation(@NonNull WindowContainerTransaction.HierarchyOp hop,
+            @Nullable IBinder errorCallbackToken, @Nullable ITaskFragmentOrganizer organizer) {
+        final IBinder fragmentToken = hop.getContainer();
+        final TaskFragment taskFragment = mLaunchTaskFragments.get(fragmentToken);
+        final TaskFragmentOperation operation = hop.getTaskFragmentOperation();
+        if (operation == null) {
+            final Throwable exception = new IllegalArgumentException(
+                    "TaskFragmentOperation must be non-null");
+            sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment,
+                    HIERARCHY_OP_TYPE_SET_TASK_FRAGMENT_OPERATION, exception);
+            return 0;
+        }
+        final int opType = operation.getOpType();
+        if (taskFragment == null || !taskFragment.isAttached()) {
+            final Throwable exception = new IllegalArgumentException(
+                    "Not allowed to apply operation on invalid fragment tokens opType=" + opType);
+            sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment,
+                    HIERARCHY_OP_TYPE_SET_TASK_FRAGMENT_OPERATION, exception);
+            return 0;
+        }
+
+        int effect = 0;
+        switch (opType) {
+            case OP_TYPE_SET_ANIMATION_PARAMS: {
+                final TaskFragmentAnimationParams animationParams = operation.getAnimationParams();
+                if (animationParams == null) {
+                    final Throwable exception = new IllegalArgumentException(
+                            "TaskFragmentAnimationParams must be non-null");
+                    sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment,
+                            HIERARCHY_OP_TYPE_SET_TASK_FRAGMENT_OPERATION, exception);
+                    break;
+                }
+                taskFragment.setAnimationParams(animationParams);
+                break;
+            }
+            // TODO(b/263436063): move other TaskFragment related operation here.
+        }
+        return effect;
+    }
+
     /** A helper method to send minimum dimension violation error to the client. */
     private void sendMinimumDimensionViolation(TaskFragment taskFragment, Point minDimensions,
             IBinder errorCallbackToken, String reason) {
@@ -1681,6 +1730,7 @@
                     break;
                 case HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT:
                 case HIERARCHY_OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT:
+                case HIERARCHY_OP_TYPE_SET_TASK_FRAGMENT_OPERATION:
                     enforceTaskFragmentOrganized(func, hop.getContainer(), organizer);
                     break;
                 case HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT:
@@ -1899,12 +1949,21 @@
                     creationParams.getPairedPrimaryFragmentToken());
             final int pairedPosition = ownerTask.mChildren.indexOf(pairedPrimaryTaskFragment);
             position = pairedPosition != -1 ? pairedPosition + 1 : POSITION_TOP;
+        } else if (creationParams.getPairedActivityToken() != null) {
+            // When there is a paired Activity, we want to place the new TaskFragment right above
+            // the paired Activity to make sure the Activity position is not changed after reparent.
+            final ActivityRecord pairedActivity = ActivityRecord.forTokenLocked(
+                    creationParams.getPairedActivityToken());
+            final int pairedPosition = ownerTask.mChildren.indexOf(pairedActivity);
+            position = pairedPosition != -1 ? pairedPosition + 1 : POSITION_TOP;
         } else {
             position = POSITION_TOP;
         }
         ownerTask.addChild(taskFragment, position);
         taskFragment.setWindowingMode(creationParams.getWindowingMode());
         taskFragment.setBounds(creationParams.getInitialBounds());
+        // Record the initial relative embedded bounds.
+        taskFragment.updateRelativeEmbeddedBounds();
         mLaunchTaskFragments.put(creationParams.getFragmentToken(), taskFragment);
 
         if (transition != null) transition.collectExistenceChange(taskFragment);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 2f55d18..ae03fbb 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -396,14 +396,6 @@
     int mPrepareSyncSeqId = 0;
 
     /**
-     * {@code true} when the client was still drawing for sync when the sync-set was finished or
-     * cancelled. This can happen if the window goes away during a sync. In this situation we need
-     * to make sure to still apply the postDrawTransaction when it finishes to prevent the client
-     * from getting stuck in a bad state.
-     */
-    boolean mClientWasDrawingForSync = false;
-
-    /**
      * Special mode that is intended only for the rounded corner overlay: during rotation
      * transition, we un-rotate the window token such that the window appears as it did before the
      * rotation.
@@ -3081,12 +3073,6 @@
         return mLastReportedConfiguration.getMergedConfiguration();
     }
 
-    /** Returns the last window configuration bounds reported to the client. */
-    Rect getLastReportedBounds() {
-        final Rect bounds = getLastReportedConfiguration().windowConfiguration.getBounds();
-        return !bounds.isEmpty() ? bounds : getBounds();
-    }
-
     void adjustStartingWindowFlags() {
         if (mAttrs.type == TYPE_BASE_APPLICATION && mActivityRecord != null
                 && mActivityRecord.mStartingWindow != null) {
@@ -4421,6 +4407,9 @@
             pw.print("null");
         }
 
+        if (mXOffset != 0 || mYOffset != 0) {
+            pw.println(prefix + "mXOffset=" + mXOffset + " mYOffset=" + mYOffset);
+        }
         if (mHScale != 1 || mVScale != 1) {
             pw.println(prefix + "mHScale=" + mHScale
                     + " mVScale=" + mVScale);
@@ -5573,7 +5562,7 @@
                 mSurfacePosition);
 
         if (mWallpaperScale != 1f) {
-            final Rect bounds = getLastReportedBounds();
+            final Rect bounds = getParentFrame();
             Matrix matrix = mTmpMatrix;
             matrix.setTranslate(mXOffset, mYOffset);
             matrix.postScale(mWallpaperScale, mWallpaperScale, bounds.exactCenterX(),
@@ -5686,6 +5675,14 @@
                     && imeTarget.compareTo(this) <= 0;
             return inTokenWithAndAboveImeTarget;
         }
+
+        // The condition is for the system dialog not belonging to any Activity.
+        // (^FLAG_NOT_FOCUSABLE & FLAG_ALT_FOCUSABLE_IM) means the dialog is still focusable but
+        // should be placed above the IME window.
+        if ((mAttrs.flags & (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM))
+                == FLAG_ALT_FOCUSABLE_IM && isTrustedOverlay() && canAddInternalSystemWindow()) {
+            return true;
+        }
         return false;
     }
 
@@ -6004,20 +6001,21 @@
 
     @Override
     boolean isSyncFinished() {
-        if (mSyncState == SYNC_STATE_WAITING_FOR_DRAW && mViewVisibility != View.VISIBLE
-                && !isVisibleRequested()) {
+        if (!isVisibleRequested()) {
             // Don't wait for invisible windows. However, we don't alter the state in case the
             // window becomes visible while the sync group is still active.
             return true;
         }
+        if (mSyncState == SYNC_STATE_WAITING_FOR_DRAW && mWinAnimator.mDrawState == HAS_DRAWN
+                && !mRedrawForSyncReported && !mWmService.mResizingWindows.contains(this)) {
+            // Complete the sync state immediately for a drawn window that doesn't need to redraw.
+            onSyncFinishedDrawing();
+        }
         return super.isSyncFinished();
     }
 
     @Override
     void finishSync(Transaction outMergedTransaction, boolean cancel) {
-        if (mSyncState == SYNC_STATE_WAITING_FOR_DRAW && mRedrawForSyncReported) {
-            mClientWasDrawingForSync = true;
-        }
         mPrepareSyncSeqId = 0;
         if (cancel) {
             // This is leaving sync so any buffers left in the sync have a chance of
@@ -6060,6 +6058,7 @@
         final boolean hasSyncHandlers = executeDrawHandlers(postDrawTransaction, syncSeqId);
 
         boolean skipLayout = false;
+        boolean layoutNeeded = false;
         // Control the timing to switch the appearance of window with different rotations.
         final AsyncRotationController asyncRotationController =
                 mDisplayContent.getAsyncRotationController();
@@ -6072,7 +6071,7 @@
         } else if (syncActive) {
             // Currently in a Sync that is using BLAST.
             if (!syncStillPending) {
-                onSyncFinishedDrawing();
+                layoutNeeded = onSyncFinishedDrawing();
             }
             if (postDrawTransaction != null) {
                 mSyncTransaction.merge(postDrawTransaction);
@@ -6081,12 +6080,10 @@
             }
         } else if (useBLASTSync()) {
             // Sync that is not using BLAST
-            onSyncFinishedDrawing();
+            layoutNeeded = onSyncFinishedDrawing();
         }
 
-        final boolean layoutNeeded =
-                mWinAnimator.finishDrawingLocked(postDrawTransaction, mClientWasDrawingForSync);
-        mClientWasDrawingForSync = false;
+        layoutNeeded |= mWinAnimator.finishDrawingLocked(postDrawTransaction);
         // We always want to force a traversal after a finish draw for blast sync.
         return !skipLayout && (hasSyncHandlers || layoutNeeded);
     }
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index a0ba8fd..f364248 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -151,17 +151,6 @@
 
     int mAttrType;
 
-    /**
-     * Handles surface changes synchronized to after the client has drawn the surface. This
-     * transaction is currently used to reparent the old surface children to the new surface once
-     * the client has completed drawing to the new surface.
-     * This transaction is also used to merge transactions parceled in by the client. The client
-     * uses the transaction to update the relative z of its children from the old parent surface
-     * to the new parent surface once window manager reparents its children.
-     */
-    private final SurfaceControl.Transaction mPostDrawTransaction =
-            new SurfaceControl.Transaction();
-
     WindowStateAnimator(final WindowState win) {
         final WindowManagerService service = win.mWmService;
 
@@ -217,8 +206,7 @@
         }
     }
 
-    boolean finishDrawingLocked(SurfaceControl.Transaction postDrawTransaction,
-            boolean forceApplyNow) {
+    boolean finishDrawingLocked(SurfaceControl.Transaction postDrawTransaction) {
         final boolean startingWindow =
                 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
         if (startingWindow) {
@@ -240,14 +228,7 @@
         }
 
         if (postDrawTransaction != null) {
-            // If there is no surface, the last draw was for the previous surface. We don't want to
-            // wait until the new surface is shown and instead just apply the transaction right
-            // away.
-            if (mLastHidden && mDrawState != NO_SURFACE && !forceApplyNow) {
-                mPostDrawTransaction.merge(postDrawTransaction);
-            } else {
-                mWin.getSyncTransaction().merge(postDrawTransaction);
-            }
+            mWin.getSyncTransaction().merge(postDrawTransaction);
             layoutNeeded = true;
         }
 
@@ -547,7 +528,6 @@
         if (!shown)
             return false;
 
-        t.merge(mPostDrawTransaction);
         return true;
     }
 
@@ -714,10 +694,6 @@
     }
 
     void destroySurface(SurfaceControl.Transaction t) {
-        // Since the SurfaceControl is getting torn down, it's safe to just clean up any
-        // pending transactions that were in mPostDrawTransaction, as well.
-        t.merge(mPostDrawTransaction);
-
         try {
             if (mSurfaceController != null) {
                 mSurfaceController.destroy(t);
diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd
index f628fba..abe48f8 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -464,6 +464,14 @@
     </xs:complexType>
 
     <xs:complexType name="refreshRateConfigs">
+        <xs:element name="defaultRefreshRate" type="xs:nonNegativeInteger"
+                    minOccurs="0" maxOccurs="1">
+            <xs:annotation name="final"/>
+        </xs:element>
+        <xs:element name="defaultPeakRefreshRate" type="xs:nonNegativeInteger"
+                    minOccurs="0" maxOccurs="1">
+            <xs:annotation name="final"/>
+        </xs:element>
         <xs:element name="lowerBlockingZoneConfigs" type="blockingZoneConfig"
                     minOccurs="0" maxOccurs="1">
             <xs:annotation name="final"/>
diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt
index cb08179..2c97af5 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -186,8 +186,12 @@
 
   public class RefreshRateConfigs {
     ctor public RefreshRateConfigs();
+    method public final java.math.BigInteger getDefaultPeakRefreshRate();
+    method public final java.math.BigInteger getDefaultRefreshRate();
     method public final com.android.server.display.config.BlockingZoneConfig getHigherBlockingZoneConfigs();
     method public final com.android.server.display.config.BlockingZoneConfig getLowerBlockingZoneConfigs();
+    method public final void setDefaultPeakRefreshRate(java.math.BigInteger);
+    method public final void setDefaultRefreshRate(java.math.BigInteger);
     method public final void setHigherBlockingZoneConfigs(com.android.server.display.config.BlockingZoneConfig);
     method public final void setLowerBlockingZoneConfigs(com.android.server.display.config.BlockingZoneConfig);
   }
diff --git a/services/people/java/com/android/server/people/data/ContactsQueryHelper.java b/services/people/java/com/android/server/people/data/ContactsQueryHelper.java
index 8a3a44ae..0993295 100644
--- a/services/people/java/com/android/server/people/data/ContactsQueryHelper.java
+++ b/services/people/java/com/android/server/people/data/ContactsQueryHelper.java
@@ -21,6 +21,7 @@
 import android.annotation.WorkerThread;
 import android.content.Context;
 import android.database.Cursor;
+import android.database.sqlite.SQLiteException;
 import android.net.Uri;
 import android.provider.ContactsContract;
 import android.provider.ContactsContract.Contacts;
@@ -149,6 +150,8 @@
 
                 found = true;
             }
+        } catch (SQLiteException exception) {
+            Slog.w("SQLite exception when querying contacts.", exception);
         }
         if (found && lookupKey != null && hasPhoneNumber) {
             return queryPhoneNumber(lookupKey);
diff --git a/services/people/java/com/android/server/people/data/ConversationInfo.java b/services/people/java/com/android/server/people/data/ConversationInfo.java
index 6ead44a..a539fdd 100644
--- a/services/people/java/com/android/server/people/data/ConversationInfo.java
+++ b/services/people/java/com/android/server/people/data/ConversationInfo.java
@@ -424,6 +424,7 @@
                 case (int) ConversationInfoProto.CREATION_TIMESTAMP:
                     builder.setCreationTimestamp(protoInputStream.readLong(
                             ConversationInfoProto.CREATION_TIMESTAMP));
+                    break;
                 case (int) ConversationInfoProto.SHORTCUT_FLAGS:
                     builder.setShortcutFlags(protoInputStream.readInt(
                             ConversationInfoProto.SHORTCUT_FLAGS));
diff --git a/services/people/java/com/android/server/people/data/DataManager.java b/services/people/java/com/android/server/people/data/DataManager.java
index 693f3a0..eff9e8d 100644
--- a/services/people/java/com/android/server/people/data/DataManager.java
+++ b/services/people/java/com/android/server/people/data/DataManager.java
@@ -271,22 +271,22 @@
     private ConversationChannel getConversationChannel(String packageName, int userId,
             String shortcutId, ConversationInfo conversationInfo) {
         ShortcutInfo shortcutInfo = getShortcut(packageName, userId, shortcutId);
-        return getConversationChannel(shortcutInfo, conversationInfo);
+        return getConversationChannel(
+                shortcutInfo, conversationInfo, packageName, userId, shortcutId);
     }
 
     @Nullable
     private ConversationChannel getConversationChannel(ShortcutInfo shortcutInfo,
-            ConversationInfo conversationInfo) {
+            ConversationInfo conversationInfo, String packageName, int userId, String shortcutId) {
         if (conversationInfo == null || conversationInfo.isDemoted()) {
             return null;
         }
         if (shortcutInfo == null) {
-            Slog.e(TAG, " Shortcut no longer found");
+            Slog.e(TAG, "Shortcut no longer found");
+            mInjector.getBackgroundExecutor().execute(
+                    () -> removeConversations(packageName, userId, Set.of(shortcutId)));
             return null;
         }
-        String packageName = shortcutInfo.getPackage();
-        String shortcutId = shortcutInfo.getId();
-        int userId = shortcutInfo.getUserId();
         int uid = mPackageManagerInternal.getPackageUid(packageName, 0, userId);
         NotificationChannel parentChannel =
                 mNotificationManagerInternal.getNotificationChannel(packageName, uid,
@@ -1130,38 +1130,41 @@
         public void onShortcutsRemoved(@NonNull String packageName,
                 @NonNull List<ShortcutInfo> shortcuts, @NonNull UserHandle user) {
             mInjector.getBackgroundExecutor().execute(() -> {
-                int uid = Process.INVALID_UID;
-                try {
-                    uid = mContext.getPackageManager().getPackageUidAsUser(
-                            packageName, user.getIdentifier());
-                } catch (PackageManager.NameNotFoundException e) {
-                    Slog.e(TAG, "Package not found: " + packageName, e);
-                }
-                PackageData packageData = getPackage(packageName, user.getIdentifier());
-                Set<String> shortcutIds = new HashSet<>();
+                HashSet<String> shortcutIds = new HashSet<>();
                 for (ShortcutInfo shortcutInfo : shortcuts) {
-                    if (packageData != null) {
-                        if (DEBUG) Log.d(TAG, "Deleting shortcut: " + shortcutInfo.getId());
-                        packageData.deleteDataForConversation(shortcutInfo.getId());
-                    }
                     shortcutIds.add(shortcutInfo.getId());
                 }
-                if (uid != Process.INVALID_UID) {
-                    mNotificationManagerInternal.onConversationRemoved(
-                            packageName, uid, shortcutIds);
-                }
+                removeConversations(packageName, user.getIdentifier(), shortcutIds);
             });
         }
     }
 
+    private void removeConversations(
+            @NonNull String packageName, @NonNull int userId, @NonNull Set<String> shortcutIds) {
+        PackageData packageData = getPackage(packageName, userId);
+        if (packageData != null) {
+            for (String shortcutId : shortcutIds) {
+                if (DEBUG) Log.d(TAG, "Deleting shortcut: " + shortcutId);
+                packageData.deleteDataForConversation(shortcutId);
+            }
+        }
+        try {
+            int uid = mContext.getPackageManager().getPackageUidAsUser(
+                    packageName, userId);
+            mNotificationManagerInternal.onConversationRemoved(packageName, uid, shortcutIds);
+        } catch (PackageManager.NameNotFoundException e) {
+            Slog.e(TAG, "Package not found when removing conversation: " + packageName, e);
+        }
+    }
+
     /** Listener for the notifications and their settings changes. */
     private class NotificationListener extends NotificationListenerService {
 
         private final int mUserId;
 
-        // Conversation package name + shortcut ID -> Number of active notifications
+        // Conversation package name + shortcut ID -> Keys of active notifications
         @GuardedBy("this")
-        private final Map<Pair<String, String>, Integer> mActiveNotifCounts = new ArrayMap<>();
+        private final Map<Pair<String, String>, Set<String>> mActiveNotifKeys = new ArrayMap<>();
 
         private NotificationListener(int userId) {
             mUserId = userId;
@@ -1175,8 +1178,10 @@
             String shortcutId = sbn.getNotification().getShortcutId();
             PackageData packageData = getPackageIfConversationExists(sbn, conversationInfo -> {
                 synchronized (this) {
-                    mActiveNotifCounts.merge(
-                            Pair.create(sbn.getPackageName(), shortcutId), 1, Integer::sum);
+                    Set<String> notificationKeys = mActiveNotifKeys.computeIfAbsent(
+                            Pair.create(sbn.getPackageName(), shortcutId),
+                            (unusedKey) -> new HashSet<>());
+                    notificationKeys.add(sbn.getKey());
                 }
             });
 
@@ -1215,12 +1220,12 @@
                 Pair<String, String> conversationKey =
                         Pair.create(sbn.getPackageName(), shortcutId);
                 synchronized (this) {
-                    int count = mActiveNotifCounts.getOrDefault(conversationKey, 0) - 1;
-                    if (count <= 0) {
-                        mActiveNotifCounts.remove(conversationKey);
+                    Set<String> notificationKeys = mActiveNotifKeys.computeIfAbsent(
+                            conversationKey, (unusedKey) -> new HashSet<>());
+                    notificationKeys.remove(sbn.getKey());
+                    if (notificationKeys.isEmpty()) {
+                        mActiveNotifKeys.remove(conversationKey);
                         cleanupCachedShortcuts(mUserId, MAX_CACHED_RECENT_SHORTCUTS);
-                    } else {
-                        mActiveNotifCounts.put(conversationKey, count);
                     }
                 }
             });
@@ -1286,7 +1291,7 @@
         }
 
         synchronized boolean hasActiveNotifications(String packageName, String shortcutId) {
-            return mActiveNotifCounts.containsKey(Pair.create(packageName, shortcutId));
+            return mActiveNotifKeys.containsKey(Pair.create(packageName, shortcutId));
         }
     }
 
@@ -1349,9 +1354,11 @@
     }
 
     private void updateConversationStoreThenNotifyListeners(ConversationStore cs,
-            ConversationInfo modifiedConv, ShortcutInfo shortcutInfo) {
+            ConversationInfo modifiedConv, @NonNull ShortcutInfo shortcutInfo) {
         cs.addOrUpdate(modifiedConv);
-        ConversationChannel channel = getConversationChannel(shortcutInfo, modifiedConv);
+        ConversationChannel channel = getConversationChannel(
+                shortcutInfo, modifiedConv, shortcutInfo.getPackage(), shortcutInfo.getUserId(),
+                shortcutInfo.getId());
         if (channel != null) {
             notifyConversationsListeners(Arrays.asList(channel));
         }
diff --git a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
index ca9ff6f..962a07a 100644
--- a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
@@ -43,23 +43,23 @@
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.intThat;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyLong;
+import static org.mockito.Mockito.argThat;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.intThat;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoInteractions;
 import static org.mockito.Mockito.when;
 import static org.robolectric.Shadows.shadowOf;
 import static org.robolectric.shadow.api.Shadow.extract;
@@ -2185,7 +2185,7 @@
         task.waitCancel();
         reset(transportMock.transport);
         taskFinished.block();
-        verifyZeroInteractions(transportMock.transport);
+        verifyNoInteractions(transportMock.transport);
     }
 
     @Test
diff --git a/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java b/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java
index e4f9eaf..9b23f8b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java
@@ -1089,8 +1089,7 @@
             Consumer<Uri> consumer = invocation.getArgument(invocation.getArguments().length - 1);
             consumer.accept(Uri.parse("a/b.png"));
             return null;
-        }).when(mMockScreenshotHelper).provideScreenshot(
-                any(), any(), any(), anyInt(), anyInt(), any(), anyInt(), any(), any());
+        }).when(mMockScreenshotHelper).takeScreenshot(any(), any(), any());
         mGameServiceProviderInstance.start();
         startTask(taskId, GAME_A_MAIN_ACTIVITY);
         mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java
index c15f6a9..5792ecb 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java
@@ -17,7 +17,6 @@
 package com.android.server.accessibility;
 
 import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_ACCESSIBILITY_ACTIONS;
-import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;
 
 import static org.hamcrest.Matchers.hasItem;
 import static org.hamcrest.Matchers.is;
@@ -301,9 +300,7 @@
         mSystemActionPerformer.performSystemAction(
                 AccessibilityService.GLOBAL_ACTION_TAKE_SCREENSHOT);
         verify(mMockScreenshotHelper).takeScreenshot(
-                eq(TAKE_SCREENSHOT_FULLSCREEN),
-                eq(SCREENSHOT_ACCESSIBILITY_ACTIONS),
-                any(Handler.class), any());
+                eq(SCREENSHOT_ACCESSIBILITY_ACTIONS), any(Handler.class), any());
     }
 
     // PendingIntent is a final class and cannot be mocked. So we are using this
diff --git a/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java b/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java
index dad9fe8..31599ee 100644
--- a/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java
+++ b/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java
@@ -74,7 +74,7 @@
         mSpyDevInventory = spy(new AudioDeviceInventory(mSpyAudioSystem));
         mSpySystemServer = spy(new NoOpSystemServerAdapter());
         mAudioDeviceBroker = new AudioDeviceBroker(mContext, mMockAudioService, mSpyDevInventory,
-                mSpySystemServer);
+                mSpySystemServer, mSpyAudioSystem);
         mSpyDevInventory.setDeviceBroker(mAudioDeviceBroker);
 
         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
index 666d401..3c735e3 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
@@ -41,7 +41,6 @@
 import android.hardware.biometrics.fingerprint.ISession;
 import android.hardware.biometrics.fingerprint.PointerContext;
 import android.hardware.fingerprint.Fingerprint;
-import android.hardware.fingerprint.FingerprintManager;
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
 import android.hardware.fingerprint.ISidefpsController;
 import android.hardware.fingerprint.IUdfpsOverlayController;
@@ -55,7 +54,6 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
-import com.android.internal.R;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
 import com.android.server.biometrics.log.CallbackWithProbe;
@@ -369,274 +367,6 @@
         verify(mCancellationSignal).cancel();
     }
 
-    @Test
-    public void fingerprintPowerIgnoresAuthInWindow() throws Exception {
-        when(mSensorProps.isAnySidefpsType()).thenReturn(true);
-        when(mHal.authenticate(anyLong())).thenReturn(mCancellationSignal);
-
-        final FingerprintAuthenticationClient client = createClient(1);
-        client.start(mCallback);
-        client.onPowerPressed();
-        client.onAuthenticated(new Fingerprint("friendly", 1 /* fingerId */, 2 /* deviceId */),
-                true /* authenticated */, new ArrayList<>());
-        mLooper.moveTimeForward(1000);
-        mLooper.dispatchAll();
-
-        verify(mCallback).onClientFinished(any(), eq(false));
-        verify(mCancellationSignal).cancel();
-    }
-
-    @Test
-    public void fingerprintAuthIgnoredWaitingForPower() throws Exception {
-        when(mSensorProps.isAnySidefpsType()).thenReturn(true);
-        when(mHal.authenticate(anyLong())).thenReturn(mCancellationSignal);
-
-        final FingerprintAuthenticationClient client = createClient(1);
-        client.start(mCallback);
-        client.onAuthenticated(new Fingerprint("friendly", 3 /* fingerId */, 4 /* deviceId */),
-                true /* authenticated */, new ArrayList<>());
-        client.onPowerPressed();
-        mLooper.moveTimeForward(1000);
-        mLooper.dispatchAll();
-
-        verify(mCallback).onClientFinished(any(), eq(false));
-        verify(mCancellationSignal).cancel();
-    }
-
-    @Test
-    public void fingerprintAuthFailsWhenAuthAfterPower() throws Exception {
-        when(mSensorProps.isAnySidefpsType()).thenReturn(true);
-        when(mHal.authenticate(anyLong())).thenReturn(mCancellationSignal);
-
-        final FingerprintAuthenticationClient client = createClient(1);
-        client.start(mCallback);
-        client.onPowerPressed();
-        mLooper.dispatchAll();
-        mLooper.moveTimeForward(1000);
-        mLooper.dispatchAll();
-        client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */),
-                true /* authenticated */, new ArrayList<>());
-        mLooper.dispatchAll();
-        mLooper.moveTimeForward(1000);
-        mLooper.dispatchAll();
-
-        verify(mCallback, never()).onClientFinished(any(), eq(true));
-        verify(mCallback).onClientFinished(any(), eq(false));
-        when(mHal.authenticateWithContext(anyLong(), any())).thenReturn(mCancellationSignal);
-    }
-
-    @Test
-    public void sideFingerprintDoesntSendAuthImmediately() throws Exception {
-        when(mSensorProps.isAnySidefpsType()).thenReturn(true);
-
-        final FingerprintAuthenticationClient client = createClient(1);
-        client.start(mCallback);
-        mLooper.dispatchAll();
-        client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */),
-                true /* authenticated */, new ArrayList<>());
-        mLooper.dispatchAll();
-
-        verify(mCallback, never()).onClientFinished(any(), anyBoolean());
-    }
-
-    @Test
-    public void sideFingerprintSkipsWindowIfFingerUp() throws Exception {
-        when(mSensorProps.isAnySidefpsType()).thenReturn(true);
-
-        mContext.getOrCreateTestableResources().addOverride(
-                R.integer.config_sidefpsSkipWaitForPowerAcquireMessage, FINGER_UP);
-
-        final FingerprintAuthenticationClient client = createClient(1);
-        client.start(mCallback);
-        mLooper.dispatchAll();
-        client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */),
-                true /* authenticated */, new ArrayList<>());
-        client.onAcquired(FINGER_UP, 0);
-        mLooper.dispatchAll();
-
-        verify(mCallback).onClientFinished(any(), eq(true));
-    }
-
-    @Test
-    public void sideFingerprintSkipsWindowIfVendorMessageMatch() throws Exception {
-        when(mSensorProps.isAnySidefpsType()).thenReturn(true);
-        final int vendorAcquireMessage = 1234;
-
-        mContext.getOrCreateTestableResources().addOverride(
-                R.integer.config_sidefpsSkipWaitForPowerAcquireMessage,
-                FingerprintManager.FINGERPRINT_ACQUIRED_VENDOR);
-        mContext.getOrCreateTestableResources().addOverride(
-                R.integer.config_sidefpsSkipWaitForPowerVendorAcquireMessage,
-                vendorAcquireMessage);
-
-        final FingerprintAuthenticationClient client = createClient(1);
-        client.start(mCallback);
-        mLooper.dispatchAll();
-        client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */),
-                true /* authenticated */, new ArrayList<>());
-        client.onAcquired(FingerprintManager.FINGERPRINT_ACQUIRED_VENDOR, vendorAcquireMessage);
-        mLooper.dispatchAll();
-
-        verify(mCallback).onClientFinished(any(), eq(true));
-    }
-
-    @Test
-    public void sideFingerprintDoesNotSkipWindowOnVendorErrorMismatch() throws Exception {
-        when(mSensorProps.isAnySidefpsType()).thenReturn(true);
-        final int vendorAcquireMessage = 1234;
-
-        mContext.getOrCreateTestableResources().addOverride(
-                R.integer.config_sidefpsSkipWaitForPowerAcquireMessage,
-                FingerprintManager.FINGERPRINT_ACQUIRED_VENDOR);
-        mContext.getOrCreateTestableResources().addOverride(
-                R.integer.config_sidefpsSkipWaitForPowerVendorAcquireMessage,
-                vendorAcquireMessage);
-
-        final FingerprintAuthenticationClient client = createClient(1);
-        client.start(mCallback);
-        mLooper.dispatchAll();
-        client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */),
-                true /* authenticated */, new ArrayList<>());
-        client.onAcquired(FingerprintManager.FINGERPRINT_ACQUIRED_VENDOR, 1);
-        mLooper.dispatchAll();
-
-        verify(mCallback, never()).onClientFinished(any(), anyBoolean());
-    }
-
-    @Test
-    public void sideFingerprintSendsAuthIfFingerUp() throws Exception {
-        when(mSensorProps.isAnySidefpsType()).thenReturn(true);
-
-        mContext.getOrCreateTestableResources().addOverride(
-                R.integer.config_sidefpsSkipWaitForPowerAcquireMessage, FINGER_UP);
-
-        final FingerprintAuthenticationClient client = createClient(1);
-        client.start(mCallback);
-        mLooper.dispatchAll();
-        client.onAcquired(FINGER_UP, 0);
-        client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */),
-                true /* authenticated */, new ArrayList<>());
-        mLooper.dispatchAll();
-
-        verify(mCallback).onClientFinished(any(), eq(true));
-    }
-
-    @Test
-    public void sideFingerprintShortCircuitExpires() throws Exception {
-        when(mSensorProps.isAnySidefpsType()).thenReturn(true);
-
-        final int timeBeforeAuthSent = 500;
-
-        mContext.getOrCreateTestableResources().addOverride(
-                R.integer.config_sidefpsKeyguardPowerPressWindow, timeBeforeAuthSent);
-        mContext.getOrCreateTestableResources().addOverride(
-                R.integer.config_sidefpsSkipWaitForPowerAcquireMessage, FINGER_UP);
-
-        final FingerprintAuthenticationClient client = createClient(1);
-        client.start(mCallback);
-        mLooper.dispatchAll();
-        client.onAcquired(FINGER_UP, 0);
-        mLooper.dispatchAll();
-
-        mLooper.moveTimeForward(500);
-        mLooper.dispatchAll();
-        client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */),
-                true /* authenticated */, new ArrayList<>());
-        mLooper.dispatchAll();
-        verify(mCallback, never()).onClientFinished(any(), anyBoolean());
-
-        mLooper.moveTimeForward(500);
-        mLooper.dispatchAll();
-        verify(mCallback).onClientFinished(any(), eq(true));
-    }
-
-    @Test
-    public void sideFingerprintPowerWindowStartsOnAcquireStart() throws Exception {
-        final int powerWindow = 500;
-        final long authStart = 300;
-
-        when(mSensorProps.isAnySidefpsType()).thenReturn(true);
-        mContext.getOrCreateTestableResources().addOverride(
-                R.integer.config_sidefpsBpPowerPressWindow, powerWindow);
-
-        final FingerprintAuthenticationClient client = createClient(1);
-        client.start(mCallback);
-
-        // Acquire start occurs at time = 0ms
-        when(mClock.millis()).thenReturn(0L);
-        client.onAcquired(FingerprintManager.FINGERPRINT_ACQUIRED_START, 0 /* vendorCode */);
-
-        // Auth occurs at time = 300
-        when(mClock.millis()).thenReturn(authStart);
-        // At this point the delay should be 500 - (300 - 0) == 200 milliseconds.
-        client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */),
-                true /* authenticated */, new ArrayList<>());
-        mLooper.dispatchAll();
-        verify(mCallback, never()).onClientFinished(any(), anyBoolean());
-
-        // After waiting 200 milliseconds, auth should succeed.
-        mLooper.moveTimeForward(powerWindow - authStart);
-        mLooper.dispatchAll();
-        verify(mCallback).onClientFinished(any(), eq(true));
-    }
-
-    @Test
-    public void sideFingerprintPowerWindowStartsOnLastAcquireStart() throws Exception {
-        final int powerWindow = 500;
-
-        when(mSensorProps.isAnySidefpsType()).thenReturn(true);
-        mContext.getOrCreateTestableResources().addOverride(
-                R.integer.config_sidefpsBpPowerPressWindow, powerWindow);
-
-        final FingerprintAuthenticationClient client = createClient(1);
-        client.start(mCallback);
-        // Acquire start occurs at time = 0ms
-        when(mClock.millis()).thenReturn(0L);
-        client.onAcquired(FingerprintManager.FINGERPRINT_ACQUIRED_START, 0 /* vendorCode */);
-
-        // Auth reject occurs at time = 300ms
-        when(mClock.millis()).thenReturn(300L);
-        client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */),
-                false /* authenticated */, new ArrayList<>());
-        mLooper.dispatchAll();
-
-        mLooper.moveTimeForward(300);
-        mLooper.dispatchAll();
-        verify(mCallback, never()).onClientFinished(any(), anyBoolean());
-
-        when(mClock.millis()).thenReturn(1300L);
-        client.onAcquired(FingerprintManager.FINGERPRINT_ACQUIRED_START, 0 /* vendorCode */);
-
-        // If code is correct, the new acquired start timestamp should be used
-        // and the code should only have to wait 500 - (1500-1300)ms.
-        when(mClock.millis()).thenReturn(1500L);
-        client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */),
-                true /* authenticated */, new ArrayList<>());
-        mLooper.dispatchAll();
-
-        mLooper.moveTimeForward(299);
-        mLooper.dispatchAll();
-        verify(mCallback, never()).onClientFinished(any(), anyBoolean());
-
-        mLooper.moveTimeForward(1);
-        mLooper.dispatchAll();
-        verify(mCallback).onClientFinished(any(), eq(true));
-    }
-
-    @Test
-    public void sideFpsPowerPressCancelsIsntantly() throws Exception {
-        when(mSensorProps.isAnySidefpsType()).thenReturn(true);
-
-        final FingerprintAuthenticationClient client = createClient(1);
-        client.start(mCallback);
-
-        client.onPowerPressed();
-        mLooper.dispatchAll();
-
-        verify(mCallback, never()).onClientFinished(any(), eq(true));
-        verify(mCallback).onClientFinished(any(), eq(false));
-    }
-
     private FingerprintAuthenticationClient createClient() throws RemoteException {
         return createClient(100 /* version */, true /* allowBackgroundAuthentication */);
     }
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java
index 86c5937..77e5d1d 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java
@@ -51,6 +51,8 @@
 public final class DisplayDeviceConfigTest {
     private static final int DEFAULT_PEAK_REFRESH_RATE = 75;
     private static final int DEFAULT_REFRESH_RATE = 120;
+    private static final int DEFAULT_HIGH_BLOCKING_ZONE_REFRESH_RATE = 55;
+    private static final int DEFAULT_LOW_BLOCKING_ZONE_REFRESH_RATE = 95;
     private static final int[] LOW_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE = new int[]{10, 30};
     private static final int[] LOW_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE = new int[]{1, 21};
     private static final int[] HIGH_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE = new int[]{160};
@@ -150,8 +152,10 @@
 
         assertEquals("ProximitySensor123", mDisplayDeviceConfig.getProximitySensor().name);
         assertEquals("prox_type_1", mDisplayDeviceConfig.getProximitySensor().type);
-        assertEquals(75, mDisplayDeviceConfig.getDefaultLowRefreshRate());
-        assertEquals(90, mDisplayDeviceConfig.getDefaultHighRefreshRate());
+        assertEquals(75, mDisplayDeviceConfig.getDefaultLowBlockingZoneRefreshRate());
+        assertEquals(90, mDisplayDeviceConfig.getDefaultHighBlockingZoneRefreshRate());
+        assertEquals(85, mDisplayDeviceConfig.getDefaultPeakRefreshRate());
+        assertEquals(45, mDisplayDeviceConfig.getDefaultRefreshRate());
         assertArrayEquals(new int[]{45, 55},
                 mDisplayDeviceConfig.getLowDisplayBrightnessThresholds());
         assertArrayEquals(new int[]{50, 60},
@@ -230,8 +234,12 @@
                 mDisplayDeviceConfig.getAmbientDarkeningLevelsIdle(), ZERO_DELTA);
         assertArrayEquals(new float[]{29, 30, 31},
                 mDisplayDeviceConfig.getAmbientDarkeningPercentagesIdle(), ZERO_DELTA);
-        assertEquals(mDisplayDeviceConfig.getDefaultLowRefreshRate(), DEFAULT_REFRESH_RATE);
-        assertEquals(mDisplayDeviceConfig.getDefaultHighRefreshRate(), DEFAULT_PEAK_REFRESH_RATE);
+        assertEquals(mDisplayDeviceConfig.getDefaultLowBlockingZoneRefreshRate(),
+                DEFAULT_LOW_BLOCKING_ZONE_REFRESH_RATE);
+        assertEquals(mDisplayDeviceConfig.getDefaultHighBlockingZoneRefreshRate(),
+                DEFAULT_HIGH_BLOCKING_ZONE_REFRESH_RATE);
+        assertEquals(mDisplayDeviceConfig.getDefaultPeakRefreshRate(), DEFAULT_PEAK_REFRESH_RATE);
+        assertEquals(mDisplayDeviceConfig.getDefaultRefreshRate(), DEFAULT_REFRESH_RATE);
         assertArrayEquals(mDisplayDeviceConfig.getLowDisplayBrightnessThresholds(),
                 LOW_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE);
         assertArrayEquals(mDisplayDeviceConfig.getLowAmbientBrightnessThresholds(),
@@ -449,6 +457,8 @@
                 +       "<type>prox_type_1</type>\n"
                 +   "</proxSensor>\n"
                 +   "<refreshRate>\n"
+                +       "<defaultRefreshRate>45</defaultRefreshRate>\n"
+                +       "<defaultPeakRefreshRate>85</defaultPeakRefreshRate>\n"
                 +       "<lowerBlockingZoneConfigs>\n"
                 +           "<defaultRefreshRate>75</defaultRefreshRate>\n"
                 +           "<blockingZoneThreshold>\n"
@@ -550,10 +560,14 @@
                 .thenReturn(new int[]{370, 380, 390});
 
         // Configs related to refresh rates and blocking zones
-        when(mResources.getInteger(com.android.internal.R.integer.config_defaultPeakRefreshRate))
+        when(mResources.getInteger(R.integer.config_defaultPeakRefreshRate))
                 .thenReturn(DEFAULT_PEAK_REFRESH_RATE);
-        when(mResources.getInteger(com.android.internal.R.integer.config_defaultRefreshRate))
+        when(mResources.getInteger(R.integer.config_defaultRefreshRate))
                 .thenReturn(DEFAULT_REFRESH_RATE);
+        when(mResources.getInteger(R.integer.config_fixedRefreshRateInHighZone))
+            .thenReturn(DEFAULT_HIGH_BLOCKING_ZONE_REFRESH_RATE);
+        when(mResources.getInteger(R.integer.config_defaultRefreshRateInZone))
+            .thenReturn(DEFAULT_LOW_BLOCKING_ZONE_REFRESH_RATE);
         when(mResources.getIntArray(R.array.config_brightnessThresholdsOfPeakRefreshRate))
                 .thenReturn(LOW_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE);
         when(mResources.getIntArray(R.array.config_ambientThresholdsOfPeakRefreshRate))
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
index cfea63b..af39dd4 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
@@ -40,6 +40,7 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
@@ -74,6 +75,7 @@
 import android.test.mock.MockContentResolver;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.TypedValue;
 import android.view.Display;
 
 import androidx.test.core.app.ApplicationProvider;
@@ -102,6 +104,7 @@
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
+import org.mockito.stubbing.Answer;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -1866,6 +1869,10 @@
             .thenReturn(75);
         when(resources.getInteger(R.integer.config_defaultRefreshRate))
             .thenReturn(45);
+        when(resources.getInteger(R.integer.config_fixedRefreshRateInHighZone))
+            .thenReturn(65);
+        when(resources.getInteger(R.integer.config_defaultRefreshRateInZone))
+            .thenReturn(85);
         when(resources.getIntArray(R.array.config_brightnessThresholdsOfPeakRefreshRate))
             .thenReturn(new int[]{5});
         when(resources.getIntArray(R.array.config_ambientThresholdsOfPeakRefreshRate))
@@ -1885,6 +1892,8 @@
         assertEquals(director.getSettingsObserver().getDefaultRefreshRate(), 45, 0.0);
         assertEquals(director.getSettingsObserver().getDefaultPeakRefreshRate(), 75,
                 0.0);
+        assertEquals(director.getBrightnessObserver().getRefreshRateInHighZone(), 65);
+        assertEquals(director.getBrightnessObserver().getRefreshRateInLowZone(), 85);
         assertArrayEquals(director.getBrightnessObserver().getHighDisplayBrightnessThreshold(),
                 new int[]{250});
         assertArrayEquals(director.getBrightnessObserver().getHighAmbientBrightnessThreshold(),
@@ -1896,17 +1905,21 @@
 
         // Notify that the default display is updated, such that DisplayDeviceConfig has new values
         DisplayDeviceConfig displayDeviceConfig = mock(DisplayDeviceConfig.class);
-        when(displayDeviceConfig.getDefaultLowRefreshRate()).thenReturn(50);
-        when(displayDeviceConfig.getDefaultHighRefreshRate()).thenReturn(55);
+        when(displayDeviceConfig.getDefaultLowBlockingZoneRefreshRate()).thenReturn(50);
+        when(displayDeviceConfig.getDefaultHighBlockingZoneRefreshRate()).thenReturn(55);
+        when(displayDeviceConfig.getDefaultRefreshRate()).thenReturn(60);
+        when(displayDeviceConfig.getDefaultPeakRefreshRate()).thenReturn(65);
         when(displayDeviceConfig.getLowDisplayBrightnessThresholds()).thenReturn(new int[]{25});
         when(displayDeviceConfig.getLowAmbientBrightnessThresholds()).thenReturn(new int[]{30});
         when(displayDeviceConfig.getHighDisplayBrightnessThresholds()).thenReturn(new int[]{210});
         when(displayDeviceConfig.getHighAmbientBrightnessThresholds()).thenReturn(new int[]{2100});
         director.defaultDisplayDeviceUpdated(displayDeviceConfig);
 
-        assertEquals(director.getSettingsObserver().getDefaultRefreshRate(), 50, 0.0);
-        assertEquals(director.getSettingsObserver().getDefaultPeakRefreshRate(), 55,
+        assertEquals(director.getSettingsObserver().getDefaultRefreshRate(), 60, 0.0);
+        assertEquals(director.getSettingsObserver().getDefaultPeakRefreshRate(), 65,
                 0.0);
+        assertEquals(director.getBrightnessObserver().getRefreshRateInHighZone(), 55);
+        assertEquals(director.getBrightnessObserver().getRefreshRateInLowZone(), 50);
         assertArrayEquals(director.getBrightnessObserver().getHighDisplayBrightnessThreshold(),
                 new int[]{210});
         assertArrayEquals(director.getBrightnessObserver().getHighAmbientBrightnessThreshold(),
@@ -1919,6 +1932,8 @@
         // Notify that the default display is updated, such that DeviceConfig has new values
         FakeDeviceConfig config = mInjector.getDeviceConfig();
         config.setDefaultPeakRefreshRate(60);
+        config.setRefreshRateInHighZone(65);
+        config.setRefreshRateInLowZone(70);
         config.setLowAmbientBrightnessThresholds(new int[]{20});
         config.setLowDisplayBrightnessThresholds(new int[]{10});
         config.setHighDisplayBrightnessThresholds(new int[]{255});
@@ -1926,9 +1941,11 @@
 
         director.defaultDisplayDeviceUpdated(displayDeviceConfig);
 
-        assertEquals(director.getSettingsObserver().getDefaultRefreshRate(), 50, 0.0);
+        assertEquals(director.getSettingsObserver().getDefaultRefreshRate(), 60, 0.0);
         assertEquals(director.getSettingsObserver().getDefaultPeakRefreshRate(), 60,
                 0.0);
+        assertEquals(director.getBrightnessObserver().getRefreshRateInHighZone(), 65);
+        assertEquals(director.getBrightnessObserver().getRefreshRateInLowZone(), 70);
         assertArrayEquals(director.getBrightnessObserver().getHighDisplayBrightnessThreshold(),
                 new int[]{255});
         assertArrayEquals(director.getBrightnessObserver().getHighAmbientBrightnessThreshold(),
@@ -1939,6 +1956,61 @@
                 new int[]{20});
     }
 
+    @Test
+    public void testSensorReloadOnDeviceSwitch() throws Exception {
+        // First, configure brightness zones or DMD won't register for sensor data.
+        final FakeDeviceConfig config = mInjector.getDeviceConfig();
+        config.setRefreshRateInHighZone(60);
+        config.setHighDisplayBrightnessThresholds(new int[] { 255 });
+        config.setHighAmbientBrightnessThresholds(new int[] { 8000 });
+
+        DisplayModeDirector director =
+                createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
+        setPeakRefreshRate(90 /*fps*/);
+        director.getSettingsObserver().setDefaultRefreshRate(90);
+        director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
+
+        Sensor lightSensorOne = TestUtils.createSensor(Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT);
+        Sensor lightSensorTwo = TestUtils.createSensor(Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT);
+        SensorManager sensorManager = createMockSensorManager(lightSensorOne, lightSensorTwo);
+        when(sensorManager.getDefaultSensor(5)).thenReturn(lightSensorOne, lightSensorTwo);
+        director.start(sensorManager);
+        ArgumentCaptor<SensorEventListener> listenerCaptor =
+                ArgumentCaptor.forClass(SensorEventListener.class);
+        verify(sensorManager, Mockito.timeout(TimeUnit.SECONDS.toMillis(1)))
+                .registerListener(
+                        listenerCaptor.capture(),
+                        eq(lightSensorOne),
+                        anyInt(),
+                        any(Handler.class));
+
+        DisplayDeviceConfig ddcMock = mock(DisplayDeviceConfig.class);
+        when(ddcMock.getDefaultLowBlockingZoneRefreshRate()).thenReturn(50);
+        when(ddcMock.getDefaultHighBlockingZoneRefreshRate()).thenReturn(55);
+        when(ddcMock.getLowDisplayBrightnessThresholds()).thenReturn(new int[]{25});
+        when(ddcMock.getLowAmbientBrightnessThresholds()).thenReturn(new int[]{30});
+        when(ddcMock.getHighDisplayBrightnessThresholds()).thenReturn(new int[]{210});
+        when(ddcMock.getHighAmbientBrightnessThresholds()).thenReturn(new int[]{2100});
+
+        Resources resMock = mock(Resources.class);
+        when(resMock.getInteger(
+                com.android.internal.R.integer.config_displayWhiteBalanceBrightnessFilterHorizon))
+                .thenReturn(3);
+        ArgumentCaptor<TypedValue> valueArgumentCaptor = ArgumentCaptor.forClass(TypedValue.class);
+        doAnswer((Answer<Void>) invocation -> {
+            valueArgumentCaptor.getValue().type = 4;
+            valueArgumentCaptor.getValue().data = 13;
+            return null;
+        }).when(resMock).getValue(anyInt(), valueArgumentCaptor.capture(), eq(true));
+        when(mContext.getResources()).thenReturn(resMock);
+
+        director.defaultDisplayDeviceUpdated(ddcMock);
+
+        verify(sensorManager).unregisterListener(any(SensorEventListener.class));
+        verify(sensorManager).registerListener(any(SensorEventListener.class),
+                eq(lightSensorTwo), anyInt(), any(Handler.class));
+    }
+
     private Temperature getSkinTemp(@Temperature.ThrottlingStatus int status) {
         return new Temperature(30.0f, Temperature.TYPE_SKIN, "test_skin_temp", status);
     }
diff --git a/services/tests/servicestests/src/com/android/server/display/HbmEventTest.java b/services/tests/servicestests/src/com/android/server/display/HbmEventTest.java
new file mode 100644
index 0000000..24fc348
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/HbmEventTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display;
+
+import static org.junit.Assert.assertEquals;
+
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public final class HbmEventTest {
+    private long mStartTimeMillis;
+    private long mEndTimeMillis;
+    private HbmEvent mHbmEvent;
+
+    @Before
+    public void setUp() {
+        mStartTimeMillis = 10;
+        mEndTimeMillis = 20;
+        mHbmEvent = new HbmEvent(mStartTimeMillis, mEndTimeMillis);
+    }
+
+    @Test
+    public void getCorrectValues() {
+        assertEquals(mHbmEvent.getStartTimeMillis(), mStartTimeMillis);
+        assertEquals(mHbmEvent.getEndTimeMillis(), mEndTimeMillis);
+    }
+
+    @Test
+    public void toStringGeneratesExpectedString() {
+        String actualString = mHbmEvent.toString();
+        String expectedString = "HbmEvent: {startTimeMillis:" + mStartTimeMillis
+                + ", endTimeMillis: " + mEndTimeMillis + "}, total: "
+                + ((mEndTimeMillis - mStartTimeMillis) / 1000) + "]";
+        assertEquals(actualString, expectedString);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java b/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java
index 53fa3e2..da2e1be 100644
--- a/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java
@@ -27,9 +27,7 @@
 import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED;
 import static com.android.server.display.AutomaticBrightnessController
                                                       .AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE;
-
 import static com.android.server.display.DisplayDeviceConfig.HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT;
-
 import static com.android.server.display.HighBrightnessModeController.HBM_TRANSITION_POINT_INVALID;
 
 import static org.junit.Assert.assertEquals;
@@ -102,6 +100,7 @@
     private Binder mDisplayToken;
     private String mDisplayUniqueId;
     private Context mContextSpy;
+    private HighBrightnessModeMetadata mHighBrightnessModeMetadata;
 
     @Rule
     public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
@@ -124,6 +123,7 @@
         mTestLooper = new TestLooper(mClock::now);
         mDisplayToken = null;
         mDisplayUniqueId = "unique_id";
+
         mContextSpy = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
         final MockContentResolver resolver = mSettingsProviderRule.mockContentResolver(mContextSpy);
         when(mContextSpy.getContentResolver()).thenReturn(resolver);
@@ -140,7 +140,8 @@
         initHandler(null);
         final HighBrightnessModeController hbmc = new HighBrightnessModeController(
                 mInjectorMock, mHandler, DISPLAY_WIDTH, DISPLAY_HEIGHT, mDisplayToken,
-                mDisplayUniqueId, DEFAULT_MIN, DEFAULT_MAX, null, null, () -> {}, mContextSpy);
+                mDisplayUniqueId, DEFAULT_MIN, DEFAULT_MAX, null, null, () -> {},
+                null, mContextSpy);
         assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_OFF);
         assertEquals(hbmc.getTransitionPoint(), HBM_TRANSITION_POINT_INVALID, 0.0f);
     }
@@ -150,7 +151,8 @@
         initHandler(null);
         final HighBrightnessModeController hbmc = new HighBrightnessModeController(
                 mInjectorMock, mHandler, DISPLAY_WIDTH, DISPLAY_HEIGHT, mDisplayToken,
-                mDisplayUniqueId, DEFAULT_MIN, DEFAULT_MAX, null, null, () -> {}, mContextSpy);
+                mDisplayUniqueId, DEFAULT_MIN, DEFAULT_MAX, null, null, () -> {},
+                null, mContextSpy);
         hbmc.setAutoBrightnessEnabled(AUTO_BRIGHTNESS_ENABLED);
         hbmc.onAmbientLuxChange(MINIMUM_LUX - 1); // below allowed range
         assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_OFF);
@@ -705,9 +707,12 @@
     // Creates instance with standard initialization values.
     private HighBrightnessModeController createDefaultHbm(OffsettableClock clock) {
         initHandler(clock);
+        if (mHighBrightnessModeMetadata == null) {
+            mHighBrightnessModeMetadata = new HighBrightnessModeMetadata();
+        }
         return new HighBrightnessModeController(mInjectorMock, mHandler, DISPLAY_WIDTH,
                 DISPLAY_HEIGHT, mDisplayToken, mDisplayUniqueId, DEFAULT_MIN, DEFAULT_MAX,
-                DEFAULT_HBM_DATA, null, () -> {}, mContextSpy);
+                DEFAULT_HBM_DATA, null, () -> {}, mHighBrightnessModeMetadata, mContextSpy);
     }
 
     private void initHandler(OffsettableClock clock) {
diff --git a/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeMetadataTest.java b/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeMetadataTest.java
new file mode 100644
index 0000000..ede54e0
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeMetadataTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display;
+
+import static org.junit.Assert.assertEquals;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public final class HighBrightnessModeMetadataTest {
+    private HighBrightnessModeMetadata mHighBrightnessModeMetadata;
+
+    private long mRunningStartTimeMillis = -1;
+
+    @Before
+    public void setUp() {
+        mHighBrightnessModeMetadata = new HighBrightnessModeMetadata();
+    }
+
+    @Test
+    public void checkDefaultValues() {
+        assertEquals(mHighBrightnessModeMetadata.getRunningStartTimeMillis(),
+                mRunningStartTimeMillis);
+        assertEquals(mHighBrightnessModeMetadata.getHbmEventQueue().size(), 0);
+    }
+
+    @Test
+    public void checkSetValues() {
+        mRunningStartTimeMillis = 10;
+        mHighBrightnessModeMetadata.setRunningStartTimeMillis(mRunningStartTimeMillis);
+        assertEquals(mHighBrightnessModeMetadata.getRunningStartTimeMillis(),
+                mRunningStartTimeMillis);
+        HbmEvent expectedHbmEvent = new HbmEvent(10, 20);
+        mHighBrightnessModeMetadata.addHbmEvent(expectedHbmEvent);
+        HbmEvent actualHbmEvent  = mHighBrightnessModeMetadata.getHbmEventQueue().peekFirst();
+        assertEquals(expectedHbmEvent.toString(), actualHbmEvent.toString());
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
index 638637d..650eef0 100644
--- a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
@@ -18,6 +18,7 @@
 
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.DEFAULT_DISPLAY_GROUP;
+import static android.view.Display.TYPE_EXTERNAL;
 import static android.view.Display.TYPE_INTERNAL;
 import static android.view.Display.TYPE_VIRTUAL;
 
@@ -173,7 +174,7 @@
 
     @Test
     public void testDisplayDeviceAddAndRemove_NonInternalTypes() {
-        testDisplayDeviceAddAndRemove_NonInternal(Display.TYPE_EXTERNAL);
+        testDisplayDeviceAddAndRemove_NonInternal(TYPE_EXTERNAL);
         testDisplayDeviceAddAndRemove_NonInternal(Display.TYPE_WIFI);
         testDisplayDeviceAddAndRemove_NonInternal(Display.TYPE_OVERLAY);
         testDisplayDeviceAddAndRemove_NonInternal(TYPE_VIRTUAL);
@@ -218,7 +219,7 @@
 
     @Test
     public void testDisplayDeviceAddAndRemove_OneExternalDefault() {
-        DisplayDevice device = createDisplayDevice(Display.TYPE_EXTERNAL, 600, 800,
+        DisplayDevice device = createDisplayDevice(TYPE_EXTERNAL, 600, 800,
                 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
 
         // add
@@ -268,7 +269,7 @@
     public void testGetDisplayIdsLocked() {
         add(createDisplayDevice(TYPE_INTERNAL, 600, 800,
                 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
-        add(createDisplayDevice(Display.TYPE_EXTERNAL, 600, 800, 0));
+        add(createDisplayDevice(TYPE_EXTERNAL, 600, 800, 0));
         add(createDisplayDevice(TYPE_VIRTUAL, 600, 800, 0));
 
         int [] ids = mLogicalDisplayMapper.getDisplayIdsLocked(Process.SYSTEM_UID,
@@ -460,7 +461,7 @@
 
         Layout layout = new Layout();
         layout.createDisplayLocked(device1.getDisplayDeviceInfoLocked().address, true, true);
-        layout.createDisplayLocked(device2.getDisplayDeviceInfoLocked().address, false, false);
+        layout.createDisplayLocked(device2.getDisplayDeviceInfoLocked().address, false, true);
         when(mDeviceStateToLayoutMapSpy.get(0)).thenReturn(layout);
 
         layout = new Layout();
@@ -469,6 +470,8 @@
         when(mDeviceStateToLayoutMapSpy.get(1)).thenReturn(layout);
         when(mDeviceStateToLayoutMapSpy.get(2)).thenReturn(layout);
 
+        when(mDeviceStateToLayoutMapSpy.size()).thenReturn(4);
+
         LogicalDisplay display1 = add(device1);
         assertEquals(info(display1).address, info(device1).address);
         assertEquals(DEFAULT_DISPLAY, id(display1));
@@ -481,8 +484,15 @@
         mLogicalDisplayMapper.setDeviceStateLocked(0, false);
         mLooper.moveTimeForward(1000);
         mLooper.dispatchAll();
+        // The new state is not applied until the boot is completed
         assertTrue(mLogicalDisplayMapper.getDisplayLocked(device1).isEnabledLocked());
         assertFalse(mLogicalDisplayMapper.getDisplayLocked(device2).isEnabledLocked());
+
+        mLogicalDisplayMapper.onBootCompleted();
+        mLooper.moveTimeForward(1000);
+        mLooper.dispatchAll();
+        assertTrue(mLogicalDisplayMapper.getDisplayLocked(device1).isEnabledLocked());
+        assertTrue(mLogicalDisplayMapper.getDisplayLocked(device2).isEnabledLocked());
         assertFalse(mLogicalDisplayMapper.getDisplayLocked(device1).isInTransitionLocked());
         assertFalse(mLogicalDisplayMapper.getDisplayLocked(device2).isInTransitionLocked());
 
@@ -581,6 +591,7 @@
         // 2) Mark the displays as STATE_OFF so that it can continue with transition
         // 3) Send DISPLAY_DEVICE_EVENT_CHANGE to inform the mapper of the new display state
         // 4) Dispatch handler events.
+        mLogicalDisplayMapper.onBootCompleted();
         mLogicalDisplayMapper.setDeviceStateLocked(0, false);
         mDisplayDeviceRepo.onDisplayDeviceEvent(device3, DISPLAY_DEVICE_EVENT_CHANGED);
         mLooper.moveTimeForward(1000);
@@ -623,6 +634,23 @@
         assertEquals(3, threeDisplaysEnabled.length);
     }
 
+    @Test
+    public void testCreateNewLogicalDisplay() {
+        DisplayDevice device1 = createDisplayDevice(TYPE_EXTERNAL, 600, 800,
+                FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+        when(mDeviceStateToLayoutMapSpy.size()).thenReturn(1);
+        LogicalDisplay display1 = add(device1);
+
+        assertTrue(display1.isEnabledLocked());
+
+        DisplayDevice device2 = createDisplayDevice(TYPE_INTERNAL, 600, 800,
+                FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+        when(mDeviceStateToLayoutMapSpy.size()).thenReturn(2);
+        LogicalDisplay display2 = add(device2);
+
+        assertFalse(display2.isEnabledLocked());
+    }
+
     /////////////////
     // Helper Methods
     /////////////////
diff --git a/services/tests/servicestests/src/com/android/server/display/ScreenOffBrightnessSensorControllerTest.java b/services/tests/servicestests/src/com/android/server/display/ScreenOffBrightnessSensorControllerTest.java
index ea04a19..5b10dc4 100644
--- a/services/tests/servicestests/src/com/android/server/display/ScreenOffBrightnessSensorControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/ScreenOffBrightnessSensorControllerTest.java
@@ -35,6 +35,7 @@
 
 import com.android.server.testutils.OffsettableClock;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -73,6 +74,15 @@
         );
     }
 
+    @After
+    public void tearDown() {
+        if (mController != null) {
+            // Stop the update Brightness loop.
+            mController.stop();
+            mController = null;
+        }
+    }
+
     @Test
     public void testBrightness() throws Exception {
         when(mSensorManager.registerListener(any(SensorEventListener.class), eq(mLightSensor),
diff --git a/services/tests/servicestests/src/com/android/server/people/data/ContactsQueryHelperTest.java b/services/tests/servicestests/src/com/android/server/people/data/ContactsQueryHelperTest.java
index 96302b9..299f153 100644
--- a/services/tests/servicestests/src/com/android/server/people/data/ContactsQueryHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/people/data/ContactsQueryHelperTest.java
@@ -25,6 +25,7 @@
 
 import android.database.Cursor;
 import android.database.MatrixCursor;
+import android.database.sqlite.SQLiteException;
 import android.net.Uri;
 import android.provider.ContactsContract;
 import android.provider.ContactsContract.Contacts;
@@ -63,6 +64,7 @@
     private MatrixCursor mContactsLookupCursor;
     private MatrixCursor mPhoneCursor;
     private ContactsQueryHelper mHelper;
+    private ContactsContentProvider contentProvider;
 
     @Before
     public void setUp() {
@@ -73,7 +75,7 @@
         mPhoneCursor = new MatrixCursor(PHONE_COLUMNS);
 
         MockContentResolver contentResolver = new MockContentResolver();
-        ContactsContentProvider contentProvider = new ContactsContentProvider();
+        contentProvider = new ContactsContentProvider();
         contentProvider.registerCursor(Contacts.CONTENT_URI, mContactsCursor);
         contentProvider.registerCursor(
                 ContactsContract.PhoneLookup.CONTENT_FILTER_URI, mContactsLookupCursor);
@@ -89,6 +91,14 @@
     }
 
     @Test
+    public void testQueryException_returnsFalse() {
+        contentProvider.setThrowException(true);
+
+        Uri contactUri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, CONTACT_LOOKUP_KEY);
+        assertFalse(mHelper.query(contactUri.toString()));
+    }
+
+    @Test
     public void testQueryWithUri() {
         mContactsCursor.addRow(new Object[] {
                 /* id= */ 11, CONTACT_LOOKUP_KEY, /* starred= */ 1, /* hasPhoneNumber= */ 1,
@@ -168,10 +178,15 @@
     private class ContactsContentProvider extends MockContentProvider {
 
         private Map<Uri, Cursor> mUriPrefixToCursorMap = new ArrayMap<>();
+        private boolean throwException = false;
 
         @Override
         public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
                 String sortOrder) {
+            if (throwException) {
+                throw new SQLiteException();
+            }
+
             for (Uri prefixUri : mUriPrefixToCursorMap.keySet()) {
                 if (uri.isPathPrefixMatch(prefixUri)) {
                     return mUriPrefixToCursorMap.get(prefixUri);
@@ -180,6 +195,10 @@
             return mUriPrefixToCursorMap.get(uri);
         }
 
+        public void setThrowException(boolean throwException) {
+            this.throwException = throwException;
+        }
+
         private void registerCursor(Uri uriPrefix, Cursor cursor) {
             mUriPrefixToCursorMap.put(uriPrefix, cursor);
         }
diff --git a/services/tests/servicestests/src/com/android/server/people/data/ConversationInfoTest.java b/services/tests/servicestests/src/com/android/server/people/data/ConversationInfoTest.java
index c90064e..9f914a1 100644
--- a/services/tests/servicestests/src/com/android/server/people/data/ConversationInfoTest.java
+++ b/services/tests/servicestests/src/com/android/server/people/data/ConversationInfoTest.java
@@ -30,6 +30,8 @@
 import android.content.LocusId;
 import android.content.pm.ShortcutInfo;
 import android.net.Uri;
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoOutputStream;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -270,4 +272,58 @@
         assertTrue(conversationInfoFromBackup.isContactStarred());
         // ConversationStatus is a transient object and not persisted
     }
+
+    @Test
+    public void testBuildFromProtoPayload() throws Exception {
+        ConversationStatus cs = new ConversationStatus.Builder("id", ACTIVITY_ANNIVERSARY).build();
+        ConversationStatus cs2 = new ConversationStatus.Builder("id2", ACTIVITY_GAME).build();
+
+        ConversationInfo conversationInfo = new ConversationInfo.Builder()
+                .setShortcutId(SHORTCUT_ID)
+                .setLocusId(LOCUS_ID)
+                .setContactUri(CONTACT_URI)
+                .setContactPhoneNumber(PHONE_NUMBER)
+                .setNotificationChannelId(NOTIFICATION_CHANNEL_ID)
+                .setParentNotificationChannelId(PARENT_NOTIFICATION_CHANNEL_ID)
+                .setLastEventTimestamp(100L)
+                .setCreationTimestamp(200L)
+                .setShortcutFlags(ShortcutInfo.FLAG_LONG_LIVED
+                        | ShortcutInfo.FLAG_CACHED_NOTIFICATIONS)
+                .setImportant(true)
+                .setNotificationSilenced(true)
+                .setBubbled(true)
+                .setDemoted(true)
+                .setPersonImportant(true)
+                .setPersonBot(true)
+                .setContactStarred(true)
+                .addOrUpdateStatus(cs)
+                .addOrUpdateStatus(cs2)
+                .build();
+
+        final ProtoOutputStream protoOutputStream = new ProtoOutputStream();
+        conversationInfo.writeToProto(protoOutputStream);
+        ConversationInfo conversationInfoFromBackup =
+                ConversationInfo.readFromProto(new ProtoInputStream(protoOutputStream.getBytes()));
+
+        assertEquals(SHORTCUT_ID, conversationInfoFromBackup.getShortcutId());
+        assertEquals(LOCUS_ID, conversationInfoFromBackup.getLocusId());
+        assertEquals(CONTACT_URI, conversationInfoFromBackup.getContactUri());
+        assertEquals(PHONE_NUMBER, conversationInfoFromBackup.getContactPhoneNumber());
+        assertEquals(
+                NOTIFICATION_CHANNEL_ID, conversationInfoFromBackup.getNotificationChannelId());
+        assertEquals(PARENT_NOTIFICATION_CHANNEL_ID,
+                conversationInfoFromBackup.getParentNotificationChannelId());
+        assertEquals(100L, conversationInfoFromBackup.getLastEventTimestamp());
+        assertEquals(200L, conversationInfoFromBackup.getCreationTimestamp());
+        assertTrue(conversationInfoFromBackup.isShortcutLongLived());
+        assertTrue(conversationInfoFromBackup.isShortcutCachedForNotification());
+        assertTrue(conversationInfoFromBackup.isImportant());
+        assertTrue(conversationInfoFromBackup.isNotificationSilenced());
+        assertTrue(conversationInfoFromBackup.isBubbled());
+        assertTrue(conversationInfoFromBackup.isDemoted());
+        assertTrue(conversationInfoFromBackup.isPersonImportant());
+        assertTrue(conversationInfoFromBackup.isPersonBot());
+        assertTrue(conversationInfoFromBackup.isContactStarred());
+        // ConversationStatus is a transient object and not persisted
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java b/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java
index 66c3f07..a27602d 100644
--- a/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java
@@ -500,6 +500,7 @@
         // The cached conversations are above the limit because every conversation has active
         // notifications. To uncache one of them, the notifications for that conversation need to
         // be dismissed.
+        String notificationKey = "";
         for (int i = 0; i < DataManager.MAX_CACHED_RECENT_SHORTCUTS + 1; i++) {
             String shortcutId = TEST_SHORTCUT_ID + i;
             ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, shortcutId,
@@ -507,11 +508,13 @@
             shortcut.setCached(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS);
             mDataManager.addOrUpdateConversationInfo(shortcut);
             when(mNotification.getShortcutId()).thenReturn(shortcutId);
-            sendGenericNotification();
+            notificationKey = String.format("notification-key-%d", i);
+            sendGenericNotificationWithKey(notificationKey);
         }
 
         // Post another notification for the last conversation.
-        sendGenericNotification();
+        String otherNotificationKey = "other-notification-key";
+        sendGenericNotificationWithKey(otherNotificationKey);
 
         // Removing one of the two notifications does not un-cache the shortcut.
         listenerService.onNotificationRemoved(mGenericSbn, null,
@@ -520,6 +523,7 @@
                 anyInt(), any(), anyString(), any(), anyInt(), anyInt());
 
         // Removing the second notification un-caches the shortcut.
+        when(mGenericSbn.getKey()).thenReturn(notificationKey);
         listenerService.onNotificationRemoved(mGenericSbn, null,
                 NotificationListenerService.REASON_CANCEL_ALL);
         verify(mShortcutServiceInternal).uncacheShortcuts(
@@ -687,6 +691,63 @@
     }
 
     @Test
+    public void testGetConversation_trackActiveConversations() {
+        mDataManager.onUserUnlocked(USER_ID_PRIMARY);
+        assertThat(mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
+                TEST_SHORTCUT_ID)).isNull();
+        ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID,
+                buildPerson());
+        shortcut.setCached(ShortcutInfo.FLAG_PINNED);
+        mDataManager.addOrUpdateConversationInfo(shortcut);
+        assertThat(mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
+                TEST_SHORTCUT_ID)).isNotNull();
+
+        sendGenericNotification();
+        sendGenericNotification();
+        ConversationChannel result = mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
+                TEST_SHORTCUT_ID);
+        assertTrue(result.hasActiveNotifications());
+
+        // Both generic notifications have the same notification key, so a single dismiss will
+        // remove both of them.
+        NotificationListenerService listenerService =
+                mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
+        listenerService.onNotificationRemoved(mGenericSbn, null,
+                NotificationListenerService.REASON_CANCEL);
+        ConversationChannel resultTwo = mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
+                TEST_SHORTCUT_ID);
+        assertFalse(resultTwo.hasActiveNotifications());
+    }
+
+    @Test
+    public void testGetConversation_unsyncedShortcut() {
+        mDataManager.onUserUnlocked(USER_ID_PRIMARY);
+        ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID,
+                buildPerson());
+        shortcut.setCached(ShortcutInfo.FLAG_PINNED);
+        mDataManager.addOrUpdateConversationInfo(shortcut);
+        assertThat(mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
+                TEST_SHORTCUT_ID)).isNotNull();
+        assertThat(mDataManager.getPackage(TEST_PKG_NAME, USER_ID_PRIMARY)
+                .getConversationStore()
+                .getConversation(TEST_SHORTCUT_ID)).isNotNull();
+
+        when(mShortcutServiceInternal.getShortcuts(
+                anyInt(), anyString(), anyLong(), anyString(), anyList(), any(), any(),
+                anyInt(), anyInt(), anyInt(), anyInt()))
+                .thenReturn(Collections.emptyList());
+        assertThat(mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
+                TEST_SHORTCUT_ID)).isNull();
+
+        // Conversation is removed from store as there is no matching shortcut in ShortcutManager
+        assertThat(mDataManager.getPackage(TEST_PKG_NAME, USER_ID_PRIMARY)
+                .getConversationStore()
+                .getConversation(TEST_SHORTCUT_ID)).isNull();
+        verify(mNotificationManagerInternal)
+                .onConversationRemoved(TEST_PKG_NAME, TEST_PKG_UID, Set.of(TEST_SHORTCUT_ID));
+    }
+
+    @Test
     public void testOnNotificationChannelModified() {
         mDataManager.onUserUnlocked(USER_ID_PRIMARY);
         assertThat(mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
@@ -1294,7 +1355,7 @@
 
         sendGenericNotification();
 
-       mDataManager.getRecentConversations(USER_ID_PRIMARY);
+        mDataManager.getRecentConversations(USER_ID_PRIMARY);
 
         verify(mShortcutServiceInternal).getShortcuts(
                 anyInt(), anyString(), anyLong(), anyString(), anyList(), any(), any(),
@@ -1665,6 +1726,12 @@
     // "Sends" a notification to a non-customized notification channel - the notification channel
     // is something generic like "messages" and the notification has a  shortcut id
     private void sendGenericNotification() {
+        sendGenericNotificationWithKey(GENERIC_KEY);
+    }
+
+    // "Sends" a notification to a non-customized notification channel with the specified key.
+    private void sendGenericNotificationWithKey(String key) {
+        when(mGenericSbn.getKey()).thenReturn(key);
         when(mNotification.getChannelId()).thenReturn(PARENT_NOTIFICATION_CHANNEL_ID);
         doAnswer(invocationOnMock -> {
             NotificationListenerService.Ranking ranking = (NotificationListenerService.Ranking)
@@ -1678,9 +1745,9 @@
                     mParentNotificationChannel.getImportance(),
                     null, null,
                     mParentNotificationChannel, null, null, true, 0, false, -1, false, null, null,
-                    false, false, false, null, 0, false);
+                    false, false, false, null, 0, false, 0);
             return true;
-        }).when(mRankingMap).getRanking(eq(GENERIC_KEY),
+        }).when(mRankingMap).getRanking(eq(key),
                 any(NotificationListenerService.Ranking.class));
         NotificationListenerService listenerService =
                 mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
@@ -1704,7 +1771,7 @@
                     mNotificationChannel.getImportance(),
                     null, null,
                     mNotificationChannel, null, null, true, 0, false, -1, false, null, null, false,
-                    false, false, null, 0, false);
+                    false, false, null, 0, false, 0);
             return true;
         }).when(mRankingMap).getRanking(eq(CUSTOM_KEY),
                 any(NotificationListenerService.Ranking.class));
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
index 12cd834..8a99c2c 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
@@ -193,7 +193,8 @@
                 tweak.isConversation(),
                 tweak.getConversationShortcutInfo(),
                 tweak.getRankingAdjustment(),
-                tweak.isBubble()
+                tweak.isBubble(),
+                tweak.getProposedImportance()
         );
         assertNotEquals(nru, nru2);
     }
@@ -274,7 +275,8 @@
                     isConversation(i),
                     getShortcutInfo(i),
                     getRankingAdjustment(i),
-                    isBubble(i)
+                    isBubble(i),
+                    getProposedImportance(i)
             );
             rankings[i] = ranking;
         }
@@ -402,6 +404,10 @@
         return index % 3 - 1;
     }
 
+    private int getProposedImportance(int index) {
+        return index % 5 - 1;
+    }
+
     private boolean isBubble(int index) {
         return index % 4 == 0;
     }
@@ -443,6 +449,7 @@
         assertEquals(comment, a.getConversationShortcutInfo().getId(),
                 b.getConversationShortcutInfo().getId());
         assertActionsEqual(a.getSmartActions(), b.getSmartActions());
+        assertEquals(a.getProposedImportance(), b.getProposedImportance());
     }
 
     private void detailedAssertEquals(RankingMap a, RankingMap b) {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordExtractorDataTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordExtractorDataTest.java
new file mode 100644
index 0000000..87e86cb
--- /dev/null
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordExtractorDataTest.java
@@ -0,0 +1,117 @@
+/*
+ * 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.notification;
+
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.graphics.drawable.Icon;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.service.notification.Adjustment;
+import android.service.notification.SnoozeCriterion;
+import android.service.notification.StatusBarNotification;
+
+import com.android.server.UiServiceTestCase;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Objects;
+
+public class NotificationRecordExtractorDataTest extends UiServiceTestCase {
+
+    @Test
+    public void testHasDiffs_noDiffs() {
+        NotificationRecord r = generateRecord();
+
+        NotificationRecordExtractorData extractorData = new NotificationRecordExtractorData(
+                1,
+                r.getPackageVisibilityOverride(),
+                r.canShowBadge(),
+                r.canBubble(),
+                r.getNotification().isBubbleNotification(),
+                r.getChannel(),
+                r.getGroupKey(),
+                r.getPeopleOverride(),
+                r.getSnoozeCriteria(),
+                r.getUserSentiment(),
+                r.getSuppressedVisualEffects(),
+                r.getSystemGeneratedSmartActions(),
+                r.getSmartReplies(),
+                r.getImportance(),
+                r.getRankingScore(),
+                r.isConversation(),
+                r.getProposedImportance());
+
+        assertFalse(extractorData.hasDiffForRankingLocked(r, 1));
+        assertFalse(extractorData.hasDiffForLoggingLocked(r, 1));
+    }
+
+    @Test
+    public void testHasDiffs_proposedImportanceChange() {
+        NotificationRecord r = generateRecord();
+
+        NotificationRecordExtractorData extractorData = new NotificationRecordExtractorData(
+                1,
+                r.getPackageVisibilityOverride(),
+                r.canShowBadge(),
+                r.canBubble(),
+                r.getNotification().isBubbleNotification(),
+                r.getChannel(),
+                r.getGroupKey(),
+                r.getPeopleOverride(),
+                r.getSnoozeCriteria(),
+                r.getUserSentiment(),
+                r.getSuppressedVisualEffects(),
+                r.getSystemGeneratedSmartActions(),
+                r.getSmartReplies(),
+                r.getImportance(),
+                r.getRankingScore(),
+                r.isConversation(),
+                r.getProposedImportance());
+
+        Bundle signals = new Bundle();
+        signals.putInt(Adjustment.KEY_IMPORTANCE_PROPOSAL, IMPORTANCE_HIGH);
+        Adjustment adjustment = new Adjustment("pkg", r.getKey(), signals, "", 0);
+        r.addAdjustment(adjustment);
+        r.applyAdjustments();
+
+        assertTrue(extractorData.hasDiffForRankingLocked(r, 1));
+        assertTrue(extractorData.hasDiffForLoggingLocked(r, 1));
+    }
+
+    private NotificationRecord generateRecord() {
+        NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
+        final Notification.Builder builder = new Notification.Builder(getContext())
+                .setContentTitle("foo")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon);
+        Notification n = builder.build();
+        StatusBarNotification sbn = new StatusBarNotification("", "", 0, "", 0,
+                0, n, UserHandle.ALL, null, System.currentTimeMillis());
+       return new NotificationRecord(getContext(), sbn, channel);
+    }
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
index 5468220..14b0048 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
@@ -19,6 +19,7 @@
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
 import static android.app.NotificationManager.IMPORTANCE_HIGH;
 import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
 import static android.service.notification.Adjustment.KEY_IMPORTANCE;
 import static android.service.notification.Adjustment.KEY_NOT_CONVERSATION;
 import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING;
@@ -755,6 +756,24 @@
     }
 
     @Test
+    public void testProposedImportance() {
+        StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
+                true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+                false /* lights */, false /* defaultLights */, groupId /* group */);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+
+        assertEquals(IMPORTANCE_UNSPECIFIED, record.getProposedImportance());
+
+        Bundle signals = new Bundle();
+        signals.putInt(Adjustment.KEY_IMPORTANCE_PROPOSAL, IMPORTANCE_DEFAULT);
+        record.addAdjustment(new Adjustment(mPkg, record.getKey(), signals, null, sbn.getUserId()));
+
+        record.applyAdjustments();
+
+        assertEquals(IMPORTANCE_DEFAULT, record.getProposedImportance());
+    }
+
+    @Test
     public void testAppImportance_returnsCorrectly() {
         StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
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 598a22b..770feab 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -1703,6 +1703,7 @@
         channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
         channel.setShowBadge(true);
         channel.setAllowBubbles(false);
+        channel.setImportantConversation(true);
         int lockMask = 0;
         for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
             lockMask |= NotificationChannel.LOCKABLE_FIELDS[i];
@@ -1718,6 +1719,7 @@
         assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
         assertFalse(savedChannel.canBypassDnd());
         assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
+        assertFalse(channel.isImportantConversation());
         assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
         assertEquals(channel.canBubble(), savedChannel.canBubble());
 
@@ -4396,7 +4398,7 @@
                 new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
         channel2.setConversationId(calls.getId(), convoId);
         channel2.setImportantConversation(true);
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel2, false, false);
 
         List<ConversationChannelWrapper> convos =
                 mHelper.getConversations(IntArray.wrap(new int[] {0}), false);
@@ -4473,7 +4475,7 @@
                 new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
         channel2.setConversationId(calls.getId(), convoId);
         channel2.setImportantConversation(true);
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel2, false, false);
 
         List<ConversationChannelWrapper> convos =
                 mHelper.getConversations(IntArray.wrap(new int[] {0}), false);
@@ -4501,13 +4503,13 @@
                 new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
         channel.setConversationId(messages.getId(), convoId);
         channel.setImportantConversation(true);
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel, false, false);
 
         NotificationChannel diffConvo =
                 new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
         diffConvo.setConversationId(p.getId(), "different convo");
         diffConvo.setImportantConversation(true);
-        mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, true, false);
+        mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, false, false);
 
         NotificationChannel channel2 =
                 new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
@@ -4534,7 +4536,7 @@
                 new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
         channel.setConversationId(messages.getId(), convoId);
         channel.setImportantConversation(true);
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel, false, false);
 
         mHelper.permanentlyDeleteNotificationChannel(PKG_O, UID_O, "messages");
 
@@ -4935,7 +4937,7 @@
                 "conversation", IMPORTANCE_DEFAULT);
         friend.setConversationId(parent.getId(), "friend");
         friend.setImportantConversation(true);
-        mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, friend, false, false);
 
         ArrayList<StatsEvent> events = new ArrayList<>();
         mHelper.pullPackageChannelPreferencesStats(events);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
index 1f117b3..9c3d5a7 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
@@ -234,7 +234,7 @@
     }
 
     @Test
-    public void testScheduleRepostsForLongTagPersistedNotification() throws Exception {
+    public void testLongTagPersistedNotification() throws Exception {
         String longTag = "A".repeat(66000);
         NotificationRecord r = getNotificationRecord("pkg", 1, longTag, UserHandle.SYSTEM);
         mSnoozeHelper.snooze(r, 0);
@@ -612,7 +612,8 @@
     public void testClearData_userPackage() {
         // snooze 2 from same package
         NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
-        NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM);
+        NotificationRecord r2 = getNotificationRecord("pkg", 2, "two" + "2".repeat(66000),
+                UserHandle.SYSTEM); // include notif with very long tag
         mSnoozeHelper.snooze(r, 1000);
         mSnoozeHelper.snooze(r2, 1000);
         assertTrue(mSnoozeHelper.isSnoozed(
@@ -634,11 +635,14 @@
 
     @Test
     public void testClearData_user() {
-        // snooze 2 from same package
+        // snooze 2 from same package, including notifs with long tag
         NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
-        NotificationRecord r2 = getNotificationRecord("pkg2", 2, "two", UserHandle.SYSTEM);
-        NotificationRecord r3 = getNotificationRecord("pkg2", 3, "three", UserHandle.SYSTEM);
-        NotificationRecord r4 = getNotificationRecord("pkg", 2, "two", UserHandle.ALL);
+        NotificationRecord r2 = getNotificationRecord("pkg2", 2, "two" + "2".repeat(66000),
+                UserHandle.SYSTEM);
+        NotificationRecord r3 = getNotificationRecord("pkg2", 3, "three",
+                UserHandle.SYSTEM);
+        NotificationRecord r4 = getNotificationRecord("pkg", 2, "two" + "2".repeat(66000),
+                UserHandle.ALL);
         mSnoozeHelper.snooze(r, 1000);
         mSnoozeHelper.snooze(r2, 1000);
         mSnoozeHelper.snooze(r3, "until");
@@ -653,6 +657,19 @@
         assertTrue(mSnoozeHelper.isSnoozed(
                 UserHandle.USER_ALL, r4.getSbn().getPackageName(), r4.getKey()));
 
+        assertFalse(0L == mSnoozeHelper.getSnoozeTimeForUnpostedNotification(
+                r.getUser().getIdentifier(), r.getSbn().getPackageName(),
+                r.getSbn().getKey()));
+        assertFalse(0L == mSnoozeHelper.getSnoozeTimeForUnpostedNotification(
+                r2.getUser().getIdentifier(), r2.getSbn().getPackageName(),
+                r2.getSbn().getKey()));
+        assertNotNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification(
+                r3.getUser().getIdentifier(), r3.getSbn().getPackageName(),
+                r3.getSbn().getKey()));
+        assertNotNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification(
+                r4.getUser().getIdentifier(), r4.getSbn().getPackageName(),
+                r4.getSbn().getKey()));
+
         // clear data
         mSnoozeHelper.clearData(UserHandle.USER_SYSTEM);
 
@@ -666,18 +683,18 @@
         assertTrue(mSnoozeHelper.isSnoozed(
                 UserHandle.USER_SYSTEM, r4.getSbn().getPackageName(), r4.getKey()));
 
-        assertNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification(
-                r3.getUser().getIdentifier(), r3.getSbn().getPackageName(),
-                r3.getSbn().getKey()));
-        assertNotNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification(
-                r4.getUser().getIdentifier(), r4.getSbn().getPackageName(),
-                r4.getSbn().getKey()));
         assertEquals(0L, mSnoozeHelper.getSnoozeTimeForUnpostedNotification(
                 r.getUser().getIdentifier(), r.getSbn().getPackageName(),
                 r.getSbn().getKey()).longValue());
         assertEquals(0L, mSnoozeHelper.getSnoozeTimeForUnpostedNotification(
                 r2.getUser().getIdentifier(), r2.getSbn().getPackageName(),
                 r2.getSbn().getKey()).longValue());
+        assertNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification(
+                r3.getUser().getIdentifier(), r3.getSbn().getPackageName(),
+                r3.getSbn().getKey()));
+        assertNotNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification(
+                r4.getUser().getIdentifier(), r4.getSbn().getPackageName(),
+                r4.getSbn().getKey()));
 
         // 2 for initial timed-snoozes, once each for canceling the USER_SYSTEM snoozes
         verify(mAm, times(5)).cancel(any(PendingIntent.class));
diff --git a/services/tests/wmtests/Android.bp b/services/tests/wmtests/Android.bp
index 079d765..2ce7cea 100644
--- a/services/tests/wmtests/Android.bp
+++ b/services/tests/wmtests/Android.bp
@@ -68,6 +68,10 @@
         "android.test.runner",
     ],
 
+    defaults: [
+        "modules-utils-testable-device-config-defaults",
+    ],
+
     // These are not normally accessible from apps so they must be explicitly included.
     jni_libs: [
         "libdexmakerjvmtiagent",
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
index eed32d7..bb20244 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
@@ -249,6 +249,19 @@
     }
 
     /**
+     * Ensures it updates recent tasks order when the last resumed activity changed.
+     */
+    @Test
+    public void testUpdateRecentTasksForTopResumed() {
+        spyOn(mSupervisor.mRecentTasks);
+        final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true).build();
+        final Task task = activity.getTask();
+
+        mAtm.setLastResumedActivityUncheckLocked(activity, "test");
+        verify(mSupervisor.mRecentTasks).add(eq(task));
+    }
+
+    /**
      * Ensures that a trusted display can launch arbitrary activity and an untrusted display can't.
      */
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
index e30e5db..74ea7d7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
@@ -40,7 +40,7 @@
 import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
 import android.view.WindowManager;
-import android.window.BackEvent;
+import android.window.BackMotionEvent;
 import android.window.BackNavigationInfo;
 import android.window.IOnBackInvokedCallback;
 import android.window.OnBackInvokedCallback;
@@ -242,11 +242,11 @@
     private IOnBackInvokedCallback createOnBackInvokedCallback() {
         return new IOnBackInvokedCallback.Stub() {
             @Override
-            public void onBackStarted(BackEvent backEvent) {
+            public void onBackStarted(BackMotionEvent backEvent) {
             }
 
             @Override
-            public void onBackProgressed(BackEvent backEvent) {
+            public void onBackProgressed(BackMotionEvent backEvent) {
             }
 
             @Override
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 98e68ca..b0639bf 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -2064,7 +2064,8 @@
         // Update the forced size and density in settings and the unique id to simualate a display
         // remap.
         dc.mWmService.mDisplayWindowSettings.setForcedSize(dc, forcedWidth, forcedHeight);
-        dc.mWmService.mDisplayWindowSettings.setForcedDensity(dc, forcedDensity, 0 /* userId */);
+        dc.mWmService.mDisplayWindowSettings.setForcedDensity(displayInfo, forcedDensity,
+                0 /* userId */);
         dc.mCurrentUniqueDisplayId = mDisplayInfo.uniqueId + "-test";
         // Trigger display changed.
         dc.onDisplayChanged();
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java
index 8bb79e3..45b30b2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java
@@ -155,6 +155,18 @@
     }
 
     @Test
+    public void testTreatmentDisabledPerApp_noForceRotationOrRefresh()
+            throws Exception {
+        configureActivity(SCREEN_ORIENTATION_PORTRAIT);
+        when(mActivity.mLetterboxUiController.shouldForceRotateForCameraCompat())
+                .thenReturn(false);
+
+        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+
+        assertNoForceRotationOrRefresh();
+    }
+
+    @Test
     public void testMultiWindowMode_returnUnspecified_noForceRotationOrRefresh() throws Exception {
         configureActivity(SCREEN_ORIENTATION_PORTRAIT);
         final TestSplitOrganizer organizer = new TestSplitOrganizer(mAtm, mDisplayContent);
@@ -327,7 +339,21 @@
     }
 
     @Test
-    public void testOnActivityConfigurationChanging_refreshDisabled_noRefresh() throws Exception {
+    public void testOnActivityConfigurationChanging_refreshDisabledViaFlag_noRefresh()
+            throws Exception {
+        configureActivity(SCREEN_ORIENTATION_PORTRAIT);
+        when(mActivity.mLetterboxUiController.shouldRefreshActivityForCameraCompat())
+                .thenReturn(false);
+
+        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+        callOnActivityConfigurationChanging(mActivity, /* isDisplayRotationChanging */ true);
+
+        assertActivityRefreshRequested(/* refreshRequested */ false);
+    }
+
+    @Test
+    public void testOnActivityConfigurationChanging_refreshDisabledPerApp_noRefresh()
+            throws Exception {
         when(mLetterboxConfiguration.isCameraCompatRefreshEnabled()).thenReturn(false);
 
         configureActivity(SCREEN_ORIENTATION_PORTRAIT);
@@ -362,6 +388,19 @@
         assertActivityRefreshRequested(/* refreshRequested */ true, /* cycleThroughStop */ false);
     }
 
+    @Test
+    public void testOnActivityConfigurationChanging_cycleThroughStopDisabledForApp()
+            throws Exception {
+        configureActivity(SCREEN_ORIENTATION_PORTRAIT);
+        when(mActivity.mLetterboxUiController.shouldRefreshActivityViaPauseForCameraCompat())
+                .thenReturn(true);
+
+        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+        callOnActivityConfigurationChanging(mActivity, /* isDisplayRotationChanging */ true);
+
+        assertActivityRefreshRequested(/* refreshRequested */ true, /* cycleThroughStop */ false);
+    }
+
     private void configureActivity(@ScreenOrientation int activityOrientation) {
         configureActivityAndDisplay(activityOrientation, ORIENTATION_PORTRAIT);
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicyTests.java
new file mode 100644
index 0000000..def4b88
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicyTests.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
+import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+
+import android.platform.test.annotations.Presubmit;
+import android.view.InsetsVisibilities;
+import android.view.Surface;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for {@link DisplayRotationImmersiveAppCompatPolicy}.
+ *
+ * Build/Install/Run:
+ *  atest WmTests:DisplayRotationImmersiveAppCompatPolicyTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(WindowTestRunner.class)
+public class DisplayRotationImmersiveAppCompatPolicyTests extends WindowTestsBase {
+
+    private DisplayRotationImmersiveAppCompatPolicy mPolicy;
+
+    private LetterboxConfiguration mMockLetterboxConfiguration;
+    private ActivityRecord mMockActivityRecord;
+    private Task mMockTask;
+    private InsetsVisibilities mMockInsetsVisibilities;
+
+    @Before
+    public void setUp() throws Exception {
+        mMockActivityRecord = mock(ActivityRecord.class);
+        mMockTask = mock(Task.class);
+        when(mMockTask.getWindowingMode()).thenReturn(WINDOWING_MODE_FULLSCREEN);
+        when(mMockActivityRecord.getTask()).thenReturn(mMockTask);
+        when(mMockActivityRecord.areBoundsLetterboxed()).thenReturn(false);
+        when(mMockActivityRecord.getRequestedConfigurationOrientation()).thenReturn(
+                ORIENTATION_LANDSCAPE);
+        WindowState mockWindowState = mock(WindowState.class);
+        mMockInsetsVisibilities = mock(InsetsVisibilities.class);
+        when(mMockInsetsVisibilities.getVisibility(eq(ITYPE_STATUS_BAR))).thenReturn(false);
+        when(mMockInsetsVisibilities.getVisibility(eq(ITYPE_NAVIGATION_BAR))).thenReturn(false);
+        when(mockWindowState.getRequestedVisibilities()).thenReturn(mMockInsetsVisibilities);
+        when(mMockActivityRecord.findMainWindow()).thenReturn(mockWindowState);
+
+        spy(mDisplayContent);
+        doReturn(mMockActivityRecord).when(mDisplayContent).topRunningActivity();
+        when(mDisplayContent.getIgnoreOrientationRequest()).thenReturn(true);
+
+        mMockLetterboxConfiguration = mock(LetterboxConfiguration.class);
+        when(mMockLetterboxConfiguration.isDisplayRotationImmersiveAppCompatPolicyEnabled(
+                /* checkDeviceConfig */ anyBoolean())).thenReturn(true);
+
+        mPolicy = DisplayRotationImmersiveAppCompatPolicy.createIfNeeded(
+                mMockLetterboxConfiguration, createDisplayRotationMock(),
+                mDisplayContent);
+    }
+
+    private DisplayRotation createDisplayRotationMock() {
+        DisplayRotation mockDisplayRotation = mock(DisplayRotation.class);
+
+        when(mockDisplayRotation.isAnyPortrait(Surface.ROTATION_0)).thenReturn(true);
+        when(mockDisplayRotation.isAnyPortrait(Surface.ROTATION_90)).thenReturn(false);
+        when(mockDisplayRotation.isAnyPortrait(Surface.ROTATION_180)).thenReturn(true);
+        when(mockDisplayRotation.isAnyPortrait(Surface.ROTATION_270)).thenReturn(false);
+        when(mockDisplayRotation.isLandscapeOrSeascape(Surface.ROTATION_0)).thenReturn(false);
+        when(mockDisplayRotation.isLandscapeOrSeascape(Surface.ROTATION_90)).thenReturn(true);
+        when(mockDisplayRotation.isLandscapeOrSeascape(Surface.ROTATION_180)).thenReturn(false);
+        when(mockDisplayRotation.isLandscapeOrSeascape(Surface.ROTATION_270)).thenReturn(true);
+
+        return mockDisplayRotation;
+    }
+
+    @Test
+    public void testIsRotationLockEnforced_landscapeActivity_lockedWhenRotatingToPortrait() {
+        // Base case: App is optimal in Landscape.
+
+        // ROTATION_* is the target display orientation counted from the natural display
+        // orientation. Outside of test environment, ROTATION_0 means that proposed display
+        // rotation is the natural device orientation.
+        // DisplayRotationImmersiveAppCompatPolicy assesses whether the proposed target
+        // orientation ROTATION_* is optimal for the top fullscreen activity or not.
+        // For instance, ROTATION_0 means portrait screen orientation (see
+        // createDisplayRotationMock) which isn't optimal for a landscape-only activity so
+        // we should show a rotation suggestion button instead of rotating directly.
+
+        // Rotation to portrait
+        assertTrue(mPolicy.isRotationLockEnforced(Surface.ROTATION_0));
+        // Rotation to landscape
+        assertFalse(mPolicy.isRotationLockEnforced(Surface.ROTATION_90));
+        // Rotation to portrait
+        assertTrue(mPolicy.isRotationLockEnforced(Surface.ROTATION_180));
+        // Rotation to landscape
+        assertFalse(mPolicy.isRotationLockEnforced(Surface.ROTATION_270));
+    }
+
+    @Test
+    public void testIsRotationLockEnforced_portraitActivity_lockedWhenRotatingToLandscape() {
+        when(mMockActivityRecord.getRequestedConfigurationOrientation()).thenReturn(
+                ORIENTATION_PORTRAIT);
+
+        // Rotation to portrait
+        assertFalse(mPolicy.isRotationLockEnforced(Surface.ROTATION_0));
+        // Rotation to landscape
+        assertTrue(mPolicy.isRotationLockEnforced(Surface.ROTATION_90));
+        // Rotation to portrait
+        assertFalse(mPolicy.isRotationLockEnforced(Surface.ROTATION_180));
+        // Rotation to landscape
+        assertTrue(mPolicy.isRotationLockEnforced(Surface.ROTATION_270));
+    }
+
+    @Test
+    public void testIsRotationLockEnforced_responsiveActivity_lockNotEnforced() {
+        // Do not fix screen orientation
+        when(mMockActivityRecord.getRequestedConfigurationOrientation()).thenReturn(
+                ORIENTATION_UNDEFINED);
+
+        assertIsRotationLockEnforcedReturnsFalseForAllRotations();
+    }
+
+    @Test
+    public void testIsRotationLockEnforced_statusBarVisible_lockNotEnforced() {
+        // Some system bars are visible
+        when(mMockInsetsVisibilities.getVisibility(eq(ITYPE_STATUS_BAR))).thenReturn(true);
+
+        assertIsRotationLockEnforcedReturnsFalseForAllRotations();
+    }
+
+    @Test
+    public void testIsRotationLockEnforced_navBarVisible_lockNotEnforced() {
+        // Some system bars are visible
+        when(mMockInsetsVisibilities.getVisibility(eq(ITYPE_NAVIGATION_BAR))).thenReturn(true);
+
+        assertIsRotationLockEnforcedReturnsFalseForAllRotations();
+    }
+
+    @Test
+    public void testIsRotationLockEnforced_activityIsLetterboxed_lockNotEnforced() {
+        // Activity is letterboxed
+        when(mMockActivityRecord.areBoundsLetterboxed()).thenReturn(true);
+
+        assertIsRotationLockEnforcedReturnsFalseForAllRotations();
+    }
+
+    @Test
+    public void testIsRotationLockEnforced_notFullscreen_lockNotEnforced() {
+        when(mMockTask.getWindowingMode()).thenReturn(WINDOWING_MODE_MULTI_WINDOW);
+
+        assertIsRotationLockEnforcedReturnsFalseForAllRotations();
+
+        when(mMockTask.getWindowingMode()).thenReturn(WINDOWING_MODE_PINNED);
+
+        assertIsRotationLockEnforcedReturnsFalseForAllRotations();
+
+        when(mMockTask.getWindowingMode()).thenReturn(WINDOWING_MODE_FREEFORM);
+
+        assertIsRotationLockEnforcedReturnsFalseForAllRotations();
+    }
+
+    @Test
+    public void testIsRotationLockEnforced_ignoreOrientationRequestDisabled_lockNotEnforced() {
+        when(mDisplayContent.getIgnoreOrientationRequest()).thenReturn(false);
+
+        assertIsRotationLockEnforcedReturnsFalseForAllRotations();
+    }
+
+    @Test
+    public void testRotationChoiceEnforcedOnly_nullTopRunningActivity_lockNotEnforced() {
+        when(mDisplayContent.topRunningActivity()).thenReturn(null);
+
+        assertIsRotationLockEnforcedReturnsFalseForAllRotations();
+    }
+
+    @Test
+    public void testRotationChoiceEnforcedOnly_featureFlagDisabled_lockNotEnforced() {
+        when(mMockLetterboxConfiguration.isDisplayRotationImmersiveAppCompatPolicyEnabled(
+                /* checkDeviceConfig */ true)).thenReturn(false);
+
+        assertIsRotationLockEnforcedReturnsFalseForAllRotations();
+    }
+
+    private void assertIsRotationLockEnforcedReturnsFalseForAllRotations() {
+        assertFalse(mPolicy.isRotationLockEnforced(Surface.ROTATION_0));
+        assertFalse(mPolicy.isRotationLockEnforced(Surface.ROTATION_90));
+        assertFalse(mPolicy.isRotationLockEnforced(Surface.ROTATION_180));
+        assertFalse(mPolicy.isRotationLockEnforced(Surface.ROTATION_270));
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
index 491f876d..4ce43e1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
@@ -1096,8 +1096,16 @@
             mMockDisplayAddress = mock(DisplayAddress.class);
 
             mMockDisplayWindowSettings = mock(DisplayWindowSettings.class);
+
             mTarget = new DisplayRotation(sMockWm, mMockDisplayContent, mMockDisplayAddress,
-                    mMockDisplayPolicy, mMockDisplayWindowSettings, mMockContext, new Object());
+                    mMockDisplayPolicy, mMockDisplayWindowSettings, mMockContext, new Object()) {
+                @Override
+                DisplayRotationImmersiveAppCompatPolicy initImmersiveAppCompatPolicy(
+                        WindowManagerService service, DisplayContent displayContent) {
+                    return null;
+                }
+            };
+
             reset(sMockWm);
 
             captureObservers();
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
index c398a0a..fb4f2ee 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
@@ -236,8 +236,8 @@
 
     @Test
     public void testSetForcedDensity() {
-        mDisplayWindowSettings.setForcedDensity(mSecondaryDisplay, 600 /* density */,
-                0 /* userId */);
+        mDisplayWindowSettings.setForcedDensity(mSecondaryDisplay.getDisplayInfo(),
+                600 /* density */, 0 /* userId */);
         mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
 
         assertEquals(600 /* density */, mSecondaryDisplay.mBaseDisplayDensity);
@@ -439,8 +439,9 @@
     public void testDisplayWindowSettingsAppliedOnDisplayReady() {
         // Set forced densities for two displays in DisplayWindowSettings
         final DisplayContent dc = createMockSimulatedDisplay();
-        mDisplayWindowSettings.setForcedDensity(mPrimaryDisplay, 123, 0 /* userId */);
-        mDisplayWindowSettings.setForcedDensity(dc, 456, 0 /* userId */);
+        mDisplayWindowSettings.setForcedDensity(mPrimaryDisplay.getDisplayInfo(), 123,
+                0 /* userId */);
+        mDisplayWindowSettings.setForcedDensity(dc.getDisplayInfo(), 456, 0 /* userId */);
 
         // Apply settings to displays - the settings will be stored, but config will not be
         // recalculated immediately.
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationDeviceConfigTests.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationDeviceConfigTests.java
new file mode 100644
index 0000000..2b7a06b
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationDeviceConfigTests.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static com.android.server.wm.LetterboxConfigurationDeviceConfig.sKeyToDefaultValueMap;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.platform.test.annotations.Presubmit;
+import android.provider.DeviceConfig;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.modules.utils.testing.TestableDeviceConfig;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.Map;
+
+/**
+ * Test class for {@link LetterboxConfigurationDeviceConfig}.
+ *
+ * atest WmTests:LetterboxConfigurationDeviceConfigTests
+ */
+@SmallTest
+@Presubmit
+public class LetterboxConfigurationDeviceConfigTests {
+
+    private LetterboxConfigurationDeviceConfig mDeviceConfig;
+
+    @Rule
+    public final TestableDeviceConfig.TestableDeviceConfigRule
+            mDeviceConfigRule = new TestableDeviceConfig.TestableDeviceConfigRule();
+
+    @Before
+    public void setUp() {
+        mDeviceConfig = new LetterboxConfigurationDeviceConfig(/* executor */ Runnable::run);
+    }
+
+    @Test
+    public void testGetFlag_flagIsActive_flagChanges() throws Throwable {
+        for (Map.Entry<String, Boolean> entry : sKeyToDefaultValueMap.entrySet()) {
+            testGetFlagForKey_flagIsActive_flagChanges(entry.getKey(), entry.getValue());
+        }
+    }
+
+    private void testGetFlagForKey_flagIsActive_flagChanges(final String key, boolean defaultValue)
+            throws InterruptedException {
+        mDeviceConfig.updateFlagActiveStatus(/* isActive */ true, key);
+
+        assertEquals("Unexpected default value for " + key,
+                mDeviceConfig.getFlag(key), defaultValue);
+
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER, key,
+                /* value */ Boolean.TRUE.toString(), /* makeDefault */ false);
+
+        assertTrue("Flag " + key + "is not true after change", mDeviceConfig.getFlag(key));
+
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER, key,
+                /* value */ Boolean.FALSE.toString(), /* makeDefault */ false);
+
+        assertFalse("Flag " + key + "is not false after change", mDeviceConfig.getFlag(key));
+    }
+
+    @Test
+    public void testGetFlag_flagIsNotActive_alwaysReturnDefaultValue() throws Throwable {
+        for (Map.Entry<String, Boolean> entry : sKeyToDefaultValueMap.entrySet()) {
+            testGetFlagForKey_flagIsNotActive_alwaysReturnDefaultValue(
+                    entry.getKey(), entry.getValue());
+        }
+    }
+
+    private void testGetFlagForKey_flagIsNotActive_alwaysReturnDefaultValue(final String key,
+            boolean defaultValue) throws InterruptedException {
+        assertEquals("Unexpected default value for " + key,
+                mDeviceConfig.getFlag(key), defaultValue);
+
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER, key,
+                /* value */ Boolean.TRUE.toString(), /* makeDefault */ false);
+
+        assertEquals("Flag " + key + "is not set to default after change",
+                mDeviceConfig.getFlag(key), defaultValue);
+
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER, key,
+                /* value */ Boolean.FALSE.toString(), /* makeDefault */ false);
+
+        assertEquals("Flag " + key + "is not set to default after change",
+                mDeviceConfig.getFlag(key), defaultValue);
+    }
+
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java
index e196704..ead1a86 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java
@@ -18,6 +18,7 @@
 
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
+import static com.android.server.wm.LetterboxConfiguration.DEVICE_CONFIG_KEY_ENABLE_COMPAT_FAKE_FOCUS;
 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER;
 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT;
 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT;
@@ -25,6 +26,8 @@
 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER;
 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP;
 
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
@@ -34,6 +37,7 @@
 
 import android.content.Context;
 import android.platform.test.annotations.Presubmit;
+import android.provider.DeviceConfig;
 
 import androidx.test.filters.SmallTest;
 
@@ -43,18 +47,25 @@
 import java.util.Arrays;
 import java.util.function.BiConsumer;
 
+/**
+ * Tests for the {@link LetterboxConfiguration} class.
+ *
+ * Build/Install/Run:
+ *  atest WmTests:LetterboxConfigurationTests
+ */
 @SmallTest
 @Presubmit
 public class LetterboxConfigurationTest {
 
+    private Context mContext;
     private LetterboxConfiguration mLetterboxConfiguration;
     private LetterboxConfigurationPersister mLetterboxConfigurationPersister;
 
     @Before
     public void setUp() throws Exception {
-        Context context = getInstrumentation().getTargetContext();
+        mContext = getInstrumentation().getTargetContext();
         mLetterboxConfigurationPersister = mock(LetterboxConfigurationPersister.class);
-        mLetterboxConfiguration = new LetterboxConfiguration(context,
+        mLetterboxConfiguration = new LetterboxConfiguration(mContext,
                 mLetterboxConfigurationPersister);
     }
 
@@ -222,6 +233,34 @@
                 LetterboxConfiguration::movePositionForVerticalReachabilityToNextBottomStop);
     }
 
+    @Test
+    public void testIsCompatFakeFocusEnabledOnDevice() {
+        boolean wasFakeFocusEnabled = DeviceConfig
+                .getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+                DEVICE_CONFIG_KEY_ENABLE_COMPAT_FAKE_FOCUS, false);
+
+        // Set runtime flag to true and build time flag to false
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+                DEVICE_CONFIG_KEY_ENABLE_COMPAT_FAKE_FOCUS, "true", false);
+        mLetterboxConfiguration.setIsCompatFakeFocusEnabled(false);
+        assertFalse(mLetterboxConfiguration.isCompatFakeFocusEnabledOnDevice());
+
+        // Set runtime flag to false and build time flag to true
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+                DEVICE_CONFIG_KEY_ENABLE_COMPAT_FAKE_FOCUS, "false", false);
+        mLetterboxConfiguration.setIsCompatFakeFocusEnabled(true);
+        assertFalse(mLetterboxConfiguration.isCompatFakeFocusEnabledOnDevice());
+
+        // Set runtime flag to true so that both are enabled
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+                DEVICE_CONFIG_KEY_ENABLE_COMPAT_FAKE_FOCUS, "true", false);
+        assertTrue(mLetterboxConfiguration.isCompatFakeFocusEnabledOnDevice());
+
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+                DEVICE_CONFIG_KEY_ENABLE_COMPAT_FAKE_FOCUS, Boolean.toString(wasFakeFocusEnabled),
+                false);
+    }
+
     private void assertForHorizontalMove(int from, int expected, int expectedTime,
             boolean halfFoldPose, BiConsumer<LetterboxConfiguration, Boolean> move) {
         // We are in the current position
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
new file mode 100644
index 0000000..5e087f0
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
+import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION;
+import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH;
+import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
+import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyString;
+
+import android.compat.testing.PlatformCompatChangeRule;
+import android.content.ComponentName;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.Property;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+
+import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+
+ /**
+ * Test class for {@link LetterboxUiControllerTest}.
+ *
+ * Build/Install/Run:
+ *  atest WmTests:LetterboxUiControllerTest
+ */
+@SmallTest
+@Presubmit
+@RunWith(WindowTestRunner.class)
+public class LetterboxUiControllerTest extends WindowTestsBase {
+
+    @Rule
+    public TestRule compatChangeRule = new PlatformCompatChangeRule();
+
+    private ActivityRecord mActivity;
+    private DisplayContent mDisplayContent;
+    private LetterboxUiController mController;
+    private LetterboxConfiguration mLetterboxConfiguration;
+
+    @Before
+    public void setUp() throws Exception {
+        mActivity = setUpActivityWithComponent();
+
+        mLetterboxConfiguration = mWm.mLetterboxConfiguration;
+        spyOn(mLetterboxConfiguration);
+
+        mController = new LetterboxUiController(mWm, mActivity);
+    }
+
+    // shouldIgnoreRequestedOrientation
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
+    public void testShouldIgnoreRequestedOrientation_activityRelaunching_returnsTrue() {
+        prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch();
+
+        assertTrue(mController.shouldIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED));
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
+    public void testShouldIgnoreRequestedOrientation_cameraCompatTreatment_returnsTrue() {
+        doReturn(true).when(mLetterboxConfiguration).isCameraCompatTreatmentEnabled(anyBoolean());
+
+        // Recreate DisplayContent with DisplayRotationCompatPolicy
+        mActivity = setUpActivityWithComponent();
+        mController = new LetterboxUiController(mWm, mActivity);
+        prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch();
+        mController.setRelauchingAfterRequestedOrientationChanged(false);
+
+        spyOn(mDisplayContent.mDisplayRotationCompatPolicy);
+        doReturn(true).when(mDisplayContent.mDisplayRotationCompatPolicy)
+                .isTreatmentEnabledForActivity(eq(mActivity));
+
+        assertTrue(mController.shouldIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED));
+    }
+
+    @Test
+    public void testShouldIgnoreRequestedOrientation_overrideDisabled_returnsFalse() {
+        prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch();
+
+        assertFalse(mController.shouldIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED));
+    }
+
+    @Test
+    public void testShouldIgnoreRequestedOrientation_propertyIsTrue_returnsTrue()
+            throws Exception {
+        doReturn(true).when(mLetterboxConfiguration)
+                .isPolicyForIgnoringRequestedOrientationEnabled();
+        mockThatProperty(PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION, /* value */ true);
+        mController = new LetterboxUiController(mWm, mActivity);
+        prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch();
+
+        assertTrue(mController.shouldIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED));
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
+    public void testShouldIgnoreRequestedOrientation_propertyIsFalseAndOverride_returnsFalse()
+            throws Exception {
+        doReturn(true).when(mLetterboxConfiguration)
+                .isPolicyForIgnoringRequestedOrientationEnabled();
+        mockThatProperty(PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION, /* value */ false);
+
+        mController = new LetterboxUiController(mWm, mActivity);
+        prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch();
+
+        assertFalse(mController.shouldIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED));
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
+    public void testShouldIgnoreRequestedOrientation_flagIsDisabled_returnsFalse() {
+        prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch();
+        doReturn(false).when(mLetterboxConfiguration)
+                .isPolicyForIgnoringRequestedOrientationEnabled();
+
+        assertFalse(mController.shouldIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED));
+    }
+
+    // shouldRefreshActivityForCameraCompat
+
+    @Test
+    public void testShouldRefreshActivityForCameraCompat_flagIsDisabled_returnsFalse() {
+        doReturn(false).when(mLetterboxConfiguration)
+                .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+
+        assertFalse(mController.shouldRefreshActivityForCameraCompat());
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
+    public void testShouldRefreshActivityForCameraCompat_overrideEnabled_returnsFalse() {
+        doReturn(true).when(mLetterboxConfiguration)
+                .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+
+        assertFalse(mController.shouldRefreshActivityForCameraCompat());
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
+    public void testShouldRefreshActivityForCameraCompat_propertyIsTrueAndOverride_returnsFalse()
+            throws Exception {
+        doReturn(true).when(mLetterboxConfiguration)
+                .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+        mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH, /* value */ true);
+
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertFalse(mController.shouldRefreshActivityForCameraCompat());
+    }
+
+    @Test
+    public void testShouldRefreshActivityForCameraCompat_propertyIsFalse_returnsFalse()
+            throws Exception {
+        doReturn(true).when(mLetterboxConfiguration)
+                .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+        mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH, /* value */ false);
+
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertFalse(mController.shouldRefreshActivityForCameraCompat());
+    }
+
+    @Test
+    public void testShouldRefreshActivityForCameraCompat_propertyIsTrue_returnsTrue()
+            throws Exception {
+        doReturn(true).when(mLetterboxConfiguration)
+                .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+        mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH, /* value */ true);
+
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertTrue(mController.shouldRefreshActivityForCameraCompat());
+    }
+
+    // shouldRefreshActivityViaPauseForCameraCompat
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE})
+    public void testShouldRefreshActivityViaPauseForCameraCompat_flagIsDisabled_returnsFalse() {
+        doReturn(false).when(mLetterboxConfiguration)
+                .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+
+        assertFalse(mController.shouldRefreshActivityViaPauseForCameraCompat());
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE})
+    public void testShouldRefreshActivityViaPauseForCameraCompat_overrideEnabled_returnsTrue() {
+        doReturn(true).when(mLetterboxConfiguration)
+                .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+
+        assertTrue(mController.shouldRefreshActivityViaPauseForCameraCompat());
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE})
+    public void testShouldRefreshActivityViaPauseForCameraCompat_propertyIsFalseAndOverride_returnFalse()
+            throws Exception {
+        doReturn(true).when(mLetterboxConfiguration)
+                .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+        mockThatProperty(PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE, /* value */ false);
+
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertFalse(mController.shouldRefreshActivityViaPauseForCameraCompat());
+    }
+
+    @Test
+    public void testShouldRefreshActivityViaPauseForCameraCompat_propertyIsTrue_returnsTrue()
+            throws Exception {
+        doReturn(true).when(mLetterboxConfiguration)
+                .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+        mockThatProperty(PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE, /* value */ true);
+
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertTrue(mController.shouldRefreshActivityViaPauseForCameraCompat());
+    }
+
+    // shouldForceRotateForCameraCompat
+
+    @Test
+    public void testShouldForceRotateForCameraCompat_flagIsDisabled_returnsFalse() {
+        doReturn(false).when(mLetterboxConfiguration)
+                .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+
+        assertFalse(mController.shouldForceRotateForCameraCompat());
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION})
+    public void testShouldForceRotateForCameraCompat_overrideEnabled_returnsFalse() {
+        doReturn(true).when(mLetterboxConfiguration)
+                .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+
+        assertFalse(mController.shouldForceRotateForCameraCompat());
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION})
+    public void testShouldForceRotateForCameraCompat_propertyIsTrueAndOverride_returnsFalse()
+            throws Exception {
+        doReturn(true).when(mLetterboxConfiguration)
+                .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+        mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION, /* value */ true);
+
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertFalse(mController.shouldForceRotateForCameraCompat());
+    }
+
+    @Test
+    public void testShouldForceRotateForCameraCompat_propertyIsFalse_returnsFalse()
+            throws Exception {
+        doReturn(true).when(mLetterboxConfiguration)
+                .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+        mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION, /* value */ false);
+
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertFalse(mController.shouldForceRotateForCameraCompat());
+    }
+
+    @Test
+    public void testShouldForceRotateForCameraCompat_propertyIsTrue_returnsTrue()
+            throws Exception {
+        doReturn(true).when(mLetterboxConfiguration)
+                .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+        mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION, /* value */ true);
+
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertTrue(mController.shouldForceRotateForCameraCompat());
+    }
+
+    private void mockThatProperty(String propertyName, boolean value) throws Exception {
+        Property property = new Property(propertyName, /* value */ value, /* packageName */ "",
+                 /* className */ "");
+        PackageManager pm = mWm.mContext.getPackageManager();
+        spyOn(pm);
+        doReturn(property).when(pm).getProperty(eq(propertyName), anyString());
+    }
+
+    private void prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch() {
+        doReturn(true).when(mLetterboxConfiguration)
+                .isPolicyForIgnoringRequestedOrientationEnabled();
+        mController.setRelauchingAfterRequestedOrientationChanged(true);
+    }
+
+    private ActivityRecord setUpActivityWithComponent() {
+        mDisplayContent = new TestDisplayContent
+                .Builder(mAtm, /* dw */ 1000, /* dh */ 2000).build();
+        Task task = new TaskBuilder(mSupervisor).setDisplay(mDisplayContent).build();
+        final ActivityRecord activity = new ActivityBuilder(mAtm)
+                .setOnTop(true)
+                .setTask(task)
+                // Set the component to be that of the test class in order to enable compat changes
+                .setComponent(ComponentName.createRelative(mContext,
+                        com.android.server.wm.LetterboxUiControllerTest.class.getName()))
+                .build();
+        return activity;
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 0462e1b..db6ac0b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -1222,10 +1222,11 @@
     @Test
     public void testCreateRecentTaskInfo_detachedTask() {
         final Task task = createTaskBuilder(".Task").build();
+        final ComponentName componentName = getUniqueComponentName();
         new ActivityBuilder(mSupervisor.mService)
                 .setTask(task)
                 .setUid(NOBODY_UID)
-                .setComponent(getUniqueComponentName())
+                .setComponent(componentName)
                 .build();
         final TaskDisplayArea tda = task.getDisplayArea();
 
@@ -1240,9 +1241,9 @@
         info = mRecentTasks.createRecentTaskInfo(task, true /* stripExtras */,
                 false /* getTasksAllowed */);
 
-        assertTrue(info.topActivity == null);
-        assertTrue(info.topActivityInfo == null);
-        assertTrue(info.baseActivity == null);
+        assertFalse(info.topActivity.equals(componentName));
+        assertFalse(info.topActivityInfo.packageName.equals(componentName.getPackageName()));
+        assertFalse(info.baseActivity.equals(componentName));
 
         // The task can be put in split screen even if it is not attached now.
         task.removeImmediately();
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 7488e1c..e5ff91f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -53,6 +53,8 @@
 import static com.android.server.wm.ActivityRecord.State.RESUMED;
 import static com.android.server.wm.ActivityRecord.State.STOPPED;
 import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING;
+import static com.android.server.wm.LetterboxConfiguration.PROPERTY_COMPAT_FAKE_FOCUS_OPT_IN;
+import static com.android.server.wm.LetterboxConfiguration.PROPERTY_COMPAT_FAKE_FOCUS_OPT_OUT;
 import static com.android.server.wm.WindowContainer.POSITION_TOP;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -195,27 +197,6 @@
     }
 
     @Test
-    public void testNotApplyStrategyToTranslucentActivitiesWithDifferentUid() {
-        mWm.mLetterboxConfiguration.setTranslucentLetterboxingOverrideEnabled(true);
-        setUpDisplaySizeWithApp(2000, 1000);
-        prepareUnresizable(mActivity, 1.5f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
-        mActivity.info.setMinAspectRatio(1.2f);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
-        // Translucent Activity
-        final ActivityRecord translucentActivity = new ActivityBuilder(mAtm)
-                .setScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE)
-                .setMinAspectRatio(1.1f)
-                .setMaxAspectRatio(3f)
-                .build();
-        doReturn(false).when(translucentActivity).fillsParent();
-        mTask.addChild(translucentActivity);
-        // We check bounds
-        final Rect opaqueBounds = mActivity.getConfiguration().windowConfiguration.getBounds();
-        final Rect translucentRequestedBounds = translucentActivity.getRequestedOverrideBounds();
-        assertNotEquals(opaqueBounds, translucentRequestedBounds);
-    }
-
-    @Test
     public void testApplyStrategyToMultipleTranslucentActivities() {
         mWm.mLetterboxConfiguration.setTranslucentLetterboxingOverrideEnabled(true);
         setUpDisplaySizeWithApp(2000, 1000);
@@ -1615,6 +1596,79 @@
     }
 
     @Test
+    public void testComputeConfigResourceOverrides_unresizableApp() {
+        // Set up a display in landscape and ignoring orientation request.
+        setUpDisplaySizeWithApp(2800, 1400);
+        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+
+        prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
+
+        final Rect activityBounds = new Rect(mActivity.getBounds());
+
+        int originalScreenWidthDp = mActivity.getConfiguration().screenWidthDp;
+        int originalScreenHeighthDp = mActivity.getConfiguration().screenHeightDp;
+
+        // App should launch in fixed orientation letterbox.
+        // Activity bounds should be 700x1400 with the ratio as the display.
+        assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+        assertFitted();
+        assertEquals(originalScreenWidthDp, mActivity.getConfiguration().smallestScreenWidthDp);
+        assertTrue(originalScreenWidthDp < originalScreenHeighthDp);
+
+        // Rotate display to portrait.
+        rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
+
+        // After we rotate, the activity should go in the size-compat mode and report the same
+        // configuration values.
+        assertScaled();
+        assertEquals(originalScreenWidthDp, mActivity.getConfiguration().smallestScreenWidthDp);
+        assertEquals(originalScreenWidthDp, mActivity.getConfiguration().screenWidthDp);
+        assertEquals(originalScreenHeighthDp, mActivity.getConfiguration().screenHeightDp);
+
+        // Restart activity
+        mActivity.restartProcessIfVisible();
+
+        // Now configuration should be updated
+        assertFitted();
+        assertNotEquals(originalScreenWidthDp, mActivity.getConfiguration().screenWidthDp);
+        assertNotEquals(originalScreenHeighthDp, mActivity.getConfiguration().screenHeightDp);
+        assertEquals(mActivity.getConfiguration().screenWidthDp,
+                mActivity.getConfiguration().smallestScreenWidthDp);
+    }
+
+    @Test
+    public void testComputeConfigResourceOverrides_resizableFixedOrientationActivity() {
+        // Set up a display in landscape and ignoring orientation request.
+        setUpDisplaySizeWithApp(2800, 1400);
+        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+
+        // Portrait fixed app without max aspect.
+        prepareLimitedBounds(mActivity, SCREEN_ORIENTATION_PORTRAIT, false /* isUnresizable */);
+
+        final Rect activityBounds = new Rect(mActivity.getBounds());
+
+        int originalScreenWidthDp = mActivity.getConfiguration().screenWidthDp;
+        int originalScreenHeighthDp = mActivity.getConfiguration().screenHeightDp;
+
+        // App should launch in fixed orientation letterbox.
+        // Activity bounds should be 700x1400 with the ratio as the display.
+        assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+        assertFitted();
+        assertEquals(originalScreenWidthDp, mActivity.getConfiguration().smallestScreenWidthDp);
+        assertTrue(originalScreenWidthDp < originalScreenHeighthDp);
+
+        // Rotate display to portrait.
+        rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
+
+        // Now configuration should be updated
+        assertFitted();
+        assertNotEquals(originalScreenWidthDp, mActivity.getConfiguration().screenWidthDp);
+        assertNotEquals(originalScreenHeighthDp, mActivity.getConfiguration().screenHeightDp);
+        assertEquals(mActivity.getConfiguration().screenWidthDp,
+                mActivity.getConfiguration().smallestScreenWidthDp);
+    }
+
+    @Test
     public void testSplitAspectRatioForUnresizablePortraitApps() {
         // Set up a display in landscape and ignoring orientation request.
         int screenWidth = 1600;
@@ -1858,6 +1912,132 @@
     }
 
     @Test
+    public void testDisplayAspectRatioForResizablePortraitApps() {
+        // Set up a display in portrait and ignoring orientation request.
+        int displayWidth = 1400;
+        int displayHeight = 1600;
+        setUpDisplaySizeWithApp(displayWidth, displayHeight);
+        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        mWm.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(2f);
+
+        // Enable display aspect ratio to take precedence before
+        // fixedOrientationLetterboxAspectRatio
+        mWm.mLetterboxConfiguration
+                .setIsDisplayAspectRatioEnabledForFixedOrientationLetterbox(true);
+
+        // Set up resizable app in portrait
+        prepareLimitedBounds(mActivity, SCREEN_ORIENTATION_PORTRAIT, false /* isUnresizable */);
+
+        final TestSplitOrganizer organizer =
+                new TestSplitOrganizer(mAtm, mActivity.getDisplayContent());
+        // Move activity to split screen which takes half of the screen.
+        mTask.reparent(organizer.mPrimary, POSITION_TOP, /* moveParents= */ false , "test");
+        organizer.mPrimary.setBounds(0, 0, displayWidth, getExpectedSplitSize(displayHeight));
+        assertEquals(WINDOWING_MODE_MULTI_WINDOW, mTask.getWindowingMode());
+        assertEquals(WINDOWING_MODE_MULTI_WINDOW, mActivity.getWindowingMode());
+
+        // App should launch in fixed orientation letterbox.
+        assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+        // Checking that there is no size compat mode.
+        assertFitted();
+        // Check that the display aspect ratio is used by the app.
+        final float targetMinAspectRatio = 1f * displayHeight / displayWidth;
+        final float delta = 0.01f;
+        assertEquals(targetMinAspectRatio, ActivityRecord
+                .computeAspectRatio(mActivity.getBounds()), delta);
+    }
+
+    @Test
+    public void testDisplayAspectRatioForResizableLandscapeApps() {
+        // Set up a display in landscape and ignoring orientation request.
+        int displayWidth = 1600;
+        int displayHeight = 1400;
+        setUpDisplaySizeWithApp(displayWidth, displayHeight);
+        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        mWm.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(2f);
+
+        // Enable display aspect ratio to take precedence before
+        // fixedOrientationLetterboxAspectRatio
+        mWm.mLetterboxConfiguration
+                .setIsDisplayAspectRatioEnabledForFixedOrientationLetterbox(true);
+
+        // Set up resizable app in landscape
+        prepareLimitedBounds(mActivity, SCREEN_ORIENTATION_LANDSCAPE, false /* isUnresizable */);
+
+        final TestSplitOrganizer organizer =
+                new TestSplitOrganizer(mAtm, mActivity.getDisplayContent());
+        // Move activity to split screen which takes half of the screen.
+        mTask.reparent(organizer.mPrimary, POSITION_TOP, /* moveParents= */ false , "test");
+        organizer.mPrimary.setBounds(0, 0, getExpectedSplitSize(displayWidth), displayHeight);
+        assertEquals(WINDOWING_MODE_MULTI_WINDOW, mTask.getWindowingMode());
+        assertEquals(WINDOWING_MODE_MULTI_WINDOW, mActivity.getWindowingMode());
+
+        // App should launch in fixed orientation letterbox.
+        assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+        // Checking that there is no size compat mode.
+        assertFitted();
+        // Check that the display aspect ratio is used by the app.
+        final float targetMinAspectRatio = 1f * displayWidth / displayHeight;
+        final float delta = 0.01f;
+        assertEquals(targetMinAspectRatio, ActivityRecord
+                .computeAspectRatio(mActivity.getBounds()), delta);
+    }
+
+    @Test
+    public void testDisplayAspectRatioForUnresizableLandscapeApps() {
+        // Set up a display in portrait and ignoring orientation request.
+        int displayWidth = 1400;
+        int displayHeight = 1600;
+        setUpDisplaySizeWithApp(displayWidth, displayHeight);
+        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+
+        mActivity.mWmService.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(1.1f);
+        // Enable display aspect ratio to take precedence before
+        // fixedOrientationLetterboxAspectRatio
+        mWm.mLetterboxConfiguration
+                .setIsDisplayAspectRatioEnabledForFixedOrientationLetterbox(true);
+
+        prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
+
+        // App should launch in fixed orientation letterbox.
+        assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+        // Checking that there is no size compat mode.
+        assertFitted();
+        // Check that the display aspect ratio is used by the app.
+        final float targetMinAspectRatio = 1f * displayHeight / displayWidth;
+        final float delta = 0.01f;
+        assertEquals(targetMinAspectRatio, ActivityRecord
+                .computeAspectRatio(mActivity.getBounds()), delta);
+    }
+
+    @Test
+    public void testDisplayAspectRatioForUnresizablePortraitApps() {
+        // Set up a display in landscape and ignoring orientation request.
+        int displayWidth = 1600;
+        int displayHeight = 1400;
+        setUpDisplaySizeWithApp(displayWidth, displayHeight);
+        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+
+        mActivity.mWmService.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(1.1f);
+        // Enable display aspect ratio to take precedence before
+        // fixedOrientationLetterboxAspectRatio
+        mWm.mLetterboxConfiguration
+                .setIsDisplayAspectRatioEnabledForFixedOrientationLetterbox(true);
+
+        prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
+
+        // App should launch in fixed orientation letterbox.
+        assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+        // Checking that there is no size compat mode.
+        assertFitted();
+        // Check that the display aspect ratio is used by the app.
+        final float targetMinAspectRatio = 1f * displayWidth / displayHeight;
+        final float delta = 0.01f;
+        assertEquals(targetMinAspectRatio, ActivityRecord
+                .computeAspectRatio(mActivity.getBounds()), delta);
+    }
+
+    @Test
     public void
             testDisplayIgnoreOrientationRequest_orientationLetterboxBecameSizeCompatAfterRotate() {
         // Set up a display in landscape and ignoring orientation request.
@@ -3228,6 +3408,80 @@
         assertEquals(newDensity, mActivity.getConfiguration().densityDpi);
     }
 
+    private ActivityRecord setUpActivityForCompatFakeFocusTest() {
+        final ActivityRecord activity = new ActivityBuilder(mAtm)
+                .setCreateTask(true)
+                .setOnTop(true)
+                // Set the component to be that of the test class in order to enable compat changes
+                .setComponent(ComponentName.createRelative(mContext,
+                        com.android.server.wm.SizeCompatTests.class.getName()))
+                .build();
+        final Task task = activity.getTask();
+        task.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+        spyOn(activity.mWmService.mLetterboxConfiguration);
+        doReturn(true).when(activity.mWmService.mLetterboxConfiguration)
+                .isCompatFakeFocusEnabledOnDevice();
+        return activity;
+    }
+
+    @Test
+    @EnableCompatChanges({ActivityInfo.OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS})
+    public void testShouldSendFakeFocus_overrideEnabled_returnsTrue() {
+        ActivityRecord activity = setUpActivityForCompatFakeFocusTest();
+
+        assertTrue(activity.shouldSendCompatFakeFocus());
+    }
+
+    @Test
+    @DisableCompatChanges({ActivityInfo.OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS})
+    public void testShouldSendFakeFocus_overrideDisabled_returnsFalse() {
+        ActivityRecord activity = setUpActivityForCompatFakeFocusTest();
+
+        assertFalse(activity.shouldSendCompatFakeFocus());
+    }
+
+    @Test
+    @EnableCompatChanges({ActivityInfo.OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS})
+    public void testIsCompatFakeFocusEnabled_optOutPropertyAndOverrideEnabled_fakeFocusDisabled() {
+        ActivityRecord activity = setUpActivityForCompatFakeFocusTest();
+        doReturn(true).when(activity.mWmService.mLetterboxConfiguration)
+                .getPackageManagerProperty(any(), eq(PROPERTY_COMPAT_FAKE_FOCUS_OPT_OUT));
+
+        assertFalse(activity.mWmService.mLetterboxConfiguration
+                .isCompatFakeFocusEnabled(activity.info));
+    }
+
+    @Test
+    @DisableCompatChanges({ActivityInfo.OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS})
+    public void testIsCompatFakeFocusEnabled_optInPropertyEnabled_noOverride_fakeFocusEnabled() {
+        ActivityRecord activity = setUpActivityForCompatFakeFocusTest();
+        doReturn(true).when(activity.mWmService.mLetterboxConfiguration)
+                .getPackageManagerProperty(any(), eq(PROPERTY_COMPAT_FAKE_FOCUS_OPT_IN));
+
+        assertTrue(activity.mWmService.mLetterboxConfiguration
+                .isCompatFakeFocusEnabled(activity.info));
+    }
+
+    @Test
+    public void testIsCompatFakeFocusEnabled_optOutPropertyEnabled_fakeFocusDisabled() {
+        ActivityRecord activity = setUpActivityForCompatFakeFocusTest();
+        doReturn(true).when(activity.mWmService.mLetterboxConfiguration)
+                .getPackageManagerProperty(any(), eq(PROPERTY_COMPAT_FAKE_FOCUS_OPT_OUT));
+
+        assertFalse(activity.mWmService.mLetterboxConfiguration
+                .isCompatFakeFocusEnabled(activity.info));
+    }
+
+    @Test
+    public void testIsCompatFakeFocusEnabled_optInPropertyEnabled_fakeFocusEnabled() {
+        ActivityRecord activity = setUpActivityForCompatFakeFocusTest();
+        doReturn(true).when(activity.mWmService.mLetterboxConfiguration)
+                .getPackageManagerProperty(any(), eq(PROPERTY_COMPAT_FAKE_FOCUS_OPT_IN));
+
+        assertTrue(activity.mWmService.mLetterboxConfiguration
+                .isCompatFakeFocusEnabled(activity.info));
+    }
+
     private int getExpectedSplitSize(int dimensionToSplit) {
         int dividerWindowWidth =
                 mActivity.mWmService.mContext.getResources().getDimensionPixelSize(
diff --git a/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java b/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java
index df7b3cd..aff9c1a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java
@@ -31,6 +31,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
@@ -108,9 +109,7 @@
         bse.onSurfacePlacement();
         verify(listener, times(0)).onTransactionReady(anyInt(), any());
 
-        mockWC.onSyncFinishedDrawing();
-        // Make sure the second traversal is requested.
-        verify(mWm.mWindowPlacerLocked, times(2)).requestTraversal();
+        assertTrue(mockWC.onSyncFinishedDrawing());
         bse.onSurfacePlacement();
         verify(listener, times(1)).onTransactionReady(eq(id), notNull());
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
index 140051d..8244f94 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
@@ -19,6 +19,7 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.view.Display.DEFAULT_DISPLAY;
+import static android.window.TaskFragmentOperation.OP_TYPE_SET_ANIMATION_PARAMS;
 import static android.window.TaskFragmentOrganizer.KEY_ERROR_CALLBACK_OP_TYPE;
 import static android.window.TaskFragmentOrganizer.KEY_ERROR_CALLBACK_THROWABLE;
 import static android.window.TaskFragmentOrganizer.getTransitionType;
@@ -66,6 +67,7 @@
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
+import android.graphics.Color;
 import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Binder;
@@ -76,8 +78,10 @@
 import android.view.RemoteAnimationDefinition;
 import android.view.SurfaceControl;
 import android.window.ITaskFragmentOrganizer;
+import android.window.TaskFragmentAnimationParams;
 import android.window.TaskFragmentCreationParams;
 import android.window.TaskFragmentInfo;
+import android.window.TaskFragmentOperation;
 import android.window.TaskFragmentOrganizer;
 import android.window.TaskFragmentOrganizerToken;
 import android.window.TaskFragmentParentInfo;
@@ -676,6 +680,57 @@
     }
 
     @Test
+    public void testApplyTransaction_enforceTaskFragmentOrganized_setTaskFragmentOperation() {
+        final Task task = createTask(mDisplayContent);
+        mTaskFragment = new TaskFragmentBuilder(mAtm)
+                .setParentTask(task)
+                .setFragmentToken(mFragmentToken)
+                .build();
+        mWindowOrganizerController.mLaunchTaskFragments.put(mFragmentToken, mTaskFragment);
+        final TaskFragmentOperation operation = new TaskFragmentOperation.Builder(
+                OP_TYPE_SET_ANIMATION_PARAMS)
+                .setAnimationParams(TaskFragmentAnimationParams.DEFAULT)
+                .build();
+        mTransaction.setTaskFragmentOperation(mFragmentToken, operation);
+        mOrganizer.applyTransaction(mTransaction);
+
+        // Not allowed because TaskFragment is not organized by the caller organizer.
+        assertApplyTransactionDisallowed(mTransaction);
+
+        mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */,
+                "Test:TaskFragmentOrganizer" /* processName */);
+
+        assertApplyTransactionAllowed(mTransaction);
+    }
+
+    @Test
+    public void testSetTaskFragmentOperation() {
+        final Task task = createTask(mDisplayContent);
+        mTaskFragment = new TaskFragmentBuilder(mAtm)
+                .setParentTask(task)
+                .setOrganizer(mOrganizer)
+                .setFragmentToken(mFragmentToken)
+                .build();
+        assertEquals(TaskFragmentAnimationParams.DEFAULT, mTaskFragment.getAnimationParams());
+
+        mWindowOrganizerController.mLaunchTaskFragments.put(mFragmentToken, mTaskFragment);
+        final TaskFragmentAnimationParams animationParams =
+                new TaskFragmentAnimationParams.Builder()
+                        .setAnimationBackgroundColor(Color.GREEN)
+                        .build();
+        final TaskFragmentOperation operation = new TaskFragmentOperation.Builder(
+                OP_TYPE_SET_ANIMATION_PARAMS)
+                .setAnimationParams(animationParams)
+                .build();
+        mTransaction.setTaskFragmentOperation(mFragmentToken, operation);
+        mOrganizer.applyTransaction(mTransaction);
+        assertApplyTransactionAllowed(mTransaction);
+
+        assertEquals(animationParams, mTaskFragment.getAnimationParams());
+        assertEquals(Color.GREEN, mTaskFragment.getAnimationParams().getAnimationBackgroundColor());
+    }
+
+    @Test
     public void testApplyTransaction_createTaskFragment_failForDifferentUid() {
         final ActivityRecord activity = createActivityRecord(mDisplayContent);
         final int uid = Binder.getCallingUid();
@@ -741,6 +796,72 @@
     }
 
     @Test
+    public void testApplyTransaction_createTaskFragment_overrideBounds() {
+        final Task task = createTask(mDisplayContent);
+        final ActivityRecord activityAtBottom = createActivityRecord(task);
+        final int uid = Binder.getCallingUid();
+        activityAtBottom.info.applicationInfo.uid = uid;
+        activityAtBottom.getTask().effectiveUid = uid;
+        mTaskFragment = new TaskFragmentBuilder(mAtm)
+                .setParentTask(task)
+                .setFragmentToken(mFragmentToken)
+                .createActivityCount(1)
+                .build();
+        mWindowOrganizerController.mLaunchTaskFragments.put(mFragmentToken, mTaskFragment);
+        final IBinder fragmentToken1 = new Binder();
+        final Rect bounds = new Rect(100, 100, 500, 1000);
+        final TaskFragmentCreationParams params = new TaskFragmentCreationParams.Builder(
+                mOrganizerToken, fragmentToken1, activityAtBottom.token)
+                .setPairedActivityToken(activityAtBottom.token)
+                .setInitialBounds(bounds)
+                .build();
+        mTransaction.setTaskFragmentOrganizer(mIOrganizer);
+        mTransaction.createTaskFragment(params);
+        assertApplyTransactionAllowed(mTransaction);
+
+        // Successfully created a TaskFragment.
+        final TaskFragment taskFragment = mWindowOrganizerController.getTaskFragment(
+                fragmentToken1);
+        assertNotNull(taskFragment);
+        // The relative embedded bounds is updated to the initial requested bounds.
+        assertEquals(bounds, taskFragment.getRelativeEmbeddedBounds());
+    }
+
+    @Test
+    public void testApplyTransaction_createTaskFragment_withPairedActivityToken() {
+        final Task task = createTask(mDisplayContent);
+        final ActivityRecord activityAtBottom = createActivityRecord(task);
+        final int uid = Binder.getCallingUid();
+        activityAtBottom.info.applicationInfo.uid = uid;
+        activityAtBottom.getTask().effectiveUid = uid;
+        mTaskFragment = new TaskFragmentBuilder(mAtm)
+                .setParentTask(task)
+                .setFragmentToken(mFragmentToken)
+                .createActivityCount(1)
+                .build();
+        mWindowOrganizerController.mLaunchTaskFragments.put(mFragmentToken, mTaskFragment);
+        final IBinder fragmentToken1 = new Binder();
+        final TaskFragmentCreationParams params = new TaskFragmentCreationParams.Builder(
+                mOrganizerToken, fragmentToken1, activityAtBottom.token)
+                .setPairedActivityToken(activityAtBottom.token)
+                .build();
+        mTransaction.setTaskFragmentOrganizer(mIOrganizer);
+        mTransaction.createTaskFragment(params);
+        assertApplyTransactionAllowed(mTransaction);
+
+        // Successfully created a TaskFragment.
+        final TaskFragment taskFragment = mWindowOrganizerController.getTaskFragment(
+                fragmentToken1);
+        assertNotNull(taskFragment);
+        // The new TaskFragment should be positioned right above the paired activity.
+        assertEquals(task.mChildren.indexOf(activityAtBottom) + 1,
+                task.mChildren.indexOf(taskFragment));
+        // The top TaskFragment should remain on top.
+        assertEquals(task.mChildren.indexOf(taskFragment) + 1,
+                task.mChildren.indexOf(mTaskFragment));
+    }
+
+    @Test
     public void testApplyTransaction_enforceHierarchyChange_reparentChildren() {
         doReturn(true).when(mTaskFragment).isAttached();
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
index bf1d1fa..d31ae6a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
@@ -203,6 +203,7 @@
             }
 
             final int displayId = SystemServicesTestRule.sNextDisplayId++;
+            mInfo.displayId = displayId;
             final Display display = new Display(DisplayManagerGlobal.getInstance(), displayId,
                     mInfo, DEFAULT_DISPLAY_ADJUSTMENTS);
             final TestDisplayContent newDisplay = createInternal(display);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
index 06a79f4..1407cdd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
@@ -391,7 +391,7 @@
         dc.updateOrientation();
         dc.sendNewConfiguration();
         spyOn(wallpaperWindow);
-        doReturn(new Rect(0, 0, width, height)).when(wallpaperWindow).getLastReportedBounds();
+        doReturn(new Rect(0, 0, width, height)).when(wallpaperWindow).getParentFrame();
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index df3b306..fa98537 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -1240,7 +1240,8 @@
         assertTrue(w1.useBLASTSync());
         assertTrue(w2.useBLASTSync());
 
-        w1.immediatelyNotifyBlastSync();
+        // A drawn window can complete the sync state automatically.
+        w1.mWinAnimator.mDrawState = WindowStateAnimator.HAS_DRAWN;
         mWm.mSyncEngine.onSurfacePlacement();
         verify(mockCallback).onTransactionReady(anyInt(), any());
         assertFalse(w1.useBLASTSync());
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 650286a..fd3776f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -42,6 +42,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
@@ -544,7 +545,12 @@
         win.applyWithNextDraw(t -> handledT[0] = t);
         assertTrue(win.useBLASTSync());
         final SurfaceControl.Transaction drawT = new StubTransaction();
+        final SurfaceControl.Transaction currT = win.getSyncTransaction();
+        clearInvocations(currT);
+        win.mWinAnimator.mLastHidden = true;
         assertTrue(win.finishDrawing(drawT, Integer.MAX_VALUE));
+        // The draw transaction should be merged to current transaction even if the state is hidden.
+        verify(currT).merge(eq(drawT));
         assertEquals(drawT, handledT[0]);
         assertFalse(win.useBLASTSync());
 
@@ -969,6 +975,19 @@
         assertFalse(sameTokenWindow.needsRelativeLayeringToIme());
     }
 
+    @UseTestDisplay(addWindows = {W_ACTIVITY, W_INPUT_METHOD})
+    @Test
+    public void testNeedsRelativeLayeringToIme_systemDialog() {
+        WindowState systemDialogWindow = createWindow(null, TYPE_SECURE_SYSTEM_OVERLAY,
+                mDisplayContent,
+                "SystemDialog", true);
+        mDisplayContent.setImeLayeringTarget(mAppWindow);
+        mAppWindow.getRootTask().setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+        makeWindowVisible(mImeWindow);
+        systemDialogWindow.mAttrs.flags |= FLAG_ALT_FOCUSABLE_IM;
+        assertTrue(systemDialogWindow.needsRelativeLayeringToIme());
+    }
+
     @Test
     public void testSetFreezeInsetsState() {
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
@@ -1032,6 +1051,9 @@
         // Simulate app requests IME with updating all windows Insets State when IME is above app.
         mDisplayContent.setImeLayeringTarget(app);
         mDisplayContent.setImeInputTarget(app);
+        final InsetsVisibilities requestedVisibilities = new InsetsVisibilities();
+        requestedVisibilities.setVisibility(ITYPE_IME, true);
+        app.setRequestedVisibilities(requestedVisibilities);
         assertTrue(mDisplayContent.shouldImeAttachedToApp());
         controller.getImeSourceProvider().scheduleShowImePostLayout(app);
         controller.getImeSourceProvider().getSource().setVisible(true);
@@ -1069,6 +1091,9 @@
         app2.mActivityRecord.mImeInsetsFrozenUntilStartInput = true;
         mDisplayContent.setImeLayeringTarget(app);
         mDisplayContent.setImeInputTarget(app);
+        final InsetsVisibilities requestedVisibilities = new InsetsVisibilities();
+        requestedVisibilities.setVisibility(ITYPE_IME, true);
+        app.setRequestedVisibilities(requestedVisibilities);
         assertTrue(mDisplayContent.shouldImeAttachedToApp());
         controller.getImeSourceProvider().scheduleShowImePostLayout(app);
         controller.getImeSourceProvider().getSource().setVisible(true);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 268aa3e..f8b8094 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -253,6 +253,12 @@
         // device form factors.
         mAtm.mWindowManager.mLetterboxConfiguration
                 .setIsSplitScreenAspectRatioForUnresizableAppsEnabled(false);
+        // Ensure aspect ratio for al apps isn't overridden on any device target.
+        // {@link com.android.internal.R.bool
+        // .config_letterboxIsDisplayAspectRatioForFixedOrientationLetterboxEnabled}, may be set on
+        // some device form factors.
+        mAtm.mWindowManager.mLetterboxConfiguration
+                .setIsDisplayAspectRatioEnabledForFixedOrientationLetterbox(false);
 
         checkDeviceSpecificOverridesNotApplied();
     }
@@ -267,6 +273,8 @@
         mAtm.mWindowManager.mLetterboxConfiguration.resetIsVerticalReachabilityEnabled();
         mAtm.mWindowManager.mLetterboxConfiguration
                 .resetIsSplitScreenAspectRatioForUnresizableAppsEnabled();
+        mAtm.mWindowManager.mLetterboxConfiguration
+                .resetIsDisplayAspectRatioEnabledForFixedOrientationLetterbox();
     }
 
     /**
diff --git a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
index 77fca45..7959d82 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
@@ -22,6 +22,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
@@ -31,6 +32,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
@@ -543,4 +545,28 @@
         assertZOrderGreaterThan(mTransaction, popupWindow.getSurfaceControl(),
                 mDisplayContent.getImeContainer().getSurfaceControl());
     }
+
+    @Test
+    public void testSystemDialogWindow_expectHigherThanIme_inMultiWindow() {
+        // Simulate the app window is in multi windowing mode and being IME target
+        mAppWindow.getConfiguration().windowConfiguration.setWindowingMode(
+                WINDOWING_MODE_MULTI_WINDOW);
+        mDisplayContent.setImeLayeringTarget(mAppWindow);
+        mDisplayContent.setImeInputTarget(mAppWindow);
+        makeWindowVisible(mImeWindow);
+
+        // Create a popupWindow
+        final WindowState systemDialogWindow = createWindow(null, TYPE_SECURE_SYSTEM_OVERLAY,
+                mDisplayContent, "SystemDialog", true);
+        systemDialogWindow.mAttrs.flags |= FLAG_ALT_FOCUSABLE_IM;
+        spyOn(systemDialogWindow);
+
+        mDisplayContent.assignChildLayers(mTransaction);
+
+        // Verify the surface layer of the popupWindow should higher than IME
+        verify(systemDialogWindow).needsRelativeLayeringToIme();
+        assertThat(systemDialogWindow.needsRelativeLayeringToIme()).isTrue();
+        assertZOrderGreaterThan(mTransaction, systemDialogWindow.getSurfaceControl(),
+                mDisplayContent.getImeContainer().getSurfaceControl());
+    }
 }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index 55bf2ab..1c57ba5 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -55,6 +55,7 @@
 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECTED;
 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECTED_FROM_RESTART;
 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECT_UNEXPECTED_CALLBACK;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__SERVICE_CRASH;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -1152,6 +1153,11 @@
                     Slog.w(TAG, "Failed to report onError status: " + e);
                 }
             }
+            // Can improve to log exit reason if needed
+            HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+                    mDetectorType,
+                    HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__SERVICE_CRASH,
+                    mVoiceInteractionServiceUid);
         }
 
         @Override
diff --git a/telephony/java/android/telephony/AccessNetworkUtils.java b/telephony/java/android/telephony/AccessNetworkUtils.java
index b5d97ab..c2a9864 100644
--- a/telephony/java/android/telephony/AccessNetworkUtils.java
+++ b/telephony/java/android/telephony/AccessNetworkUtils.java
@@ -4,8 +4,8 @@
 import static android.telephony.ServiceState.DUPLEX_MODE_TDD;
 import static android.telephony.ServiceState.DUPLEX_MODE_UNKNOWN;
 
-import android.telephony.AccessNetworkConstants.EutranBandArfcnFrequency;
 import android.telephony.AccessNetworkConstants.EutranBand;
+import android.telephony.AccessNetworkConstants.EutranBandArfcnFrequency;
 import android.telephony.AccessNetworkConstants.GeranBand;
 import android.telephony.AccessNetworkConstants.GeranBandArfcnFrequency;
 import android.telephony.AccessNetworkConstants.NgranArfcnFrequency;
@@ -13,7 +13,6 @@
 import android.telephony.AccessNetworkConstants.UtranBand;
 import android.telephony.AccessNetworkConstants.UtranBandArfcnFrequency;
 import android.telephony.ServiceState.DuplexMode;
-import android.util.Log;
 
 import java.util.Arrays;
 import java.util.HashSet;
@@ -232,6 +231,108 @@
     }
 
     /**
+     * Gets the NR Operating band for a given downlink NRARFCN.
+     *
+     * <p>See 3GPP TS 38.104 Table 5.2-1 NR operating bands in FR1 and
+     * Table 5.2-2 NR operating bands in FR2
+     *
+     * @param nrarfcn The downlink NRARFCN
+     * @return Operating band number, or {@link #INVALID_BAND} if no corresponding band exists
+     */
+    public static int getOperatingBandForNrarfcn(int nrarfcn) {
+        if (nrarfcn >= 422000 && nrarfcn <= 434000) {
+            return NgranBands.BAND_1;
+        } else if (nrarfcn >= 386000 && nrarfcn <= 398000) {
+            return NgranBands.BAND_2;
+        } else if (nrarfcn >= 361000 && nrarfcn <= 376000) {
+            return NgranBands.BAND_3;
+        } else if (nrarfcn >= 173800 && nrarfcn <= 178800) {
+            return NgranBands.BAND_5;
+        } else if (nrarfcn >= 524000 && nrarfcn <= 538000) {
+            return NgranBands.BAND_7;
+        } else if (nrarfcn >= 185000 && nrarfcn <= 192000) {
+            return NgranBands.BAND_8;
+        } else if (nrarfcn >= 145800 && nrarfcn <= 149200) {
+            return NgranBands.BAND_12;
+        } else if (nrarfcn >= 151600 && nrarfcn <= 153600) {
+            return NgranBands.BAND_14;
+        } else if (nrarfcn >= 172000 && nrarfcn <= 175000) {
+            return NgranBands.BAND_18;
+        } else if (nrarfcn >= 158200 && nrarfcn <= 164200) {
+            return NgranBands.BAND_20;
+        } else if (nrarfcn >= 386000 && nrarfcn <= 399000) {
+            return NgranBands.BAND_25;
+        } else if (nrarfcn >= 171800 && nrarfcn <= 178800) {
+            return NgranBands.BAND_26;
+        } else if (nrarfcn >= 151600 && nrarfcn <= 160600) {
+            return NgranBands.BAND_28;
+        } else if (nrarfcn >= 143400 && nrarfcn <= 145600) {
+            return NgranBands.BAND_29;
+        } else if (nrarfcn >= 470000 && nrarfcn <= 472000) {
+            return NgranBands.BAND_30;
+        } else if (nrarfcn >= 402000 && nrarfcn <= 405000) {
+            return NgranBands.BAND_34;
+        } else if (nrarfcn >= 514000 && nrarfcn <= 524000) {
+            return NgranBands.BAND_38;
+        } else if (nrarfcn >= 376000 && nrarfcn <= 384000) {
+            return NgranBands.BAND_39;
+        } else if (nrarfcn >= 460000 && nrarfcn <= 480000) {
+            return NgranBands.BAND_40;
+        } else if (nrarfcn >= 499200 && nrarfcn <= 537999) {
+            return NgranBands.BAND_41;
+        } else if (nrarfcn >= 743334 && nrarfcn <= 795000) {
+            return NgranBands.BAND_46;
+        } else if (nrarfcn >= 636667 && nrarfcn <= 646666) {
+            return NgranBands.BAND_48;
+        } else if (nrarfcn >= 286400 && nrarfcn <= 303400) {
+            return NgranBands.BAND_50;
+        } else if (nrarfcn >= 285400 && nrarfcn <= 286400) {
+            return NgranBands.BAND_51;
+        } else if (nrarfcn >= 496700 && nrarfcn <= 499000) {
+            return NgranBands.BAND_53;
+        } else if (nrarfcn >= 422000 && nrarfcn <= 440000) {
+            return NgranBands.BAND_65; // BAND_66 has the same channels
+        } else if (nrarfcn >= 399000 && nrarfcn <= 404000) {
+            return NgranBands.BAND_70;
+        } else if (nrarfcn >= 123400 && nrarfcn <= 130400) {
+            return NgranBands.BAND_71;
+        } else if (nrarfcn >= 295000 && nrarfcn <= 303600) {
+            return NgranBands.BAND_74;
+        } else if (nrarfcn >= 286400 && nrarfcn <= 303400) {
+            return NgranBands.BAND_75;
+        } else if (nrarfcn >= 285400 && nrarfcn <= 286400) {
+            return NgranBands.BAND_76;
+        } else if (nrarfcn >= 620000 && nrarfcn <= 680000) {
+            return NgranBands.BAND_77;
+        } else if (nrarfcn >= 620000 && nrarfcn <= 653333) {
+            return NgranBands.BAND_78;
+        } else if (nrarfcn >= 693334 && nrarfcn <= 733333) {
+            return NgranBands.BAND_79;
+        } else if (nrarfcn >= 499200 && nrarfcn <= 538000) {
+            return NgranBands.BAND_90;
+        } else if (nrarfcn >= 285400 && nrarfcn <= 286400) {
+            return NgranBands.BAND_91;
+        } else if (nrarfcn >= 286400 && nrarfcn <= 303400) {
+            return NgranBands.BAND_92;
+        } else if (nrarfcn >= 285400 && nrarfcn <= 286400) {
+            return NgranBands.BAND_93;
+        } else if (nrarfcn >= 286400 && nrarfcn <= 303400) {
+            return NgranBands.BAND_94;
+        } else if (nrarfcn >= 795000 && nrarfcn <= 875000) {
+            return NgranBands.BAND_96;
+        } else if (nrarfcn >= 2054166 && nrarfcn <= 2104165) {
+            return NgranBands.BAND_257;
+        } else if (nrarfcn >= 2016667 && nrarfcn <= 2070832) {
+            return NgranBands.BAND_258;
+        } else if (nrarfcn >= 2229166 && nrarfcn <= 2279165) {
+            return NgranBands.BAND_260;
+        } else if (nrarfcn >= 2070833 && nrarfcn <= 2084999) {
+            return NgranBands.BAND_261;
+        }
+        return INVALID_BAND;
+    }
+
+    /**
      * Gets the GERAN Operating band for a given ARFCN.
      *
      * <p>See 3GPP TS 45.005 clause 2 for calculation.
diff --git a/telephony/java/android/telephony/NetworkScanRequest.java b/telephony/java/android/telephony/NetworkScanRequest.java
index 326f417..65c2146 100644
--- a/telephony/java/android/telephony/NetworkScanRequest.java
+++ b/telephony/java/android/telephony/NetworkScanRequest.java
@@ -26,7 +26,7 @@
 import java.util.Arrays;
 
 /**
- * Defines a request to peform a network scan.
+ * Defines a request to perform a network scan.
  *
  * This class defines whether the network scan will be performed only once or periodically until
  * cancelled, when the scan is performed periodically, the time interval is not controlled by the
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
index 28307d2..4836c9f 100644
--- a/telephony/java/android/telephony/SmsMessage.java
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -1031,6 +1031,15 @@
     }
 
     /**
+     * Check if format of the message is 3GPP.
+     *
+     * @hide
+     */
+    public boolean is3gpp() {
+        return (mWrappedSmsMessage instanceof com.android.internal.telephony.gsm.SmsMessage);
+    }
+
+    /**
      * Determines whether or not to use CDMA format for MO SMS.
      * If SMS over IMS is supported, then format is based on IMS SMS format,
      * otherwise format is based on current phone type.
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/NotificationTest.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/NotificationTest.java
index 47f87d6..573b3b69 100644
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/NotificationTest.java
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/NotificationTest.java
@@ -102,6 +102,7 @@
     @After
     public void tearDown() {
         mNotificationManager.cancelAll();
+        mUiDevice.pressHome();
     }
 
     @Test